diff options
Diffstat (limited to 'drivers/isdn/hardware')
114 files changed, 48189 insertions, 26647 deletions
diff --git a/drivers/isdn/hardware/Kconfig b/drivers/isdn/hardware/Kconfig index 139f1979771..30d028d2495 100644 --- a/drivers/isdn/hardware/Kconfig +++ b/drivers/isdn/hardware/Kconfig @@ -2,7 +2,6 @@ # ISDN hardware drivers # comment "CAPI hardware drivers" - depends on NET && ISDN && ISDN_CAPI source "drivers/isdn/hardware/avm/Kconfig" diff --git a/drivers/isdn/hardware/Makefile b/drivers/isdn/hardware/Makefile index 11c8a183948..a5d8fce4c4c 100644 --- a/drivers/isdn/hardware/Makefile +++ b/drivers/isdn/hardware/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_CAPI_AVM) += avm/ obj-$(CONFIG_CAPI_EICON) += eicon/ +obj-$(CONFIG_MISDN) += mISDN/ diff --git a/drivers/isdn/hardware/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig index 29a32a8830c..b99b906ea9b 100644 --- a/drivers/isdn/hardware/avm/Kconfig +++ b/drivers/isdn/hardware/avm/Kconfig @@ -2,23 +2,22 @@ # ISDN AVM drivers # -menu "Active AVM cards" - depends on NET && ISDN && ISDN_CAPI!=n - -config CAPI_AVM - bool "Support AVM cards" +menuconfig CAPI_AVM + bool "Active AVM cards" help Enable support for AVM active ISDN cards. +if CAPI_AVM + config ISDN_DRV_AVMB1_B1ISA tristate "AVM B1 ISA support" - depends on CAPI_AVM && ISDN_CAPI && ISA + depends on ISA help Enable support for the ISA version of the AVM B1 card. config ISDN_DRV_AVMB1_B1PCI tristate "AVM B1 PCI support" - depends on CAPI_AVM && ISDN_CAPI && PCI + depends on PCI help Enable support for the PCI version of the AVM B1 card. @@ -30,37 +29,36 @@ config ISDN_DRV_AVMB1_B1PCIV4 config ISDN_DRV_AVMB1_T1ISA tristate "AVM T1/T1-B ISA support" - depends on CAPI_AVM && ISDN_CAPI && ISA + depends on ISA help Enable support for the AVM T1 T1B card. Note: This is a PRI card and handle 30 B-channels. config ISDN_DRV_AVMB1_B1PCMCIA tristate "AVM B1/M1/M2 PCMCIA support" - depends on CAPI_AVM && ISDN_CAPI + depends on PCMCIA help Enable support for the PCMCIA version of the AVM B1 card. config ISDN_DRV_AVMB1_AVM_CS tristate "AVM B1/M1/M2 PCMCIA cs module" - depends on ISDN_DRV_AVMB1_B1PCMCIA && PCMCIA + depends on ISDN_DRV_AVMB1_B1PCMCIA help Enable the PCMCIA client driver for the AVM B1/M1/M2 PCMCIA cards. config ISDN_DRV_AVMB1_T1PCI tristate "AVM T1/T1-B PCI support" - depends on CAPI_AVM && ISDN_CAPI && PCI + depends on PCI help Enable support for the AVM T1 T1B card. Note: This is a PRI card and handle 30 B-channels. config ISDN_DRV_AVMB1_C4 tristate "AVM C4/C2 support" - depends on CAPI_AVM && ISDN_CAPI && PCI + depends on PCI help Enable support for the AVM C4/C2 PCI cards. These cards handle 4/2 BRI ISDN lines (8/4 channels). -endmenu - +endif # CAPI_AVM diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 2a2b03ff096..62b8030ee33 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -12,18 +12,13 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/sched.h> #include <linux/ptrace.h> -#include <linux/slab.h> #include <linux/string.h> #include <linux/tty.h> #include <linux/serial.h> #include <linux/major.h> #include <asm/io.h> -#include <asm/system.h> -#include <pcmcia/cs_types.h> -#include <pcmcia/cs.h> #include <pcmcia/cistpl.h> #include <pcmcia/ciscode.h> #include <pcmcia/ds.h> @@ -42,381 +37,118 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ -/* - The event() function is this driver's Card Services event handler. - It will be called by Card Services when an appropriate card status - event is received. The config() and release() entry points are - used to configure or release a socket, in response to card insertion - and ejection events. They are invoked from the skeleton event - handler. -*/ - -static void avmcs_config(dev_link_t *link); -static void avmcs_release(dev_link_t *link); - -/* - The attach() and detach() entry points are used to create and destroy - "instances" of the driver, where each instance represents everything - needed to manage one actual PCMCIA card. -*/ - +static int avmcs_config(struct pcmcia_device *link); +static void avmcs_release(struct pcmcia_device *link); static void avmcs_detach(struct pcmcia_device *p_dev); -/* - A linked list of "instances" of the skeleton device. Each actual - PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). - - You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor - device numbers are used to derive the corresponding array index. -*/ - -/* - A driver needs to provide a dev_node_t structure for each device - on a card. In some cases, there is only one device per card (for - example, ethernet cards, modems). In other cases, there may be - many actual or logical devices (SCSI adapters, memory cards with - multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a dev_link_t - structure. We allocate them in the card's private data structure, - because they generally can't be allocated dynamically. -*/ - -typedef struct local_info_t { - dev_node_t node; -} local_info_t; - -/*====================================================================== - - avmcs_attach() creates an "instance" of the driver, allocating - local data structures for one device. The device is registered - with Card Services. - - The dev_link structure is initialized, but we don't actually - configure the card at this point -- we wait until we receive a - card insertion event. - -======================================================================*/ - -static int avmcs_attach(struct pcmcia_device *p_dev) +static int avmcs_probe(struct pcmcia_device *p_dev) { - dev_link_t *link; - local_info_t *local; + /* General socket configuration */ + p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; + p_dev->config_index = 1; + p_dev->config_regs = PRESENT_OPTION; - /* Initialize the dev_link_t structure */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - if (!link) - goto err; - memset(link, 0, sizeof(struct dev_link_t)); - - /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.NumPorts2 = 0; - - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; - - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - - /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; - - /* Allocate space for private device-specific data */ - local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) - goto err_kfree; - memset(local, 0, sizeof(local_info_t)); - link->priv = local; - - link->handle = p_dev; - p_dev->instance = link; - - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - avmcs_config(link); - - return 0; - - err_kfree: - kfree(link); - err: - return -EINVAL; + return avmcs_config(p_dev); } /* avmcs_attach */ -/*====================================================================== - - This deletes a driver "instance". The device is de-registered - with Card Services. If it has been released, all local data - structures are freed. Otherwise, the structures will be freed - when the device is released. -======================================================================*/ - -static void avmcs_detach(struct pcmcia_device *p_dev) +static void avmcs_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); - - if (link->state & DEV_CONFIG) avmcs_release(link); - - kfree(link->priv); - kfree(link); } /* avmcs_detach */ -/*====================================================================== - - avmcs_config() is scheduled to run after a CARD_INSERTION event - is received, to configure the PCMCIA socket, and to make the - ethernet device available to the system. - -======================================================================*/ - -static int get_tuple(client_handle_t handle, tuple_t *tuple, - cisparse_t *parse) +static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data) { - int i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) return i; - return pcmcia_parse_tuple(handle, tuple, parse); -} - -static int first_tuple(client_handle_t handle, tuple_t *tuple, - cisparse_t *parse) -{ - int i = pcmcia_get_first_tuple(handle, tuple); - if (i != CS_SUCCESS) return i; - return get_tuple(handle, tuple, parse); -} + p_dev->resource[0]->end = 16; + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; -static int next_tuple(client_handle_t handle, tuple_t *tuple, - cisparse_t *parse) -{ - int i = pcmcia_get_next_tuple(handle, tuple); - if (i != CS_SUCCESS) return i; - return get_tuple(handle, tuple, parse); + return pcmcia_request_io(p_dev); } -static void avmcs_config(dev_link_t *link) +static int avmcs_config(struct pcmcia_device *link) { - client_handle_t handle; - tuple_t tuple; - cisparse_t parse; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; - local_info_t *dev; - int i; - u_char buf[64]; - char devname[128]; - int cardtype; - int (*addcard)(unsigned int port, unsigned irq); - - handle = link->handle; - dev = link->priv; - - /* - This reads the card's CONFIG tuple to find its configuration - registers. - */ - do { - tuple.DesiredTuple = CISTPL_CONFIG; - i = pcmcia_get_first_tuple(handle, &tuple); - if (i != CS_SUCCESS) break; - tuple.TupleData = buf; - tuple.TupleDataMax = 64; - tuple.TupleOffset = 0; - i = pcmcia_get_tuple_data(handle, &tuple); - if (i != CS_SUCCESS) break; - i = pcmcia_parse_tuple(handle, &tuple, &parse); - if (i != CS_SUCCESS) break; - link->conf.ConfigBase = parse.config.base; - } while (0); - if (i != CS_SUCCESS) { - cs_error(link->handle, ParseTuple, i); - link->state &= ~DEV_CONFIG_PENDING; - return; - } - - /* Configure card */ - link->state |= DEV_CONFIG; - - do { - - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = 254; - tuple.TupleOffset = 0; - tuple.DesiredTuple = CISTPL_VERS_1; + int i = -1; + char devname[128]; + int cardtype; + int (*addcard)(unsigned int port, unsigned irq); devname[0] = 0; - if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { - strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], - sizeof(devname)); - } - /* - * find IO port - */ - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleOffset = 0; tuple.TupleDataMax = 255; - tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(handle, &tuple, &parse); - while (i == CS_SUCCESS) { - if (cf->io.nwin > 0) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - link->io.NumPorts1 = cf->io.win[0].len; - link->io.NumPorts2 = 0; - printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", - link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - i = pcmcia_request_io(link->handle, &link->io); - if (i == CS_SUCCESS) goto found_port; - } - i = next_tuple(handle, &tuple, &parse); - } + if (link->prod_id[1]) + strlcpy(devname, link->prod_id[1], sizeof(devname)); -found_port: - if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIO, i); - break; - } - /* - * allocate an interrupt line + * find IO port */ - i = pcmcia_request_irq(link->handle, &link->irq); - if (i != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, i); - pcmcia_release_io(link->handle, &link->io); - break; + if (pcmcia_loop_config(link, avmcs_configcheck, NULL)) + return -ENODEV; + + do { + if (!link->irq) { + /* undo */ + pcmcia_disable_device(link); + break; + } + + /* + * configure the PCMCIA socket + */ + i = pcmcia_enable_device(link); + if (i != 0) { + pcmcia_disable_device(link); + break; + } + + } while (0); + + if (devname[0]) { + char *s = strrchr(devname, ' '); + if (!s) + s = devname; + else s++; + if (strcmp("M1", s) == 0) { + cardtype = AVM_CARDTYPE_M1; + } else if (strcmp("M2", s) == 0) { + cardtype = AVM_CARDTYPE_M2; + } else { + cardtype = AVM_CARDTYPE_B1; + } + } else + cardtype = AVM_CARDTYPE_B1; + + /* If any step failed, release any partially configured state */ + if (i != 0) { + avmcs_release(link); + return -ENODEV; } - - /* - * configure the PCMCIA socket - */ - i = pcmcia_request_configuration(link->handle, &link->conf); - if (i != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, i); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - break; - } - - } while (0); - /* At this point, the dev_node_t structure(s) should be - initialized and arranged in a linked list at link->dev. */ - if (devname[0]) { - char *s = strrchr(devname, ' '); - if (!s) - s = devname; - else s++; - strcpy(dev->node.dev_name, s); - if (strcmp("M1", s) == 0) { - cardtype = AVM_CARDTYPE_M1; - } else if (strcmp("M2", s) == 0) { - cardtype = AVM_CARDTYPE_M2; - } else { - cardtype = AVM_CARDTYPE_B1; - } - } else { - strcpy(dev->node.dev_name, "b1"); - cardtype = AVM_CARDTYPE_B1; - } - - dev->node.major = 64; - dev->node.minor = 0; - link->dev = &dev->node; - - link->state &= ~DEV_CONFIG_PENDING; - /* If any step failed, release any partially configured state */ - if (i != 0) { - avmcs_release(link); - return; - } - - - switch (cardtype) { - case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break; - case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break; + switch (cardtype) { + case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break; + case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break; default: - case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; - } - if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { - printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", - dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); - avmcs_release(link); - return; - } - dev->node.minor = i; + case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; + } + if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) { + dev_err(&link->dev, + "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n", + (unsigned int) link->resource[0]->start, link->irq); + avmcs_release(link); + return -ENODEV; + } + return 0; } /* avmcs_config */ -/*====================================================================== - - After a card is removed, avmcs_release() will unregister the net - device, and release the PCMCIA configuration. If the device is - still open, this will be postponed until it is closed. - -======================================================================*/ -static void avmcs_release(dev_link_t *link) +static void avmcs_release(struct pcmcia_device *link) { - b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ); - - /* Unlink the device chain */ - link->dev = NULL; - - /* Don't bother checking to see if these succeed or not */ - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); - link->state &= ~DEV_CONFIG; + b1pcmcia_delcard(link->resource[0]->start, link->irq); + pcmcia_disable_device(link); } /* avmcs_release */ -static int avmcs_suspend(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state |= DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - - return 0; -} -static int avmcs_resume(struct pcmcia_device *dev) -{ - dev_link_t *link = dev_to_instance(dev); - - link->state &= ~DEV_SUSPEND; - if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); - - return 0; -} - -/*====================================================================== - - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. A CARD_REMOVAL event - also sets some flags to discourage the net drivers from trying - to talk to the card any more. - - When a CARD_REMOVAL event is received, we immediately set a flag - to block future accesses to this device. All the functions that - actually access the device should check this flag to make sure - the card is still present. - -======================================================================*/ - - -static struct pcmcia_device_id avmcs_ids[] = { +static const struct pcmcia_device_id avmcs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M1", 0x95d42008, 0x81e10430), PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M2", 0x95d42008, 0x18e8558a), @@ -426,25 +158,9 @@ MODULE_DEVICE_TABLE(pcmcia, avmcs_ids); static struct pcmcia_driver avmcs_driver = { .owner = THIS_MODULE, - .drv = { - .name = "avm_cs", - }, - .probe = avmcs_attach, + .name = "avm_cs", + .probe = avmcs_probe, .remove = avmcs_detach, .id_table = avmcs_ids, - .suspend= avmcs_suspend, - .resume = avmcs_resume, }; - -static int __init avmcs_init(void) -{ - return pcmcia_register_driver(&avmcs_driver); -} - -static void __exit avmcs_exit(void) -{ - pcmcia_unregister_driver(&avmcs_driver); -} - -module_init(avmcs_init); -module_exit(avmcs_exit); +module_pcmcia_driver(avmcs_driver); diff --git a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h index 296d6a6f749..c95712dbfa9 100644 --- a/drivers/isdn/hardware/avm/avmcard.h +++ b/drivers/isdn/hardware/avm/avmcard.h @@ -44,16 +44,16 @@ enum avmcardtype { }; typedef struct avmcard_dmabuf { - long size; - u8 *dmabuf; - dma_addr_t dmaaddr; + long size; + u8 *dmabuf; + dma_addr_t dmaaddr; } avmcard_dmabuf; typedef struct avmcard_dmainfo { u32 recvlen; - avmcard_dmabuf recvbuf; + avmcard_dmabuf recvbuf; - avmcard_dmabuf sendbuf; + avmcard_dmabuf sendbuf; struct sk_buff_head send_queue; struct pci_dev *pcidev; @@ -61,22 +61,22 @@ typedef struct avmcard_dmainfo { typedef struct avmctrl_info { char cardname[32]; - + int versionlen; char versionbuf[1024]; char *version[AVM_MAXVERSION]; - + char infobuf[128]; /* for function procinfo */ - + struct avmcard *card; struct capi_ctr capi_ctrl; - + struct list_head ncci_head; } avmctrl_info; typedef struct avmcard { char name[32]; - + spinlock_t lock; unsigned int port; unsigned irq; @@ -103,95 +103,95 @@ typedef struct avmcard { extern int b1_irq_table[16]; /* - * LLI Messages to the ISDN-ControllerISDN Controller + * LLI Messages to the ISDN-ControllerISDN Controller */ #define SEND_POLL 0x72 /* - * after load <- RECEIVE_POLL + * after load <- RECEIVE_POLL */ #define SEND_INIT 0x11 /* - * first message <- RECEIVE_INIT - * int32 NumApplications int32 - * NumNCCIs int32 BoardNumber + * first message <- RECEIVE_INIT + * int32 NumApplications int32 + * NumNCCIs int32 BoardNumber */ #define SEND_REGISTER 0x12 /* - * register an application int32 - * ApplIDId int32 NumMessages - * int32 NumB3Connections int32 - * NumB3Blocks int32 B3Size - * - * AnzB3Connection != 0 && - * AnzB3Blocks >= 1 && B3Size >= 1 + * register an application int32 + * ApplIDId int32 NumMessages + * int32 NumB3Connections int32 + * NumB3Blocks int32 B3Size + * + * AnzB3Connection != 0 && + * AnzB3Blocks >= 1 && B3Size >= 1 */ #define SEND_RELEASE 0x14 /* - * deregister an application int32 - * ApplID + * deregister an application int32 + * ApplID */ #define SEND_MESSAGE 0x15 /* - * send capi-message int32 length - * capi-data ... + * send capi-message int32 length + * capi-data ... */ #define SEND_DATA_B3_REQ 0x13 /* - * send capi-data-message int32 - * MsgLength capi-data ... int32 - * B3Length data .... + * send capi-data-message int32 + * MsgLength capi-data ... int32 + * B3Length data .... */ #define SEND_CONFIG 0x21 /* - */ + */ #define SEND_POLLACK 0x73 /* T1 Watchdog */ /* - * LLI Messages from the ISDN-ControllerISDN Controller + * LLI Messages from the ISDN-ControllerISDN Controller */ #define RECEIVE_POLL 0x32 /* - * <- after SEND_POLL + * <- after SEND_POLL */ #define RECEIVE_INIT 0x27 /* - * <- after SEND_INIT int32 length - * byte total length b1struct board - * driver revision b1struct card - * type b1struct reserved b1struct - * serial number b1struct driver - * capability b1struct d-channel - * protocol b1struct CAPI-2.0 - * profile b1struct capi version + * <- after SEND_INIT int32 length + * byte total length b1struct board + * driver revision b1struct card + * type b1struct reserved b1struct + * serial number b1struct driver + * capability b1struct d-channel + * protocol b1struct CAPI-2.0 + * profile b1struct capi version */ #define RECEIVE_MESSAGE 0x21 /* - * <- after SEND_MESSAGE int32 - * AppllID int32 Length capi-data - * .... + * <- after SEND_MESSAGE int32 + * AppllID int32 Length capi-data + * .... */ #define RECEIVE_DATA_B3_IND 0x22 /* - * received data int32 AppllID - * int32 Length capi-data ... - * int32 B3Length data ... + * received data int32 AppllID + * int32 Length capi-data ... + * int32 B3Length data ... */ #define RECEIVE_START 0x23 /* - * Handshake + * Handshake */ #define RECEIVE_STOP 0x24 /* - * Handshake + * Handshake */ #define RECEIVE_NEW_NCCI 0x25 /* - * int32 AppllID int32 NCCI int32 - * WindowSize + * int32 AppllID int32 NCCI int32 + * WindowSize */ #define RECEIVE_FREE_NCCI 0x26 /* - * int32 AppllID int32 NCCI + * int32 AppllID int32 NCCI */ #define RECEIVE_RELEASE 0x26 /* - * int32 AppllID int32 0xffffffff + * int32 AppllID int32 0xffffffff */ #define RECEIVE_TASK_READY 0x31 /* - * int32 tasknr - * int32 Length Taskname ... + * int32 tasknr + * int32 Length Taskname ... */ #define RECEIVE_DEBUGMSG 0x71 /* - * int32 Length message - * + * int32 Length message + * */ #define RECEIVE_POLLDWORD 0x75 /* t1pci in dword mode */ @@ -264,7 +264,7 @@ static inline void b1_put_byte(unsigned int base, unsigned char val) static inline int b1_save_put_byte(unsigned int base, unsigned char val) { unsigned long stop = jiffies + 2 * HZ; - while (!b1_tx_empty(base) && time_before(jiffies,stop)); + while (!b1_tx_empty(base) && time_before(jiffies, stop)); if (!b1_tx_empty(base)) return -1; b1outp(base, B1_WRITE, val); return 0; @@ -298,21 +298,21 @@ static inline void b1_put_slice(unsigned int base, } static void b1_wr_reg(unsigned int base, - unsigned int reg, + unsigned int reg, unsigned int value) { b1_put_byte(base, WRITE_REGISTER); - b1_put_word(base, reg); - b1_put_word(base, value); + b1_put_word(base, reg); + b1_put_word(base, value); } static inline unsigned int b1_rd_reg(unsigned int base, - unsigned int reg) + unsigned int reg) { b1_put_byte(base, READ_REGISTER); - b1_put_word(base, reg); - return b1_get_word(base); - + b1_put_word(base, reg); + return b1_get_word(base); + } static inline void b1_reset(unsigned int base) @@ -338,13 +338,13 @@ static inline void b1_set_test_bit(unsigned int base, enum avmcardtype cardtype, int onoff) { - b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20); + b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20); } static inline int b1_get_test_bit(unsigned int base, - enum avmcardtype cardtype) + enum avmcardtype cardtype) { - return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0; + return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0; } /* ---------------------------------------------------------------- */ @@ -391,7 +391,7 @@ static inline void t1outp(unsigned int base, } static inline unsigned char t1inp(unsigned int base, - unsigned short offset) + unsigned short offset) { return inb(base + offset); } @@ -415,44 +415,42 @@ static inline unsigned int t1_get_slice(unsigned int base, #endif len = i = b1_get_word(base); - if (t1_isfastlink(base)) { + if (t1_isfastlink(base)) { int status; while (i > 0) { - status = t1_fifostatus(base) & (T1F_IREADY|T1F_IHALF); + status = t1_fifostatus(base) & (T1F_IREADY | T1F_IHALF); if (i >= FIFO_INPBSIZE) status |= T1F_IFULL; switch (status) { - case T1F_IREADY|T1F_IHALF|T1F_IFULL: - insb(base+B1_READ, dp, FIFO_INPBSIZE); - dp += FIFO_INPBSIZE; - i -= FIFO_INPBSIZE; + case T1F_IREADY | T1F_IHALF | T1F_IFULL: + insb(base + B1_READ, dp, FIFO_INPBSIZE); + dp += FIFO_INPBSIZE; + i -= FIFO_INPBSIZE; #ifdef FASTLINK_DEBUG - wcnt += FIFO_INPBSIZE; + wcnt += FIFO_INPBSIZE; #endif - break; - case T1F_IREADY|T1F_IHALF: - insb(base+B1_READ,dp, i); + break; + case T1F_IREADY | T1F_IHALF: + insb(base + B1_READ, dp, i); #ifdef FASTLINK_DEBUG - wcnt += i; + wcnt += i; #endif - dp += i; - i = 0; - if (i == 0) - break; - /* fall through */ - default: - *dp++ = b1_get_byte(base); - i--; + dp += i; + i = 0; + break; + default: + *dp++ = b1_get_byte(base); + i--; #ifdef FASTLINK_DEBUG - bcnt++; + bcnt++; #endif - break; + break; } - } + } #ifdef FASTLINK_DEBUG - if (wcnt) - printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n", - base, len, wcnt, bcnt); + if (wcnt) + printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n", + base, len, wcnt, bcnt); #endif } else { while (i-- > 0) @@ -466,26 +464,26 @@ static inline void t1_put_slice(unsigned int base, { unsigned i = len; b1_put_word(base, i); - if (t1_isfastlink(base)) { + if (t1_isfastlink(base)) { int status; while (i > 0) { - status = t1_fifostatus(base) & (T1F_OREADY|T1F_OHALF); + status = t1_fifostatus(base) & (T1F_OREADY | T1F_OHALF); if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY; switch (status) { - case T1F_OREADY|T1F_OHALF|T1F_OEMPTY: - outsb(base+B1_WRITE, dp, FIFO_OUTBSIZE); - dp += FIFO_OUTBSIZE; - i -= FIFO_OUTBSIZE; - break; - case T1F_OREADY|T1F_OHALF: - outsb(base+B1_WRITE, dp, i); - dp += i; - i = 0; - break; - default: - b1_put_byte(base, *dp++); - i--; - break; + case T1F_OREADY | T1F_OHALF | T1F_OEMPTY: + outsb(base + B1_WRITE, dp, FIFO_OUTBSIZE); + dp += FIFO_OUTBSIZE; + i -= FIFO_OUTBSIZE; + break; + case T1F_OREADY | T1F_OHALF: + outsb(base + B1_WRITE, dp, i); + dp += i; + i = 0; + break; + default: + b1_put_byte(base, *dp++); + i--; + break; } } } else { @@ -496,18 +494,18 @@ static inline void t1_put_slice(unsigned int base, static inline void t1_disable_irq(unsigned int base) { - t1outp(base, T1_IRQMASTER, 0x00); + t1outp(base, T1_IRQMASTER, 0x00); } static inline void t1_reset(unsigned int base) { - /* reset T1 Controller */ - b1_reset(base); - /* disable irq on HEMA */ - t1outp(base, B1_INSTAT, 0x00); - t1outp(base, B1_OUTSTAT, 0x00); - t1outp(base, T1_IRQMASTER, 0x00); - /* reset HEMA board configuration */ + /* reset T1 Controller */ + b1_reset(base); + /* disable irq on HEMA */ + t1outp(base, B1_INSTAT, 0x00); + t1outp(base, B1_OUTSTAT, 0x00); + t1outp(base, T1_IRQMASTER, 0x00); + /* reset HEMA board configuration */ t1outp(base, T1_RESETBOARD, 0xf); } @@ -515,29 +513,29 @@ static inline void b1_setinterrupt(unsigned int base, unsigned irq, enum avmcardtype cardtype) { switch (cardtype) { - case avm_t1isa: - t1outp(base, B1_INSTAT, 0x00); - t1outp(base, B1_INSTAT, 0x02); - t1outp(base, T1_IRQMASTER, 0x08); - break; - case avm_b1isa: - b1outp(base, B1_INSTAT, 0x00); - b1outp(base, B1_RESET, b1_irq_table[irq]); - b1outp(base, B1_INSTAT, 0x02); - break; - default: - case avm_m1: - case avm_m2: - case avm_b1pci: - b1outp(base, B1_INSTAT, 0x00); - b1outp(base, B1_RESET, 0xf0); - b1outp(base, B1_INSTAT, 0x02); - break; - case avm_c4: - case avm_t1pci: - b1outp(base, B1_RESET, 0xf0); - break; - } + case avm_t1isa: + t1outp(base, B1_INSTAT, 0x00); + t1outp(base, B1_INSTAT, 0x02); + t1outp(base, T1_IRQMASTER, 0x08); + break; + case avm_b1isa: + b1outp(base, B1_INSTAT, 0x00); + b1outp(base, B1_RESET, b1_irq_table[irq]); + b1outp(base, B1_INSTAT, 0x02); + break; + default: + case avm_m1: + case avm_m2: + case avm_b1pci: + b1outp(base, B1_INSTAT, 0x00); + b1outp(base, B1_RESET, 0xf0); + b1outp(base, B1_INSTAT, 0x02); + break; + case avm_c4: + case avm_t1pci: + b1outp(base, B1_RESET, 0xf0); + break; + } } /* b1.c */ @@ -545,21 +543,20 @@ avmcard *b1_alloc_card(int nr_controllers); void b1_free_card(avmcard *card); int b1_detect(unsigned int base, enum avmcardtype cardtype); void b1_getrevision(avmcard *card); -int b1_load_t4file(avmcard *card, capiloaddatapart * t4file); -int b1_load_config(avmcard *card, capiloaddatapart * config); +int b1_load_t4file(avmcard *card, capiloaddatapart *t4file); +int b1_load_config(avmcard *card, capiloaddatapart *config); int b1_loaded(avmcard *card); int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); void b1_reset_ctr(struct capi_ctr *ctrl); void b1_register_appl(struct capi_ctr *ctrl, u16 appl, - capi_register_params *rp); + capi_register_params *rp); void b1_release_appl(struct capi_ctr *ctrl, u16 appl); u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); void b1_parse_version(avmctrl_info *card); -irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs); +irqreturn_t b1_interrupt(int interrupt, void *devptr); -int b1ctl_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl); +extern const struct file_operations b1ctl_proc_fops; avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *, long rsize, long ssize); @@ -569,17 +566,16 @@ void avmcard_dma_free(avmcard_dmainfo *); int b1pciv4_detect(avmcard *card); int t1pci_detect(avmcard *card); void b1dma_reset(avmcard *card); -irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs); +irqreturn_t b1dma_interrupt(int interrupt, void *devptr); int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); void b1dma_reset_ctr(struct capi_ctr *ctrl); void b1dma_remove_ctr(struct capi_ctr *ctrl); void b1dma_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp); + u16 appl, + capi_register_params *rp); void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl); u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); -int b1dmactl_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl); +extern const struct file_operations b1dmactl_proc_fops; #endif /* _AVMCARD_H_ */ diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index 0c7061d5502..4d9b195547c 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c @@ -1,7 +1,7 @@ /* $Id: b1.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * + * * Common module for AVM B1 cards. - * + * * Copyright 1999 by Carsten Paeth <calle@calle.de> * * This software may be used and distributed according to the terms @@ -12,6 +12,8 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/pci.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/skbuff.h> #include <linux/delay.h> #include <linux/mm.h> @@ -19,6 +21,7 @@ #include <linux/ioport.h> #include <linux/capi.h> #include <linux/kernelcapi.h> +#include <linux/slab.h> #include <asm/io.h> #include <linux/init.h> #include <asm/uaccess.h> @@ -57,7 +60,7 @@ int b1_irq_table[16] = 112, /* irq 15 */ }; -/* ------------------------------------------------------------- */ +/* ------------------------------------------------------------- */ avmcard *b1_alloc_card(int nr_controllers) { @@ -65,18 +68,15 @@ avmcard *b1_alloc_card(int nr_controllers) avmctrl_info *cinfo; int i; - card = kmalloc(sizeof(*card), GFP_KERNEL); + card = kzalloc(sizeof(*card), GFP_KERNEL); if (!card) return NULL; - memset(card, 0, sizeof(*card)); - - cinfo = kmalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL); + cinfo = kzalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL); if (!cinfo) { kfree(card); return NULL; } - memset(cinfo, 0, sizeof(*cinfo) * nr_controllers); card->ctrlinfo = cinfo; for (i = 0; i < nr_controllers; i++) { @@ -104,13 +104,13 @@ int b1_detect(unsigned int base, enum avmcardtype cardtype) int onoff, i; /* - * Statusregister 0000 00xx + * Statusregister 0000 00xx */ if ((inb(base + B1_INSTAT) & 0xfc) || (inb(base + B1_OUTSTAT) & 0xfc)) return 1; /* - * Statusregister 0000 001x + * Statusregister 0000 001x */ b1outp(base, B1_INSTAT, 0x2); /* enable irq */ /* b1outp(base, B1_OUTSTAT, 0x2); */ @@ -118,38 +118,38 @@ int b1_detect(unsigned int base, enum avmcardtype cardtype) /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */) return 2; /* - * Statusregister 0000 000x + * Statusregister 0000 000x */ b1outp(base, B1_INSTAT, 0x0); /* disable irq */ b1outp(base, B1_OUTSTAT, 0x0); if ((inb(base + B1_INSTAT) & 0xfe) || (inb(base + B1_OUTSTAT) & 0xfe)) return 3; - - for (onoff = !0, i= 0; i < 10 ; i++) { + + for (onoff = !0, i = 0; i < 10; i++) { b1_set_test_bit(base, cardtype, onoff); if (b1_get_test_bit(base, cardtype) != onoff) - return 4; + return 4; onoff = !onoff; } if (cardtype == avm_m1) - return 0; + return 0; - if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01) - return 5; + if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01) + return 5; return 0; } void b1_getrevision(avmcard *card) { - card->class = inb(card->port + B1_ANALYSE); - card->revision = inb(card->port + B1_REVISION); + card->class = inb(card->port + B1_ANALYSE); + card->revision = inb(card->port + B1_REVISION); } #define FWBUF_SIZE 256 -int b1_load_t4file(avmcard *card, capiloaddatapart * t4file) +int b1_load_t4file(avmcard *card, capiloaddatapart *t4file) { unsigned char buf[FWBUF_SIZE]; unsigned char *dp; @@ -168,7 +168,7 @@ int b1_load_t4file(avmcard *card, capiloaddatapart * t4file) for (i = 0; i < FWBUF_SIZE; i++) if (b1_save_put_byte(base, buf[i]) < 0) { printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); + card->name); return -EIO; } left -= FWBUF_SIZE; @@ -184,14 +184,14 @@ int b1_load_t4file(avmcard *card, capiloaddatapart * t4file) for (i = 0; i < left; i++) if (b1_save_put_byte(base, buf[i]) < 0) { printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); + card->name); return -EIO; } } return 0; } -int b1_load_config(avmcard *card, capiloaddatapart * config) +int b1_load_config(avmcard *card, capiloaddatapart *config) { unsigned char buf[FWBUF_SIZE]; unsigned char *dp; @@ -202,9 +202,9 @@ int b1_load_config(avmcard *card, capiloaddatapart * config) left = config->len; if (left) { b1_put_byte(base, SEND_CONFIG); - b1_put_word(base, 1); + b1_put_word(base, 1); b1_put_byte(base, SEND_CONFIG); - b1_put_word(base, left); + b1_put_word(base, left); } while (left > FWBUF_SIZE) { if (config->user) { @@ -215,7 +215,7 @@ int b1_load_config(avmcard *card, capiloaddatapart * config) } for (i = 0; i < FWBUF_SIZE; ) { b1_put_byte(base, SEND_CONFIG); - for (j=0; j < 4; j++) { + for (j = 0; j < 4; j++) { b1_put_byte(base, buf[i++]); } } @@ -231,7 +231,7 @@ int b1_load_config(avmcard *card, capiloaddatapart * config) } for (i = 0; i < left; ) { b1_put_byte(base, SEND_CONFIG); - for (j=0; j < 4; j++) { + for (j = 0; j < 4; j++) { if (i < left) b1_put_byte(base, buf[i++]); else @@ -255,7 +255,7 @@ int b1_loaded(avmcard *card) } if (!b1_tx_empty(base)) { printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?\n", - card->name); + card->name); return 0; } b1_put_byte(base, SEND_POLL); @@ -265,7 +265,7 @@ int b1_loaded(avmcard *card) return 1; } printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not running\n", - card->name, ans); + card->name, ans); return 0; } } @@ -288,7 +288,7 @@ int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) if ((retval = b1_load_t4file(card, &data->firmware))) { b1_reset(port); printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); + card->name); return retval; } @@ -298,7 +298,7 @@ int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) if ((retval = b1_load_config(card, &data->configuration))) { b1_reset(port); printk(KERN_ERR "%s: failed to load config!!\n", - card->name); + card->name); return retval; } } @@ -312,7 +312,7 @@ int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) b1_setinterrupt(port, card->irq, card->cardtype); b1_put_byte(port, SEND_INIT); b1_put_word(port, CAPI_MAXAPPL); - b1_put_word(port, AVM_NCCI_PER_CHANNEL*2); + b1_put_word(port, AVM_NCCI_PER_CHANNEL * 2); b1_put_word(port, ctrl->cnr - 1); spin_unlock_irqrestore(&card->lock, flags); @@ -324,18 +324,21 @@ void b1_reset_ctr(struct capi_ctr *ctrl) avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; unsigned int port = card->port; + unsigned long flags; b1_reset(port); b1_reset(port); memset(cinfo->version, 0, sizeof(cinfo->version)); + spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); - capi_ctr_reseted(ctrl); + spin_unlock_irqrestore(&card->lock, flags); + capi_ctr_down(ctrl); } void b1_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp) + u16 appl, + capi_register_params *rp) { avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; @@ -350,7 +353,7 @@ void b1_register_appl(struct capi_ctr *ctrl, spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_REGISTER); b1_put_word(port, appl); - b1_put_word(port, 1024 * (nconn+1)); + b1_put_word(port, 1024 * (nconn + 1)); b1_put_word(port, nconn); b1_put_word(port, rp->datablkcnt); b1_put_word(port, rp->datablklen); @@ -364,9 +367,8 @@ void b1_release_appl(struct capi_ctr *ctrl, u16 appl) unsigned int port = card->port; unsigned long flags; - capilib_release_appl(&cinfo->ncci_head, appl); - spin_lock_irqsave(&card->lock, flags); + capilib_release_appl(&cinfo->ncci_head, appl); b1_put_byte(port, SEND_RELEASE); b1_put_word(port, appl); spin_unlock_irqrestore(&card->lock, flags); @@ -383,27 +385,27 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); u16 dlen, retval; + spin_lock_irqsave(&card->lock, flags); if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - if (retval != CAPI_NOERROR) + if (retval != CAPI_NOERROR) { + spin_unlock_irqrestore(&card->lock, flags); return retval; + } dlen = CAPIMSG_DATALEN(skb->data); - spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_DATA_B3_REQ); b1_put_slice(port, skb->data, len); b1_put_slice(port, skb->data + len, dlen); - spin_unlock_irqrestore(&card->lock, flags); } else { - spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_MESSAGE); b1_put_slice(port, skb->data, len); - spin_unlock_irqrestore(&card->lock, flags); } + spin_unlock_irqrestore(&card->lock, flags); dev_kfree_skb_any(skb); return CAPI_NOERROR; @@ -428,7 +430,7 @@ void b1_parse_version(avmctrl_info *cinfo) cinfo->version[j] = &cinfo->versionbuf[i + 1]; strlcpy(ctrl->serial, cinfo->version[VER_SERIAL], sizeof(ctrl->serial)); - memcpy(&ctrl->profile, cinfo->version[VER_PROFILE],sizeof(capi_profile)); + memcpy(&ctrl->profile, cinfo->version[VER_PROFILE], sizeof(capi_profile)); strlcpy(ctrl->manu, "AVM GmbH", sizeof(ctrl->manu)); dversion = cinfo->version[VER_DRIVER]; ctrl->version.majorversion = 2; @@ -437,55 +439,55 @@ void b1_parse_version(avmctrl_info *cinfo) ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf); ctrl->version.minormanuversion = (dversion[3] - '0') << 4; ctrl->version.minormanuversion |= - (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf); + (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf); profp = &ctrl->profile; flag = ((u8 *)(profp->manu))[1]; switch (flag) { case 0: if (cinfo->version[VER_CARDTYPE]) - strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]); - else strcpy(cinfo->cardname, "B1"); + strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]); + else strcpy(cinfo->cardname, "B1"); break; - case 3: strcpy(cinfo->cardname,"PCMCIA B"); break; - case 4: strcpy(cinfo->cardname,"PCMCIA M1"); break; - case 5: strcpy(cinfo->cardname,"PCMCIA M2"); break; - case 6: strcpy(cinfo->cardname,"B1 V3.0"); break; - case 7: strcpy(cinfo->cardname,"B1 PCI"); break; + case 3: strcpy(cinfo->cardname, "PCMCIA B"); break; + case 4: strcpy(cinfo->cardname, "PCMCIA M1"); break; + case 5: strcpy(cinfo->cardname, "PCMCIA M2"); break; + case 6: strcpy(cinfo->cardname, "B1 V3.0"); break; + case 7: strcpy(cinfo->cardname, "B1 PCI"); break; default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break; - } - printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n", - card->name, ctrl->cnr, cinfo->cardname); + } + printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n", + card->name, ctrl->cnr, cinfo->cardname); - flag = ((u8 *)(profp->manu))[3]; - if (flag) + flag = ((u8 *)(profp->manu))[3]; + if (flag) printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%s\n", - card->name, - ctrl->cnr, - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" + card->name, + ctrl->cnr, + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" ); - flag = ((u8 *)(profp->manu))[5]; + flag = ((u8 *)(profp->manu))[5]; if (flag) printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%s\n", - card->name, - ctrl->cnr, - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" + card->name, + ctrl->cnr, + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" ); } /* ------------------------------------------------------------- */ -irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +irqreturn_t b1_interrupt(int interrupt, void *devptr) { avmcard *card = devptr; avmctrl_info *cinfo = &card->ctrlinfo[0]; @@ -519,13 +521,13 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) spin_unlock_irqrestore(&card->lock, flags); if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf+MsgLen, 0, 30-MsgLen); + memset(card->msgbuf + MsgLen, 0, 30-MsgLen); MsgLen = 30; CAPIMSG_SETLEN(card->msgbuf, 30); } if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); @@ -537,17 +539,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) ApplId = (unsigned) b1_get_word(card->port); MsgLen = b1_get_slice(card->port, card->msgbuf); - spin_unlock_irqrestore(&card->lock, flags); if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); + spin_unlock_irqrestore(&card->lock, flags); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) capilib_data_b3_conf(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - + spin_unlock_irqrestore(&card->lock, flags); capi_ctr_handle_message(ctrl, ApplId, skb); } break; @@ -557,25 +559,21 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); WindowSize = b1_get_word(card->port); - spin_unlock_irqrestore(&card->lock, flags); - capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); - + spin_unlock_irqrestore(&card->lock, flags); break; case RECEIVE_FREE_NCCI: ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); - spin_unlock_irqrestore(&card->lock, flags); - if (NCCI != 0xffffffff) capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - + spin_unlock_irqrestore(&card->lock, flags); break; case RECEIVE_START: - /* b1_put_byte(card->port, SEND_POLLACK); */ + /* b1_put_byte(card->port, SEND_POLLACK); */ spin_unlock_irqrestore(&card->lock, flags); capi_ctr_resume_output(ctrl); break; @@ -602,24 +600,24 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) MsgLen = b1_get_slice(card->port, card->msgbuf); spin_unlock_irqrestore(&card->lock, flags); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); + card->name, ApplId, card->msgbuf); break; case RECEIVE_DEBUGMSG: MsgLen = b1_get_slice(card->port, card->msgbuf); spin_unlock_irqrestore(&card->lock, flags); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); @@ -632,25 +630,24 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs) default: spin_unlock_irqrestore(&card->lock, flags); printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n", - card->name, b1cmd); + card->name, b1cmd); return IRQ_HANDLED; } return IRQ_HANDLED; } /* ------------------------------------------------------------- */ -int b1ctl_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl) +static int b1ctl_proc_show(struct seq_file *m, void *v) { + struct capi_ctr *ctrl = m->private; avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; u8 flag; - int len = 0; char *s; - len += sprintf(page+len, "%-16s %s\n", "name", card->name); - len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); - len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); + seq_printf(m, "%-16s %s\n", "name", card->name); + seq_printf(m, "%-16s 0x%x\n", "io", card->port); + seq_printf(m, "%-16s %d\n", "irq", card->irq); switch (card->cardtype) { case avm_b1isa: s = "B1 ISA"; break; case avm_b1pci: s = "B1 PCI"; break; @@ -663,51 +660,60 @@ int b1ctl_read_proc(char *page, char **start, off_t off, case avm_c2: s = "C2"; break; default: s = "???"; break; } - len += sprintf(page+len, "%-16s %s\n", "type", s); + seq_printf(m, "%-16s %s\n", "type", s); if (card->cardtype == avm_t1isa) - len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr); - if ((s = cinfo->version[VER_DRIVER]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); - if ((s = cinfo->version[VER_CARDTYPE]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); - if ((s = cinfo->version[VER_SERIAL]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); + seq_printf(m, "%-16s %d\n", "cardnr", card->cardnr); + if ((s = cinfo->version[VER_DRIVER]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_driver", s); + if ((s = cinfo->version[VER_CARDTYPE]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_cardtype", s); + if ((s = cinfo->version[VER_SERIAL]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_serial", s); if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[3]; - if (flag) - len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", - "protocol", - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" - ); + flag = ((u8 *)(ctrl->profile.manu))[3]; + if (flag) + seq_printf(m, "%-16s%s%s%s%s%s%s%s\n", + "protocol", + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); } if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[5]; + flag = ((u8 *)(ctrl->profile.manu))[5]; if (flag) - len += sprintf(page+len, "%-16s%s%s%s%s\n", - "linetype", - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" - ); + seq_printf(m, "%-16s%s%s%s%s\n", + "linetype", + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); } - len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); - - if (off+count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len-off) ? count : len-off); + seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname); + + return 0; +} + +static int b1ctl_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, b1ctl_proc_show, PDE_DATA(inode)); } +const struct file_operations b1ctl_proc_fops = { + .owner = THIS_MODULE, + .open = b1ctl_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +EXPORT_SYMBOL(b1ctl_proc_fops); + /* ------------------------------------------------------------- */ #ifdef CONFIG_PCI @@ -718,12 +724,11 @@ avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize) avmcard_dmainfo *p; void *buf; - p = kmalloc(sizeof(avmcard_dmainfo), GFP_KERNEL); + p = kzalloc(sizeof(avmcard_dmainfo), GFP_KERNEL); if (!p) { printk(KERN_WARNING "%s: no memory.\n", name); goto err; } - memset(p, 0, sizeof(avmcard_dmainfo)); p->recvbuf.size = rsize; buf = pci_alloc_consistent(pdev, rsize, &p->recvbuf.dmaaddr); @@ -745,12 +750,12 @@ avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize) return p; - err_free_consistent: +err_free_consistent: pci_free_consistent(p->pcidev, p->recvbuf.size, p->recvbuf.dmabuf, p->recvbuf.dmaaddr); - err_kfree: +err_kfree: kfree(p); - err: +err: return NULL; } @@ -787,17 +792,15 @@ EXPORT_SYMBOL(b1_send_message); EXPORT_SYMBOL(b1_parse_version); EXPORT_SYMBOL(b1_interrupt); -EXPORT_SYMBOL(b1ctl_read_proc); - static int __init b1_init(void) { char *p; char rev[32]; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index 91dd0551fc7..19b113faeb7 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c @@ -1,17 +1,18 @@ /* $Id: b1dma.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ - * + * * Common module for AVM B1 cards that support dma with AMCC - * + * * Copyright 2000 by Carsten Paeth <calle@calle.de> - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/skbuff.h> #include <linux/delay.h> #include <linux/mm.h> @@ -19,6 +20,7 @@ #include <linux/ioport.h> #include <linux/capi.h> #include <linux/kernelcapi.h> +#include <linux/gfp.h> #include <asm/io.h> #include <linux/init.h> #include <asm/uaccess.h> @@ -30,7 +32,7 @@ static char *revision = "$Revision: 1.1.2.3 $"; -#undef CONFIG_B1DMA_DEBUG +#undef AVM_B1DMA_DEBUG /* ------------------------------------------------------------- */ @@ -38,8 +40,8 @@ MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards"); MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); -static int suppress_pollack = 0; -MODULE_PARM(suppress_pollack, "0-1i"); +static bool suppress_pollack = 0; +module_param(suppress_pollack, bool, 0); /* ------------------------------------------------------------- */ @@ -108,11 +110,11 @@ static int b1dma_tolink(avmcard *card, void *buf, unsigned int len) unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ unsigned char *s = (unsigned char *)buf; while (len--) { - while ( !b1dma_tx_empty(card->port) + while (!b1dma_tx_empty(card->port) && time_before(jiffies, stop)); - if (!b1dma_tx_empty(card->port)) + if (!b1dma_tx_empty(card->port)) return -1; - t1outp(card->port, 0x01, *s++); + t1outp(card->port, 0x01, *s++); } return 0; } @@ -122,11 +124,11 @@ static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len) unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ unsigned char *s = (unsigned char *)buf; while (len--) { - while ( !b1dma_rx_full(card->port) + while (!b1dma_rx_full(card->port) && time_before(jiffies, stop)); - if (!b1dma_rx_full(card->port)) + if (!b1dma_rx_full(card->port)) return -1; - *s++ = t1inp(card->port, 0x00); + *s++ = t1inp(card->port, 0x00); } return 0; } @@ -134,7 +136,7 @@ static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len) static int WriteReg(avmcard *card, u32 reg, u8 val) { u8 cmd = 0x00; - if ( b1dma_tolink(card, &cmd, 1) == 0 + if (b1dma_tolink(card, &cmd, 1) == 0 && b1dma_tolink(card, ®, 4) == 0) { u32 tmp = val; return b1dma_tolink(card, &tmp, 4); @@ -145,7 +147,7 @@ static int WriteReg(avmcard *card, u32 reg, u8 val) static u8 ReadReg(avmcard *card, u32 reg) { u8 cmd = 0x01; - if ( b1dma_tolink(card, &cmd, 1) == 0 + if (b1dma_tolink(card, &cmd, 1) == 0 && b1dma_tolink(card, ®, 4) == 0) { u32 tmp; if (b1dma_fromlink(card, &tmp, 4) == 0) @@ -256,30 +258,30 @@ static int b1dma_detect(avmcard *card) b1dma_writel(card, 0xffffffff, AMCC_RXPTR); b1dma_writel(card, 0xffffffff, AMCC_TXPTR); - if ( b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc + if (b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc || b1dma_readl(card, AMCC_TXPTR) != 0xfffffffc) return 2; b1dma_writel(card, 0x0, AMCC_RXPTR); b1dma_writel(card, 0x0, AMCC_TXPTR); - if ( b1dma_readl(card, AMCC_RXPTR) != 0x0 + if (b1dma_readl(card, AMCC_RXPTR) != 0x0 || b1dma_readl(card, AMCC_TXPTR) != 0x0) return 3; t1outp(card->port, 0x10, 0x00); t1outp(card->port, 0x07, 0x00); - + t1outp(card->port, 0x02, 0x02); t1outp(card->port, 0x03, 0x02); - if ( (t1inp(card->port, 0x02) & 0xFE) != 0x02 + if ((t1inp(card->port, 0x02) & 0xFE) != 0x02 || t1inp(card->port, 0x3) != 0x03) return 4; t1outp(card->port, 0x02, 0x00); t1outp(card->port, 0x03, 0x00); - if ( (t1inp(card->port, 0x02) & 0xFE) != 0x00 + if ((t1inp(card->port, 0x02) & 0xFE) != 0x00 || t1inp(card->port, 0x3) != 0x01) return 5; @@ -292,28 +294,28 @@ int t1pci_detect(avmcard *card) if ((ret = b1dma_detect(card)) != 0) return ret; - + /* Transputer test */ - - if ( WriteReg(card, 0x80001000, 0x11) != 0 + + if (WriteReg(card, 0x80001000, 0x11) != 0 || WriteReg(card, 0x80101000, 0x22) != 0 || WriteReg(card, 0x80201000, 0x33) != 0 || WriteReg(card, 0x80301000, 0x44) != 0) return 6; - if ( ReadReg(card, 0x80001000) != 0x11 + if (ReadReg(card, 0x80001000) != 0x11 || ReadReg(card, 0x80101000) != 0x22 || ReadReg(card, 0x80201000) != 0x33 || ReadReg(card, 0x80301000) != 0x44) return 7; - if ( WriteReg(card, 0x80001000, 0x55) != 0 + if (WriteReg(card, 0x80001000, 0x55) != 0 || WriteReg(card, 0x80101000, 0x66) != 0 || WriteReg(card, 0x80201000, 0x77) != 0 || WriteReg(card, 0x80301000, 0x88) != 0) return 8; - if ( ReadReg(card, 0x80001000) != 0x55 + if (ReadReg(card, 0x80001000) != 0x55 || ReadReg(card, 0x80101000) != 0x66 || ReadReg(card, 0x80201000) != 0x77 || ReadReg(card, 0x80301000) != 0x88) @@ -328,20 +330,20 @@ int b1pciv4_detect(avmcard *card) if ((ret = b1dma_detect(card)) != 0) return ret; - - for (i=0; i < 5 ; i++) { + + for (i = 0; i < 5; i++) { if (WriteReg(card, 0x80A00000, 0x21) != 0) return 6; if ((ReadReg(card, 0x80A00000) & 0x01) != 0x01) return 7; } - for (i=0; i < 5 ; i++) { + for (i = 0; i < 5; i++) { if (WriteReg(card, 0x80A00000, 0x20) != 0) return 8; if ((ReadReg(card, 0x80A00000) & 0x01) != 0x00) return 9; } - + return 0; } @@ -371,7 +373,7 @@ static void b1dma_dispatch_tx(avmcard *card) u16 len; u32 txlen; void *p; - + skb = skb_dequeue(&dma->send_queue); len = CAPIMSG_LEN(skb->data); @@ -392,20 +394,21 @@ static void b1dma_dispatch_tx(avmcard *card) _put_slice(&p, skb->data, len); } txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf; -#ifdef CONFIG_B1DMA_DEBUG +#ifdef AVM_B1DMA_DEBUG printk(KERN_DEBUG "tx: put msg len=%d\n", txlen); #endif } else { - txlen = skb->len-2; -#ifdef CONFIG_B1DMA_POLLDEBUG + txlen = skb->len - 2; +#ifdef AVM_B1DMA_POLLDEBUG if (skb->data[2] == SEND_POLLACK) printk(KERN_INFO "%s: send ack\n", card->name); #endif -#ifdef CONFIG_B1DMA_DEBUG - printk(KERN_DEBUG "tx: put 0x%x len=%d\n", +#ifdef AVM_B1DMA_DEBUG + printk(KERN_DEBUG "tx: put 0x%x len=%d\n", skb->data[2], txlen); #endif - memcpy(dma->sendbuf.dmabuf, skb->data+2, skb->len-2); + skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf, + skb->len - 2); } txlen = (txlen + 3) & ~3; @@ -427,7 +430,7 @@ static void queue_pollack(avmcard *card) skb = alloc_skb(3, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost poll ack\n", - card->name); + card->name); return; } p = skb->data; @@ -447,14 +450,14 @@ static void b1dma_handle_rx(avmcard *card) avmcard_dmainfo *dma = card->dma; struct capi_ctr *ctrl = &cinfo->capi_ctrl; struct sk_buff *skb; - void *p = dma->recvbuf.dmabuf+4; + void *p = dma->recvbuf.dmabuf + 4; u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize; u8 b1cmd = _get_byte(&p); -#ifdef CONFIG_B1DMA_DEBUG +#ifdef AVM_B1DMA_DEBUG printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen); #endif - + switch (b1cmd) { case RECEIVE_DATA_B3_IND: @@ -463,13 +466,13 @@ static void b1dma_handle_rx(avmcard *card) DataB3Len = _get_slice(&p, card->databuf); if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf+MsgLen, 0, 30-MsgLen); + memset(card->msgbuf + MsgLen, 0, 30 - MsgLen); MsgLen = 30; CAPIMSG_SETLEN(card->msgbuf, 30); } - if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) { + if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); @@ -483,14 +486,16 @@ static void b1dma_handle_rx(avmcard *card) MsgLen = _get_slice(&p, card->msgbuf); if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) + if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) { + spin_lock(&card->lock); capilib_data_b3_conf(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - + spin_unlock(&card->lock); + } capi_ctr_handle_message(ctrl, ApplId, skb); } break; @@ -500,9 +505,9 @@ static void b1dma_handle_rx(avmcard *card) ApplId = _get_word(&p); NCCI = _get_word(&p); WindowSize = _get_word(&p); - + spin_lock(&card->lock); capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); - + spin_unlock(&card->lock); break; case RECEIVE_FREE_NCCI: @@ -510,13 +515,15 @@ static void b1dma_handle_rx(avmcard *card) ApplId = _get_word(&p); NCCI = _get_word(&p); - if (NCCI != 0xffffffff) + if (NCCI != 0xffffffff) { + spin_lock(&card->lock); capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - + spin_unlock(&card->lock); + } break; case RECEIVE_START: -#ifdef CONFIG_B1DMA_POLLDEBUG +#ifdef AVM_B1DMA_POLLDEBUG printk(KERN_INFO "%s: receive poll\n", card->name); #endif if (!suppress_pollack) @@ -543,23 +550,23 @@ static void b1dma_handle_rx(avmcard *card) ApplId = (unsigned) _get_word(&p); MsgLen = _get_slice(&p, card->msgbuf); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); + card->name, ApplId, card->msgbuf); break; case RECEIVE_DEBUGMSG: MsgLen = _get_slice(&p, card->msgbuf); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); @@ -567,7 +574,7 @@ static void b1dma_handle_rx(avmcard *card) default: printk(KERN_ERR "%s: b1dma_interrupt: 0x%x ???\n", - card->name, b1cmd); + card->name, b1cmd); return; } } @@ -587,7 +594,7 @@ static void b1dma_handle_interrupt(avmcard *card) return; } - newcsr = card->csr | (status & ALL_INT); + newcsr = card->csr | (status & ALL_INT); if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT; if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT; b1dma_writel(card, newcsr, AMCC_INTCSR); @@ -595,23 +602,23 @@ static void b1dma_handle_interrupt(avmcard *card) if ((status & RX_TC_INT) != 0) { struct avmcard_dmainfo *dma = card->dma; u32 rxlen; - if (card->dma->recvlen == 0) { - rxlen = b1dma_readl(card, AMCC_RXLEN); + if (card->dma->recvlen == 0) { + rxlen = b1dma_readl(card, AMCC_RXLEN); if (rxlen == 0) { dma->recvlen = *((u32 *)dma->recvbuf.dmabuf); rxlen = (dma->recvlen + 3) & ~3; - b1dma_writel(card, dma->recvbuf.dmaaddr+4, AMCC_RXPTR); + b1dma_writel(card, dma->recvbuf.dmaaddr + 4, AMCC_RXPTR); b1dma_writel(card, rxlen, AMCC_RXLEN); -#ifdef CONFIG_B1DMA_DEBUG +#ifdef AVM_B1DMA_DEBUG } else { printk(KERN_ERR "%s: rx not complete (%d).\n", - card->name, rxlen); + card->name, rxlen); #endif } } else { spin_unlock(&card->lock); b1dma_handle_rx(card); - dma->recvlen = 0; + dma->recvlen = 0; spin_lock(&card->lock); b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR); b1dma_writel(card, 4, AMCC_RXLEN); @@ -629,7 +636,7 @@ static void b1dma_handle_interrupt(avmcard *card) spin_unlock(&card->lock); } -irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +irqreturn_t b1dma_interrupt(int interrupt, void *devptr) { avmcard *card = devptr; @@ -652,7 +659,7 @@ static int b1dma_loaded(avmcard *card) } if (!b1_tx_empty(base)) { printk(KERN_ERR "%s: b1dma_loaded: tx err, corrupted t4 file ?\n", - card->name); + card->name); return 0; } b1_put_byte(base, SEND_POLLACK); @@ -679,7 +686,7 @@ static void b1dma_send_init(avmcard *card) skb = alloc_skb(15, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); + card->name); return; } p = skb->data; @@ -687,7 +694,7 @@ static void b1dma_send_init(avmcard *card) _put_byte(&p, 0); _put_byte(&p, SEND_INIT); _put_word(&p, CAPI_MAXAPPL); - _put_word(&p, AVM_NCCI_PER_CHANNEL*30); + _put_word(&p, AVM_NCCI_PER_CHANNEL * 30); _put_word(&p, card->cardnr - 1); skb_put(skb, (u8 *)p - (u8 *)skb->data); @@ -705,7 +712,7 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) if ((retval = b1_load_t4file(card, &data->firmware))) { b1dma_reset(card); printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); + card->name); return retval; } @@ -713,7 +720,7 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) if ((retval = b1_load_config(card, &data->configuration))) { b1dma_reset(card); printk(KERN_ERR "%s: failed to load config!!\n", - card->name); + card->name); return retval; } } @@ -726,8 +733,8 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) card->csr = AVM_FLAG; b1dma_writel(card, card->csr, AMCC_INTCSR); - b1dma_writel(card, EN_A2P_TRANSFERS|EN_P2A_TRANSFERS|A2P_HI_PRIORITY| - P2A_HI_PRIORITY|RESET_A2P_FLAGS|RESET_P2A_FLAGS, + b1dma_writel(card, EN_A2P_TRANSFERS | EN_P2A_TRANSFERS | A2P_HI_PRIORITY | + P2A_HI_PRIORITY | RESET_A2P_FLAGS | RESET_P2A_FLAGS, AMCC_MCSR); t1outp(card->port, 0x07, 0x30); t1outp(card->port, 0x10, 0xF0); @@ -738,7 +745,7 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) card->csr |= EN_RX_TC_INT; b1dma_writel(card, card->csr, AMCC_INTCSR); - b1dma_send_init(card); + b1dma_send_init(card); return 0; } @@ -750,19 +757,19 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl) unsigned long flags; spin_lock_irqsave(&card->lock, flags); - b1dma_reset(card); - spin_unlock_irqrestore(&card->lock, flags); + b1dma_reset(card); memset(cinfo->version, 0, sizeof(cinfo->version)); capilib_release(&cinfo->ncci_head); - capi_ctr_reseted(ctrl); + spin_unlock_irqrestore(&card->lock, flags); + capi_ctr_down(ctrl); } /* ------------------------------------------------------------- */ void b1dma_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp) + u16 appl, + capi_register_params *rp) { avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; @@ -778,7 +785,7 @@ void b1dma_register_appl(struct capi_ctr *ctrl, skb = alloc_skb(23, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); + card->name); return; } p = skb->data; @@ -786,7 +793,7 @@ void b1dma_register_appl(struct capi_ctr *ctrl, _put_byte(&p, 0); _put_byte(&p, SEND_REGISTER); _put_word(&p, appl); - _put_word(&p, 1024 * (nconn+1)); + _put_word(&p, 1024 * (nconn + 1)); _put_word(&p, nconn); _put_word(&p, rp->datablkcnt); _put_word(&p, rp->datablklen); @@ -803,13 +810,16 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl) avmcard *card = cinfo->card; struct sk_buff *skb; void *p; + unsigned long flags; + spin_lock_irqsave(&card->lock, flags); capilib_release_appl(&cinfo->ncci_head, appl); + spin_unlock_irqrestore(&card->lock, flags); skb = alloc_skb(7, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost release appl.\n", - card->name); + card->name); return; } p = skb->data; @@ -831,13 +841,16 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) avmcard *card = cinfo->card; u16 retval = CAPI_NOERROR; - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { + if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { + unsigned long flags; + spin_lock_irqsave(&card->lock, flags); retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); + spin_unlock_irqrestore(&card->lock, flags); } - if (retval == CAPI_NOERROR) + if (retval == CAPI_NOERROR) b1dma_queue_tx(card, skb); return retval; @@ -845,21 +858,20 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) /* ------------------------------------------------------------- */ -int b1dmactl_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl) +static int b1dmactl_proc_show(struct seq_file *m, void *v) { + struct capi_ctr *ctrl = m->private; avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; u8 flag; - int len = 0; char *s; u32 txoff, txlen, rxoff, rxlen, csr; unsigned long flags; - len += sprintf(page+len, "%-16s %s\n", "name", card->name); - len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); - len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); - len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); + seq_printf(m, "%-16s %s\n", "name", card->name); + seq_printf(m, "%-16s 0x%x\n", "io", card->port); + seq_printf(m, "%-16s %d\n", "irq", card->irq); + seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase); switch (card->cardtype) { case avm_b1isa: s = "B1 ISA"; break; case avm_b1pci: s = "B1 PCI"; break; @@ -872,40 +884,40 @@ int b1dmactl_read_proc(char *page, char **start, off_t off, case avm_c2: s = "C2"; break; default: s = "???"; break; } - len += sprintf(page+len, "%-16s %s\n", "type", s); - if ((s = cinfo->version[VER_DRIVER]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); - if ((s = cinfo->version[VER_CARDTYPE]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); - if ((s = cinfo->version[VER_SERIAL]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); + seq_printf(m, "%-16s %s\n", "type", s); + if ((s = cinfo->version[VER_DRIVER]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_driver", s); + if ((s = cinfo->version[VER_CARDTYPE]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_cardtype", s); + if ((s = cinfo->version[VER_SERIAL]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_serial", s); if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[3]; - if (flag) - len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", - "protocol", - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" - ); + flag = ((u8 *)(ctrl->profile.manu))[3]; + if (flag) + seq_printf(m, "%-16s%s%s%s%s%s%s%s\n", + "protocol", + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); } if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[5]; + flag = ((u8 *)(ctrl->profile.manu))[5]; if (flag) - len += sprintf(page+len, "%-16s%s%s%s%s\n", - "linetype", - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" - ); + seq_printf(m, "%-16s%s%s%s%s\n", + "linetype", + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); } - len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); + seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname); spin_lock_irqsave(&card->lock, flags); @@ -920,27 +932,30 @@ int b1dmactl_read_proc(char *page, char **start, off_t off, spin_unlock_irqrestore(&card->lock, flags); - len += sprintf(page+len, "%-16s 0x%lx\n", - "csr (cached)", (unsigned long)card->csr); - len += sprintf(page+len, "%-16s 0x%lx\n", - "csr", (unsigned long)csr); - len += sprintf(page+len, "%-16s %lu\n", - "txoff", (unsigned long)txoff); - len += sprintf(page+len, "%-16s %lu\n", - "txlen", (unsigned long)txlen); - len += sprintf(page+len, "%-16s %lu\n", - "rxoff", (unsigned long)rxoff); - len += sprintf(page+len, "%-16s %lu\n", - "rxlen", (unsigned long)rxlen); - - if (off+count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len-off) ? count : len-off); + seq_printf(m, "%-16s 0x%lx\n", "csr (cached)", (unsigned long)card->csr); + seq_printf(m, "%-16s 0x%lx\n", "csr", (unsigned long)csr); + seq_printf(m, "%-16s %lu\n", "txoff", (unsigned long)txoff); + seq_printf(m, "%-16s %lu\n", "txlen", (unsigned long)txlen); + seq_printf(m, "%-16s %lu\n", "rxoff", (unsigned long)rxoff); + seq_printf(m, "%-16s %lu\n", "rxlen", (unsigned long)rxlen); + + return 0; +} + +static int b1dmactl_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, b1dmactl_proc_show, PDE_DATA(inode)); } +const struct file_operations b1dmactl_proc_fops = { + .owner = THIS_MODULE, + .open = b1dmactl_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +EXPORT_SYMBOL(b1dmactl_proc_fops); + /* ------------------------------------------------------------- */ EXPORT_SYMBOL(b1dma_reset); @@ -953,17 +968,16 @@ EXPORT_SYMBOL(b1dma_reset_ctr); EXPORT_SYMBOL(b1dma_register_appl); EXPORT_SYMBOL(b1dma_release_appl); EXPORT_SYMBOL(b1dma_send_message); -EXPORT_SYMBOL(b1dmactl_read_proc); static int __init b1dma_init(void) { char *p; char rev[32]; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, sizeof(rev)); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c index 38bd4dfecbd..31ef8130a87 100644 --- a/drivers/isdn/hardware/avm/b1isa.c +++ b/drivers/isdn/hardware/avm/b1isa.c @@ -1,9 +1,9 @@ /* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ - * + * * Module for AVM B1 ISA-card. - * + * * Copyright 1999 by Carsten Paeth <calle@calle.de> - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * @@ -80,7 +80,7 @@ static int b1isa_probe(struct pci_dev *pdev) card->cardtype = avm_b1isa; sprintf(card->name, "b1isa-%x", card->port); - if ( card->port != 0x150 && card->port != 0x250 + if (card->port != 0x150 && card->port != 0x250 && card->port != 0x300 && card->port != 0x340) { printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port); retval = -EINVAL; @@ -121,7 +121,7 @@ static int b1isa_probe(struct pci_dev *pdev) cinfo->capi_ctrl.load_firmware = b1_load_firmware; cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; cinfo->capi_ctrl.procinfo = b1isa_procinfo; - cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; + cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops; strcpy(cinfo->capi_ctrl.name, card->name); retval = attach_capi_ctr(&cinfo->capi_ctrl); @@ -136,13 +136,13 @@ static int b1isa_probe(struct pci_dev *pdev) pci_set_drvdata(pdev, cinfo); return 0; - err_free_irq: +err_free_irq: free_irq(card->irq, card); - err_release_region: +err_release_region: release_region(card->port, AVMB1_PORTLEN); - err_free: +err_free: b1_free_card(card); - err: +err: return retval; } @@ -169,8 +169,8 @@ static struct pci_dev isa_dev[MAX_CARDS]; static int io[MAX_CARDS]; static int irq[MAX_CARDS]; -MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i"); -MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); MODULE_PARM_DESC(io, "I/O base address(es)"); MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); @@ -203,10 +203,10 @@ static int __init b1isa_init(void) char rev[32]; int i; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); @@ -233,10 +233,8 @@ static void __exit b1isa_exit(void) int i; for (i = 0; i < MAX_CARDS; i++) { - if (!io[i]) - break; - - b1isa_remove(&isa_dev[i]); + if (isa_dev[i].resource[0].start) + b1isa_remove(&isa_dev[i]); } unregister_capi_driver(&capi_driver_b1isa); } diff --git a/drivers/isdn/hardware/avm/b1pci.c b/drivers/isdn/hardware/avm/b1pci.c index 5435a6cfb5e..ac4863c2ecb 100644 --- a/drivers/isdn/hardware/avm/b1pci.c +++ b/drivers/isdn/hardware/avm/b1pci.c @@ -1,15 +1,14 @@ /* $Id: b1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * + * * Module for AVM B1 PCI-card. - * + * * Copyright 1999 by Carsten Paeth <calle@calle.de> - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/skbuff.h> @@ -80,7 +79,7 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev) card->port = p->port; card->irq = p->irq; card->cardtype = avm_b1pci; - + if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n", card->port, card->port + AVMB1_PORTLEN); @@ -97,14 +96,14 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev) } b1_reset(card->port); b1_getrevision(card); - - retval = request_irq(card->irq, b1_interrupt, SA_SHIRQ, card->name, card); + + retval = request_irq(card->irq, b1_interrupt, IRQF_SHARED, card->name, card); if (retval) { printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq); retval = -EBUSY; goto err_release_region; } - + cinfo->capi_ctrl.driver_name = "b1pci"; cinfo->capi_ctrl.driverdata = cinfo; cinfo->capi_ctrl.register_appl = b1_register_appl; @@ -113,7 +112,7 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev) cinfo->capi_ctrl.load_firmware = b1_load_firmware; cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; cinfo->capi_ctrl.procinfo = b1pci_procinfo; - cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; + cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops; strcpy(cinfo->capi_ctrl.name, card->name); cinfo->capi_ctrl.owner = THIS_MODULE; @@ -134,13 +133,13 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev) pci_set_drvdata(pdev, card); return 0; - err_free_irq: +err_free_irq: free_irq(card->irq, card); - err_release_region: +err_release_region: release_region(card->port, AVMB1_PORTLEN); - err_free: +err_free: b1_free_card(card); - err: +err: return retval; } @@ -194,7 +193,7 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev) goto err; } - card->dma = avmcard_dma_alloc("b1pci", pdev, 2048+128, 2048+128); + card->dma = avmcard_dma_alloc("b1pci", pdev, 2048 + 128, 2048 + 128); if (!card->dma) { printk(KERN_WARNING "b1pci: dma alloc.\n"); retval = -ENOMEM; @@ -235,7 +234,7 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev) b1dma_reset(card); b1_getrevision(card); - retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card); + retval = request_irq(card->irq, b1dma_interrupt, IRQF_SHARED, card->name, card); if (retval) { printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq); @@ -252,7 +251,7 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev) cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; cinfo->capi_ctrl.procinfo = b1pciv4_procinfo; - cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc; + cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops; strcpy(cinfo->capi_ctrl.name, card->name); retval = attach_capi_ctr(&cinfo->capi_ctrl); @@ -268,17 +267,17 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev) pci_set_drvdata(pdev, card); return 0; - err_free_irq: +err_free_irq: free_irq(card->irq, card); - err_unmap: +err_unmap: iounmap(card->mbase); - err_release_region: +err_release_region: release_region(card->port, AVMB1_PORTLEN); - err_free_dma: +err_free_dma: avmcard_dma_free(card->dma); - err_free: +err_free: b1_free_card(card); - err: +err: return retval; } @@ -288,20 +287,20 @@ static void b1pciv4_remove(struct pci_dev *pdev) avmcard *card = pci_get_drvdata(pdev); avmctrl_info *cinfo = card->ctrlinfo; - b1dma_reset(card); + b1dma_reset(card); detach_capi_ctr(&cinfo->capi_ctrl); free_irq(card->irq, card); iounmap(card->mbase); release_region(card->port, AVMB1_PORTLEN); - avmcard_dma_free(card->dma); + avmcard_dma_free(card->dma); b1_free_card(card); } #endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */ -static int __devinit b1pci_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int b1pci_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct capicardparams param; int retval; @@ -327,7 +326,7 @@ static int __devinit b1pci_pci_probe(struct pci_dev *pdev, retval = b1pci_probe(¶m, pdev); #endif if (retval != 0) { - printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n", + printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n", param.port, param.irq, param.membase); } } else { @@ -338,14 +337,14 @@ static int __devinit b1pci_pci_probe(struct pci_dev *pdev, param.port, param.irq); retval = b1pci_probe(¶m, pdev); if (retval != 0) { - printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n", + printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n", param.port, param.irq); } } return retval; } -static void __devexit b1pci_pci_remove(struct pci_dev *pdev) +static void b1pci_pci_remove(struct pci_dev *pdev) { #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4 avmcard *card = pci_get_drvdata(pdev); @@ -363,7 +362,7 @@ static struct pci_driver b1pci_pci_driver = { .name = "b1pci", .id_table = b1pci_pci_tbl, .probe = b1pci_pci_probe, - .remove = __devexit_p(b1pci_pci_remove), + .remove = b1pci_pci_remove, }; static struct capi_driver capi_driver_b1pci = { @@ -383,10 +382,10 @@ static int __init b1pci_init(void) char rev[32]; int err; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c index 9746cc5ffff..6b0d19d963d 100644 --- a/drivers/isdn/hardware/avm/b1pcmcia.c +++ b/drivers/isdn/hardware/avm/b1pcmcia.c @@ -1,9 +1,9 @@ /* $Id: b1pcmcia.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * + * * Module for AVM B1/M1/M2 PCMCIA-card. - * + * * Copyright 1999 by Carsten Paeth <calle@calle.de> - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * @@ -74,15 +74,15 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq, cinfo = card->ctrlinfo; switch (cardtype) { - case avm_m1: sprintf(card->name, "m1-%x", port); break; - case avm_m2: sprintf(card->name, "m2-%x", port); break; - default: sprintf(card->name, "b1pcmcia-%x", port); break; + case avm_m1: sprintf(card->name, "m1-%x", port); break; + case avm_m2: sprintf(card->name, "m2-%x", port); break; + default: sprintf(card->name, "b1pcmcia-%x", port); break; } card->port = port; card->irq = irq; card->cardtype = cardtype; - retval = request_irq(card->irq, b1_interrupt, 0, card->name, card); + retval = request_irq(card->irq, b1_interrupt, IRQF_SHARED, card->name, card); if (retval) { printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", card->irq); @@ -108,7 +108,7 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq, cinfo->capi_ctrl.load_firmware = b1_load_firmware; cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo; - cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; + cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops; strcpy(cinfo->capi_ctrl.name, card->name); retval = attach_capi_ctr(&cinfo->capi_ctrl); @@ -117,9 +117,9 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq, goto err_free_irq; } switch (cardtype) { - case avm_m1: cardname = "M1"; break; - case avm_m2: cardname = "M2"; break; - default : cardname = "B1 PCMCIA"; break; + case avm_m1: cardname = "M1"; break; + case avm_m2: cardname = "M2"; break; + default: cardname = "B1 PCMCIA"; break; } printk(KERN_INFO "b1pcmcia: AVM %s at i/o %#x, irq %d, revision %d\n", @@ -128,11 +128,11 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq, list_add(&card->list, &cards); return cinfo->capi_ctrl.cnr; - err_free_irq: +err_free_irq: free_irq(card->irq, card); - err_free: +err_free: b1_free_card(card); - err: +err: return retval; } @@ -175,7 +175,7 @@ int b1pcmcia_delcard(unsigned int port, unsigned irq) { struct list_head *l; avmcard *card; - + list_for_each(l, &cards) { card = list_entry(l, avmcard, list); if (card->port == port && card->irq == irq) { @@ -201,10 +201,10 @@ static int __init b1pcmcia_init(void) char *p; char rev[32]; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index 724aac2c1cc..5d00d72fe48 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c @@ -1,7 +1,7 @@ /* $Id: c4.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * + * * Module for AVM C4 & C2 card. - * + * * Copyright 1999 by Carsten Paeth <calle@calle.de> * * This software may be used and distributed according to the terms @@ -9,9 +9,10 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/skbuff.h> #include <linux/delay.h> #include <linux/mm.h> @@ -21,6 +22,7 @@ #include <linux/capi.h> #include <linux/kernelcapi.h> #include <linux/init.h> +#include <linux/gfp.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/netdevice.h> @@ -29,8 +31,8 @@ #include <linux/isdn/capilli.h> #include "avmcard.h" -#undef CONFIG_C4_DEBUG -#undef CONFIG_C4_POLLDEBUG +#undef AVM_C4_DEBUG +#undef AVM_C4_POLLDEBUG /* ------------------------------------------------------------- */ @@ -38,7 +40,7 @@ static char *revision = "$Revision: 1.1.2.2 $"; /* ------------------------------------------------------------- */ -static int suppress_pollack; +static bool suppress_pollack; static struct pci_device_id c4_pci_tbl[] = { { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 0, 0, (unsigned long)4 }, @@ -50,7 +52,7 @@ MODULE_DEVICE_TABLE(pci, c4_pci_tbl); MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards"); MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); -MODULE_PARM(suppress_pollack, "0-1i"); +module_param(suppress_pollack, bool, 0); /* ------------------------------------------------------------- */ @@ -127,8 +129,8 @@ static void c4_dispatch_tx(avmcard *card); /* ------------------------------------------------------------- */ -#define RESET_TIMEOUT (15*HZ) /* 15 sec */ -#define PEEK_POKE_TIMEOUT (HZ/10) /* 0.1 sec */ +#define RESET_TIMEOUT (15 * HZ) /* 15 sec */ +#define PEEK_POKE_TIMEOUT (HZ / 10) /* 0.1 sec */ /* ------------------------------------------------------------- */ @@ -146,7 +148,7 @@ static inline int wait_for_doorbell(avmcard *card, unsigned long t) unsigned long stop; stop = jiffies + t; - while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) { + while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) { if (!time_before(jiffies, stop)) return -1; mb(); @@ -157,40 +159,40 @@ static inline int wait_for_doorbell(avmcard *card, unsigned long t) static int c4_poke(avmcard *card, unsigned long off, unsigned long value) { - if (wait_for_doorbell(card, HZ/10) < 0) + if (wait_for_doorbell(card, HZ / 10) < 0) return -1; - - c4outmeml(card->mbase+MBOX_PEEK_POKE, off); - c4outmeml(card->mbase+DOORBELL, DBELL_ADDR); - if (wait_for_doorbell(card, HZ/10) < 0) + c4outmeml(card->mbase + MBOX_PEEK_POKE, off); + c4outmeml(card->mbase + DOORBELL, DBELL_ADDR); + + if (wait_for_doorbell(card, HZ / 10) < 0) return -1; - c4outmeml(card->mbase+MBOX_PEEK_POKE, value); - c4outmeml(card->mbase+DOORBELL, DBELL_DATA | DBELL_ADDR); + c4outmeml(card->mbase + MBOX_PEEK_POKE, value); + c4outmeml(card->mbase + DOORBELL, DBELL_DATA | DBELL_ADDR); return 0; } static int c4_peek(avmcard *card, unsigned long off, unsigned long *valuep) { - if (wait_for_doorbell(card, HZ/10) < 0) + if (wait_for_doorbell(card, HZ / 10) < 0) return -1; - c4outmeml(card->mbase+MBOX_PEEK_POKE, off); - c4outmeml(card->mbase+DOORBELL, DBELL_RNWR | DBELL_ADDR); + c4outmeml(card->mbase + MBOX_PEEK_POKE, off); + c4outmeml(card->mbase + DOORBELL, DBELL_RNWR | DBELL_ADDR); - if (wait_for_doorbell(card, HZ/10) < 0) + if (wait_for_doorbell(card, HZ / 10) < 0) return -1; - *valuep = c4inmeml(card->mbase+MBOX_PEEK_POKE); + *valuep = c4inmeml(card->mbase + MBOX_PEEK_POKE); return 0; } /* ------------------------------------------------------------- */ -static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file) +static int c4_load_t4file(avmcard *card, capiloaddatapart *t4file) { u32 val; unsigned char *dp; @@ -200,7 +202,7 @@ static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file) dp = t4file->data; left = t4file->len; while (left >= sizeof(u32)) { - if (t4file->user) { + if (t4file->user) { if (copy_from_user(&val, dp, sizeof(val))) return -EFAULT; } else { @@ -208,7 +210,7 @@ static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file) } if (c4_poke(card, loadoff, val)) { printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); + card->name); return -EIO; } left -= sizeof(u32); @@ -225,7 +227,7 @@ static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file) } if (c4_poke(card, loadoff, val)) { printk(KERN_ERR "%s: corrupted firmware file ?\n", - card->name); + card->name); return -EIO; } } @@ -295,13 +297,13 @@ static void c4_reset(avmcard *card) { unsigned long stop; - c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM); + c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM); - stop = jiffies + HZ*10; - while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) { + stop = jiffies + HZ * 10; + while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) { if (!time_before(jiffies, stop)) return; - c4outmeml(card->mbase+DOORBELL, DBELL_ADDR); + c4outmeml(card->mbase + DOORBELL, DBELL_ADDR); mb(); } @@ -315,89 +317,89 @@ static int c4_detect(avmcard *card) { unsigned long stop, dummy; - c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c); - if (c4inmeml(card->mbase+PCI_OUT_INT_MASK) != 0x0c) + c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c); + if (c4inmeml(card->mbase + PCI_OUT_INT_MASK) != 0x0c) return 1; - c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM); + c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM); - stop = jiffies + HZ*10; - while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) { + stop = jiffies + HZ * 10; + while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) { if (!time_before(jiffies, stop)) return 2; - c4outmeml(card->mbase+DOORBELL, DBELL_ADDR); + c4outmeml(card->mbase + DOORBELL, DBELL_ADDR); mb(); } c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0); c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0); - c4outmeml(card->mbase+MAILBOX_0, 0x55aa55aa); - if (c4inmeml(card->mbase+MAILBOX_0) != 0x55aa55aa) return 3; + c4outmeml(card->mbase + MAILBOX_0, 0x55aa55aa); + if (c4inmeml(card->mbase + MAILBOX_0) != 0x55aa55aa) return 3; - c4outmeml(card->mbase+MAILBOX_0, 0xaa55aa55); - if (c4inmeml(card->mbase+MAILBOX_0) != 0xaa55aa55) return 4; + c4outmeml(card->mbase + MAILBOX_0, 0xaa55aa55); + if (c4inmeml(card->mbase + MAILBOX_0) != 0xaa55aa55) return 4; - if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_SA_MASK, 0)) return 5; - if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_PCI_MASK, 0)) return 6; - if (c4_poke(card, DC21285_ARMCSR_BASE+SA_CONTROL, SA_CTL_ALLRIGHT)) + if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_SA_MASK, 0)) return 5; + if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_PCI_MASK, 0)) return 6; + if (c4_poke(card, DC21285_ARMCSR_BASE + SA_CONTROL, SA_CTL_ALLRIGHT)) return 7; - if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_CYCLE, INIT_XBUS_CYCLE)) + if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_CYCLE, INIT_XBUS_CYCLE)) return 8; - if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_STROBE, INIT_XBUS_STROBE)) + if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_STROBE, INIT_XBUS_STROBE)) return 8; - if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, 0)) return 9; + if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, 0)) return 9; - mdelay(1); + mdelay(1); if (c4_peek(card, DC21285_DRAM_A0MR, &dummy)) return 10; if (c4_peek(card, DC21285_DRAM_A1MR, &dummy)) return 11; if (c4_peek(card, DC21285_DRAM_A2MR, &dummy)) return 12; if (c4_peek(card, DC21285_DRAM_A3MR, &dummy)) return 13; - if (c4_poke(card, DC21285_DRAM_A0MR+CAS_OFFSET, 0)) return 14; - if (c4_poke(card, DC21285_DRAM_A1MR+CAS_OFFSET, 0)) return 15; - if (c4_poke(card, DC21285_DRAM_A2MR+CAS_OFFSET, 0)) return 16; - if (c4_poke(card, DC21285_DRAM_A3MR+CAS_OFFSET, 0)) return 17; + if (c4_poke(card, DC21285_DRAM_A0MR + CAS_OFFSET, 0)) return 14; + if (c4_poke(card, DC21285_DRAM_A1MR + CAS_OFFSET, 0)) return 15; + if (c4_poke(card, DC21285_DRAM_A2MR + CAS_OFFSET, 0)) return 16; + if (c4_poke(card, DC21285_DRAM_A3MR + CAS_OFFSET, 0)) return 17; - mdelay(1); + mdelay(1); - if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, DRAM_TIMING_DEF)) + if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, DRAM_TIMING_DEF)) return 18; - if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_0,DRAM_AD_SZ_DEF0)) + if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_0, DRAM_AD_SZ_DEF0)) return 19; - if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_1,DRAM_AD_SZ_NULL)) + if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_1, DRAM_AD_SZ_NULL)) return 20; - if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_2,DRAM_AD_SZ_NULL)) + if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_2, DRAM_AD_SZ_NULL)) return 21; - if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_3,DRAM_AD_SZ_NULL)) + if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_3, DRAM_AD_SZ_NULL)) return 22; /* Transputer test */ - - if ( c4_poke(card, 0x000000, 0x11111111) + + if (c4_poke(card, 0x000000, 0x11111111) || c4_poke(card, 0x400000, 0x22222222) - || c4_poke(card, 0x800000, 0x33333333) - || c4_poke(card, 0xC00000, 0x44444444)) + || c4_poke(card, 0x800000, 0x33333333) + || c4_poke(card, 0xC00000, 0x44444444)) return 23; - if ( c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111 + if (c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111 || c4_peek(card, 0x400000, &dummy) || dummy != 0x22222222 - || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333 - || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444) + || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333 + || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444) return 24; - if ( c4_poke(card, 0x000000, 0x55555555) + if (c4_poke(card, 0x000000, 0x55555555) || c4_poke(card, 0x400000, 0x66666666) - || c4_poke(card, 0x800000, 0x77777777) - || c4_poke(card, 0xC00000, 0x88888888)) + || c4_poke(card, 0x800000, 0x77777777) + || c4_poke(card, 0xC00000, 0x88888888)) return 25; - if ( c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555 + if (c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555 || c4_peek(card, 0x400000, &dummy) || dummy != 0x66666666 - || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777 - || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888) + || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777 + || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888) return 26; return 0; @@ -421,7 +423,7 @@ static void c4_dispatch_tx(avmcard *card) skb = skb_dequeue(&dma->send_queue); if (!skb) { -#ifdef CONFIG_C4_DEBUG +#ifdef AVM_C4_DEBUG printk(KERN_DEBUG "%s: tx underrun\n", card->name); #endif return; @@ -445,29 +447,30 @@ static void c4_dispatch_tx(avmcard *card) _put_slice(&p, skb->data, len); } txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf; -#ifdef CONFIG_C4_DEBUG +#ifdef AVM_C4_DEBUG printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen); #endif } else { - txlen = skb->len-2; -#ifdef CONFIG_C4_POLLDEBUG + txlen = skb->len - 2; +#ifdef AVM_C4_POLLDEBUG if (skb->data[2] == SEND_POLLACK) printk(KERN_INFO "%s: ack to c4\n", card->name); #endif -#ifdef CONFIG_C4_DEBUG +#ifdef AVM_C4_DEBUG printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n", - card->name, skb->data[2], txlen); + card->name, skb->data[2], txlen); #endif - memcpy(dma->sendbuf.dmabuf, skb->data+2, skb->len-2); + skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf, + skb->len - 2); } txlen = (txlen + 3) & ~3; - c4outmeml(card->mbase+MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr); - c4outmeml(card->mbase+MBOX_DOWN_LEN, txlen); + c4outmeml(card->mbase + MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr); + c4outmeml(card->mbase + MBOX_DOWN_LEN, txlen); card->csr |= DBELL_DOWN_ARM; - c4outmeml(card->mbase+DOORBELL, DBELL_DOWN_ARM); + c4outmeml(card->mbase + DOORBELL, DBELL_DOWN_ARM); dev_kfree_skb_any(skb); } @@ -482,7 +485,7 @@ static void queue_pollack(avmcard *card) skb = alloc_skb(3, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost poll ack\n", - card->name); + card->name); return; } p = skb->data; @@ -509,11 +512,11 @@ static void c4_handle_rx(avmcard *card) u32 cidx; -#ifdef CONFIG_C4_DEBUG +#ifdef AVM_C4_DEBUG printk(KERN_DEBUG "%s: rx 0x%x len=%lu\n", card->name, - b1cmd, (unsigned long)dma->recvlen); + b1cmd, (unsigned long)dma->recvlen); #endif - + switch (b1cmd) { case RECEIVE_DATA_B3_IND: @@ -525,13 +528,13 @@ static void c4_handle_rx(avmcard *card) ctrl = &card->ctrlinfo[cidx].capi_ctrl; if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf+MsgLen, 0, 30-MsgLen); + memset(card->msgbuf + MsgLen, 0, 30 - MsgLen); MsgLen = 30; CAPIMSG_SETLEN(card->msgbuf, 30); } - if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) { + if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); @@ -550,7 +553,7 @@ static void c4_handle_rx(avmcard *card) if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) @@ -567,7 +570,7 @@ static void c4_handle_rx(avmcard *card) ApplId = _get_word(&p); NCCI = _get_word(&p); WindowSize = _get_word(&p); - cidx = (NCCI&0x7f) - card->cardnr; + cidx = (NCCI & 0x7f) - card->cardnr; if (cidx >= card->nlogcontr) cidx = 0; capilib_new_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI, WindowSize); @@ -580,26 +583,26 @@ static void c4_handle_rx(avmcard *card) NCCI = _get_word(&p); if (NCCI != 0xffffffff) { - cidx = (NCCI&0x7f) - card->cardnr; + cidx = (NCCI & 0x7f) - card->cardnr; if (cidx >= card->nlogcontr) cidx = 0; capilib_free_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI); } break; case RECEIVE_START: -#ifdef CONFIG_C4_POLLDEBUG +#ifdef AVM_C4_POLLDEBUG printk(KERN_INFO "%s: poll from c4\n", card->name); #endif if (!suppress_pollack) queue_pollack(card); - for (cidx=0; cidx < card->nr_controllers; cidx++) { + for (cidx = 0; cidx < card->nr_controllers; cidx++) { ctrl = &card->ctrlinfo[cidx].capi_ctrl; capi_ctr_resume_output(ctrl); } break; case RECEIVE_STOP: - for (cidx=0; cidx < card->nr_controllers; cidx++) { + for (cidx = 0; cidx < card->nr_controllers; cidx++) { ctrl = &card->ctrlinfo[cidx].capi_ctrl; capi_ctr_suspend_output(ctrl); } @@ -607,14 +610,14 @@ static void c4_handle_rx(avmcard *card) case RECEIVE_INIT: - cidx = card->nlogcontr; + cidx = card->nlogcontr; if (cidx >= card->nr_controllers) { printk(KERN_ERR "%s: card with %d controllers ??\n", - card->name, cidx+1); + card->name, cidx + 1); break; } - card->nlogcontr++; - cinfo = &card->ctrlinfo[cidx]; + card->nlogcontr++; + cinfo = &card->ctrlinfo[cidx]; ctrl = &cinfo->capi_ctrl; cinfo->versionlen = _get_slice(&p, cinfo->versionbuf); b1_parse_version(cinfo); @@ -629,23 +632,23 @@ static void c4_handle_rx(avmcard *card) ApplId = (unsigned) _get_word(&p); MsgLen = _get_slice(&p, card->msgbuf); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); + card->name, ApplId, card->msgbuf); break; case RECEIVE_DEBUGMSG: MsgLen = _get_slice(&p, card->msgbuf); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); @@ -653,7 +656,7 @@ static void c4_handle_rx(avmcard *card) default: printk(KERN_ERR "%s: c4_interrupt: 0x%x ???\n", - card->name, b1cmd); + card->name, b1cmd); return; } } @@ -666,20 +669,22 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) u32 status; spin_lock_irqsave(&card->lock, flags); - status = c4inmeml(card->mbase+DOORBELL); + status = c4inmeml(card->mbase + DOORBELL); if (status & DBELL_RESET_HOST) { u_int i; - c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c); + c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c); spin_unlock_irqrestore(&card->lock, flags); if (card->nlogcontr == 0) return IRQ_HANDLED; printk(KERN_ERR "%s: unexpected reset\n", card->name); - for (i=0; i < card->nr_controllers; i++) { + for (i = 0; i < card->nr_controllers; i++) { avmctrl_info *cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); + spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); - capi_ctr_reseted(&cinfo->capi_ctrl); + spin_unlock_irqrestore(&card->lock, flags); + capi_ctr_down(&cinfo->capi_ctrl); } card->nlogcontr = 0; return IRQ_HANDLED; @@ -690,23 +695,23 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) spin_unlock_irqrestore(&card->lock, flags); return IRQ_HANDLED; } - c4outmeml(card->mbase+DOORBELL, status); + c4outmeml(card->mbase + DOORBELL, status); if ((status & DBELL_UP_HOST) != 0) { - card->dma->recvlen = c4inmeml(card->mbase+MBOX_UP_LEN); - c4outmeml(card->mbase+MBOX_UP_LEN, 0); + card->dma->recvlen = c4inmeml(card->mbase + MBOX_UP_LEN); + c4outmeml(card->mbase + MBOX_UP_LEN, 0); c4_handle_rx(card); card->dma->recvlen = 0; - c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size); - c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM); + c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size); + c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM); } if ((status & DBELL_DOWN_HOST) != 0) { card->csr &= ~DBELL_DOWN_ARM; - c4_dispatch_tx(card); + c4_dispatch_tx(card); } else if (card->csr & DBELL_DOWN_HOST) { - if (c4inmeml(card->mbase+MBOX_DOWN_LEN) == 0) { - card->csr &= ~DBELL_DOWN_ARM; + if (c4inmeml(card->mbase + MBOX_DOWN_LEN) == 0) { + card->csr &= ~DBELL_DOWN_ARM; c4_dispatch_tx(card); } } @@ -714,7 +719,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) return IRQ_HANDLED; } -static irqreturn_t c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +static irqreturn_t c4_interrupt(int interrupt, void *devptr) { avmcard *card = devptr; @@ -727,11 +732,12 @@ static void c4_send_init(avmcard *card) { struct sk_buff *skb; void *p; + unsigned long flags; skb = alloc_skb(15, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); + card->name); return; } p = skb->data; @@ -739,23 +745,26 @@ static void c4_send_init(avmcard *card) _put_byte(&p, 0); _put_byte(&p, SEND_INIT); _put_word(&p, CAPI_MAXAPPL); - _put_word(&p, AVM_NCCI_PER_CHANNEL*30); + _put_word(&p, AVM_NCCI_PER_CHANNEL * 30); _put_word(&p, card->cardnr - 1); skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); + spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); + spin_unlock_irqrestore(&card->lock, flags); } static int queue_sendconfigword(avmcard *card, u32 val) { struct sk_buff *skb; + unsigned long flags; void *p; - skb = alloc_skb(3+4, GFP_ATOMIC); + skb = alloc_skb(3 + 4, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, send config\n", - card->name); + card->name); return -ENOMEM; } p = skb->data; @@ -766,7 +775,9 @@ static int queue_sendconfigword(avmcard *card, u32 val) skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); + spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); + spin_unlock_irqrestore(&card->lock, flags); return 0; } @@ -776,10 +787,10 @@ static int queue_sendconfig(avmcard *card, char cval[4]) unsigned long flags; void *p; - skb = alloc_skb(3+4, GFP_ATOMIC); + skb = alloc_skb(3 + 4, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, send config\n", - card->name); + card->name); return -ENOMEM; } p = skb->data; @@ -793,20 +804,20 @@ static int queue_sendconfig(avmcard *card, char cval[4]) skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); - + spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); spin_unlock_irqrestore(&card->lock, flags); return 0; } -static int c4_send_config(avmcard *card, capiloaddatapart * config) +static int c4_send_config(avmcard *card, capiloaddatapart *config) { u8 val[4]; unsigned char *dp; u_int left; int retval; - + if ((retval = queue_sendconfigword(card, 1)) != 0) return retval; if ((retval = queue_sendconfigword(card, config->len)) != 0) @@ -815,7 +826,7 @@ static int c4_send_config(avmcard *card, capiloaddatapart * config) dp = config->data; left = config->len; while (left >= sizeof(u32)) { - if (config->user) { + if (config->user) { if (copy_from_user(val, dp, sizeof(val))) return -EFAULT; } else { @@ -849,37 +860,37 @@ static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) if ((retval = c4_load_t4file(card, &data->firmware))) { printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); + card->name); c4_reset(card); return retval; } card->csr = 0; - c4outmeml(card->mbase+MBOX_UP_LEN, 0); - c4outmeml(card->mbase+MBOX_DOWN_LEN, 0); - c4outmeml(card->mbase+DOORBELL, DBELL_INIT); + c4outmeml(card->mbase + MBOX_UP_LEN, 0); + c4outmeml(card->mbase + MBOX_DOWN_LEN, 0); + c4outmeml(card->mbase + DOORBELL, DBELL_INIT); mdelay(1); - c4outmeml(card->mbase+DOORBELL, - DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST); + c4outmeml(card->mbase + DOORBELL, + DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST); - c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x08); + c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x08); card->dma->recvlen = 0; - c4outmeml(card->mbase+MBOX_UP_ADDR, card->dma->recvbuf.dmaaddr); - c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size); - c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM); + c4outmeml(card->mbase + MBOX_UP_ADDR, card->dma->recvbuf.dmaaddr); + c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size); + c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM); if (data->configuration.len > 0 && data->configuration.data) { retval = c4_send_config(card, &data->configuration); if (retval) { printk(KERN_ERR "%s: failed to set config!!\n", - card->name); + card->name); c4_reset(card); return retval; } } - c4_send_init(card); + c4_send_init(card); return 0; } @@ -894,14 +905,14 @@ static void c4_reset_ctr(struct capi_ctr *ctrl) spin_lock_irqsave(&card->lock, flags); - c4_reset(card); + c4_reset(card); spin_unlock_irqrestore(&card->lock, flags); - for (i=0; i < card->nr_controllers; i++) { + for (i = 0; i < card->nr_controllers; i++) { cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); - capi_ctr_reseted(&cinfo->capi_ctrl); + capi_ctr_down(&cinfo->capi_ctrl); } card->nlogcontr = 0; } @@ -915,9 +926,9 @@ static void c4_remove(struct pci_dev *pdev) if (!card) return; - c4_reset(card); + c4_reset(card); - for (i=0; i < card->nr_controllers; i++) { + for (i = 0; i < card->nr_controllers; i++) { cinfo = &card->ctrlinfo[i]; detach_capi_ctr(&cinfo->capi_ctrl); } @@ -925,8 +936,8 @@ static void c4_remove(struct pci_dev *pdev) free_irq(card->irq, card); iounmap(card->mbase); release_region(card->port, AVMB1_PORTLEN); - avmcard_dma_free(card->dma); - pci_set_drvdata(pdev, NULL); + avmcard_dma_free(card->dma); + pci_set_drvdata(pdev, NULL); b1_free_card(card); } @@ -934,8 +945,8 @@ static void c4_remove(struct pci_dev *pdev) static void c4_register_appl(struct capi_ctr *ctrl, - u16 appl, - capi_register_params *rp) + u16 appl, + capi_register_params *rp) { avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; @@ -954,7 +965,7 @@ static void c4_register_appl(struct capi_ctr *ctrl, skb = alloc_skb(23, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost register appl.\n", - card->name); + card->name); return; } p = skb->data; @@ -962,14 +973,14 @@ static void c4_register_appl(struct capi_ctr *ctrl, _put_byte(&p, 0); _put_byte(&p, SEND_REGISTER); _put_word(&p, appl); - _put_word(&p, 1024 * (nconn+1)); + _put_word(&p, 1024 * (nconn + 1)); _put_word(&p, nconn); _put_word(&p, rp->datablkcnt); _put_word(&p, rp->datablklen); skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); - + spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); spin_unlock_irqrestore(&card->lock, flags); @@ -986,13 +997,15 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl) struct sk_buff *skb; void *p; + spin_lock_irqsave(&card->lock, flags); capilib_release_appl(&cinfo->ncci_head, appl); + spin_unlock_irqrestore(&card->lock, flags); if (ctrl->cnr == card->cardnr) { skb = alloc_skb(7, GFP_ATOMIC); if (!skb) { printk(KERN_CRIT "%s: no memory, lost release appl.\n", - card->name); + card->name); return; } p = skb->data; @@ -1019,7 +1032,8 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) u16 retval = CAPI_NOERROR; unsigned long flags; - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { + spin_lock_irqsave(&card->lock, flags); + if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), @@ -1027,10 +1041,9 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) } if (retval == CAPI_NOERROR) { skb_queue_tail(&card->dma->send_queue, skb); - spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); } + spin_unlock_irqrestore(&card->lock, flags); return retval; } @@ -1052,19 +1065,18 @@ static char *c4_procinfo(struct capi_ctr *ctrl) return cinfo->infobuf; } -static int c4_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl) +static int c4_proc_show(struct seq_file *m, void *v) { + struct capi_ctr *ctrl = m->private; avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; u8 flag; - int len = 0; char *s; - len += sprintf(page+len, "%-16s %s\n", "name", card->name); - len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); - len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); - len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); + seq_printf(m, "%-16s %s\n", "name", card->name); + seq_printf(m, "%-16s 0x%x\n", "io", card->port); + seq_printf(m, "%-16s %d\n", "irq", card->irq); + seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase); switch (card->cardtype) { case avm_b1isa: s = "B1 ISA"; break; case avm_b1pci: s = "B1 PCI"; break; @@ -1077,49 +1089,57 @@ static int c4_read_proc(char *page, char **start, off_t off, case avm_c2: s = "C2"; break; default: s = "???"; break; } - len += sprintf(page+len, "%-16s %s\n", "type", s); - if ((s = cinfo->version[VER_DRIVER]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); - if ((s = cinfo->version[VER_CARDTYPE]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); - if ((s = cinfo->version[VER_SERIAL]) != 0) - len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); + seq_printf(m, "%-16s %s\n", "type", s); + if ((s = cinfo->version[VER_DRIVER]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_driver", s); + if ((s = cinfo->version[VER_CARDTYPE]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_cardtype", s); + if ((s = cinfo->version[VER_SERIAL]) != NULL) + seq_printf(m, "%-16s %s\n", "ver_serial", s); if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[3]; - if (flag) - len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", - "protocol", - (flag & 0x01) ? " DSS1" : "", - (flag & 0x02) ? " CT1" : "", - (flag & 0x04) ? " VN3" : "", - (flag & 0x08) ? " NI1" : "", - (flag & 0x10) ? " AUSTEL" : "", - (flag & 0x20) ? " ESS" : "", - (flag & 0x40) ? " 1TR6" : "" - ); + flag = ((u8 *)(ctrl->profile.manu))[3]; + if (flag) + seq_printf(m, "%-16s%s%s%s%s%s%s%s\n", + "protocol", + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); } if (card->cardtype != avm_m1) { - flag = ((u8 *)(ctrl->profile.manu))[5]; + flag = ((u8 *)(ctrl->profile.manu))[5]; if (flag) - len += sprintf(page+len, "%-16s%s%s%s%s\n", - "linetype", - (flag & 0x01) ? " point to point" : "", - (flag & 0x02) ? " point to multipoint" : "", - (flag & 0x08) ? " leased line without D-channel" : "", - (flag & 0x04) ? " leased line with D-channel" : "" - ); + seq_printf(m, "%-16s%s%s%s%s\n", + "linetype", + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); } - len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); - - if (off+count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len-off) ? count : len-off); + seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname); + + return 0; +} + +static int c4_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, c4_proc_show, PDE_DATA(inode)); } +static const struct file_operations c4_proc_fops = { + .owner = THIS_MODULE, + .open = c4_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* ------------------------------------------------------------- */ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, @@ -1136,7 +1156,7 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, retval = -ENOMEM; goto err; } - card->dma = avmcard_dma_alloc("c4", dev, 2048+128, 2048+128); + card->dma = avmcard_dma_alloc("c4", dev, 2048 + 128, 2048 + 128); if (!card->dma) { printk(KERN_WARNING "c4: no memory.\n"); retval = -ENOMEM; @@ -1157,7 +1177,7 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, } card->mbase = ioremap(card->membase, 128); - if (card->mbase == 0) { + if (card->mbase == NULL) { printk(KERN_NOTICE "c4: can't remap memory at 0x%lx\n", card->membase); retval = -EIO; @@ -1173,14 +1193,14 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, } c4_reset(card); - retval = request_irq(card->irq, c4_interrupt, SA_SHIRQ, card->name, card); + retval = request_irq(card->irq, c4_interrupt, IRQF_SHARED, card->name, card); if (retval) { - printk(KERN_ERR "c4: unable to get IRQ %d.\n",card->irq); + printk(KERN_ERR "c4: unable to get IRQ %d.\n", card->irq); retval = -EBUSY; goto err_unmap; } - for (i=0; i < nr_controllers ; i++) { + for (i = 0; i < nr_controllers; i++) { cinfo = &card->ctrlinfo[i]; cinfo->capi_ctrl.owner = THIS_MODULE; cinfo->capi_ctrl.driver_name = "c4"; @@ -1191,7 +1211,7 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, cinfo->capi_ctrl.load_firmware = c4_load_firmware; cinfo->capi_ctrl.reset_ctr = c4_reset_ctr; cinfo->capi_ctrl.procinfo = c4_procinfo; - cinfo->capi_ctrl.ctr_read_proc = c4_read_proc; + cinfo->capi_ctrl.proc_fops = &c4_proc_fops; strcpy(cinfo->capi_ctrl.name, card->name); retval = attach_capi_ctr(&cinfo->capi_ctrl); @@ -1213,24 +1233,23 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, pci_set_drvdata(dev, card); return 0; - err_free_irq: +err_free_irq: free_irq(card->irq, card); - err_unmap: +err_unmap: iounmap(card->mbase); - err_release_region: +err_release_region: release_region(card->port, AVMB1_PORTLEN); - err_free_dma: +err_free_dma: avmcard_dma_free(card->dma); - err_free: +err_free: b1_free_card(card); - err: +err: return retval; } /* ------------------------------------------------------------- */ -static int __devinit c4_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int c4_probe(struct pci_dev *dev, const struct pci_device_id *ent) { int nr = ent->driver_data; int retval = 0; @@ -1245,24 +1264,25 @@ static int __devinit c4_probe(struct pci_dev *dev, param.port = pci_resource_start(dev, 1); param.irq = dev->irq; param.membase = pci_resource_start(dev, 0); - + printk(KERN_INFO "c4: PCI BIOS reports AVM-C%d at i/o %#x, irq %d, mem %#x\n", nr, param.port, param.irq, param.membase); - + retval = c4_add_card(¶m, dev, nr); if (retval != 0) { printk(KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n", nr, param.port, param.irq, param.membase); + pci_disable_device(dev); return -ENODEV; } return 0; } static struct pci_driver c4_pci_driver = { - .name = "c4", - .id_table = c4_pci_tbl, - .probe = c4_probe, - .remove = c4_remove, + .name = "c4", + .id_table = c4_pci_tbl, + .probe = c4_probe, + .remove = c4_remove, }; static struct capi_driver capi_driver_c2 = { @@ -1281,10 +1301,10 @@ static int __init c4_init(void) char rev[32]; int err; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c index 3b701d97bdf..72ef1885395 100644 --- a/drivers/isdn/hardware/avm/t1isa.c +++ b/drivers/isdn/hardware/avm/t1isa.c @@ -1,9 +1,9 @@ /* $Id: t1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ - * + * * Module for AVM T1 HEMA-card. - * + * * Copyright 1999 by Carsten Paeth <calle@calle.de> - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * @@ -21,6 +21,7 @@ #include <linux/kernelcapi.h> #include <linux/init.h> #include <linux/pci.h> +#include <linux/gfp.h> #include <asm/io.h> #include <linux/isdn/capicmd.h> #include <linux/isdn/capiutil.h> @@ -66,7 +67,7 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) int i; reverse_cardnr = ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1) - | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3); + | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3); cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf); cregs[1] = 0x00; /* fast & slow link connected to CON1 */ cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */ @@ -85,53 +86,53 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) /* board reset */ t1outp(base, T1_RESETBOARD, 0xf); mdelay(100); - dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */ + dummy = t1inp(base, T1_FASTLINK + T1_OUTSTAT); /* first read */ /* write config */ dummy = (base >> 4) & 0xff; - for (i=1;i<=0xf;i++) t1outp(base, i, dummy); + for (i = 1; i <= 0xf; i++) t1outp(base, i, dummy); t1outp(base, HEMA_PAL_ID & 0xf, dummy); t1outp(base, HEMA_PAL_ID >> 4, cregs[0]); - for(i=1;i<7;i++) t1outp(base, 0, cregs[i]); + for (i = 1; i < 7; i++) t1outp(base, 0, cregs[i]); t1outp(base, ((base >> 4)) & 0x3, cregs[7]); /* restore_flags(flags); */ mdelay(100); - t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); - t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); + t1outp(base, T1_FASTLINK + T1_RESETLINK, 0); + t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0); mdelay(10); - t1outp(base, T1_FASTLINK+T1_RESETLINK, 1); - t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1); + t1outp(base, T1_FASTLINK + T1_RESETLINK, 1); + t1outp(base, T1_SLOWLINK + T1_RESETLINK, 1); mdelay(100); - t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); - t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); + t1outp(base, T1_FASTLINK + T1_RESETLINK, 0); + t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0); mdelay(10); - t1outp(base, T1_FASTLINK+T1_ANALYSE, 0); + t1outp(base, T1_FASTLINK + T1_ANALYSE, 0); mdelay(5); - t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0); + t1outp(base, T1_SLOWLINK + T1_ANALYSE, 0); - if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */ + if (t1inp(base, T1_FASTLINK + T1_OUTSTAT) != 0x1) /* tx empty */ return 1; - if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */ + if (t1inp(base, T1_FASTLINK + T1_INSTAT) != 0x0) /* rx empty */ return 2; - if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0) + if (t1inp(base, T1_FASTLINK + T1_IRQENABLE) != 0x0) return 3; - if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70) + if ((t1inp(base, T1_FASTLINK + T1_FIFOSTAT) & 0xf0) != 0x70) return 4; - if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0) + if ((t1inp(base, T1_FASTLINK + T1_IRQMASTER) & 0x0e) != 0) return 5; - if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1) + if ((t1inp(base, T1_FASTLINK + T1_IDENT) & 0x7d) != 1) return 6; - if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */ + if (t1inp(base, T1_SLOWLINK + T1_OUTSTAT) != 0x1) /* tx empty */ return 7; - if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0) + if ((t1inp(base, T1_SLOWLINK + T1_IRQMASTER) & 0x0e) != 0) return 8; - if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0) + if ((t1inp(base, T1_SLOWLINK + T1_IDENT) & 0x7d) != 0) return 9; - return 0; + return 0; } -static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +static irqreturn_t t1isa_interrupt(int interrupt, void *devptr) { avmcard *card = devptr; avmctrl_info *cinfo = &card->ctrlinfo[0]; @@ -162,13 +163,13 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs * spin_unlock_irqrestore(&card->lock, flags); if (MsgLen < 30) { /* not CAPI 64Bit */ - memset(card->msgbuf+MsgLen, 0, 30-MsgLen); + memset(card->msgbuf + MsgLen, 0, 30 - MsgLen); MsgLen = 30; CAPIMSG_SETLEN(card->msgbuf, 30); } - if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) { + if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); @@ -180,17 +181,17 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs * ApplId = (unsigned) b1_get_word(card->port); MsgLen = t1_get_slice(card->port, card->msgbuf); - spin_unlock_irqrestore(&card->lock, flags); if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { + spin_unlock_irqrestore(&card->lock, flags); printk(KERN_ERR "%s: incoming packet dropped\n", - card->name); + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3) capilib_data_b3_conf(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - + spin_unlock_irqrestore(&card->lock, flags); capi_ctr_handle_message(ctrl, ApplId, skb); } break; @@ -200,21 +201,17 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs * ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); WindowSize = b1_get_word(card->port); - spin_unlock_irqrestore(&card->lock, flags); - capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); - + spin_unlock_irqrestore(&card->lock, flags); break; case RECEIVE_FREE_NCCI: ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); - spin_unlock_irqrestore(&card->lock, flags); - if (NCCI != 0xffffffff) capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - + spin_unlock_irqrestore(&card->lock, flags); break; case RECEIVE_START: @@ -245,24 +242,24 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs * MsgLen = t1_get_slice(card->port, card->msgbuf); spin_unlock_irqrestore(&card->lock, flags); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: task %d \"%s\" ready.\n", - card->name, ApplId, card->msgbuf); + card->name, ApplId, card->msgbuf); break; case RECEIVE_DEBUGMSG: MsgLen = t1_get_slice(card->port, card->msgbuf); spin_unlock_irqrestore(&card->lock, flags); card->msgbuf[MsgLen] = 0; - while ( MsgLen > 0 - && ( card->msgbuf[MsgLen-1] == '\n' - || card->msgbuf[MsgLen-1] == '\r')) { - card->msgbuf[MsgLen-1] = 0; + while (MsgLen > 0 + && (card->msgbuf[MsgLen - 1] == '\n' + || card->msgbuf[MsgLen - 1] == '\r')) { + card->msgbuf[MsgLen - 1] = 0; MsgLen--; } printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); @@ -276,7 +273,7 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs * default: spin_unlock_irqrestore(&card->lock, flags); printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n", - card->name, b1cmd); + card->name, b1cmd); return IRQ_NONE; } } @@ -299,7 +296,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) if ((retval = b1_load_t4file(card, &data->firmware))) { b1_reset(port); printk(KERN_ERR "%s: failed to load t4file!!\n", - card->name); + card->name); return retval; } @@ -307,7 +304,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) if ((retval = b1_load_config(card, &data->configuration))) { b1_reset(port); printk(KERN_ERR "%s: failed to load config!!\n", - card->name); + card->name); return retval; } } @@ -321,7 +318,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) b1_setinterrupt(port, card->irq, card->cardtype); b1_put_byte(port, SEND_INIT); b1_put_word(port, CAPI_MAXAPPL); - b1_put_word(port, AVM_NCCI_PER_CHANNEL*30); + b1_put_word(port, AVM_NCCI_PER_CHANNEL * 30); b1_put_word(port, ctrl->cnr - 1); spin_unlock_irqrestore(&card->lock, flags); @@ -333,21 +330,24 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl) avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; unsigned int port = card->port; + unsigned long flags; t1_disable_irq(port); b1_reset(port); b1_reset(port); memset(cinfo->version, 0, sizeof(cinfo->version)); + spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); - capi_ctr_reseted(ctrl); + spin_unlock_irqrestore(&card->lock, flags); + capi_ctr_down(ctrl); } static void t1isa_remove(struct pci_dev *pdev) { avmctrl_info *cinfo = pci_get_drvdata(pdev); avmcard *card; - + if (!cinfo) return; @@ -393,7 +393,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr) printk(KERN_WARNING "t1isa: invalid port 0x%x.\n", card->port); retval = -EINVAL; goto err_free; - } + } if (hema_irq_table[card->irq & 0xf] == 0) { printk(KERN_WARNING "t1isa: irq %d not valid.\n", card->irq); retval = -EINVAL; @@ -412,7 +412,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr) goto err_release_region; } - if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) { + if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) { printk(KERN_INFO "t1isa: NO card at 0x%x (%d)\n", card->port, retval); retval = -ENODEV; @@ -430,7 +430,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr) cinfo->capi_ctrl.load_firmware = t1isa_load_firmware; cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr; cinfo->capi_ctrl.procinfo = t1isa_procinfo; - cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; + cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops; strcpy(cinfo->capi_ctrl.name, card->name); retval = attach_capi_ctr(&cinfo->capi_ctrl); @@ -445,13 +445,13 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr) pci_set_drvdata(pdev, cinfo); return 0; - err_free_irq: +err_free_irq: free_irq(card->irq, card); - err_release_region: +err_release_region: release_region(card->port, AVMB1_PORTLEN); - err_free: +err_free: b1_free_card(card); - err: +err: return retval; } @@ -466,29 +466,26 @@ static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); u16 dlen, retval; + spin_lock_irqsave(&card->lock, flags); if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - if (retval != CAPI_NOERROR) + if (retval != CAPI_NOERROR) { + spin_unlock_irqrestore(&card->lock, flags); return retval; - + } dlen = CAPIMSG_DATALEN(skb->data); - spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_DATA_B3_REQ); t1_put_slice(port, skb->data, len); t1_put_slice(port, skb->data + len, dlen); - spin_unlock_irqrestore(&card->lock, flags); } else { - - spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_MESSAGE); t1_put_slice(port, skb->data, len); - spin_unlock_irqrestore(&card->lock, flags); } - + spin_unlock_irqrestore(&card->lock, flags); dev_kfree_skb_any(skb); return CAPI_NOERROR; } @@ -519,9 +516,9 @@ static int io[MAX_CARDS]; static int irq[MAX_CARDS]; static int cardnr[MAX_CARDS]; -MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i"); -MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); -MODULE_PARM(cardnr, "1-" __MODULE_STRING(MAX_CARDS) "i"); +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(cardnr, int, NULL, 0); MODULE_PARM_DESC(io, "I/O base address(es)"); MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); MODULE_PARM_DESC(cardnr, "Card number(s) (as jumpered)"); @@ -555,10 +552,10 @@ static int __init t1isa_init(void) char *p; int i; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); @@ -584,6 +581,7 @@ static void __exit t1isa_exit(void) { int i; + unregister_capi_driver(&capi_driver_t1isa); for (i = 0; i < MAX_CARDS; i++) { if (!io[i]) break; diff --git a/drivers/isdn/hardware/avm/t1pci.c b/drivers/isdn/hardware/avm/t1pci.c index 2ceec8e8419..2180b168569 100644 --- a/drivers/isdn/hardware/avm/t1pci.c +++ b/drivers/isdn/hardware/avm/t1pci.c @@ -1,15 +1,14 @@ /* $Id: t1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $ - * + * * Module for AVM T1 PCI-card. - * + * * Copyright 1999 by Carsten Paeth <calle@calle.de> - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/skbuff.h> @@ -60,7 +59,7 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev) goto err; } - card->dma = avmcard_dma_alloc("t1pci", pdev, 2048+128, 2048+128); + card->dma = avmcard_dma_alloc("t1pci", pdev, 2048 + 128, 2048 + 128); if (!card->dma) { printk(KERN_WARNING "t1pci: no memory.\n"); retval = -ENOMEM; @@ -104,7 +103,7 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev) } b1dma_reset(card); - retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card); + retval = request_irq(card->irq, b1dma_interrupt, IRQF_SHARED, card->name, card); if (retval) { printk(KERN_ERR "t1pci: unable to get IRQ %d.\n", card->irq); retval = -EBUSY; @@ -120,7 +119,7 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev) cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; cinfo->capi_ctrl.procinfo = t1pci_procinfo; - cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc; + cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops; strcpy(cinfo->capi_ctrl.name, card->name); retval = attach_capi_ctr(&cinfo->capi_ctrl); @@ -137,17 +136,17 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev) pci_set_drvdata(pdev, card); return 0; - err_free_irq: +err_free_irq: free_irq(card->irq, card); - err_unmap: +err_unmap: iounmap(card->mbase); - err_release_region: +err_release_region: release_region(card->port, AVMB1_PORTLEN); - err_free_dma: +err_free_dma: avmcard_dma_free(card->dma); - err_free: +err_free: b1_free_card(card); - err: +err: return retval; } @@ -158,7 +157,7 @@ static void t1pci_remove(struct pci_dev *pdev) avmcard *card = pci_get_drvdata(pdev); avmctrl_info *cinfo = card->ctrlinfo; - b1dma_reset(card); + b1dma_reset(card); detach_capi_ctr(&cinfo->capi_ctrl); free_irq(card->irq, card); @@ -188,8 +187,7 @@ static char *t1pci_procinfo(struct capi_ctr *ctrl) /* ------------------------------------------------------------- */ -static int __devinit t1pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int t1pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { struct capicardparams param; int retval; @@ -211,16 +209,17 @@ static int __devinit t1pci_probe(struct pci_dev *dev, if (retval != 0) { printk(KERN_ERR "t1pci: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n", param.port, param.irq, param.membase); + pci_disable_device(dev); return -ENODEV; } return 0; } static struct pci_driver t1pci_pci_driver = { - .name = "t1pci", - .id_table = t1pci_pci_tbl, - .probe = t1pci_probe, - .remove = t1pci_remove, + .name = "t1pci", + .id_table = t1pci_pci_tbl, + .probe = t1pci_probe, + .remove = t1pci_remove, }; static struct capi_driver capi_driver_t1pci = { @@ -234,10 +233,10 @@ static int __init t1pci_init(void) char rev[32]; int err; - if ((p = strchr(revision, ':')) != 0 && p[1]) { + if ((p = strchr(revision, ':')) != NULL && p[1]) { strlcpy(rev, p + 2, 32); - if ((p = strchr(rev, '$')) != 0 && p > rev) - *(p-1) = 0; + if ((p = strchr(rev, '$')) != NULL && p > rev) + *(p - 1) = 0; } else strcpy(rev, "1.0"); diff --git a/drivers/isdn/hardware/eicon/Kconfig b/drivers/isdn/hardware/eicon/Kconfig index 51e66bc6420..6082b6a5ced 100644 --- a/drivers/isdn/hardware/eicon/Kconfig +++ b/drivers/isdn/hardware/eicon/Kconfig @@ -2,52 +2,50 @@ # ISDN DIVAS Eicon driver # -menu "Active Eicon DIVA Server cards" - depends on NET && ISDN && ISDN_CAPI!=n - -config CAPI_EICON - bool "Support Eicon cards" +menuconfig CAPI_EICON + bool "Active Eicon DIVA Server cards" help Enable support for Eicon Networks active ISDN cards. +if CAPI_EICON + config ISDN_DIVAS tristate "Support Eicon DIVA Server cards" - depends on CAPI_EICON && PROC_FS && PCI + depends on PROC_FS && PCI help Say Y here if you have an Eicon Networks DIVA Server PCI ISDN card. In order to use this card, additional firmware is necessary, which has to be downloaded into the card using the divactrl utility. +if ISDN_DIVAS + config ISDN_DIVAS_BRIPCI bool "DIVA Server BRI/PCI support" - depends on ISDN_DIVAS help Enable support for DIVA Server BRI-PCI. config ISDN_DIVAS_PRIPCI bool "DIVA Server PRI/PCI support" - depends on ISDN_DIVAS help Enable support for DIVA Server PRI-PCI. config ISDN_DIVAS_DIVACAPI tristate "DIVA CAPI2.0 interface support" - depends on ISDN_DIVAS && ISDN_CAPI help You need this to provide the CAPI interface for DIVA Server cards. config ISDN_DIVAS_USERIDI tristate "DIVA User-IDI interface support" - depends on ISDN_DIVAS help Enable support for user-mode IDI interface. config ISDN_DIVAS_MAINT tristate "DIVA Maint driver support" - depends on ISDN_DIVAS && m + depends on m help - Enable Divas Maintainance driver. + Enable Divas Maintenance driver. -endmenu +endif # ISDN_DIVAS +endif # CAPI_EICON diff --git a/drivers/isdn/hardware/eicon/capi20.h b/drivers/isdn/hardware/eicon/capi20.h index 7ebcccda74d..391e4175b0b 100644 --- a/drivers/isdn/hardware/eicon/capi20.h +++ b/drivers/isdn/hardware/eicon/capi20.h @@ -1,74 +1,74 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -#ifndef _INC_CAPI20 +#ifndef _INC_CAPI20 #define _INC_CAPI20 - /* operations on message queues */ - /* the common device type for CAPI20 drivers */ +/* operations on message queues */ +/* the common device type for CAPI20 drivers */ #define FILE_DEVICE_CAPI20 0x8001 - /* DEVICE_CONTROL codes for user and kernel mode applications */ +/* DEVICE_CONTROL codes for user and kernel mode applications */ #define CAPI20_CTL_REGISTER 0x0801 #define CAPI20_CTL_RELEASE 0x0802 #define CAPI20_CTL_GET_MANUFACTURER 0x0805 #define CAPI20_CTL_GET_VERSION 0x0806 #define CAPI20_CTL_GET_SERIAL 0x0807 #define CAPI20_CTL_GET_PROFILE 0x0808 - /* INTERNAL_DEVICE_CONTROL codes for kernel mode applicatios only */ +/* INTERNAL_DEVICE_CONTROL codes for kernel mode applicatios only */ #define CAPI20_CTL_PUT_MESSAGE 0x0803 #define CAPI20_CTL_GET_MESSAGE 0x0804 - /* the wrapped codes as required by the system */ -#define CAPI_CTL_CODE(f,m) CTL_CODE(FILE_DEVICE_CAPI20,f,m,FILE_ANY_ACCESS) -#define IOCTL_CAPI_REGISTER CAPI_CTL_CODE(CAPI20_CTL_REGISTER,METHOD_BUFFERED) -#define IOCTL_CAPI_RELEASE CAPI_CTL_CODE(CAPI20_CTL_RELEASE,METHOD_BUFFERED) -#define IOCTL_CAPI_GET_MANUFACTURER CAPI_CTL_CODE(CAPI20_CTL_GET_MANUFACTURER,METHOD_BUFFERED) -#define IOCTL_CAPI_GET_VERSION CAPI_CTL_CODE(CAPI20_CTL_GET_VERSION,METHOD_BUFFERED) -#define IOCTL_CAPI_GET_SERIAL CAPI_CTL_CODE(CAPI20_CTL_GET_SERIAL,METHOD_BUFFERED) -#define IOCTL_CAPI_GET_PROFILE CAPI_CTL_CODE(CAPI20_CTL_GET_PROFILE,METHOD_BUFFERED) -#define IOCTL_CAPI_PUT_MESSAGE CAPI_CTL_CODE(CAPI20_CTL_PUT_MESSAGE,METHOD_BUFFERED) -#define IOCTL_CAPI_GET_MESSAGE CAPI_CTL_CODE(CAPI20_CTL_GET_MESSAGE,METHOD_BUFFERED) +/* the wrapped codes as required by the system */ +#define CAPI_CTL_CODE(f, m) CTL_CODE(FILE_DEVICE_CAPI20, f, m, FILE_ANY_ACCESS) +#define IOCTL_CAPI_REGISTER CAPI_CTL_CODE(CAPI20_CTL_REGISTER, METHOD_BUFFERED) +#define IOCTL_CAPI_RELEASE CAPI_CTL_CODE(CAPI20_CTL_RELEASE, METHOD_BUFFERED) +#define IOCTL_CAPI_GET_MANUFACTURER CAPI_CTL_CODE(CAPI20_CTL_GET_MANUFACTURER, METHOD_BUFFERED) +#define IOCTL_CAPI_GET_VERSION CAPI_CTL_CODE(CAPI20_CTL_GET_VERSION, METHOD_BUFFERED) +#define IOCTL_CAPI_GET_SERIAL CAPI_CTL_CODE(CAPI20_CTL_GET_SERIAL, METHOD_BUFFERED) +#define IOCTL_CAPI_GET_PROFILE CAPI_CTL_CODE(CAPI20_CTL_GET_PROFILE, METHOD_BUFFERED) +#define IOCTL_CAPI_PUT_MESSAGE CAPI_CTL_CODE(CAPI20_CTL_PUT_MESSAGE, METHOD_BUFFERED) +#define IOCTL_CAPI_GET_MESSAGE CAPI_CTL_CODE(CAPI20_CTL_GET_MESSAGE, METHOD_BUFFERED) struct divas_capi_register_params { - word MessageBufferSize; - word maxLogicalConnection; - word maxBDataBlocks; - word maxBDataLen; + word MessageBufferSize; + word maxLogicalConnection; + word maxBDataBlocks; + word maxBDataLen; }; struct divas_capi_version { - word CapiMajor; - word CapiMinor; - word ManuMajor; - word ManuMinor; + word CapiMajor; + word CapiMinor; + word ManuMajor; + word ManuMinor; }; typedef struct api_profile_s { - word Number; - word Channels; - dword Global_Options; - dword B1_Protocols; - dword B2_Protocols; - dword B3_Protocols; + word Number; + word Channels; + dword Global_Options; + dword B1_Protocols; + dword B2_Protocols; + dword B3_Protocols; } API_PROFILE; - /* ISDN Common API message types */ +/* ISDN Common API message types */ #define _ALERT_R 0x8001 #define _CONNECT_R 0x8002 #define _CONNECT_I 0x8202 @@ -93,9 +93,9 @@ typedef struct api_profile_s { #define _CONNECT_B3_T90_ACTIVE_I 0x8288 #define _MANUFACTURER_R 0x80ff #define _MANUFACTURER_I 0x82ff - /* OR this to convert a REQUEST to a CONFIRM */ +/* OR this to convert a REQUEST to a CONFIRM */ #define CONFIRM 0x0100 - /* OR this to convert a INDICATION to a RESPONSE */ +/* OR this to convert a INDICATION to a RESPONSE */ #define RESPONSE 0x0100 /*------------------------------------------------------------------*/ /* diehl isdn private MANUFACTURER codes */ @@ -115,248 +115,248 @@ typedef struct api_profile_s { /*------------------------------------------------------------------*/ /* parameter structures */ /*------------------------------------------------------------------*/ - /* ALERT-REQUEST */ +/* ALERT-REQUEST */ typedef struct { - byte structs[1]; /* Additional Info */ + byte structs[0]; /* Additional Info */ } _ALT_REQP; - /* ALERT-CONFIRM */ +/* ALERT-CONFIRM */ typedef struct { - word Info; + word Info; } _ALT_CONP; - /* CONNECT-REQUEST */ -typedef struct { - word CIP_Value; - byte structs[1]; /* Called party number, - Called party subaddress, - Calling party number, - Calling party subaddress, - B_protocol, - BC, - LLC, - HLC, - Additional Info */ +/* CONNECT-REQUEST */ +typedef struct { + word CIP_Value; + byte structs[0]; /* Called party number, + Called party subaddress, + Calling party number, + Calling party subaddress, + B_protocol, + BC, + LLC, + HLC, + Additional Info */ } _CON_REQP; - /* CONNECT-CONFIRM */ +/* CONNECT-CONFIRM */ typedef struct { - word Info; + word Info; } _CON_CONP; - /* CONNECT-INDICATION */ -typedef struct { - word CIP_Value; - byte structs[1]; /* Called party number, - Called party subaddress, - Calling party number, - Calling party subaddress, - BC, - LLC, - HLC, - Additional Info */ +/* CONNECT-INDICATION */ +typedef struct { + word CIP_Value; + byte structs[0]; /* Called party number, + Called party subaddress, + Calling party number, + Calling party subaddress, + BC, + LLC, + HLC, + Additional Info */ } _CON_INDP; - /* CONNECT-RESPONSE */ +/* CONNECT-RESPONSE */ typedef struct { - word Accept; - byte structs[1]; /* B_protocol, - Connected party number, - Connected party subaddress, - LLC */ + word Accept; + byte structs[0]; /* B_protocol, + Connected party number, + Connected party subaddress, + LLC */ } _CON_RESP; - /* CONNECT-ACTIVE-INDICATION */ +/* CONNECT-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* Connected party number, - Connected party subaddress, - LLC */ + byte structs[0]; /* Connected party number, + Connected party subaddress, + LLC */ } _CON_A_INDP; - /* CONNECT-ACTIVE-RESPONSE */ +/* CONNECT-ACTIVE-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _CON_A_RESP; - /* DISCONNECT-REQUEST */ +/* DISCONNECT-REQUEST */ typedef struct { - byte structs[1]; /* Additional Info */ + byte structs[0]; /* Additional Info */ } _DIS_REQP; - /* DISCONNECT-CONFIRM */ +/* DISCONNECT-CONFIRM */ typedef struct { - word Info; + word Info; } _DIS_CONP; - /* DISCONNECT-INDICATION */ +/* DISCONNECT-INDICATION */ typedef struct { - word Info; + word Info; } _DIS_INDP; - /* DISCONNECT-RESPONSE */ +/* DISCONNECT-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _DIS_RESP; - /* LISTEN-REQUEST */ +/* LISTEN-REQUEST */ typedef struct { - dword Info_Mask; - dword CIP_Mask; - byte structs[1]; /* Calling party number, - Calling party subaddress */ + dword Info_Mask; + dword CIP_Mask; + byte structs[0]; /* Calling party number, + Calling party subaddress */ } _LIS_REQP; - /* LISTEN-CONFIRM */ +/* LISTEN-CONFIRM */ typedef struct { - word Info; + word Info; } _LIS_CONP; - /* INFO-REQUEST */ +/* INFO-REQUEST */ typedef struct { - byte structs[1]; /* Called party number, - Additional Info */ + byte structs[0]; /* Called party number, + Additional Info */ } _INF_REQP; - /* INFO-CONFIRM */ +/* INFO-CONFIRM */ typedef struct { - word Info; + word Info; } _INF_CONP; - /* INFO-INDICATION */ +/* INFO-INDICATION */ typedef struct { - word Number; - byte structs[1]; /* Info element */ + word Number; + byte structs[0]; /* Info element */ } _INF_INDP; - /* INFO-RESPONSE */ +/* INFO-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _INF_RESP; - /* SELECT-B-REQUEST */ +/* SELECT-B-REQUEST */ typedef struct { - byte structs[1]; /* B-protocol */ + byte structs[0]; /* B-protocol */ } _SEL_B_REQP; - /* SELECT-B-CONFIRM */ +/* SELECT-B-CONFIRM */ typedef struct { - word Info; + word Info; } _SEL_B_CONP; - /* FACILITY-REQUEST */ +/* FACILITY-REQUEST */ typedef struct { - word Selector; - byte structs[1]; /* Facility parameters */ + word Selector; + byte structs[0]; /* Facility parameters */ } _FAC_REQP; - /* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */ +/* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */ typedef struct { - byte struct_length; - word function; - byte length; - word SupplementaryServiceInfo; - dword SupportedServices; + byte struct_length; + word function; + byte length; + word SupplementaryServiceInfo; + dword SupportedServices; } _FAC_CON_STRUCTS; - /* FACILITY-CONFIRM */ +/* FACILITY-CONFIRM */ typedef struct { - word Info; - word Selector; - byte structs[1]; /* Facility parameters */ + word Info; + word Selector; + byte structs[0]; /* Facility parameters */ } _FAC_CONP; - /* FACILITY-INDICATION */ +/* FACILITY-INDICATION */ typedef struct { - word Selector; - byte structs[1]; /* Facility parameters */ + word Selector; + byte structs[0]; /* Facility parameters */ } _FAC_INDP; - /* FACILITY-RESPONSE */ +/* FACILITY-RESPONSE */ typedef struct { - word Selector; - byte structs[1]; /* Facility parameters */ + word Selector; + byte structs[0]; /* Facility parameters */ } _FAC_RESP; - /* CONNECT-B3-REQUEST */ +/* CONNECT-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_REQP; - /* CONNECT-B3-CONFIRM */ +/* CONNECT-B3-CONFIRM */ typedef struct { - word Info; + word Info; } _CON_B3_CONP; - /* CONNECT-B3-INDICATION */ +/* CONNECT-B3-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_INDP; - /* CONNECT-B3-RESPONSE */ +/* CONNECT-B3-RESPONSE */ typedef struct { - word Accept; - byte structs[1]; /* NCPI */ + word Accept; + byte structs[0]; /* NCPI */ } _CON_B3_RESP; - /* CONNECT-B3-ACTIVE-INDICATION */ +/* CONNECT-B3-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_A_INDP; - /* CONNECT-B3-ACTIVE-RESPONSE */ +/* CONNECT-B3-ACTIVE-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _CON_B3_A_RESP; - /* DISCONNECT-B3-REQUEST */ +/* DISCONNECT-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _DIS_B3_REQP; - /* DISCONNECT-B3-CONFIRM */ +/* DISCONNECT-B3-CONFIRM */ typedef struct { - word Info; + word Info; } _DIS_B3_CONP; - /* DISCONNECT-B3-INDICATION */ +/* DISCONNECT-B3-INDICATION */ typedef struct { - word Info; - byte structs[1]; /* NCPI */ + word Info; + byte structs[0]; /* NCPI */ } _DIS_B3_INDP; - /* DISCONNECT-B3-RESPONSE */ +/* DISCONNECT-B3-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _DIS_B3_RESP; - /* DATA-B3-REQUEST */ +/* DATA-B3-REQUEST */ typedef struct { - dword Data; - word Data_Length; - word Number; - word Flags; + dword Data; + word Data_Length; + word Number; + word Flags; } _DAT_B3_REQP; - /* DATA-B3-REQUEST 64 BIT Systems */ +/* DATA-B3-REQUEST 64 BIT Systems */ typedef struct { - dword Data; - word Data_Length; - word Number; - word Flags; - void *pData; + dword Data; + word Data_Length; + word Number; + word Flags; + void *pData; } _DAT_B3_REQ64P; - /* DATA-B3-CONFIRM */ +/* DATA-B3-CONFIRM */ typedef struct { - word Number; - word Info; + word Number; + word Info; } _DAT_B3_CONP; - /* DATA-B3-INDICATION */ +/* DATA-B3-INDICATION */ typedef struct { - dword Data; - word Data_Length; - word Number; - word Flags; + dword Data; + word Data_Length; + word Number; + word Flags; } _DAT_B3_INDP; - /* DATA-B3-INDICATION 64 BIT Systems */ +/* DATA-B3-INDICATION 64 BIT Systems */ typedef struct { - dword Data; - word Data_Length; - word Number; - word Flags; - void *pData; + dword Data; + word Data_Length; + word Number; + word Flags; + void *pData; } _DAT_B3_IND64P; - /* DATA-B3-RESPONSE */ +/* DATA-B3-RESPONSE */ typedef struct { - word Number; + word Number; } _DAT_B3_RESP; - /* RESET-B3-REQUEST */ +/* RESET-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _RES_B3_REQP; - /* RESET-B3-CONFIRM */ +/* RESET-B3-CONFIRM */ typedef struct { - word Info; + word Info; } _RES_B3_CONP; - /* RESET-B3-INDICATION */ +/* RESET-B3-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _RES_B3_INDP; - /* RESET-B3-RESPONSE */ +/* RESET-B3-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _RES_B3_RESP; - /* CONNECT-B3-T90-ACTIVE-INDICATION */ +/* CONNECT-B3-T90-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_T90_A_INDP; - /* CONNECT-B3-T90-ACTIVE-RESPONSE */ +/* CONNECT-B3-T90-ACTIVE-RESPONSE */ typedef struct { - word Reject; - byte structs[1]; /* NCPI */ + word Reject; + byte structs[0]; /* NCPI */ } _CON_B3_T90_A_RESP; /*------------------------------------------------------------------*/ /* message structure */ @@ -364,64 +364,64 @@ typedef struct { typedef struct _API_MSG CAPI_MSG; typedef struct _MSG_HEADER CAPI_MSG_HEADER; struct _API_MSG { - struct _MSG_HEADER { - word length; - word appl_id; - word command; - word number; - byte controller; - byte plci; - word ncci; - } header; - union { - _ALT_REQP alert_req; - _ALT_CONP alert_con; - _CON_REQP connect_req; - _CON_CONP connect_con; - _CON_INDP connect_ind; - _CON_RESP connect_res; - _CON_A_INDP connect_a_ind; - _CON_A_RESP connect_a_res; - _DIS_REQP disconnect_req; - _DIS_CONP disconnect_con; - _DIS_INDP disconnect_ind; - _DIS_RESP disconnect_res; - _LIS_REQP listen_req; - _LIS_CONP listen_con; - _INF_REQP info_req; - _INF_CONP info_con; - _INF_INDP info_ind; - _INF_RESP info_res; - _SEL_B_REQP select_b_req; - _SEL_B_CONP select_b_con; - _FAC_REQP facility_req; - _FAC_CONP facility_con; - _FAC_INDP facility_ind; - _FAC_RESP facility_res; - _CON_B3_REQP connect_b3_req; - _CON_B3_CONP connect_b3_con; - _CON_B3_INDP connect_b3_ind; - _CON_B3_RESP connect_b3_res; - _CON_B3_A_INDP connect_b3_a_ind; - _CON_B3_A_RESP connect_b3_a_res; - _DIS_B3_REQP disconnect_b3_req; - _DIS_B3_CONP disconnect_b3_con; - _DIS_B3_INDP disconnect_b3_ind; - _DIS_B3_RESP disconnect_b3_res; - _DAT_B3_REQP data_b3_req; - _DAT_B3_REQ64P data_b3_req64; - _DAT_B3_CONP data_b3_con; - _DAT_B3_INDP data_b3_ind; - _DAT_B3_IND64P data_b3_ind64; - _DAT_B3_RESP data_b3_res; - _RES_B3_REQP reset_b3_req; - _RES_B3_CONP reset_b3_con; - _RES_B3_INDP reset_b3_ind; - _RES_B3_RESP reset_b3_res; - _CON_B3_T90_A_INDP connect_b3_t90_a_ind; - _CON_B3_T90_A_RESP connect_b3_t90_a_res; - byte b[200]; - } info; + struct _MSG_HEADER { + word length; + word appl_id; + word command; + word number; + byte controller; + byte plci; + word ncci; + } header; + union { + _ALT_REQP alert_req; + _ALT_CONP alert_con; + _CON_REQP connect_req; + _CON_CONP connect_con; + _CON_INDP connect_ind; + _CON_RESP connect_res; + _CON_A_INDP connect_a_ind; + _CON_A_RESP connect_a_res; + _DIS_REQP disconnect_req; + _DIS_CONP disconnect_con; + _DIS_INDP disconnect_ind; + _DIS_RESP disconnect_res; + _LIS_REQP listen_req; + _LIS_CONP listen_con; + _INF_REQP info_req; + _INF_CONP info_con; + _INF_INDP info_ind; + _INF_RESP info_res; + _SEL_B_REQP select_b_req; + _SEL_B_CONP select_b_con; + _FAC_REQP facility_req; + _FAC_CONP facility_con; + _FAC_INDP facility_ind; + _FAC_RESP facility_res; + _CON_B3_REQP connect_b3_req; + _CON_B3_CONP connect_b3_con; + _CON_B3_INDP connect_b3_ind; + _CON_B3_RESP connect_b3_res; + _CON_B3_A_INDP connect_b3_a_ind; + _CON_B3_A_RESP connect_b3_a_res; + _DIS_B3_REQP disconnect_b3_req; + _DIS_B3_CONP disconnect_b3_con; + _DIS_B3_INDP disconnect_b3_ind; + _DIS_B3_RESP disconnect_b3_res; + _DAT_B3_REQP data_b3_req; + _DAT_B3_REQ64P data_b3_req64; + _DAT_B3_CONP data_b3_con; + _DAT_B3_INDP data_b3_ind; + _DAT_B3_IND64P data_b3_ind64; + _DAT_B3_RESP data_b3_res; + _RES_B3_REQP reset_b3_req; + _RES_B3_CONP reset_b3_con; + _RES_B3_INDP reset_b3_ind; + _RES_B3_RESP reset_b3_res; + _CON_B3_T90_A_INDP connect_b3_t90_a_ind; + _CON_B3_T90_A_RESP connect_b3_t90_a_res; + byte b[200]; + } info; }; /*------------------------------------------------------------------*/ /* non-fatal errors */ @@ -696,4 +696,4 @@ struct _API_MSG { /* function prototypes */ /*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/ -#endif /* _INC_CAPI20 */ +#endif /* _INC_CAPI20 */ diff --git a/drivers/isdn/hardware/eicon/capidtmf.c b/drivers/isdn/hardware/eicon/capidtmf.c index f130724144f..e3f77841519 100644 --- a/drivers/isdn/hardware/eicon/capidtmf.c +++ b/drivers/isdn/hardware/eicon/capidtmf.c @@ -1,34 +1,34 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" - - + + @@ -51,74 +51,74 @@ static short capidtmf_expand_table_alaw[0x0100] = { - -5504, 5504, -344, 344, -22016, 22016, -1376, 1376, - -2752, 2752, -88, 88, -11008, 11008, -688, 688, - -7552, 7552, -472, 472, -30208, 30208, -1888, 1888, - -3776, 3776, -216, 216, -15104, 15104, -944, 944, - -4480, 4480, -280, 280, -17920, 17920, -1120, 1120, - -2240, 2240, -24, 24, -8960, 8960, -560, 560, - -6528, 6528, -408, 408, -26112, 26112, -1632, 1632, - -3264, 3264, -152, 152, -13056, 13056, -816, 816, - -6016, 6016, -376, 376, -24064, 24064, -1504, 1504, - -3008, 3008, -120, 120, -12032, 12032, -752, 752, - -8064, 8064, -504, 504, -32256, 32256, -2016, 2016, - -4032, 4032, -248, 248, -16128, 16128, -1008, 1008, - -4992, 4992, -312, 312, -19968, 19968, -1248, 1248, - -2496, 2496, -56, 56, -9984, 9984, -624, 624, - -7040, 7040, -440, 440, -28160, 28160, -1760, 1760, - -3520, 3520, -184, 184, -14080, 14080, -880, 880, - -5248, 5248, -328, 328, -20992, 20992, -1312, 1312, - -2624, 2624, -72, 72, -10496, 10496, -656, 656, - -7296, 7296, -456, 456, -29184, 29184, -1824, 1824, - -3648, 3648, -200, 200, -14592, 14592, -912, 912, - -4224, 4224, -264, 264, -16896, 16896, -1056, 1056, - -2112, 2112, -8, 8, -8448, 8448, -528, 528, - -6272, 6272, -392, 392, -25088, 25088, -1568, 1568, - -3136, 3136, -136, 136, -12544, 12544, -784, 784, - -5760, 5760, -360, 360, -23040, 23040, -1440, 1440, - -2880, 2880, -104, 104, -11520, 11520, -720, 720, - -7808, 7808, -488, 488, -31232, 31232, -1952, 1952, - -3904, 3904, -232, 232, -15616, 15616, -976, 976, - -4736, 4736, -296, 296, -18944, 18944, -1184, 1184, - -2368, 2368, -40, 40, -9472, 9472, -592, 592, - -6784, 6784, -424, 424, -27136, 27136, -1696, 1696, - -3392, 3392, -168, 168, -13568, 13568, -848, 848 + -5504, 5504, -344, 344, -22016, 22016, -1376, 1376, + -2752, 2752, -88, 88, -11008, 11008, -688, 688, + -7552, 7552, -472, 472, -30208, 30208, -1888, 1888, + -3776, 3776, -216, 216, -15104, 15104, -944, 944, + -4480, 4480, -280, 280, -17920, 17920, -1120, 1120, + -2240, 2240, -24, 24, -8960, 8960, -560, 560, + -6528, 6528, -408, 408, -26112, 26112, -1632, 1632, + -3264, 3264, -152, 152, -13056, 13056, -816, 816, + -6016, 6016, -376, 376, -24064, 24064, -1504, 1504, + -3008, 3008, -120, 120, -12032, 12032, -752, 752, + -8064, 8064, -504, 504, -32256, 32256, -2016, 2016, + -4032, 4032, -248, 248, -16128, 16128, -1008, 1008, + -4992, 4992, -312, 312, -19968, 19968, -1248, 1248, + -2496, 2496, -56, 56, -9984, 9984, -624, 624, + -7040, 7040, -440, 440, -28160, 28160, -1760, 1760, + -3520, 3520, -184, 184, -14080, 14080, -880, 880, + -5248, 5248, -328, 328, -20992, 20992, -1312, 1312, + -2624, 2624, -72, 72, -10496, 10496, -656, 656, + -7296, 7296, -456, 456, -29184, 29184, -1824, 1824, + -3648, 3648, -200, 200, -14592, 14592, -912, 912, + -4224, 4224, -264, 264, -16896, 16896, -1056, 1056, + -2112, 2112, -8, 8, -8448, 8448, -528, 528, + -6272, 6272, -392, 392, -25088, 25088, -1568, 1568, + -3136, 3136, -136, 136, -12544, 12544, -784, 784, + -5760, 5760, -360, 360, -23040, 23040, -1440, 1440, + -2880, 2880, -104, 104, -11520, 11520, -720, 720, + -7808, 7808, -488, 488, -31232, 31232, -1952, 1952, + -3904, 3904, -232, 232, -15616, 15616, -976, 976, + -4736, 4736, -296, 296, -18944, 18944, -1184, 1184, + -2368, 2368, -40, 40, -9472, 9472, -592, 592, + -6784, 6784, -424, 424, -27136, 27136, -1696, 1696, + -3392, 3392, -168, 168, -13568, 13568, -848, 848 }; static short capidtmf_expand_table_ulaw[0x0100] = { - -32124, 32124, -1884, 1884, -7932, 7932, -372, 372, - -15996, 15996, -876, 876, -3900, 3900, -120, 120, - -23932, 23932, -1372, 1372, -5884, 5884, -244, 244, - -11900, 11900, -620, 620, -2876, 2876, -56, 56, - -28028, 28028, -1628, 1628, -6908, 6908, -308, 308, - -13948, 13948, -748, 748, -3388, 3388, -88, 88, - -19836, 19836, -1116, 1116, -4860, 4860, -180, 180, - -9852, 9852, -492, 492, -2364, 2364, -24, 24, - -30076, 30076, -1756, 1756, -7420, 7420, -340, 340, - -14972, 14972, -812, 812, -3644, 3644, -104, 104, - -21884, 21884, -1244, 1244, -5372, 5372, -212, 212, - -10876, 10876, -556, 556, -2620, 2620, -40, 40, - -25980, 25980, -1500, 1500, -6396, 6396, -276, 276, - -12924, 12924, -684, 684, -3132, 3132, -72, 72, - -17788, 17788, -988, 988, -4348, 4348, -148, 148, - -8828, 8828, -428, 428, -2108, 2108, -8, 8, - -31100, 31100, -1820, 1820, -7676, 7676, -356, 356, - -15484, 15484, -844, 844, -3772, 3772, -112, 112, - -22908, 22908, -1308, 1308, -5628, 5628, -228, 228, - -11388, 11388, -588, 588, -2748, 2748, -48, 48, - -27004, 27004, -1564, 1564, -6652, 6652, -292, 292, - -13436, 13436, -716, 716, -3260, 3260, -80, 80, - -18812, 18812, -1052, 1052, -4604, 4604, -164, 164, - -9340, 9340, -460, 460, -2236, 2236, -16, 16, - -29052, 29052, -1692, 1692, -7164, 7164, -324, 324, - -14460, 14460, -780, 780, -3516, 3516, -96, 96, - -20860, 20860, -1180, 1180, -5116, 5116, -196, 196, - -10364, 10364, -524, 524, -2492, 2492, -32, 32, - -24956, 24956, -1436, 1436, -6140, 6140, -260, 260, - -12412, 12412, -652, 652, -3004, 3004, -64, 64, - -16764, 16764, -924, 924, -4092, 4092, -132, 132, - -8316, 8316, -396, 396, -1980, 1980, 0, 0 + -32124, 32124, -1884, 1884, -7932, 7932, -372, 372, + -15996, 15996, -876, 876, -3900, 3900, -120, 120, + -23932, 23932, -1372, 1372, -5884, 5884, -244, 244, + -11900, 11900, -620, 620, -2876, 2876, -56, 56, + -28028, 28028, -1628, 1628, -6908, 6908, -308, 308, + -13948, 13948, -748, 748, -3388, 3388, -88, 88, + -19836, 19836, -1116, 1116, -4860, 4860, -180, 180, + -9852, 9852, -492, 492, -2364, 2364, -24, 24, + -30076, 30076, -1756, 1756, -7420, 7420, -340, 340, + -14972, 14972, -812, 812, -3644, 3644, -104, 104, + -21884, 21884, -1244, 1244, -5372, 5372, -212, 212, + -10876, 10876, -556, 556, -2620, 2620, -40, 40, + -25980, 25980, -1500, 1500, -6396, 6396, -276, 276, + -12924, 12924, -684, 684, -3132, 3132, -72, 72, + -17788, 17788, -988, 988, -4348, 4348, -148, 148, + -8828, 8828, -428, 428, -2108, 2108, -8, 8, + -31100, 31100, -1820, 1820, -7676, 7676, -356, 356, + -15484, 15484, -844, 844, -3772, 3772, -112, 112, + -22908, 22908, -1308, 1308, -5628, 5628, -228, 228, + -11388, 11388, -588, 588, -2748, 2748, -48, 48, + -27004, 27004, -1564, 1564, -6652, 6652, -292, 292, + -13436, 13436, -716, 716, -3260, 3260, -80, 80, + -18812, 18812, -1052, 1052, -4604, 4604, -164, 164, + -9340, 9340, -460, 460, -2236, 2236, -16, 16, + -29052, 29052, -1692, 1692, -7164, 7164, -324, 324, + -14460, 14460, -780, 780, -3516, 3516, -96, 96, + -20860, 20860, -1180, 1180, -5116, 5116, -196, 196, + -10364, 10364, -524, 524, -2492, 2492, -32, 32, + -24956, 24956, -1436, 1436, -6140, 6140, -260, 260, + -12412, 12412, -652, 652, -3004, 3004, -64, 64, + -16764, 16764, -924, 924, -4092, 4092, -132, 132, + -8316, 8316, -396, 396, -1980, 1980, 0, 0 }; @@ -126,52 +126,52 @@ static short capidtmf_expand_table_ulaw[0x0100] = static short capidtmf_recv_window_function[CAPIDTMF_RECV_ACCUMULATE_CYCLES] = { - -500L, -999L, -1499L, -1998L, -2496L, -2994L, -3491L, -3988L, - -4483L, -4978L, -5471L, -5963L, -6454L, -6943L, -7431L, -7917L, - -8401L, -8883L, -9363L, -9840L, -10316L, -10789L, -11259L, -11727L, - -12193L, -12655L, -13115L, -13571L, -14024L, -14474L, -14921L, -15364L, - -15804L, -16240L, -16672L, -17100L, -17524L, -17944L, -18360L, -18772L, - -19180L, -19583L, -19981L, -20375L, -20764L, -21148L, -21527L, -21901L, - -22270L, -22634L, -22993L, -23346L, -23694L, -24037L, -24374L, -24705L, - -25030L, -25350L, -25664L, -25971L, -26273L, -26568L, -26858L, -27141L, - -27418L, -27688L, -27952L, -28210L, -28461L, -28705L, -28943L, -29174L, - -29398L, -29615L, -29826L, -30029L, -30226L, -30415L, -30598L, -30773L, - -30941L, -31102L, -31256L, -31402L, -31541L, -31673L, -31797L, -31914L, - -32024L, -32126L, -32221L, -32308L, -32388L, -32460L, -32524L, -32581L, - -32631L, -32673L, -32707L, -32734L, -32753L, -32764L, -32768L, -32764L, - -32753L, -32734L, -32707L, -32673L, -32631L, -32581L, -32524L, -32460L, - -32388L, -32308L, -32221L, -32126L, -32024L, -31914L, -31797L, -31673L, - -31541L, -31402L, -31256L, -31102L, -30941L, -30773L, -30598L, -30415L, - -30226L, -30029L, -29826L, -29615L, -29398L, -29174L, -28943L, -28705L, - -28461L, -28210L, -27952L, -27688L, -27418L, -27141L, -26858L, -26568L, - -26273L, -25971L, -25664L, -25350L, -25030L, -24705L, -24374L, -24037L, - -23694L, -23346L, -22993L, -22634L, -22270L, -21901L, -21527L, -21148L, - -20764L, -20375L, -19981L, -19583L, -19180L, -18772L, -18360L, -17944L, - -17524L, -17100L, -16672L, -16240L, -15804L, -15364L, -14921L, -14474L, - -14024L, -13571L, -13115L, -12655L, -12193L, -11727L, -11259L, -10789L, - -10316L, -9840L, -9363L, -8883L, -8401L, -7917L, -7431L, -6943L, - -6454L, -5963L, -5471L, -4978L, -4483L, -3988L, -3491L, -2994L, - -2496L, -1998L, -1499L, -999L, -500L, + -500L, -999L, -1499L, -1998L, -2496L, -2994L, -3491L, -3988L, + -4483L, -4978L, -5471L, -5963L, -6454L, -6943L, -7431L, -7917L, + -8401L, -8883L, -9363L, -9840L, -10316L, -10789L, -11259L, -11727L, + -12193L, -12655L, -13115L, -13571L, -14024L, -14474L, -14921L, -15364L, + -15804L, -16240L, -16672L, -17100L, -17524L, -17944L, -18360L, -18772L, + -19180L, -19583L, -19981L, -20375L, -20764L, -21148L, -21527L, -21901L, + -22270L, -22634L, -22993L, -23346L, -23694L, -24037L, -24374L, -24705L, + -25030L, -25350L, -25664L, -25971L, -26273L, -26568L, -26858L, -27141L, + -27418L, -27688L, -27952L, -28210L, -28461L, -28705L, -28943L, -29174L, + -29398L, -29615L, -29826L, -30029L, -30226L, -30415L, -30598L, -30773L, + -30941L, -31102L, -31256L, -31402L, -31541L, -31673L, -31797L, -31914L, + -32024L, -32126L, -32221L, -32308L, -32388L, -32460L, -32524L, -32581L, + -32631L, -32673L, -32707L, -32734L, -32753L, -32764L, -32768L, -32764L, + -32753L, -32734L, -32707L, -32673L, -32631L, -32581L, -32524L, -32460L, + -32388L, -32308L, -32221L, -32126L, -32024L, -31914L, -31797L, -31673L, + -31541L, -31402L, -31256L, -31102L, -30941L, -30773L, -30598L, -30415L, + -30226L, -30029L, -29826L, -29615L, -29398L, -29174L, -28943L, -28705L, + -28461L, -28210L, -27952L, -27688L, -27418L, -27141L, -26858L, -26568L, + -26273L, -25971L, -25664L, -25350L, -25030L, -24705L, -24374L, -24037L, + -23694L, -23346L, -22993L, -22634L, -22270L, -21901L, -21527L, -21148L, + -20764L, -20375L, -19981L, -19583L, -19180L, -18772L, -18360L, -17944L, + -17524L, -17100L, -16672L, -16240L, -15804L, -15364L, -14921L, -14474L, + -14024L, -13571L, -13115L, -12655L, -12193L, -11727L, -11259L, -10789L, + -10316L, -9840L, -9363L, -8883L, -8401L, -7917L, -7431L, -6943L, + -6454L, -5963L, -5471L, -4978L, -4483L, -3988L, -3491L, -2994L, + -2496L, -1998L, -1499L, -999L, -500L, }; static byte capidtmf_leading_zeroes_table[0x100] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define capidtmf_byte_leading_zeroes(b) (capidtmf_leading_zeroes_table[(BYTE)(b)]) @@ -182,140 +182,140 @@ static byte capidtmf_leading_zeroes_table[0x100] = /*---------------------------------------------------------------------------*/ -static void capidtmf_goertzel_loop (long *buffer, long *coeffs, short *sample, long count) +static void capidtmf_goertzel_loop(long *buffer, long *coeffs, short *sample, long count) { - int i, j; - long c, d, q0, q1, q2; - - for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1; i++) - { - q1 = buffer[i]; - q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; - d = coeffs[i] >> 1; - c = d << 1; - if (c >= 0) - { - for (j = 0; j < count; j++) - { - q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15); - q2 = q1; - q1 = q0; - } - } - else - { - c = -c; - d = -d; - for (j = 0; j < count; j++) - { - q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15)); - q2 = q1; - q1 = q0; - } - } - buffer[i] = q1; - buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2; - } - q1 = buffer[i]; - q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; - c = (coeffs[i] >> 1) << 1; - if (c >= 0) - { - for (j = 0; j < count; j++) - { - q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15); - q2 = q1; - q1 = q0; - c -= CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT; - } - } - else - { - c = -c; - for (j = 0; j < count; j++) - { - q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15)); - q2 = q1; - q1 = q0; - c += CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT; - } - } - coeffs[i] = c; - buffer[i] = q1; - buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2; + int i, j; + long c, d, q0, q1, q2; + + for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1; i++) + { + q1 = buffer[i]; + q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; + d = coeffs[i] >> 1; + c = d << 1; + if (c >= 0) + { + for (j = 0; j < count; j++) + { + q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15); + q2 = q1; + q1 = q0; + } + } + else + { + c = -c; + d = -d; + for (j = 0; j < count; j++) + { + q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15)); + q2 = q1; + q1 = q0; + } + } + buffer[i] = q1; + buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2; + } + q1 = buffer[i]; + q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; + c = (coeffs[i] >> 1) << 1; + if (c >= 0) + { + for (j = 0; j < count; j++) + { + q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15); + q2 = q1; + q1 = q0; + c -= CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT; + } + } + else + { + c = -c; + for (j = 0; j < count; j++) + { + q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15)); + q2 = q1; + q1 = q0; + c += CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT; + } + } + coeffs[i] = c; + buffer[i] = q1; + buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2; } -static void capidtmf_goertzel_result (long *buffer, long *coeffs) +static void capidtmf_goertzel_result(long *buffer, long *coeffs) { - int i; - long d, e, q1, q2, lo, mid, hi; - dword k; - - for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) - { - q1 = buffer[i]; - q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; - d = coeffs[i] >> 1; - if (d >= 0) - d = ((d << 1) * (-q1 >> 16)) + (((dword)(((dword) d) * ((dword)(-q1 & 0xffff)))) >> 15); - else - d = ((-d << 1) * (-q1 >> 16)) + (((dword)(((dword) -d) * ((dword)(-q1 & 0xffff)))) >> 15); - e = (q2 >= 0) ? q2 : -q2; - if (d >= 0) - { - k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff)); - lo = k & 0xffff; - mid = k >> 16; - k = ((dword)(d >> 16)) * ((dword)(e & 0xffff)); - mid += k & 0xffff; - hi = k >> 16; - k = ((dword)(d & 0xffff)) * ((dword)(e >> 16)); - mid += k & 0xffff; - hi += k >> 16; - hi += ((dword)(d >> 16)) * ((dword)(e >> 16)); - } - else - { - d = -d; - k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff)); - lo = -((long)(k & 0xffff)); - mid = -((long)(k >> 16)); - k = ((dword)(d >> 16)) * ((dword)(e & 0xffff)); - mid -= k & 0xffff; - hi = -((long)(k >> 16)); - k = ((dword)(d & 0xffff)) * ((dword)(e >> 16)); - mid -= k & 0xffff; - hi -= k >> 16; - hi -= ((dword)(d >> 16)) * ((dword)(e >> 16)); - } - if (q2 < 0) - { - lo = -lo; - mid = -mid; - hi = -hi; - } - d = (q1 >= 0) ? q1 : -q1; - k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff)); - lo += k & 0xffff; - mid += k >> 16; - k = ((dword)(d >> 16)) * ((dword)(d & 0xffff)); - mid += (k & 0xffff) << 1; - hi += (k >> 16) << 1; - hi += ((dword)(d >> 16)) * ((dword)(d >> 16)); - d = (q2 >= 0) ? q2 : -q2; - k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff)); - lo += k & 0xffff; - mid += k >> 16; - k = ((dword)(d >> 16)) * ((dword)(d & 0xffff)); - mid += (k & 0xffff) << 1; - hi += (k >> 16) << 1; - hi += ((dword)(d >> 16)) * ((dword)(d >> 16)); - mid += lo >> 16; - hi += mid >> 16; - buffer[i] = (lo & 0xffff) | (mid << 16); - buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = hi; - } + int i; + long d, e, q1, q2, lo, mid, hi; + dword k; + + for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) + { + q1 = buffer[i]; + q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; + d = coeffs[i] >> 1; + if (d >= 0) + d = ((d << 1) * (-q1 >> 16)) + (((dword)(((dword) d) * ((dword)(-q1 & 0xffff)))) >> 15); + else + d = ((-d << 1) * (-q1 >> 16)) + (((dword)(((dword) -d) * ((dword)(-q1 & 0xffff)))) >> 15); + e = (q2 >= 0) ? q2 : -q2; + if (d >= 0) + { + k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff)); + lo = k & 0xffff; + mid = k >> 16; + k = ((dword)(d >> 16)) * ((dword)(e & 0xffff)); + mid += k & 0xffff; + hi = k >> 16; + k = ((dword)(d & 0xffff)) * ((dword)(e >> 16)); + mid += k & 0xffff; + hi += k >> 16; + hi += ((dword)(d >> 16)) * ((dword)(e >> 16)); + } + else + { + d = -d; + k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff)); + lo = -((long)(k & 0xffff)); + mid = -((long)(k >> 16)); + k = ((dword)(d >> 16)) * ((dword)(e & 0xffff)); + mid -= k & 0xffff; + hi = -((long)(k >> 16)); + k = ((dword)(d & 0xffff)) * ((dword)(e >> 16)); + mid -= k & 0xffff; + hi -= k >> 16; + hi -= ((dword)(d >> 16)) * ((dword)(e >> 16)); + } + if (q2 < 0) + { + lo = -lo; + mid = -mid; + hi = -hi; + } + d = (q1 >= 0) ? q1 : -q1; + k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff)); + lo += k & 0xffff; + mid += k >> 16; + k = ((dword)(d >> 16)) * ((dword)(d & 0xffff)); + mid += (k & 0xffff) << 1; + hi += (k >> 16) << 1; + hi += ((dword)(d >> 16)) * ((dword)(d >> 16)); + d = (q2 >= 0) ? q2 : -q2; + k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff)); + lo += k & 0xffff; + mid += k >> 16; + k = ((dword)(d >> 16)) * ((dword)(d & 0xffff)); + mid += (k & 0xffff) << 1; + hi += (k >> 16) << 1; + hi += ((dword)(d >> 16)) * ((dword)(d >> 16)); + mid += lo >> 16; + hi += mid >> 16; + buffer[i] = (lo & 0xffff) | (mid << 16); + buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = hi; + } } @@ -346,339 +346,339 @@ static void capidtmf_goertzel_result (long *buffer, long *coeffs) static long capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = { - 0xda97L * 2, /* 697 Hz (Low group 697 Hz) */ - 0xd299L * 2, /* 770 Hz (Low group 770 Hz) */ - 0xc8cbL * 2, /* 852 Hz (Low group 852 Hz) */ - 0xbd36L * 2, /* 941 Hz (Low group 941 Hz) */ - 0x9501L * 2, /* 1209 Hz (High group 1209 Hz) */ - 0x7f89L * 2, /* 1336 Hz (High group 1336 Hz) */ - 0x6639L * 2, /* 1477 Hz (High group 1477 Hz) */ - 0x48c6L * 2, /* 1633 Hz (High group 1633 Hz) */ - 0xe14cL * 2, /* 630 Hz (Lower guard of low group 631 Hz) */ - 0xb2e0L * 2, /* 1015 Hz (Upper guard of low group 1039 Hz) */ - 0xa1a0L * 2, /* 1130 Hz (Lower guard of high group 1140 Hz) */ - 0x8a87L * 2, /* 1272 Hz (Guard between 1209 Hz and 1336 Hz: 1271 Hz) */ - 0x7353L * 2, /* 1405 Hz (2nd harmonics of 697 Hz and guard between 1336 Hz and 1477 Hz: 1405 Hz) */ - 0x583bL * 2, /* 1552 Hz (2nd harmonics of 770 Hz and guard between 1477 Hz and 1633 Hz: 1553 Hz) */ - 0x37d8L * 2, /* 1720 Hz (2nd harmonics of 852 Hz and upper guard of high group: 1715 Hz) */ - 0x0000L * 2 /* 100-630 Hz (fundamentals) */ + 0xda97L * 2, /* 697 Hz (Low group 697 Hz) */ + 0xd299L * 2, /* 770 Hz (Low group 770 Hz) */ + 0xc8cbL * 2, /* 852 Hz (Low group 852 Hz) */ + 0xbd36L * 2, /* 941 Hz (Low group 941 Hz) */ + 0x9501L * 2, /* 1209 Hz (High group 1209 Hz) */ + 0x7f89L * 2, /* 1336 Hz (High group 1336 Hz) */ + 0x6639L * 2, /* 1477 Hz (High group 1477 Hz) */ + 0x48c6L * 2, /* 1633 Hz (High group 1633 Hz) */ + 0xe14cL * 2, /* 630 Hz (Lower guard of low group 631 Hz) */ + 0xb2e0L * 2, /* 1015 Hz (Upper guard of low group 1039 Hz) */ + 0xa1a0L * 2, /* 1130 Hz (Lower guard of high group 1140 Hz) */ + 0x8a87L * 2, /* 1272 Hz (Guard between 1209 Hz and 1336 Hz: 1271 Hz) */ + 0x7353L * 2, /* 1405 Hz (2nd harmonics of 697 Hz and guard between 1336 Hz and 1477 Hz: 1405 Hz) */ + 0x583bL * 2, /* 1552 Hz (2nd harmonics of 770 Hz and guard between 1477 Hz and 1633 Hz: 1553 Hz) */ + 0x37d8L * 2, /* 1720 Hz (2nd harmonics of 852 Hz and upper guard of high group: 1715 Hz) */ + 0x0000L * 2 /* 100-630 Hz (fundamentals) */ }; static word capidtmf_recv_guard_snr_low_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = { - 14, /* Low group peak versus 697 Hz */ - 14, /* Low group peak versus 770 Hz */ - 16, /* Low group peak versus 852 Hz */ - 16, /* Low group peak versus 941 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1209 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1336 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1477 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1633 Hz */ - 14, /* Low group peak versus 635 Hz */ - 16, /* Low group peak versus 1010 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1140 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1272 Hz */ - DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 8, /* Low group peak versus 1405 Hz */ - DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1555 Hz */ - DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1715 Hz */ - 12 /* Low group peak versus 100-630 Hz */ + 14, /* Low group peak versus 697 Hz */ + 14, /* Low group peak versus 770 Hz */ + 16, /* Low group peak versus 852 Hz */ + 16, /* Low group peak versus 941 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1209 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1336 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1477 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1633 Hz */ + 14, /* Low group peak versus 635 Hz */ + 16, /* Low group peak versus 1010 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1140 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* Low group peak versus 1272 Hz */ + DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 8, /* Low group peak versus 1405 Hz */ + DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1555 Hz */ + DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4, /* Low group peak versus 1715 Hz */ + 12 /* Low group peak versus 100-630 Hz */ }; static word capidtmf_recv_guard_snr_high_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = { - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 697 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 770 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 852 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 941 Hz */ - 20, /* High group peak versus 1209 Hz */ - 20, /* High group peak versus 1336 Hz */ - 20, /* High group peak versus 1477 Hz */ - 20, /* High group peak versus 1633 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 635 Hz */ - CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 1010 Hz */ - 16, /* High group peak versus 1140 Hz */ - 4, /* High group peak versus 1272 Hz */ - 6, /* High group peak versus 1405 Hz */ - 8, /* High group peak versus 1555 Hz */ - 16, /* High group peak versus 1715 Hz */ - 12 /* High group peak versus 100-630 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 697 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 770 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 852 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 941 Hz */ + 20, /* High group peak versus 1209 Hz */ + 20, /* High group peak versus 1336 Hz */ + 20, /* High group peak versus 1477 Hz */ + 20, /* High group peak versus 1633 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 635 Hz */ + CAPIDTMF_RECV_GUARD_SNR_DONTCARE, /* High group peak versus 1010 Hz */ + 16, /* High group peak versus 1140 Hz */ + 4, /* High group peak versus 1272 Hz */ + 6, /* High group peak versus 1405 Hz */ + 8, /* High group peak versus 1555 Hz */ + 16, /* High group peak versus 1715 Hz */ + 12 /* High group peak versus 100-630 Hz */ }; /*---------------------------------------------------------------------------*/ -static void capidtmf_recv_init (t_capidtmf_state *p_state) +static void capidtmf_recv_init(t_capidtmf_state *p_state) { - p_state->recv.min_gap_duration = 1; - p_state->recv.min_digit_duration = 1; - - p_state->recv.cycle_counter = 0; - p_state->recv.current_digit_on_time = 0; - p_state->recv.current_digit_off_time = 0; - p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT; - - p_state->recv.digit_write_pos = 0; - p_state->recv.digit_read_pos = 0; - p_state->recv.indication_state = 0; - p_state->recv.indication_state_ack = 0; - p_state->recv.state = CAPIDTMF_RECV_STATE_IDLE; + p_state->recv.min_gap_duration = 1; + p_state->recv.min_digit_duration = 1; + + p_state->recv.cycle_counter = 0; + p_state->recv.current_digit_on_time = 0; + p_state->recv.current_digit_off_time = 0; + p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT; + + p_state->recv.digit_write_pos = 0; + p_state->recv.digit_read_pos = 0; + p_state->recv.indication_state = 0; + p_state->recv.indication_state_ack = 0; + p_state->recv.state = CAPIDTMF_RECV_STATE_IDLE; } -void capidtmf_recv_enable (t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration) +void capidtmf_recv_enable(t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration) { - p_state->recv.indication_state_ack &= CAPIDTMF_RECV_INDICATION_DIGIT; - p_state->recv.min_digit_duration = (word)(((((dword) min_digit_duration) * 8) + - ((dword)(CAPIDTMF_RECV_TIME_GRANULARITY / 2))) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY)); - if (p_state->recv.min_digit_duration <= 1) - p_state->recv.min_digit_duration = 1; - else - (p_state->recv.min_digit_duration)--; - p_state->recv.min_gap_duration = - (word)((((dword) min_gap_duration) * 8) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY)); - if (p_state->recv.min_gap_duration <= 1) - p_state->recv.min_gap_duration = 1; - else - (p_state->recv.min_gap_duration)--; - p_state->recv.state |= CAPIDTMF_RECV_STATE_DTMF_ACTIVE; + p_state->recv.indication_state_ack &= CAPIDTMF_RECV_INDICATION_DIGIT; + p_state->recv.min_digit_duration = (word)(((((dword) min_digit_duration) * 8) + + ((dword)(CAPIDTMF_RECV_TIME_GRANULARITY / 2))) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY)); + if (p_state->recv.min_digit_duration <= 1) + p_state->recv.min_digit_duration = 1; + else + (p_state->recv.min_digit_duration)--; + p_state->recv.min_gap_duration = + (word)((((dword) min_gap_duration) * 8) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY)); + if (p_state->recv.min_gap_duration <= 1) + p_state->recv.min_gap_duration = 1; + else + (p_state->recv.min_gap_duration)--; + p_state->recv.state |= CAPIDTMF_RECV_STATE_DTMF_ACTIVE; } -void capidtmf_recv_disable (t_capidtmf_state *p_state) +void capidtmf_recv_disable(t_capidtmf_state *p_state) { - p_state->recv.state &= ~CAPIDTMF_RECV_STATE_DTMF_ACTIVE; - if (p_state->recv.state == CAPIDTMF_RECV_STATE_IDLE) - capidtmf_recv_init (p_state); - else - { - p_state->recv.cycle_counter = 0; - p_state->recv.current_digit_on_time = 0; - p_state->recv.current_digit_off_time = 0; - p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT; - } + p_state->recv.state &= ~CAPIDTMF_RECV_STATE_DTMF_ACTIVE; + if (p_state->recv.state == CAPIDTMF_RECV_STATE_IDLE) + capidtmf_recv_init(p_state); + else + { + p_state->recv.cycle_counter = 0; + p_state->recv.current_digit_on_time = 0; + p_state->recv.current_digit_off_time = 0; + p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT; + } } -word capidtmf_recv_indication (t_capidtmf_state *p_state, byte *buffer) +word capidtmf_recv_indication(t_capidtmf_state *p_state, byte *buffer) { - word i, j, k, flags; - - flags = p_state->recv.indication_state ^ p_state->recv.indication_state_ack; - p_state->recv.indication_state_ack ^= flags & CAPIDTMF_RECV_INDICATION_DIGIT; - if (p_state->recv.digit_write_pos != p_state->recv.digit_read_pos) - { - i = 0; - k = p_state->recv.digit_write_pos; - j = p_state->recv.digit_read_pos; - do - { - buffer[i++] = p_state->recv.digit_buffer[j]; - j = (j == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 0 : j + 1; - } while (j != k); - p_state->recv.digit_read_pos = k; - return (i); - } - p_state->recv.indication_state_ack ^= flags; - return (0); + word i, j, k, flags; + + flags = p_state->recv.indication_state ^ p_state->recv.indication_state_ack; + p_state->recv.indication_state_ack ^= flags & CAPIDTMF_RECV_INDICATION_DIGIT; + if (p_state->recv.digit_write_pos != p_state->recv.digit_read_pos) + { + i = 0; + k = p_state->recv.digit_write_pos; + j = p_state->recv.digit_read_pos; + do + { + buffer[i++] = p_state->recv.digit_buffer[j]; + j = (j == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 0 : j + 1; + } while (j != k); + p_state->recv.digit_read_pos = k; + return (i); + } + p_state->recv.indication_state_ack ^= flags; + return (0); } #define CAPIDTMF_RECV_WINDOWED_SAMPLES 32 -void capidtmf_recv_block (t_capidtmf_state *p_state, byte *buffer, word length) +void capidtmf_recv_block(t_capidtmf_state *p_state, byte *buffer, word length) { - byte result_digit; - word sample_number, cycle_counter, n, i; - word low_peak, high_peak; - dword lo, hi; - byte *p; - short *q; - byte goertzel_result_buffer[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; - short windowed_sample_buffer[CAPIDTMF_RECV_WINDOWED_SAMPLES]; - - - if (p_state->recv.state & CAPIDTMF_RECV_STATE_DTMF_ACTIVE) - { - cycle_counter = p_state->recv.cycle_counter; - sample_number = 0; - while (sample_number < length) - { - if (cycle_counter < CAPIDTMF_RECV_ACCUMULATE_CYCLES) - { - if (cycle_counter == 0) - { - for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) - { - p_state->recv.goertzel_buffer[0][i] = 0; - p_state->recv.goertzel_buffer[1][i] = 0; - } - } - n = CAPIDTMF_RECV_ACCUMULATE_CYCLES - cycle_counter; - if (n > length - sample_number) - n = length - sample_number; - if (n > CAPIDTMF_RECV_WINDOWED_SAMPLES) - n = CAPIDTMF_RECV_WINDOWED_SAMPLES; - p = buffer + sample_number; - q = capidtmf_recv_window_function + cycle_counter; - if (p_state->ulaw) - { - for (i = 0; i < n; i++) - { - windowed_sample_buffer[i] = - (short)((capidtmf_expand_table_ulaw[p[i]] * ((long)(q[i]))) >> 15); - } - } - else - { - for (i = 0; i < n; i++) - { - windowed_sample_buffer[i] = - (short)((capidtmf_expand_table_alaw[p[i]] * ((long)(q[i]))) >> 15); - } - } - capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1] = CAPIDTMF_RECV_FUNDAMENTAL_OFFSET; - capidtmf_goertzel_loop (p_state->recv.goertzel_buffer[0], - capidtmf_recv_goertzel_coef_table, windowed_sample_buffer, n); - cycle_counter += n; - sample_number += n; - } - else - { - capidtmf_goertzel_result (p_state->recv.goertzel_buffer[0], - capidtmf_recv_goertzel_coef_table); - for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) - { - lo = (dword)(p_state->recv.goertzel_buffer[0][i]); - hi = (dword)(p_state->recv.goertzel_buffer[1][i]); - if (hi != 0) - { - n = capidtmf_dword_leading_zeroes (hi); - hi = (hi << n) | (lo >> (32 - n)); - } - else - { - n = capidtmf_dword_leading_zeroes (lo); - hi = lo << n; - n += 32; - } - n = 195 - 3 * n; - if (hi >= 0xcb300000L) - n += 2; - else if (hi >= 0xa1450000L) - n++; - goertzel_result_buffer[i] = (byte) n; - } - low_peak = DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT; - result_digit = CAPIDTMF_RECV_NO_DIGIT; - for (i = 0; i < CAPIDTMF_LOW_GROUP_FREQUENCIES; i++) - { - if (goertzel_result_buffer[i] > low_peak) - { - low_peak = goertzel_result_buffer[i]; - result_digit = (byte) i; - } - } - high_peak = DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT; - n = CAPIDTMF_RECV_NO_DIGIT; - for (i = CAPIDTMF_LOW_GROUP_FREQUENCIES; i < CAPIDTMF_RECV_BASE_FREQUENCY_COUNT; i++) - { - if (goertzel_result_buffer[i] > high_peak) - { - high_peak = goertzel_result_buffer[i]; - n = (i - CAPIDTMF_LOW_GROUP_FREQUENCIES) << 2; - } - } - result_digit |= (byte) n; - if (low_peak + DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT < high_peak) - result_digit = CAPIDTMF_RECV_NO_DIGIT; - if (high_peak + DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT < low_peak) - result_digit = CAPIDTMF_RECV_NO_DIGIT; - n = 0; - for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) - { - if ((((short)(low_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_low_table[i])) < 0) - || (((short)(high_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_high_table[i])) < 0)) - { - n++; - } - } - if (n != 2) - result_digit = CAPIDTMF_RECV_NO_DIGIT; - - if (result_digit == CAPIDTMF_RECV_NO_DIGIT) - { - if (p_state->recv.current_digit_on_time != 0) - { - if (++(p_state->recv.current_digit_off_time) >= p_state->recv.min_gap_duration) - { - p_state->recv.current_digit_on_time = 0; - p_state->recv.current_digit_off_time = 0; - } - } - else - { - if (p_state->recv.current_digit_off_time != 0) - (p_state->recv.current_digit_off_time)--; - } - } - else - { - if ((p_state->recv.current_digit_on_time == 0) - && (p_state->recv.current_digit_off_time != 0)) - { - (p_state->recv.current_digit_off_time)--; - } - else - { - n = p_state->recv.current_digit_off_time; - if ((p_state->recv.current_digit_on_time != 0) - && (result_digit != p_state->recv.current_digit_value)) - { - p_state->recv.current_digit_on_time = 0; - n = 0; - } - p_state->recv.current_digit_value = result_digit; - p_state->recv.current_digit_off_time = 0; - if (p_state->recv.current_digit_on_time != 0xffff) - { - p_state->recv.current_digit_on_time += n + 1; - if (p_state->recv.current_digit_on_time >= p_state->recv.min_digit_duration) - { - p_state->recv.current_digit_on_time = 0xffff; - i = (p_state->recv.digit_write_pos == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? - 0 : p_state->recv.digit_write_pos + 1; - if (i == p_state->recv.digit_read_pos) - { - trace (dprintf ("%s,%d: Receive digit overrun", - (char *)(FILE_), __LINE__)); - } - else - { - p_state->recv.digit_buffer[p_state->recv.digit_write_pos] = result_digit; - p_state->recv.digit_write_pos = i; - p_state->recv.indication_state = - (p_state->recv.indication_state & ~CAPIDTMF_RECV_INDICATION_DIGIT) | - (~p_state->recv.indication_state_ack & CAPIDTMF_RECV_INDICATION_DIGIT); - } - } - } - } - } - cycle_counter = 0; - sample_number++; - } - } - p_state->recv.cycle_counter = cycle_counter; - } + byte result_digit; + word sample_number, cycle_counter, n, i; + word low_peak, high_peak; + dword lo, hi; + byte *p; + short *q; + byte goertzel_result_buffer[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; + short windowed_sample_buffer[CAPIDTMF_RECV_WINDOWED_SAMPLES]; + + + if (p_state->recv.state & CAPIDTMF_RECV_STATE_DTMF_ACTIVE) + { + cycle_counter = p_state->recv.cycle_counter; + sample_number = 0; + while (sample_number < length) + { + if (cycle_counter < CAPIDTMF_RECV_ACCUMULATE_CYCLES) + { + if (cycle_counter == 0) + { + for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) + { + p_state->recv.goertzel_buffer[0][i] = 0; + p_state->recv.goertzel_buffer[1][i] = 0; + } + } + n = CAPIDTMF_RECV_ACCUMULATE_CYCLES - cycle_counter; + if (n > length - sample_number) + n = length - sample_number; + if (n > CAPIDTMF_RECV_WINDOWED_SAMPLES) + n = CAPIDTMF_RECV_WINDOWED_SAMPLES; + p = buffer + sample_number; + q = capidtmf_recv_window_function + cycle_counter; + if (p_state->ulaw) + { + for (i = 0; i < n; i++) + { + windowed_sample_buffer[i] = + (short)((capidtmf_expand_table_ulaw[p[i]] * ((long)(q[i]))) >> 15); + } + } + else + { + for (i = 0; i < n; i++) + { + windowed_sample_buffer[i] = + (short)((capidtmf_expand_table_alaw[p[i]] * ((long)(q[i]))) >> 15); + } + } + capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1] = CAPIDTMF_RECV_FUNDAMENTAL_OFFSET; + capidtmf_goertzel_loop(p_state->recv.goertzel_buffer[0], + capidtmf_recv_goertzel_coef_table, windowed_sample_buffer, n); + cycle_counter += n; + sample_number += n; + } + else + { + capidtmf_goertzel_result(p_state->recv.goertzel_buffer[0], + capidtmf_recv_goertzel_coef_table); + for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) + { + lo = (dword)(p_state->recv.goertzel_buffer[0][i]); + hi = (dword)(p_state->recv.goertzel_buffer[1][i]); + if (hi != 0) + { + n = capidtmf_dword_leading_zeroes(hi); + hi = (hi << n) | (lo >> (32 - n)); + } + else + { + n = capidtmf_dword_leading_zeroes(lo); + hi = lo << n; + n += 32; + } + n = 195 - 3 * n; + if (hi >= 0xcb300000L) + n += 2; + else if (hi >= 0xa1450000L) + n++; + goertzel_result_buffer[i] = (byte) n; + } + low_peak = DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT; + result_digit = CAPIDTMF_RECV_NO_DIGIT; + for (i = 0; i < CAPIDTMF_LOW_GROUP_FREQUENCIES; i++) + { + if (goertzel_result_buffer[i] > low_peak) + { + low_peak = goertzel_result_buffer[i]; + result_digit = (byte) i; + } + } + high_peak = DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT; + n = CAPIDTMF_RECV_NO_DIGIT; + for (i = CAPIDTMF_LOW_GROUP_FREQUENCIES; i < CAPIDTMF_RECV_BASE_FREQUENCY_COUNT; i++) + { + if (goertzel_result_buffer[i] > high_peak) + { + high_peak = goertzel_result_buffer[i]; + n = (i - CAPIDTMF_LOW_GROUP_FREQUENCIES) << 2; + } + } + result_digit |= (byte) n; + if (low_peak + DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT < high_peak) + result_digit = CAPIDTMF_RECV_NO_DIGIT; + if (high_peak + DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT < low_peak) + result_digit = CAPIDTMF_RECV_NO_DIGIT; + n = 0; + for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++) + { + if ((((short)(low_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_low_table[i])) < 0) + || (((short)(high_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_high_table[i])) < 0)) + { + n++; + } + } + if (n != 2) + result_digit = CAPIDTMF_RECV_NO_DIGIT; + + if (result_digit == CAPIDTMF_RECV_NO_DIGIT) + { + if (p_state->recv.current_digit_on_time != 0) + { + if (++(p_state->recv.current_digit_off_time) >= p_state->recv.min_gap_duration) + { + p_state->recv.current_digit_on_time = 0; + p_state->recv.current_digit_off_time = 0; + } + } + else + { + if (p_state->recv.current_digit_off_time != 0) + (p_state->recv.current_digit_off_time)--; + } + } + else + { + if ((p_state->recv.current_digit_on_time == 0) + && (p_state->recv.current_digit_off_time != 0)) + { + (p_state->recv.current_digit_off_time)--; + } + else + { + n = p_state->recv.current_digit_off_time; + if ((p_state->recv.current_digit_on_time != 0) + && (result_digit != p_state->recv.current_digit_value)) + { + p_state->recv.current_digit_on_time = 0; + n = 0; + } + p_state->recv.current_digit_value = result_digit; + p_state->recv.current_digit_off_time = 0; + if (p_state->recv.current_digit_on_time != 0xffff) + { + p_state->recv.current_digit_on_time += n + 1; + if (p_state->recv.current_digit_on_time >= p_state->recv.min_digit_duration) + { + p_state->recv.current_digit_on_time = 0xffff; + i = (p_state->recv.digit_write_pos == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? + 0 : p_state->recv.digit_write_pos + 1; + if (i == p_state->recv.digit_read_pos) + { + trace(dprintf("%s,%d: Receive digit overrun", + (char *)(FILE_), __LINE__)); + } + else + { + p_state->recv.digit_buffer[p_state->recv.digit_write_pos] = result_digit; + p_state->recv.digit_write_pos = i; + p_state->recv.indication_state = + (p_state->recv.indication_state & ~CAPIDTMF_RECV_INDICATION_DIGIT) | + (~p_state->recv.indication_state_ack & CAPIDTMF_RECV_INDICATION_DIGIT); + } + } + } + } + } + cycle_counter = 0; + sample_number++; + } + } + p_state->recv.cycle_counter = cycle_counter; + } } -void capidtmf_init (t_capidtmf_state *p_state, byte ulaw) +void capidtmf_init(t_capidtmf_state *p_state, byte ulaw) { - p_state->ulaw = ulaw; - capidtmf_recv_init (p_state); + p_state->ulaw = ulaw; + capidtmf_recv_init(p_state); } diff --git a/drivers/isdn/hardware/eicon/capidtmf.h b/drivers/isdn/hardware/eicon/capidtmf.h index 242048fb2dd..0a9cf59bb22 100644 --- a/drivers/isdn/hardware/eicon/capidtmf.h +++ b/drivers/isdn/hardware/eicon/capidtmf.h @@ -1,29 +1,29 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -#ifndef CAPIDTMF_H_ +#ifndef CAPIDTMF_H_ #define CAPIDTMF_H_ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -48,32 +48,32 @@ #define CAPIDTMF_RECV_STATE_DTMF_ACTIVE 0x01 typedef struct tag_capidtmf_recv_state { - byte digit_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE]; - word digit_write_pos; - word digit_read_pos; - word indication_state; - word indication_state_ack; - long goertzel_buffer[2][CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; - word min_gap_duration; - word min_digit_duration; - word cycle_counter; - word current_digit_on_time; - word current_digit_off_time; - byte current_digit_value; - byte state; + byte digit_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE]; + word digit_write_pos; + word digit_read_pos; + word indication_state; + word indication_state_ack; + long goertzel_buffer[2][CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT]; + word min_gap_duration; + word min_digit_duration; + word cycle_counter; + word current_digit_on_time; + word current_digit_off_time; + byte current_digit_value; + byte state; } t_capidtmf_recv_state; typedef struct tag_capidtmf_state { - byte ulaw; - t_capidtmf_recv_state recv; + byte ulaw; + t_capidtmf_recv_state recv; } t_capidtmf_state; -word capidtmf_recv_indication (t_capidtmf_state *p_state, byte *buffer); -void capidtmf_recv_block (t_capidtmf_state *p_state, byte *buffer, word length); -void capidtmf_init (t_capidtmf_state *p_state, byte ulaw); -void capidtmf_recv_enable (t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration); -void capidtmf_recv_disable (t_capidtmf_state *p_state); -#define capidtmf_indication(p_state,buffer) (((p_state)->recv.indication_state != (p_state)->recv.indication_state_ack) ? capidtmf_recv_indication (p_state, buffer) : 0) -#define capidtmf_recv_process_block(p_state,buffer,length) { if ((p_state)->recv.state != CAPIDTMF_RECV_STATE_IDLE) capidtmf_recv_block (p_state, buffer, length); } +word capidtmf_recv_indication(t_capidtmf_state *p_state, byte *buffer); +void capidtmf_recv_block(t_capidtmf_state *p_state, byte *buffer, word length); +void capidtmf_init(t_capidtmf_state *p_state, byte ulaw); +void capidtmf_recv_enable(t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration); +void capidtmf_recv_disable(t_capidtmf_state *p_state); +#define capidtmf_indication(p_state, buffer) (((p_state)->recv.indication_state != (p_state)->recv.indication_state_ack) ? capidtmf_recv_indication(p_state, buffer) : 0) +#define capidtmf_recv_process_block(p_state, buffer, length) { if ((p_state)->recv.state != CAPIDTMF_RECV_STATE_IDLE) capidtmf_recv_block(p_state, buffer, length); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#endif +#endif diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c index 0afd7633556..7a0bdbdd87e 100644 --- a/drivers/isdn/hardware/eicon/capifunc.c +++ b/drivers/isdn/hardware/eicon/capifunc.c @@ -2,10 +2,10 @@ * * ISDN interface module for Eicon active cards DIVA. * CAPI Interface common functions - * - * Copyright 2000-2003 by Armin Schindler (mac@melware.de) + * + * Copyright 2000-2003 by Armin Schindler (mac@melware.de) * Copyright 2000-2003 Cytronics & Melware (info@melware.de) - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * @@ -43,7 +43,7 @@ static diva_os_spin_lock_t api_lock; static LIST_HEAD(cards); static dword notify_handle; -static void DIRequest(ENTITY * e); +static void DIRequest(ENTITY *e); static DESCRIPTOR MAdapter; static DESCRIPTOR DAdapter; static byte ControllerMap[MAX_DESCRIPTORS + 1]; @@ -160,7 +160,7 @@ static int find_free_id(void) break; num++; } - return(num + 1); + return (num + 1); } /* @@ -176,37 +176,37 @@ static diva_card *find_card_by_ctrl(word controller) if (ControllerMap[card->Id] == controller) { if (card->remove_in_progress) card = NULL; - return(card); + return (card); } } return (diva_card *) 0; } /* - * Buffer RX/TX + * Buffer RX/TX */ -void *TransmitBufferSet(APPL * appl, dword ref) +void *TransmitBufferSet(APPL *appl, dword ref) { - appl->xbuffer_used[ref] = TRUE; + appl->xbuffer_used[ref] = true; DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1)) - return (void *) ref; + return (void *)(long)ref; } -void *TransmitBufferGet(APPL * appl, void *p) +void *TransmitBufferGet(APPL *appl, void *p) { - if (appl->xbuffer_internal[(dword) p]) - return appl->xbuffer_internal[(dword) p]; + if (appl->xbuffer_internal[(dword)(long)p]) + return appl->xbuffer_internal[(dword)(long)p]; - return appl->xbuffer_ptr[(dword) p]; + return appl->xbuffer_ptr[(dword)(long)p]; } -void TransmitBufferFree(APPL * appl, void *p) +void TransmitBufferFree(APPL *appl, void *p) { - appl->xbuffer_used[(dword) p] = FALSE; - DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword) p) + 1)) -} + appl->xbuffer_used[(dword)(long)p] = false; + DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1)) + } -void *ReceiveBufferGet(APPL * appl, int Num) +void *ReceiveBufferGet(APPL *appl, int Num) { return &appl->ReceiveBuffer[Num * appl->MaxDataLength]; } @@ -217,12 +217,12 @@ void *ReceiveBufferGet(APPL * appl, int Num) void api_remove_complete(void) { DBG_PRV1(("api_remove_complete")) -} + } /* * main function called by message.c */ -void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...) +void sendf(APPL *appl, word command, dword Id, word Number, byte *format, ...) { word i, j; word length = 12, dlength = 0; @@ -240,14 +240,14 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...) DBG_PRV1(("sendf(a=%d,cmd=%x,format=%s)", appl->Id, command, (byte *) format)) - PUT_WORD(&msg.header.appl_id, appl->Id); + PUT_WORD(&msg.header.appl_id, appl->Id); PUT_WORD(&msg.header.command, command); if ((byte) (command >> 8) == 0x82) Number = appl->Number++; PUT_WORD(&msg.header.number, Number); PUT_DWORD(&msg.header.controller, Id); - write = (byte *) & msg; + write = (byte *)&msg; write += 12; va_start(ap, format); @@ -287,21 +287,21 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...) if (command == _DATA_B3_I) dlength = GET_WORD( - ((byte *) & msg.info.data_b3_ind.Data_Length)); + ((byte *)&msg.info.data_b3_ind.Data_Length)); if (!(dmb = diva_os_alloc_message_buffer(length + dlength, - (void **) &write))) { + (void **) &write))) { DBG_ERR(("sendf: alloc_message_buffer failed, incoming msg dropped.")) - return; + return; } /* copy msg header to sk_buff */ - memcpy(write, (byte *) & msg, length); + memcpy(write, (byte *)&msg, length); /* if DATA_B3_IND, copy data too */ if (command == _DATA_B3_I) { dword data = GET_DWORD(&msg.info.data_b3_ind.Data); - memcpy(write + length, (void *) data, dlength); + memcpy(write + length, (void *)(long)data, dlength); } #ifndef DIVA_NO_DEBUGLIB @@ -318,10 +318,10 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...) if (myDriverDebugHandle.dbgMask & DL_BLK) { xlog("\x00\x02", &msg, 0x81, length); for (i = 0; i < dlength; i += 256) { - DBG_BLK((((char *) GET_DWORD(&msg.info.data_b3_ind.Data)) + i, - ((dlength - i) < 256) ? (dlength - i) : 256)) - if (!(myDriverDebugHandle.dbgMask & DL_PRV0)) - break; /* not more if not explicitely requested */ + DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i, + ((dlength - i) < 256) ? (dlength - i) : 256)) + if (!(myDriverDebugHandle.dbgMask & DL_PRV0)) + break; /* not more if not explicitly requested */ } } break; @@ -333,7 +333,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...) if (!(card = find_card_by_ctrl(write[8] & 0x7f))) { DBG_ERR(("sendf - controller %d not found, incoming msg dropped", write[8] & 0x7f)) - diva_os_free_message_buffer(dmb); + diva_os_free_message_buffer(dmb); return; } /* send capi msg to capi layer */ @@ -388,7 +388,7 @@ static void clean_adapter(int id, struct list_head *free_mem_q) * remove a card, but ensures consistent state of LI tables * in the time adapter is removed */ -static void divacapi_remove_card(DESCRIPTOR * d) +static void divacapi_remove_card(DESCRIPTOR *d) { diva_card *card = NULL; diva_os_spin_lock_magic_t old_irql; @@ -427,14 +427,14 @@ static void divacapi_remove_card(DESCRIPTOR * d) clean_adapter(card->Id - 1, &free_mem_q); DBG_TRC(("DelAdapterMap (%d) -> (%d)", - ControllerMap[card->Id], card->Id)) - ControllerMap[card->Id] = 0; + ControllerMap[card->Id], card->Id)) + ControllerMap[card->Id] = 0; DBG_TRC(("adapter remove, max_adapter=%d", - max_adapter)); + max_adapter)); diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card"); - + /* After releasing the lock, we can free the memory */ - diva_os_free (0, card); + diva_os_free(0, card); } /* free queued memory areas */ @@ -469,13 +469,13 @@ rescan: /* * sync_callback */ -static void sync_callback(ENTITY * e) +static void sync_callback(ENTITY *e) { diva_os_spin_lock_magic_t old_irql; DBG_TRC(("cb:Id=%x,Rc=%x,Ind=%x", e->Id, e->Rc, e->Ind)) - diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback"); + diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback"); callback(e); diva_os_leave_spin_lock(&api_lock, &old_irql, "sync_callback"); } @@ -483,7 +483,7 @@ static void sync_callback(ENTITY * e) /* * add a new card */ -static int diva_add_card(DESCRIPTOR * d) +static int diva_add_card(DESCRIPTOR *d) { int k = 0, i = 0; diva_os_spin_lock_magic_t old_irql; @@ -492,19 +492,19 @@ static int diva_add_card(DESCRIPTOR * d) DIVA_CAPI_ADAPTER *a = NULL; IDI_SYNC_REQ sync_req; char serial[16]; - void* mem_to_free; + void *mem_to_free; LI_CONFIG *new_li_config_table; int j; if (!(card = (diva_card *) diva_os_malloc(0, sizeof(diva_card)))) { DBG_ERR(("diva_add_card: failed to allocate card struct.")) - return (0); + return (0); } memset((char *) card, 0x00, sizeof(diva_card)); memcpy(&card->d, d, sizeof(DESCRIPTOR)); sync_req.GetName.Req = 0; sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME; - card->d.request((ENTITY *) & sync_req); + card->d.request((ENTITY *)&sync_req); strlcpy(card->name, sync_req.GetName.name, sizeof(card->name)); ctrl = &card->capi_ctrl; strcpy(ctrl->name, card->name); @@ -517,14 +517,14 @@ static int diva_add_card(DESCRIPTOR * d) if (attach_capi_ctr(ctrl)) { DBG_ERR(("diva_add_card: failed to attach controller.")) - diva_os_free(0, card); + diva_os_free(0, card); return (0); } - + diva_os_enter_spin_lock(&api_lock, &old_irql, "find id"); card->Id = find_free_id(); diva_os_leave_spin_lock(&api_lock, &old_irql, "find id"); - + strlcpy(ctrl->manu, M_COMPANY, sizeof(ctrl->manu)); ctrl->version.majorversion = 2; ctrl->version.minorversion = 0; @@ -533,7 +533,7 @@ static int diva_add_card(DESCRIPTOR * d) sync_req.GetSerial.Req = 0; sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL; sync_req.GetSerial.serial = 0; - card->d.request((ENTITY *) & sync_req); + card->d.request((ENTITY *)&sync_req); if ((i = ((sync_req.GetSerial.serial & 0xff000000) >> 24))) { sprintf(serial, "%ld-%d", sync_req.GetSerial.serial & 0x00ffffff, i + 1); @@ -550,15 +550,15 @@ static int diva_add_card(DESCRIPTOR * d) DBG_TRC(("AddAdapterMap (%d) -> (%d)", ctrl->cnr, card->Id)) - sync_req.xdi_capi_prms.Req = 0; + sync_req.xdi_capi_prms.Req = 0; sync_req.xdi_capi_prms.Rc = IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS; sync_req.xdi_capi_prms.info.structure_length = - sizeof(diva_xdi_get_capi_parameters_t); - card->d.request((ENTITY *) & sync_req); + sizeof(diva_xdi_get_capi_parameters_t); + card->d.request((ENTITY *)&sync_req); a->flag_dynamic_l1_down = - sync_req.xdi_capi_prms.info.flag_dynamic_l1_down; + sync_req.xdi_capi_prms.info.flag_dynamic_l1_down; a->group_optimization_enabled = - sync_req.xdi_capi_prms.info.group_optimization_enabled; + sync_req.xdi_capi_prms.info.group_optimization_enabled; a->request = DIRequest; /* card->d.request; */ a->max_plci = card->d.channels + 30; a->max_listen = (card->d.channels > 2) ? 8 : 2; @@ -566,7 +566,7 @@ static int diva_add_card(DESCRIPTOR * d) (a->plci = (PLCI *) diva_os_malloc(0, sizeof(PLCI) * a->max_plci))) { DBG_ERR(("diva_add_card: failed alloc plci struct.")) - memset(a, 0, sizeof(DIVA_CAPI_ADAPTER)); + memset(a, 0, sizeof(DIVA_CAPI_ADAPTER)); return (0); } memset(a->plci, 0, sizeof(PLCI) * a->max_plci); @@ -625,13 +625,13 @@ static int diva_add_card(DESCRIPTOR * d) (LI_CONFIG *) diva_os_malloc(0, ((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * k) * ((k + 3) & ~3)); if (new_li_config_table == NULL) { DBG_ERR(("diva_add_card: failed alloc li_config table.")) - memset(a, 0, sizeof(DIVA_CAPI_ADAPTER)); + memset(a, 0, sizeof(DIVA_CAPI_ADAPTER)); return (0); } /* Prevent access to line interconnect table in process update */ diva_os_enter_spin_lock(&api_lock, &old_irql, "add card"); - + j = 0; for (i = 0; i < k; i++) { if ((i >= a->li_base) && (i < a->li_base + a->li_channels)) @@ -659,11 +659,11 @@ static int diva_add_card(DESCRIPTOR * d) memset(&new_li_config_table[i].coef_table[a->li_base], 0, a->li_channels); if (a->li_base + a->li_channels < k) { memcpy(&new_li_config_table[i].flag_table[a->li_base + - a->li_channels], + a->li_channels], &li_config_table[j].flag_table[a->li_base], k - (a->li_base + a->li_channels)); memcpy(&new_li_config_table[i].coef_table[a->li_base + - a->li_channels], + a->li_channels], &li_config_table[j].coef_table[a->li_base], k - (a->li_base + a->li_channels)); } @@ -689,7 +689,7 @@ static int diva_add_card(DESCRIPTOR * d) diva_os_leave_spin_lock(&api_lock, &old_irql, "add card"); if (mem_to_free) { - diva_os_free (0, mem_to_free); + diva_os_free(0, mem_to_free); } i = 0; @@ -722,7 +722,7 @@ static int diva_add_card(DESCRIPTOR * d) * register appl */ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl, - capi_register_params * rp) + capi_register_params *rp) { APPL *this; word bnum, xnum; @@ -737,38 +737,38 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl, if (diva_os_in_irq()) { DBG_ERR(("CAPI_REGISTER - in irq context !")) - return; + return; } DBG_TRC(("application register Id=%d", appl)) - if (appl > MAX_APPL) { - DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL")) - return; - } + if (appl > MAX_APPL) { + DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL")) + return; + } if (nconn <= 0) nconn = ctrl->profile.nbchannel * -nconn; - if (nconn == 0) + if (nconn == 0) nconn = ctrl->profile.nbchannel; DBG_LOG(("CAPI_REGISTER - Id = %d", appl)) - DBG_LOG((" MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt)) - DBG_LOG((" MaxBDataBuffers = %d", rp->datablkcnt)) - DBG_LOG((" MaxBDataLength = %d", rp->datablklen)) - - if (nconn < 1 || - nconn > 255 || - rp->datablklen < 80 || - rp->datablklen > 2150 || rp->datablkcnt > 255) { - DBG_ERR(("CAPI_REGISTER - invalid parameters")) - return; - } + DBG_LOG((" MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt)) + DBG_LOG((" MaxBDataBuffers = %d", rp->datablkcnt)) + DBG_LOG((" MaxBDataLength = %d", rp->datablklen)) + + if (nconn < 1 || + nconn > 255 || + rp->datablklen < 80 || + rp->datablklen > 2150 || rp->datablkcnt > 255) { + DBG_ERR(("CAPI_REGISTER - invalid parameters")) + return; + } if (application[appl - 1].Id == appl) { DBG_LOG(("CAPI_REGISTER - appl already registered")) - return; /* appl already registered */ + return; /* appl already registered */ } /* alloc memory */ @@ -785,10 +785,10 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl, mem_len += xnum * rp->datablklen; /* xbuffer_ptr[xnum] */ DBG_LOG((" Allocated Memory = %d", mem_len)) - if (!(p = diva_os_malloc(0, mem_len))) { - DBG_ERR(("CAPI_REGISTER - memory allocation failed")) - return; - } + if (!(p = diva_os_malloc(0, mem_len))) { + DBG_ERR(("CAPI_REGISTER - memory allocation failed")) + return; + } memset(p, 0, mem_len); DataNCCI = (void *)p; @@ -853,10 +853,10 @@ static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl) DBG_TRC(("application %d(%d) cleanup", this->Id, appl)) - if (diva_os_in_irq()) { - DBG_ERR(("CAPI_RELEASE - in irq context !")) - return; - } + 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) { @@ -876,7 +876,7 @@ static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl) * send message */ static u16 diva_send_message(struct capi_ctr *ctrl, - diva_os_message_buffer_s * dmb) + diva_os_message_buffer_s *dmb) { int i = 0; word ret = 0; @@ -891,14 +891,14 @@ static u16 diva_send_message(struct capi_ctr *ctrl, if (diva_os_in_irq()) { DBG_ERR(("CAPI_SEND_MSG - in irq context !")) - return CAPI_REGOSRESOURCEERR; + 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; - } + 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"); @@ -909,7 +909,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl, /* patch controller number */ msg->header.controller = ControllerMap[card->Id] - | (msg->header.controller & 0x80); /* preserve external controller bit */ + | (msg->header.controller & 0x80); /* preserve external controller bit */ switch (command) { default: @@ -937,15 +937,15 @@ static u16 diva_send_message(struct capi_ctr *ctrl, || GET_WORD(&msg->info.data_b3_req.Data_Length) > (length - clength)) { DBG_ERR(("Write - invalid message size")) - retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL; + retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL; goto write_end; } for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI) - && this->xbuffer_used[i]; i++); + && this->xbuffer_used[i]; i++); if (i == (MAX_DATA_B3 * this->MaxNCCI)) { DBG_ERR(("Write - too many data pending")) - retval = CAPI_SENDQUEUEFULL; + retval = CAPI_SENDQUEUEFULL; goto write_end; } msg->info.data_b3_req.Data = i; @@ -959,13 +959,13 @@ static u16 diva_send_message(struct capi_ctr *ctrl, && (myDriverDebugHandle.dbgMask & DL_XLOG)) { int j; for (j = 0; j < - GET_WORD(&msg->info.data_b3_req.Data_Length); + 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) < + ((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 */ + if (!(myDriverDebugHandle.dbgMask & DL_PRV0)) + break; /* not more if not explicitly requested */ } } #endif @@ -984,19 +984,19 @@ static u16 diva_send_message(struct capi_ctr *ctrl, break; case _BAD_MSG: DBG_ERR(("Write - bad message")) - retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL; + retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL; break; case _QUEUE_FULL: DBG_ERR(("Write - queue full")) - retval = CAPI_SENDQUEUEFULL; + retval = CAPI_SENDQUEUEFULL; break; default: DBG_ERR(("Write - api_put returned unknown error")) - retval = CAPI_UNKNOWNNOTPAR; + retval = CAPI_UNKNOWNNOTPAR; break; } - write_end: +write_end: diva_os_leave_spin_lock(&api_lock, &old_irql, "send message"); if (retval == CAPI_NOERROR) diva_os_free_message_buffer(dmb); @@ -1007,7 +1007,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl, /* * cards request function */ -static void DIRequest(ENTITY * e) +static void DIRequest(ENTITY *e) { DIVA_CAPI_ADAPTER *a = &(adapter[(byte) e->user[0]]); diva_card *os_card = (diva_card *) a->os_card; @@ -1022,7 +1022,7 @@ static void DIRequest(ENTITY * e) /* * callback function from didd */ -static void didd_callback(void *context, DESCRIPTOR * adapter, int removal) +static void didd_callback(void *context, DESCRIPTOR *adapter, int removal) { if (adapter->type == IDI_DADAPTER) { DBG_ERR(("Notification about IDI_DADAPTER change ! Oops.")); @@ -1071,17 +1071,17 @@ static int divacapi_connect_didd(void) 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; + 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); + 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 */ + else if ((DIDD_Table[x].type > 0) && (DIDD_Table[x].type < 16)) { /* IDI Adapter found */ diva_add_card(&DIDD_Table[x]); } } @@ -1105,12 +1105,12 @@ static void divacapi_disconnect_didd(void) 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); + DAdapter.request((ENTITY *)&req); } /* * we do not provide date/time here, - * the application should do this. + * the application should do this. */ int fax_head_line_time(char *buffer) { @@ -1120,23 +1120,23 @@ int fax_head_line_time(char *buffer) /* * init (alloc) main structures */ -static int DIVA_INIT_FUNCTION init_main_structs(void) +static int __init 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; + 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); + 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, mapped_msg); diva_os_free(0, adapter); return 0; } @@ -1176,12 +1176,12 @@ static void do_api_remove_start(void) if (ret) DBG_ERR(("could not remove signaling ID's")) -} + } /* * init */ -int DIVA_INIT_FUNCTION init_capifunc(void) +int __init init_capifunc(void) { diva_os_initialize_spin_lock(&api_lock, "capifunc"); memset(ControllerMap, 0, MAX_DESCRIPTORS + 1); @@ -1190,13 +1190,13 @@ int DIVA_INIT_FUNCTION init_capifunc(void) if (!init_main_structs()) { DBG_ERR(("init: failed to init main structs.")) - diva_os_destroy_spin_lock(&api_lock, "capifunc"); + 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(); + do_api_remove_start(); divacapi_remove_cards(); remove_main_structs(); diva_os_destroy_spin_lock(&api_lock, "capifunc"); @@ -1209,7 +1209,7 @@ int DIVA_INIT_FUNCTION init_capifunc(void) /* * finit */ -void DIVA_EXIT_FUNCTION finit_capifunc(void) +void __exit finit_capifunc(void) { do_api_remove_start(); divacapi_disconnect_didd(); diff --git a/drivers/isdn/hardware/eicon/capifunc.h b/drivers/isdn/hardware/eicon/capifunc.h index bd256f29738..e96c45bb563 100644 --- a/drivers/isdn/hardware/eicon/capifunc.h +++ b/drivers/isdn/hardware/eicon/capifunc.h @@ -2,8 +2,8 @@ * * ISDN interface module for Eicon active cards DIVA. * CAPI Interface common functions - * - * Copyright 2000-2003 by Armin Schindler (mac@melware.de) + * + * Copyright 2000-2003 by Armin Schindler (mac@melware.de) * Copyright 2000-2003 Cytronics & Melware (info@melware.de) * * This software may be used and distributed according to the terms diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c index 8fe4f3f0935..997d46abf5b 100644 --- a/drivers/isdn/hardware/eicon/capimain.c +++ b/drivers/isdn/hardware/eicon/capimain.c @@ -2,19 +2,19 @@ * * ISDN interface module for Eicon active cards DIVA. * CAPI Interface - * - * Copyright 2000-2003 by Armin Schindler (mac@melware.de) + * + * Copyright 2000-2003 by Armin Schindler (mac@melware.de) * Copyright 2000-2003 Cytronics & Melware (info@melware.de) - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. */ -#include <linux/config.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/init.h> #include <asm/uaccess.h> -#include <linux/smp_lock.h> +#include <linux/seq_file.h> #include <linux/skbuff.h> #include "os_capi.h" @@ -28,7 +28,7 @@ static char *main_revision = "$Revision: 1.24 $"; static char *DRIVERNAME = - "Eicon DIVA - CAPI Interface driver (http://www.melware.net)"; + "Eicon DIVA - CAPI Interface driver (http://www.melware.net)"; static char *DRIVERLNAME = "divacapi"; MODULE_DESCRIPTION("CAPI driver for Eicon DIVA cards"); @@ -69,7 +69,7 @@ diva_os_message_buffer_s *diva_os_alloc_message_buffer(unsigned long size, /* * free a message buffer */ -void diva_os_free_message_buffer(diva_os_message_buffer_s * dmb) +void diva_os_free_message_buffer(diva_os_message_buffer_s *dmb) { kfree_skb(dmb); } @@ -77,25 +77,32 @@ void diva_os_free_message_buffer(diva_os_message_buffer_s * dmb) /* * proc function for controller info */ -static int diva_ctl_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl) +static int diva_ctl_proc_show(struct seq_file *m, void *v) { + struct capi_ctr *ctrl = m->private; diva_card *card = (diva_card *) ctrl->driverdata; - int len = 0; - - len += sprintf(page + len, "%s\n", ctrl->name); - len += sprintf(page + len, "Serial No. : %s\n", ctrl->serial); - len += sprintf(page + len, "Id : %d\n", card->Id); - len += sprintf(page + len, "Channels : %d\n", card->d.channels); - - if (off + count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len - off) ? count : len - off); + + seq_printf(m, "%s\n", ctrl->name); + seq_printf(m, "Serial No. : %s\n", ctrl->serial); + seq_printf(m, "Id : %d\n", card->Id); + seq_printf(m, "Channels : %d\n", card->d.channels); + + return 0; } +static int diva_ctl_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, diva_ctl_proc_show, NULL); +} + +static const struct file_operations diva_ctl_proc_fops = { + .owner = THIS_MODULE, + .open = diva_ctl_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* * set additional os settings in capi_ctr struct */ @@ -104,14 +111,14 @@ void diva_os_set_controller_struct(struct capi_ctr *ctrl) ctrl->driver_name = DRIVERLNAME; ctrl->load_firmware = NULL; ctrl->reset_ctr = NULL; - ctrl->ctr_read_proc = diva_ctl_read_proc; + ctrl->proc_fops = &diva_ctl_proc_fops; ctrl->owner = THIS_MODULE; } /* * module init */ -static int DIVA_INIT_FUNCTION divacapi_init(void) +static int __init divacapi_init(void) { char tmprev[32]; int ret = 0; @@ -137,7 +144,7 @@ static int DIVA_INIT_FUNCTION divacapi_init(void) /* * module exit */ -static void DIVA_EXIT_FUNCTION divacapi_exit(void) +static void __exit divacapi_exit(void) { finit_capifunc(); printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME); diff --git a/drivers/isdn/hardware/eicon/cardtype.h b/drivers/isdn/hardware/eicon/cardtype.h index 18a5c42fffd..8b20e22cae1 100644 --- a/drivers/isdn/hardware/eicon/cardtype.h +++ b/drivers/isdn/hardware/eicon/cardtype.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _CARDTYPE_H_ @@ -94,7 +94,7 @@ */ #define CARD_UNKNOWN 0 #define CARD_NONE 0 - /* DIVA cards */ +/* DIVA cards */ #define CARDTYPE_DIVA_MCA 0 #define CARDTYPE_DIVA_ISA 1 #define CARDTYPE_DIVA_PCM 2 @@ -102,10 +102,10 @@ #define CARDTYPE_DIVAPRO_PCM 4 #define CARDTYPE_DIVAPICO_ISA 5 #define CARDTYPE_DIVAPICO_PCM 6 - /* DIVA 2.0 cards */ +/* DIVA 2.0 cards */ #define CARDTYPE_DIVAPRO20_PCI 7 #define CARDTYPE_DIVA20_PCI 8 - /* S cards */ +/* S cards */ #define CARDTYPE_QUADRO_ISA 9 #define CARDTYPE_S_ISA 10 #define CARDTYPE_S_MCA 11 @@ -117,57 +117,57 @@ #define CARDTYPE_SCOM_MCA 17 #define CARDTYPE_PR_ISA 18 #define CARDTYPE_PR_MCA 19 - /* Diva Server cards (formerly called Maestra, later Amadeo) */ +/* Diva Server cards (formerly called Maestra, later Amadeo) */ #define CARDTYPE_MAESTRA_ISA 20 #define CARDTYPE_MAESTRA_PCI 21 - /* Diva Server cards to be developed (Quadro, Primary rate) */ +/* Diva Server cards to be developed (Quadro, Primary rate) */ #define CARDTYPE_DIVASRV_Q_8M_PCI 22 #define CARDTYPE_DIVASRV_P_30M_PCI 23 #define CARDTYPE_DIVASRV_P_2M_PCI 24 #define CARDTYPE_DIVASRV_P_9M_PCI 25 - /* DIVA 2.0 cards */ +/* DIVA 2.0 cards */ #define CARDTYPE_DIVA20_ISA 26 #define CARDTYPE_DIVA20U_ISA 27 #define CARDTYPE_DIVA20U_PCI 28 #define CARDTYPE_DIVAPRO20_ISA 29 #define CARDTYPE_DIVAPRO20U_ISA 30 #define CARDTYPE_DIVAPRO20U_PCI 31 - /* DIVA combi cards (piccola ISDN + rockwell V.34 modem) */ +/* DIVA combi cards (piccola ISDN + rockwell V.34 modem) */ #define CARDTYPE_DIVAMOBILE_PCM 32 #define CARDTYPE_TDKGLOBALPRO_PCM 33 - /* DIVA Pro PC OEM card for 'New Media Corporation' */ +/* DIVA Pro PC OEM card for 'New Media Corporation' */ #define CARDTYPE_NMC_DIVAPRO_PCM 34 - /* DIVA Pro 2.0 OEM cards for 'British Telecom' */ +/* DIVA Pro 2.0 OEM cards for 'British Telecom' */ #define CARDTYPE_BT_EXLANE_PCI 35 #define CARDTYPE_BT_EXLANE_ISA 36 - /* DIVA low cost cards, 1st name DIVA 3.0, 2nd DIVA 2.01, 3rd ??? */ +/* DIVA low cost cards, 1st name DIVA 3.0, 2nd DIVA 2.01, 3rd ??? */ #define CARDTYPE_DIVALOW_ISA 37 #define CARDTYPE_DIVALOWU_ISA 38 #define CARDTYPE_DIVALOW_PCI 39 #define CARDTYPE_DIVALOWU_PCI 40 - /* DIVA combi cards (piccola ISDN + rockwell V.90 modem) */ +/* DIVA combi cards (piccola ISDN + rockwell V.90 modem) */ #define CARDTYPE_DIVAMOBILE_V90_PCM 41 #define CARDTYPE_TDKGLOBPRO_V90_PCM 42 #define CARDTYPE_DIVASRV_P_23M_PCI 43 #define CARDTYPE_DIVALOW_USB 44 - /* DIVA Audio (CT) family */ +/* DIVA Audio (CT) family */ #define CARDTYPE_DIVA_CT_ST 45 #define CARDTYPE_DIVA_CT_U 46 #define CARDTYPE_DIVA_CTLITE_ST 47 #define CARDTYPE_DIVA_CTLITE_U 48 - /* DIVA ISDN plus V.90 series */ +/* DIVA ISDN plus V.90 series */ #define CARDTYPE_DIVAISDN_V90_PCM 49 #define CARDTYPE_DIVAISDN_V90_PCI 50 #define CARDTYPE_DIVAISDN_TA 51 - /* DIVA Server Voice cards */ +/* DIVA Server Voice cards */ #define CARDTYPE_DIVASRV_VOICE_Q_8M_PCI 52 - /* DIVA Server V2 cards */ +/* DIVA Server V2 cards */ #define CARDTYPE_DIVASRV_Q_8M_V2_PCI 53 #define CARDTYPE_DIVASRV_P_30M_V2_PCI 54 - /* DIVA Server Voice V2 cards */ +/* DIVA Server Voice V2 cards */ #define CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI 55 #define CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI 56 - /* Diva LAN */ +/* Diva LAN */ #define CARDTYPE_DIVAISDN_LAN 57 #define CARDTYPE_DIVA_202_PCI_ST 58 #define CARDTYPE_DIVA_202_PCI_U 59 @@ -182,7 +182,7 @@ #define CARDTYPE_DIVA_V2_PCM 67 /* Re-badged Diva Pro PC Card */ #define CARDTYPE_DIVA_PC_CARD 68 - /* next free card type identifier */ +/* next free card type identifier */ #define CARDTYPE_MAX 69 /* * The card families @@ -246,47 +246,47 @@ */ typedef struct CARD_PROPERTIES { char *Name; /* official marketing name */ - unsigned short PnPId; /* plug and play ID (for non PCMIA cards) */ - unsigned short Version; /* major and minor version no of the card */ - unsigned char DescType; /* card type to set in the IDI descriptor */ - unsigned char Family; /* basic family of the card */ - unsigned short Features; /* features bits to set in the IDI desc. */ - unsigned char Card; /* basic card type */ - unsigned char IType; /* internal type of S cards (read from ram) */ - unsigned char Bus; /* bus type this card is designed for */ - unsigned char Chip; /* chipset used on card */ - unsigned char Adapters; /* number of adapters on card */ - unsigned char Channels; /* # of channels per adapter */ - unsigned short E_info; /* # of ram entity info structs per adapter */ - unsigned short SizeIo; /* size of IO window per adapter */ - unsigned short SizeMem; /* size of memory window per adapter */ + unsigned short PnPId; /* plug and play ID (for non PCMIA cards) */ + unsigned short Version; /* major and minor version no of the card */ + unsigned char DescType; /* card type to set in the IDI descriptor */ + unsigned char Family; /* basic family of the card */ + unsigned short Features; /* features bits to set in the IDI desc. */ + unsigned char Card; /* basic card type */ + unsigned char IType; /* internal type of S cards (read from ram) */ + unsigned char Bus; /* bus type this card is designed for */ + unsigned char Chip; /* chipset used on card */ + unsigned char Adapters; /* number of adapters on card */ + unsigned char Channels; /* # of channels per adapter */ + unsigned short E_info; /* # of ram entity info structs per adapter */ + unsigned short SizeIo; /* size of IO window per adapter */ + unsigned short SizeMem; /* size of memory window per adapter */ } CARD_PROPERTIES; typedef struct CARD_RESOURCE -{ unsigned char Int [10]; - unsigned short IoFirst; - unsigned short IoStep; - unsigned short IoCnt; - unsigned long MemFirst; - unsigned long MemStep; - unsigned short MemCnt; +{ unsigned char Int[10]; + unsigned short IoFirst; + unsigned short IoStep; + unsigned short IoCnt; + unsigned long MemFirst; + unsigned long MemStep; + unsigned short MemCnt; } CARD_RESOURCE; /* test if the card of type 't' is a plug & play card */ -#define IS_PNP(t) \ -( \ - ( \ - CardProperties[t].Bus != BUS_ISA \ - && \ - CardProperties[t].Bus != BUS_MCA \ - ) \ - || \ - ( \ - CardProperties[t].Family != FAMILY_S \ - && \ - CardProperties[t].Card != CARD_DIVA \ - ) \ -) +#define IS_PNP(t) \ + ( \ + ( \ + CardProperties[t].Bus != BUS_ISA \ + && \ + CardProperties[t].Bus != BUS_MCA \ + ) \ + || \ + ( \ + CardProperties[t].Family != FAMILY_S \ + && \ + CardProperties[t].Card != CARD_DIVA \ + ) \ + ) /* extract IDI Descriptor info for card type 't' (p == DescType/Features) */ -#define IDI_PROP(t,p) (CardProperties[t].p) +#define IDI_PROP(t, p) (CardProperties[t].p) #if CARDTYPE_H_WANT_DATA #if CARDTYPE_H_WANT_IDI_DATA /* include "di_defs.h" for IDI adapter type and feature flag definitions */ @@ -328,502 +328,502 @@ typedef struct CARD_RESOURCE #define DI_SOFT_V110 0 #endif /*--- CardProperties [Index=CARDTYPE_....] ---------------------------------*/ -CARD_PROPERTIES CardProperties [ ] = +CARD_PROPERTIES CardProperties[] = { -{ /* 0 */ - "Diva MCA", 0x6336, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3, - CARD_DIVA, CARD_I_NONE, BUS_MCA, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 1 */ - "Diva ISA", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3, - CARD_DIVA, CARD_I_NONE, BUS_ISA, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 2 */ - "Diva/PCM", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3, - CARD_DIVA, CARD_I_NONE, BUS_PCM, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 3 */ - "Diva PRO ISA", 0x0031, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, - CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 4 */ - "Diva PRO PC-Card", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 5 */ - "Diva PICCOLA ISA", 0x0051, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 6 */ - "Diva PICCOLA PCM", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 7 */ - "Diva PRO 2.0 S/T PCI", 0xe001, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, - CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 8 */ - "Diva 2.0 S/T PCI", 0xe002, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCI, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 9 */ - "QUADRO ISA", 0x0000, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_NULL, - CARD_QUAD, CARD_I_QUAD, BUS_ISA, CHIP_NONE, - 4, 2, 16, 0, 0x800 -}, -{ /* 10 */ - "S ISA", 0x0000, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_CODEC, - CARD_S, CARD_I_S, BUS_ISA, CHIP_NONE, - 1, 1, 16, 0, 0x800 -}, -{ /* 11 */ - "S MCA", 0x6a93, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_CODEC, - CARD_S, CARD_I_S, BUS_MCA, CHIP_NONE, - 1, 1, 16, 16, 0x400 -}, -{ /* 12 */ - "SX ISA", 0x0000, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_NULL, - CARD_SX, CARD_I_SX, BUS_ISA, CHIP_NONE, - 1, 2, 16, 0, 0x800 -}, -{ /* 13 */ - "SX MCA", 0x6a93, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_NULL, - CARD_SX, CARD_I_SX, BUS_MCA, CHIP_NONE, - 1, 2, 16, 16, 0x400 -}, -{ /* 14 */ - "SXN ISA", 0x0000, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_NULL, - CARD_SXN, CARD_I_SCOM, BUS_ISA, CHIP_NONE, - 1, 2, 16, 0, 0x800 -}, -{ /* 15 */ - "SXN MCA", 0x6a93, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_NULL, - CARD_SXN, CARD_I_SCOM, BUS_MCA, CHIP_NONE, - 1, 2, 16, 16, 0x400 -}, -{ /* 16 */ - "SCOM ISA", 0x0000, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_CODEC, - CARD_SCOM, CARD_I_SCOM, BUS_ISA, CHIP_NONE, - 1, 2, 16, 0, 0x800 -}, -{ /* 17 */ - "SCOM MCA", 0x6a93, 0x0100, - IDI_ADAPTER_S, FAMILY_S, DI_CODEC, - CARD_SCOM, CARD_I_SCOM, BUS_MCA, CHIP_NONE, - 1, 2, 16, 16, 0x400 -}, -{ /* 18 */ - "S2M ISA", 0x0000, 0x0100, - IDI_ADAPTER_PR, FAMILY_S, DI_NULL, - CARD_PR, CARD_I_PR, BUS_ISA, CHIP_NONE, - 1, 30, 256, 0, 0x4000 -}, -{ /* 19 */ - "S2M MCA", 0x6abb, 0x0100, - IDI_ADAPTER_PR, FAMILY_S, DI_NULL, - CARD_PR, CARD_I_PR, BUS_MCA, CHIP_NONE, - 1, 30, 256, 16, 0x4000 -}, -{ /* 20 */ - "Diva Server BRI-2M ISA", 0x0041, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAE, CARD_I_NONE, BUS_ISA, CHIP_DSP, - 1, 2, 16, 8, 0 -}, -{ /* 21 */ - "Diva Server BRI-2M PCI", 0xE010, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAE, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 16, 8, 0 -}, -{ /* 22 */ - "Diva Server 4BRI-8M PCI", 0xE012, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 4, 2, 16, 8, 0 -}, -{ /* 23 */ - "Diva Server PRI-30M PCI", 0xE014, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 30, 256, 8, 0 -}, -{ /* 24 */ - "Diva Server PRI-2M PCI", 0xe014, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 30, 256, 8, 0 -}, -{ /* 25 */ - "Diva Server PRI-9M PCI", 0x0000, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 30, 256, 8, 0 -}, -{ /* 26 */ - "Diva 2.0 S/T ISA", 0x0071, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 27 */ - "Diva 2.0 U ISA", 0x0091, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 28 */ - "Diva 2.0 U PCI", 0xe004, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCI, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 29 */ - "Diva PRO 2.0 S/T ISA", 0x0061, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, - CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 30 */ - "Diva PRO 2.0 U ISA", 0x0081, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, - CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 31 */ - "Diva PRO 2.0 U PCI", 0xe003, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, - CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 32 */ - "Diva MOBILE", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 33 */ - "TDK DFI3600", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 34 (OEM version of 4 - "Diva PRO PC-Card") */ - "New Media ISDN", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 35 (OEM version of 7 - "Diva PRO 2.0 S/T PCI") */ - "BT ExLane PCI", 0xe101, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, - CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 36 (OEM version of 29 - "Diva PRO 2.0 S/T ISA") */ - "BT ExLane ISA", 0x1061, 0x0200, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, - CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -{ /* 37 */ - "Diva 2.01 S/T ISA", 0x00A1, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_ISA, CHIP_IPAC, - 1, 2, 0, 8, 0 -}, -{ /* 38 */ - "Diva 2.01 U ISA", 0x00B1, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_ISA, CHIP_IPAC, - 1, 2, 0, 8, 0 -}, -{ /* 39 */ - "Diva 2.01 S/T PCI", 0xe005, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC, - 1, 2, 0, 8, 0 -}, -{ /* 40 no ID yet */ - "Diva 2.01 U PCI", 0x0000, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC, - 1, 2, 0, 8, 0 -}, -{ /* 41 */ - "Diva MOBILE V.90", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 42 */ - "TDK DFI3600 V.90", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, - 1, 2, 0, 8, 0 -}, -{ /* 43 */ - "Diva Server PRI-23M PCI", 0xe014, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 30, 256, 8, 0 -}, -{ /* 44 */ - "Diva 2.01 S/T USB", 0x1000, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_USB, CHIP_IPAC, - 1, 2, 0, 8, 0 -}, -{ /* 45 */ - "Diva CT S/T PCI", 0xe006, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, - CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 0, 0 -}, -{ /* 46 */ - "Diva CT U PCI", 0xe007, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, - CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 0, 0 -}, -{ /* 47 */ - "Diva CT Lite S/T PCI", 0xe008, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, - CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 0, 0 -}, -{ /* 48 */ - "Diva CT Lite U PCI", 0xe009, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, - CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 0, 0 -}, -{ /* 49 */ - "Diva ISDN+V.90 PC Card", 0x8D8C, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, - CARD_DIVALOW, CARD_I_NONE, BUS_PCM, CHIP_IPAC, - 1, 2, 0, 8, 0 -}, -{ /* 50 */ - "Diva ISDN+V.90 PCI", 0xe00A, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC, - 1, 2, 0, 8, 0 -}, -{ /* 51 (DivaTA) no ID */ - "Diva TA", 0x0000, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES, - CARD_DIVATA, CARD_I_NONE, BUS_COM, CHIP_EXTERN, - 1, 1, 0, 8, 0 -}, -{ /* 52 (Diva Server 4BRI-8M PCI adapter enabled for Voice) */ - "Diva Server Voice 4BRI-8M PCI", 0xE016, 0x0100, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, - CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 4, 2, 16, 8, 0 -}, -{ /* 53 (Diva Server 4BRI 2.0 adapter) */ - "Diva Server 4BRI-8M 2.0 PCI", 0xE013, 0x0200, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 4, 2, 16, 8, 0 -}, -{ /* 54 (Diva Server PRI 2.0 adapter) */ - "Diva Server PRI 2.0 PCI", 0xE015, 0x0200, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 30, 256, 8, 0 -}, -{ /* 55 (Diva Server 4BRI-8M 2.0 PCI adapter enabled for Voice) */ - "Diva Server Voice 4BRI-8M 2.0 PCI", 0xE017, 0x0200, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, - CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 4, 2, 16, 8, 0 -}, -{ /* 56 (Diva Server PRI 2.0 PCI adapter enabled for Voice) */ - "Diva Server Voice PRI 2.0 PCI", 0xE019, 0x0200, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, - CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 30, 256, 8, 0 -}, -{ - /* 57 (DivaLan ) no ID */ - "Diva LAN", 0x0000, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALAN, CARD_I_NONE, BUS_LAN, CHIP_EXTERN, - 1, 1, 0, 8, 0 -}, -{ /* 58 */ - "Diva 2.02 PCI S/T", 0xE00B, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES | DI_SOFT_V110, - CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPACX, - 1, 2, 0, 8, 0 -}, -{ /* 59 */ - "Diva 2.02 PCI U", 0xE00C, 0x0300, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPACX, - 1, 2, 0, 8, 0 -}, -{ /* 60 */ - "Diva Server BRI-2M 2.0 PCI", 0xE018, 0x0200, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 16, 8, 0 -}, -{ /* 61 (the previous name was Diva Server BRI-2F 2.0 PCI) */ - "Diva Server 2FX", 0xE01A, 0x0200, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_SOFT_V110, - CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_IPACX, - 1, 2, 16, 8, 0 -}, -{ /* 62 */ - " Diva ISDN USB 2.0", 0x1003, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_DIVALOW, CARD_I_NONE, BUS_USB, CHIP_IPACX, - 1, 2, 0, 8, 0 -}, -{ /* 63 (Diva Server BRI-2M 2.0 PCI adapter enabled for Voice) */ - "Diva Server Voice BRI-2M 2.0 PCI", 0xE01B, 0x0200, - IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, - CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 16, 8, 0 -}, -{ /* 64 */ - "Diva Pro 3.0 PCI", 0xe00d, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM, - CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 0, 0 -}, -{ /* 65 */ - "Diva ISDN + CT 2.0", 0xE00E, 0x0300, - IDI_ADAPTER_DIVA ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, - CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, - 1, 2, 0, 0, 0 -}, -{ /* 66 */ - "Diva Mobile V.90 PC Card", 0x8331, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_IPACX, - 1, 2, 0, 8, 0 -}, -{ /* 67 */ - "Diva ISDN PC Card", 0x8311, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_IPACX, - 1, 2, 0, 8, 0 -}, -{ /* 68 */ - "Diva ISDN PC Card", 0x0000, 0x0100, - IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, - CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP, - 1, 2, 0, 8, 0 -}, -} ; + { /* 0 */ + "Diva MCA", 0x6336, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3, + CARD_DIVA, CARD_I_NONE, BUS_MCA, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 1 */ + "Diva ISA", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3, + CARD_DIVA, CARD_I_NONE, BUS_ISA, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 2 */ + "Diva/PCM", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3, + CARD_DIVA, CARD_I_NONE, BUS_PCM, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 3 */ + "Diva PRO ISA", 0x0031, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, + CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 4 */ + "Diva PRO PC-Card", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 5 */ + "Diva PICCOLA ISA", 0x0051, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 6 */ + "Diva PICCOLA PCM", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 7 */ + "Diva PRO 2.0 S/T PCI", 0xe001, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, + CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 8 */ + "Diva 2.0 S/T PCI", 0xe002, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCI, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 9 */ + "QUADRO ISA", 0x0000, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_NULL, + CARD_QUAD, CARD_I_QUAD, BUS_ISA, CHIP_NONE, + 4, 2, 16, 0, 0x800 + }, + { /* 10 */ + "S ISA", 0x0000, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_CODEC, + CARD_S, CARD_I_S, BUS_ISA, CHIP_NONE, + 1, 1, 16, 0, 0x800 + }, + { /* 11 */ + "S MCA", 0x6a93, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_CODEC, + CARD_S, CARD_I_S, BUS_MCA, CHIP_NONE, + 1, 1, 16, 16, 0x400 + }, + { /* 12 */ + "SX ISA", 0x0000, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_NULL, + CARD_SX, CARD_I_SX, BUS_ISA, CHIP_NONE, + 1, 2, 16, 0, 0x800 + }, + { /* 13 */ + "SX MCA", 0x6a93, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_NULL, + CARD_SX, CARD_I_SX, BUS_MCA, CHIP_NONE, + 1, 2, 16, 16, 0x400 + }, + { /* 14 */ + "SXN ISA", 0x0000, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_NULL, + CARD_SXN, CARD_I_SCOM, BUS_ISA, CHIP_NONE, + 1, 2, 16, 0, 0x800 + }, + { /* 15 */ + "SXN MCA", 0x6a93, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_NULL, + CARD_SXN, CARD_I_SCOM, BUS_MCA, CHIP_NONE, + 1, 2, 16, 16, 0x400 + }, + { /* 16 */ + "SCOM ISA", 0x0000, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_CODEC, + CARD_SCOM, CARD_I_SCOM, BUS_ISA, CHIP_NONE, + 1, 2, 16, 0, 0x800 + }, + { /* 17 */ + "SCOM MCA", 0x6a93, 0x0100, + IDI_ADAPTER_S, FAMILY_S, DI_CODEC, + CARD_SCOM, CARD_I_SCOM, BUS_MCA, CHIP_NONE, + 1, 2, 16, 16, 0x400 + }, + { /* 18 */ + "S2M ISA", 0x0000, 0x0100, + IDI_ADAPTER_PR, FAMILY_S, DI_NULL, + CARD_PR, CARD_I_PR, BUS_ISA, CHIP_NONE, + 1, 30, 256, 0, 0x4000 + }, + { /* 19 */ + "S2M MCA", 0x6abb, 0x0100, + IDI_ADAPTER_PR, FAMILY_S, DI_NULL, + CARD_PR, CARD_I_PR, BUS_MCA, CHIP_NONE, + 1, 30, 256, 16, 0x4000 + }, + { /* 20 */ + "Diva Server BRI-2M ISA", 0x0041, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAE, CARD_I_NONE, BUS_ISA, CHIP_DSP, + 1, 2, 16, 8, 0 + }, + { /* 21 */ + "Diva Server BRI-2M PCI", 0xE010, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAE, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 16, 8, 0 + }, + { /* 22 */ + "Diva Server 4BRI-8M PCI", 0xE012, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 4, 2, 16, 8, 0 + }, + { /* 23 */ + "Diva Server PRI-30M PCI", 0xE014, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 30, 256, 8, 0 + }, + { /* 24 */ + "Diva Server PRI-2M PCI", 0xe014, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 30, 256, 8, 0 + }, + { /* 25 */ + "Diva Server PRI-9M PCI", 0x0000, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 30, 256, 8, 0 + }, + { /* 26 */ + "Diva 2.0 S/T ISA", 0x0071, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 27 */ + "Diva 2.0 U ISA", 0x0091, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_ISA, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 28 */ + "Diva 2.0 U PCI", 0xe004, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCI, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 29 */ + "Diva PRO 2.0 S/T ISA", 0x0061, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, + CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 30 */ + "Diva PRO 2.0 U ISA", 0x0081, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, + CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 31 */ + "Diva PRO 2.0 U PCI", 0xe003, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, + CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 32 */ + "Diva MOBILE", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 33 */ + "TDK DFI3600", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 34 (OEM version of 4 - "Diva PRO PC-Card") */ + "New Media ISDN", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 35 (OEM version of 7 - "Diva PRO 2.0 S/T PCI") */ + "BT ExLane PCI", 0xe101, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, + CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 36 (OEM version of 29 - "Diva PRO 2.0 S/T ISA") */ + "BT ExLane ISA", 0x1061, 0x0200, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS, + CARD_PRO, CARD_I_NONE, BUS_ISA, CHIP_DSP, + 1, 2, 0, 8, 0 + }, + { /* 37 */ + "Diva 2.01 S/T ISA", 0x00A1, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_ISA, CHIP_IPAC, + 1, 2, 0, 8, 0 + }, + { /* 38 */ + "Diva 2.01 U ISA", 0x00B1, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_ISA, CHIP_IPAC, + 1, 2, 0, 8, 0 + }, + { /* 39 */ + "Diva 2.01 S/T PCI", 0xe005, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC, + 1, 2, 0, 8, 0 + }, + { /* 40 no ID yet */ + "Diva 2.01 U PCI", 0x0000, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC, + 1, 2, 0, 8, 0 + }, + { /* 41 */ + "Diva MOBILE V.90", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 42 */ + "TDK DFI3600 V.90", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_HSCX, + 1, 2, 0, 8, 0 + }, + { /* 43 */ + "Diva Server PRI-23M PCI", 0xe014, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 30, 256, 8, 0 + }, + { /* 44 */ + "Diva 2.01 S/T USB", 0x1000, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_USB, CHIP_IPAC, + 1, 2, 0, 8, 0 + }, + { /* 45 */ + "Diva CT S/T PCI", 0xe006, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, + CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 0, 0 + }, + { /* 46 */ + "Diva CT U PCI", 0xe007, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, + CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 0, 0 + }, + { /* 47 */ + "Diva CT Lite S/T PCI", 0xe008, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, + CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 0, 0 + }, + { /* 48 */ + "Diva CT Lite U PCI", 0xe009, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, + CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 0, 0 + }, + { /* 49 */ + "Diva ISDN+V.90 PC Card", 0x8D8C, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, + CARD_DIVALOW, CARD_I_NONE, BUS_PCM, CHIP_IPAC, + 1, 2, 0, 8, 0 + }, + { /* 50 */ + "Diva ISDN+V.90 PCI", 0xe00A, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPAC, + 1, 2, 0, 8, 0 + }, + { /* 51 (DivaTA) no ID */ + "Diva TA", 0x0000, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES, + CARD_DIVATA, CARD_I_NONE, BUS_COM, CHIP_EXTERN, + 1, 1, 0, 8, 0 + }, + { /* 52 (Diva Server 4BRI-8M PCI adapter enabled for Voice) */ + "Diva Server Voice 4BRI-8M PCI", 0xE016, 0x0100, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, + CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 4, 2, 16, 8, 0 + }, + { /* 53 (Diva Server 4BRI 2.0 adapter) */ + "Diva Server 4BRI-8M 2.0 PCI", 0xE013, 0x0200, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 4, 2, 16, 8, 0 + }, + { /* 54 (Diva Server PRI 2.0 adapter) */ + "Diva Server PRI 2.0 PCI", 0xE015, 0x0200, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 30, 256, 8, 0 + }, + { /* 55 (Diva Server 4BRI-8M 2.0 PCI adapter enabled for Voice) */ + "Diva Server Voice 4BRI-8M 2.0 PCI", 0xE017, 0x0200, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, + CARD_MAEQ, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 4, 2, 16, 8, 0 + }, + { /* 56 (Diva Server PRI 2.0 PCI adapter enabled for Voice) */ + "Diva Server Voice PRI 2.0 PCI", 0xE019, 0x0200, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, + CARD_MAEP, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 30, 256, 8, 0 + }, + { + /* 57 (DivaLan ) no ID */ + "Diva LAN", 0x0000, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALAN, CARD_I_NONE, BUS_LAN, CHIP_EXTERN, + 1, 1, 0, 8, 0 + }, + { /* 58 */ + "Diva 2.02 PCI S/T", 0xE00B, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES | DI_SOFT_V110, + CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPACX, + 1, 2, 0, 8, 0 + }, + { /* 59 */ + "Diva 2.02 PCI U", 0xE00C, 0x0300, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_PCI, CHIP_IPACX, + 1, 2, 0, 8, 0 + }, + { /* 60 */ + "Diva Server BRI-2M 2.0 PCI", 0xE018, 0x0200, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 16, 8, 0 + }, + { /* 61 (the previous name was Diva Server BRI-2F 2.0 PCI) */ + "Diva Server 2FX", 0xE01A, 0x0200, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_SOFT_V110, + CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_IPACX, + 1, 2, 16, 8, 0 + }, + { /* 62 */ + " Diva ISDN USB 2.0", 0x1003, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_DIVALOW, CARD_I_NONE, BUS_USB, CHIP_IPACX, + 1, 2, 0, 8, 0 + }, + { /* 63 (Diva Server BRI-2M 2.0 PCI adapter enabled for Voice) */ + "Diva Server Voice BRI-2M 2.0 PCI", 0xE01B, 0x0200, + IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP, + CARD_MAE2, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 16, 8, 0 + }, + { /* 64 */ + "Diva Pro 3.0 PCI", 0xe00d, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM, + CARD_PRO, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 0, 0 + }, + { /* 65 */ + "Diva ISDN + CT 2.0", 0xE00E, 0x0300, + IDI_ADAPTER_DIVA , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC, + CARD_CT, CARD_I_NONE, BUS_PCI, CHIP_DSP, + 1, 2, 0, 0, 0 + }, + { /* 66 */ + "Diva Mobile V.90 PC Card", 0x8331, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_IPACX, + 1, 2, 0, 8, 0 + }, + { /* 67 */ + "Diva ISDN PC Card", 0x8311, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PICO, CARD_I_NONE, BUS_PCM, CHIP_IPACX, + 1, 2, 0, 8, 0 + }, + { /* 68 */ + "Diva ISDN PC Card", 0x0000, 0x0100, + IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES, + CARD_PRO, CARD_I_NONE, BUS_PCM, CHIP_DSP, + 1, 2, 0, 8, 0 + }, +}; #if CARDTYPE_H_WANT_RESOURCE_DATA /*--- CardResource [Index=CARDTYPE_....] ---------------------------(GEI)-*/ -CARD_RESOURCE CardResource [ ] = { +CARD_RESOURCE CardResource[] = { /* Interrupts IO-Address Mem-Address */ -/* 0*/ { 3,4,9,0,0,0,0,0,0,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA MCA -/* 1*/ { 3,4,9,10,11,12,0,0,0,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA ISA -/* 2*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PCMCIA -/* 3*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO ISA -/* 4*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO PCMCIA -/* 5*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PICCOLA ISA -/* 6*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA PICCOLA PCMCIA -/* 7*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO 2.0 PCI -/* 8*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.0 PCI -/* 9*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x2000,64 }, // QUADRO ISA -/*10*/ { 3,4,9,10,11,12,0,0,0,0, 0x0,0x0,0, 0xc0000,0x2000,16 }, // S ISA -/*11*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // S MCA -/*12*/ { 3,4,9,10,11,12,0,0,0,0, 0x0,0x0,0, 0xc0000,0x2000,16 }, // SX ISA -/*13*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SX MCA -/*14*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x0800,256 }, // SXN ISA -/*15*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SXN MCA -/*16*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x0800,256 }, // SCOM ISA -/*17*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SCOM MCA -/*18*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0xc0000,0x4000,16 }, // S2M ISA -/*19*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x4000,16 }, // S2M MCA -/*20*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA ISA -/*21*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA PCI -/*22*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA QUADRO ISA -/*23*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA QUADRO PCI -/*24*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA PRIMARY ISA -/*25*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA PRIMARY PCI -/*26*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.0 ISA -/*27*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.0 /U ISA -/*28*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.0 /U PCI -/*29*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO 2.0 ISA -/*30*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO 2.0 /U ISA -/*31*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO 2.0 /U PCI -/*32*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA MOBILE -/*33*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // TDK DFI3600 (same as DIVA MOBILE [32]) -/*34*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // New Media ISDN (same as DIVA PRO PCMCIA [4]) -/*35*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // BT ExLane PCI (same as DIVA PRO 2.0 PCI [7]) -/*36*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // BT ExLane ISA (same as DIVA PRO 2.0 ISA [29]) -/*37*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.01 S/T ISA -/*38*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.01 U ISA -/*39*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.01 S/T PCI -/*40*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.01 U PCI -/*41*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA MOBILE V.90 -/*42*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // TDK DFI3600 V.90 (same as DIVA MOBILE V.90 [39]) -/*43*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // DIVA Server PRI-23M PCI -/*44*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA 2.01 S/T USB -/*45*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT S/T PCI -/*46*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT U PCI -/*47*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT Lite S/T PCI -/*48*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT Lite U PCI -/*49*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA ISDN+V.90 PC Card -/*50*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA ISDN+V.90 PCI -/*51*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA TA -/*52*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI -/*53*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI -/*54*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA VOICE PRIMARY PCI -/*55*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI -/*56*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA VOICE PRIMARY PCI -/*57*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA LAN -/*58*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.02 S/T PCI -/*59*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.02 U PCI -/*60*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server BRI-2M 2.0 PCI -/*61*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server BRI-2F PCI -/*62*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA 2.01 S/T USB -/*63*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server Voice BRI-2M 2.0 PCI -/*64*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 3.0 PCI -/*65*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT S/T PCI V2.0 -/*66*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA Mobile V.90 PC Card -/*67*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA ISDN PC Card -/*68*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA ISDN PC Card + /* 0*/ { 3,4,9,0,0,0,0,0,0,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA MCA + /* 1*/ { 3,4,9,10,11,12,0,0,0,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA ISA + /* 2*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PCMCIA + /* 3*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO ISA + /* 4*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO PCMCIA + /* 5*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PICCOLA ISA + /* 6*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA PICCOLA PCMCIA + /* 7*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO 2.0 PCI + /* 8*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.0 PCI + /* 9*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x2000,64 }, // QUADRO ISA + /*10*/ { 3,4,9,10,11,12,0,0,0,0, 0x0,0x0,0, 0xc0000,0x2000,16 }, // S ISA + /*11*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // S MCA + /*12*/ { 3,4,9,10,11,12,0,0,0,0, 0x0,0x0,0, 0xc0000,0x2000,16 }, // SX ISA + /*13*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SX MCA + /*14*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x0800,256 }, // SXN ISA + /*15*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SXN MCA + /*16*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0x80000,0x0800,256 }, // SCOM ISA + /*17*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x2000,16 }, // SCOM MCA + /*18*/ { 3,4,5,7,9,10,11,12,0,0, 0x0,0x0,0, 0xc0000,0x4000,16 }, // S2M ISA + /*19*/ { 3,4,9,0,0,0,0,0,0,0, 0xc00,0x10,16, 0xc0000,0x4000,16 }, // S2M MCA + /*20*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA ISA + /*21*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA PCI + /*22*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA QUADRO ISA + /*23*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA QUADRO PCI + /*24*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // MAESTRA PRIMARY ISA + /*25*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA PRIMARY PCI + /*26*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.0 ISA + /*27*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.0 /U ISA + /*28*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.0 /U PCI + /*29*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO 2.0 ISA + /*30*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA PRO 2.0 /U ISA + /*31*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA PRO 2.0 /U PCI + /*32*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA MOBILE + /*33*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // TDK DFI3600 (same as DIVA MOBILE [32]) + /*34*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // New Media ISDN (same as DIVA PRO PCMCIA [4]) + /*35*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // BT ExLane PCI (same as DIVA PRO 2.0 PCI [7]) + /*36*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // BT ExLane ISA (same as DIVA PRO 2.0 ISA [29]) + /*37*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.01 S/T ISA + /*38*/ { 3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16, 0x0,0x0,0 }, // DIVA 2.01 U ISA + /*39*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.01 S/T PCI + /*40*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.01 U PCI + /*41*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA MOBILE V.90 + /*42*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // TDK DFI3600 V.90 (same as DIVA MOBILE V.90 [39]) + /*43*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // DIVA Server PRI-23M PCI + /*44*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA 2.01 S/T USB + /*45*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT S/T PCI + /*46*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT U PCI + /*47*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT Lite S/T PCI + /*48*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT Lite U PCI + /*49*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA ISDN+V.90 PC Card + /*50*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA ISDN+V.90 PCI + /*51*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA TA + /*52*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI + /*53*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI + /*54*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA VOICE PRIMARY PCI + /*55*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048, 0x0,0x0,0 }, // MAESTRA VOICE QUADRO PCI + /*56*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // MAESTRA VOICE PRIMARY PCI + /*57*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA LAN + /*58*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.02 S/T PCI + /*59*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 2.02 U PCI + /*60*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server BRI-2M 2.0 PCI + /*61*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server BRI-2F PCI + /*62*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA 2.01 S/T USB + /*63*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // Diva Server Voice BRI-2M 2.0 PCI + /*64*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA 3.0 PCI + /*65*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA CT S/T PCI V2.0 + /*66*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA Mobile V.90 PC Card + /*67*/ { 0,0,0,0,0,0,0,0,0,0, 0x0,0x0,0, 0x0,0x0,0 }, // DIVA ISDN PC Card + /*68*/ { 3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192, 0x0,0x0,0 }, // DIVA ISDN PC Card }; #endif /*CARDTYPE_H_WANT_RESOURCE_DATA*/ #else /*!CARDTYPE_H_WANT_DATA*/ -extern CARD_PROPERTIES CardProperties [] ; -extern CARD_RESOURCE CardResource [] ; +extern CARD_PROPERTIES CardProperties[]; +extern CARD_RESOURCE CardResource[]; #endif /*CARDTYPE_H_WANT_DATA*/ /* * all existing download files @@ -902,197 +902,197 @@ extern CARD_RESOURCE CardResource [] ; #define CARD_D_NEW_DSP_COMBIFILE 63 typedef struct CARD_FILES_DATA { - char * Name; - unsigned char Type; + char *Name; + unsigned char Type; } -CARD_FILES_DATA; + CARD_FILES_DATA; typedef struct CARD_FILES { - unsigned char Boot; - unsigned char Dsp [CARD_DSP_CNT]; - unsigned char DspTelindus; - unsigned char Prot [CARD_PROT_CNT]; + unsigned char Boot; + unsigned char Dsp[CARD_DSP_CNT]; + unsigned char DspTelindus; + unsigned char Prot[CARD_PROT_CNT]; } -CARD_FILES; + CARD_FILES; #if CARDTYPE_H_WANT_DATA #if CARDTYPE_H_WANT_FILE_DATA -CARD_FILES_DATA CardFData [] = { +CARD_FILES_DATA CardFData[] = { // Filename Filetype - 0, CARD_FT_UNKNOWN, - "didnload.bin", CARD_FT_B, - "diprload.bin", CARD_FT_B, - "didiva.bin", CARD_FT_D, - "didivapp.bin", CARD_FT_D, - "dihscx.bin", CARD_FT_D, - "div110.bin", CARD_FT_D, - "dimodem.bin", CARD_FT_D, - "difax.bin", CARD_FT_D, - "di_etsi.bin", CARD_FT_S, - "di_1tr6.bin", CARD_FT_S, - "di_belg.bin", CARD_FT_S, - "di_franc.bin", CARD_FT_S, - "di_atel.bin", CARD_FT_S, - "di_ni.bin", CARD_FT_S, - "di_5ess.bin", CARD_FT_S, - "di_japan.bin", CARD_FT_S, - "di_etsi.sx", CARD_FT_S, - "di_1tr6.sx", CARD_FT_S, - "di_belg.sx", CARD_FT_S, - "di_franc.sx", CARD_FT_S, - "di_atel.sx", CARD_FT_S, - "di_ni.sx", CARD_FT_S, - "di_5ess.sx", CARD_FT_S, - "di_japan.sx", CARD_FT_S, - "di_etsi.sy", CARD_FT_S, - "di_1tr6.sy", CARD_FT_S, - "di_belg.sy", CARD_FT_S, - "di_franc.sy", CARD_FT_S, - "di_atel.sy", CARD_FT_S, - "di_ni.sy", CARD_FT_S, - "di_5ess.sy", CARD_FT_S, - "di_japan.sy", CARD_FT_S, - "di_etsi.sq", CARD_FT_S, - "di_1tr6.sq", CARD_FT_S, - "di_belg.sq", CARD_FT_S, - "di_franc.sq", CARD_FT_S, - "di_atel.sq", CARD_FT_S, - "di_ni.sq", CARD_FT_S, - "di_5ess.sq", CARD_FT_S, - "di_japan.sq", CARD_FT_S, - "di_etsi.p", CARD_FT_S, - "di_1tr6.p", CARD_FT_S, - "di_belg.p", CARD_FT_S, - "di_franc.p", CARD_FT_S, - "di_atel.p", CARD_FT_S, - "di_ni.p", CARD_FT_S, - "di_5ess.p", CARD_FT_S, - "di_japan.p", CARD_FT_S, - "di_etsi.sm", CARD_FT_M, - "di_1tr6.sm", CARD_FT_M, - "di_belg.sm", CARD_FT_M, - "di_franc.sm", CARD_FT_M, - "di_atel.sm", CARD_FT_M, - "di_ni.sm", CARD_FT_M, - "di_5ess.sm", CARD_FT_M, - "di_japan.sm", CARD_FT_M, - "di_swed.bin", CARD_FT_S, - "di_swed.sx", CARD_FT_S, - "di_swed.sy", CARD_FT_S, - "di_swed.sq", CARD_FT_S, - "di_swed.p", CARD_FT_S, - "di_swed.sm", CARD_FT_M, - "didspdld.bin", CARD_FT_NEW_DSP_COMBIFILE + 0, CARD_FT_UNKNOWN, + "didnload.bin", CARD_FT_B, + "diprload.bin", CARD_FT_B, + "didiva.bin", CARD_FT_D, + "didivapp.bin", CARD_FT_D, + "dihscx.bin", CARD_FT_D, + "div110.bin", CARD_FT_D, + "dimodem.bin", CARD_FT_D, + "difax.bin", CARD_FT_D, + "di_etsi.bin", CARD_FT_S, + "di_1tr6.bin", CARD_FT_S, + "di_belg.bin", CARD_FT_S, + "di_franc.bin", CARD_FT_S, + "di_atel.bin", CARD_FT_S, + "di_ni.bin", CARD_FT_S, + "di_5ess.bin", CARD_FT_S, + "di_japan.bin", CARD_FT_S, + "di_etsi.sx", CARD_FT_S, + "di_1tr6.sx", CARD_FT_S, + "di_belg.sx", CARD_FT_S, + "di_franc.sx", CARD_FT_S, + "di_atel.sx", CARD_FT_S, + "di_ni.sx", CARD_FT_S, + "di_5ess.sx", CARD_FT_S, + "di_japan.sx", CARD_FT_S, + "di_etsi.sy", CARD_FT_S, + "di_1tr6.sy", CARD_FT_S, + "di_belg.sy", CARD_FT_S, + "di_franc.sy", CARD_FT_S, + "di_atel.sy", CARD_FT_S, + "di_ni.sy", CARD_FT_S, + "di_5ess.sy", CARD_FT_S, + "di_japan.sy", CARD_FT_S, + "di_etsi.sq", CARD_FT_S, + "di_1tr6.sq", CARD_FT_S, + "di_belg.sq", CARD_FT_S, + "di_franc.sq", CARD_FT_S, + "di_atel.sq", CARD_FT_S, + "di_ni.sq", CARD_FT_S, + "di_5ess.sq", CARD_FT_S, + "di_japan.sq", CARD_FT_S, + "di_etsi.p", CARD_FT_S, + "di_1tr6.p", CARD_FT_S, + "di_belg.p", CARD_FT_S, + "di_franc.p", CARD_FT_S, + "di_atel.p", CARD_FT_S, + "di_ni.p", CARD_FT_S, + "di_5ess.p", CARD_FT_S, + "di_japan.p", CARD_FT_S, + "di_etsi.sm", CARD_FT_M, + "di_1tr6.sm", CARD_FT_M, + "di_belg.sm", CARD_FT_M, + "di_franc.sm", CARD_FT_M, + "di_atel.sm", CARD_FT_M, + "di_ni.sm", CARD_FT_M, + "di_5ess.sm", CARD_FT_M, + "di_japan.sm", CARD_FT_M, + "di_swed.bin", CARD_FT_S, + "di_swed.sx", CARD_FT_S, + "di_swed.sy", CARD_FT_S, + "di_swed.sq", CARD_FT_S, + "di_swed.p", CARD_FT_S, + "di_swed.sm", CARD_FT_M, + "didspdld.bin", CARD_FT_NEW_DSP_COMBIFILE }; -CARD_FILES CardFiles [] = +CARD_FILES CardFiles[] = { - { /* CARD_UNKNOWN */ - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE - }, - { /* CARD_DIVA */ - CARD_FILE_NONE, - CARD_D_K1, CARD_D_H, CARD_D_V, CARD_FILE_NONE, CARD_D_F, - CARD_D_NEW_DSP_COMBIFILE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE - }, - { /* CARD_PRO */ - CARD_FILE_NONE, - CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F, - CARD_D_NEW_DSP_COMBIFILE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE - }, - { /* CARD_PICO */ - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE - }, - { /* CARD_S */ - CARD_B_S, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_P_S_E, CARD_P_S_1, CARD_P_S_B, CARD_P_S_F, - CARD_P_S_A, CARD_P_S_N, CARD_P_S_5, CARD_P_S_J, - CARD_P_S_S - }, - { /* CARD_SX */ - CARD_B_S, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_P_SX_E, CARD_P_SX_1, CARD_P_SX_B, CARD_P_SX_F, - CARD_P_SX_A, CARD_P_SX_N, CARD_P_SX_5, CARD_P_SX_J, - CARD_P_SX_S - }, - { /* CARD_SXN */ - CARD_B_S, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F, - CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J, - CARD_P_SY_S - }, - { /* CARD_SCOM */ - CARD_B_S, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F, - CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J, - CARD_P_SY_S - }, - { /* CARD_QUAD */ - CARD_B_S, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_P_SQ_E, CARD_P_SQ_1, CARD_P_SQ_B, CARD_P_SQ_F, - CARD_P_SQ_A, CARD_P_SQ_N, CARD_P_SQ_5, CARD_P_SQ_J, - CARD_P_SQ_S - }, - { /* CARD_PR */ - CARD_B_P, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_P_P_E, CARD_P_P_1, CARD_P_P_B, CARD_P_P_F, - CARD_P_P_A, CARD_P_P_N, CARD_P_P_5, CARD_P_P_J, - CARD_P_P_S - }, - { /* CARD_MAE */ - CARD_FILE_NONE, - CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F, - CARD_D_NEW_DSP_COMBIFILE, - CARD_P_M_E, CARD_P_M_1, CARD_P_M_B, CARD_P_M_F, - CARD_P_M_A, CARD_P_M_N, CARD_P_M_5, CARD_P_M_J, - CARD_P_M_S - }, - { /* CARD_MAEQ */ /* currently not supported */ - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE - }, - { /* CARD_MAEP */ /* currently not supported */ - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, - CARD_FILE_NONE - } + { /* CARD_UNKNOWN */ + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE + }, + { /* CARD_DIVA */ + CARD_FILE_NONE, + CARD_D_K1, CARD_D_H, CARD_D_V, CARD_FILE_NONE, CARD_D_F, + CARD_D_NEW_DSP_COMBIFILE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE + }, + { /* CARD_PRO */ + CARD_FILE_NONE, + CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F, + CARD_D_NEW_DSP_COMBIFILE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE + }, + { /* CARD_PICO */ + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE + }, + { /* CARD_S */ + CARD_B_S, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_P_S_E, CARD_P_S_1, CARD_P_S_B, CARD_P_S_F, + CARD_P_S_A, CARD_P_S_N, CARD_P_S_5, CARD_P_S_J, + CARD_P_S_S + }, + { /* CARD_SX */ + CARD_B_S, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_P_SX_E, CARD_P_SX_1, CARD_P_SX_B, CARD_P_SX_F, + CARD_P_SX_A, CARD_P_SX_N, CARD_P_SX_5, CARD_P_SX_J, + CARD_P_SX_S + }, + { /* CARD_SXN */ + CARD_B_S, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F, + CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J, + CARD_P_SY_S + }, + { /* CARD_SCOM */ + CARD_B_S, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F, + CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J, + CARD_P_SY_S + }, + { /* CARD_QUAD */ + CARD_B_S, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_P_SQ_E, CARD_P_SQ_1, CARD_P_SQ_B, CARD_P_SQ_F, + CARD_P_SQ_A, CARD_P_SQ_N, CARD_P_SQ_5, CARD_P_SQ_J, + CARD_P_SQ_S + }, + { /* CARD_PR */ + CARD_B_P, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_P_P_E, CARD_P_P_1, CARD_P_P_B, CARD_P_P_F, + CARD_P_P_A, CARD_P_P_N, CARD_P_P_5, CARD_P_P_J, + CARD_P_P_S + }, + { /* CARD_MAE */ + CARD_FILE_NONE, + CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F, + CARD_D_NEW_DSP_COMBIFILE, + CARD_P_M_E, CARD_P_M_1, CARD_P_M_B, CARD_P_M_F, + CARD_P_M_A, CARD_P_M_N, CARD_P_M_5, CARD_P_M_J, + CARD_P_M_S + }, + { /* CARD_MAEQ */ /* currently not supported */ + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE + }, + { /* CARD_MAEP */ /* currently not supported */ + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, + CARD_FILE_NONE + } }; #endif /*CARDTYPE_H_WANT_FILE_DATA*/ #else /*!CARDTYPE_H_WANT_DATA*/ -extern CARD_FILES_DATA CardFData [] ; -extern CARD_FILES CardFiles [] ; +extern CARD_FILES_DATA CardFData[]; +extern CARD_FILES CardFiles[]; #endif /*CARDTYPE_H_WANT_DATA*/ #endif /* _CARDTYPE_H_ */ diff --git a/drivers/isdn/hardware/eicon/cp_vers.h b/drivers/isdn/hardware/eicon/cp_vers.h index cb5ada31111..c97230c60e7 100644 --- a/drivers/isdn/hardware/eicon/cp_vers.h +++ b/drivers/isdn/hardware/eicon/cp_vers.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -static char diva_capi_common_code_build[] = "102-28"; +static char diva_capi_common_code_build[] = "102-28"; diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c index 89497890158..51420999418 100644 --- a/drivers/isdn/hardware/eicon/dadapter.c +++ b/drivers/isdn/hardware/eicon/dadapter.c @@ -1,26 +1,25 @@ - /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -30,337 +29,336 @@ #include "divasync.h" #include "dadapter.h" /* -------------------------------------------------------------------------- - Adapter array change notification framework + Adapter array change notification framework -------------------------------------------------------------------------- */ typedef struct _didd_adapter_change_notification { - didd_adapter_change_callback_t callback; - void IDI_CALL_ENTITY_T * context; -} didd_adapter_change_notification_t, \ - * IDI_CALL_ENTITY_T pdidd_adapter_change_notification_t; + didd_adapter_change_callback_t callback; + void IDI_CALL_ENTITY_T *context; +} didd_adapter_change_notification_t, \ + * IDI_CALL_ENTITY_T pdidd_adapter_change_notification_t; #define DIVA_DIDD_MAX_NOTIFICATIONS 256 -static didd_adapter_change_notification_t\ - NotificationTable[DIVA_DIDD_MAX_NOTIFICATIONS]; +static didd_adapter_change_notification_t \ +NotificationTable[DIVA_DIDD_MAX_NOTIFICATIONS]; /* -------------------------------------------------------------------------- - Array to held adapter information + Array to held adapter information -------------------------------------------------------------------------- */ static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS]; static dword Adapters = 0; /* Number of adapters */ /* -------------------------------------------------------------------------- - Shadow IDI_DIMAINT - and 'shadow' debug stuff + Shadow IDI_DIMAINT + and 'shadow' debug stuff -------------------------------------------------------------------------- */ -static void no_printf (unsigned char * format, ...) +static void no_printf(unsigned char *format, ...) { #ifdef EBUG va_list ap; - va_start (ap, format); + va_start(ap, format); debug((format, ap)); - va_end (ap); + va_end(ap); #endif } /* ------------------------------------------------------------------------- - Portable debug Library - ------------------------------------------------------------------------- */ + Portable debug Library + ------------------------------------------------------------------------- */ #include "debuglib.c" - + static DESCRIPTOR MAdapter = {IDI_DIMAINT, /* Adapter Type */ - 0x00, /* Channels */ - 0x0000, /* Features */ - (IDI_CALL)no_printf}; + 0x00, /* Channels */ + 0x0000, /* Features */ + (IDI_CALL)no_printf}; /* -------------------------------------------------------------------------- - DAdapter. Only IDI clients with buffer, that is huge enough to - get all descriptors will receive information about DAdapter - { byte type, byte channels, word features, IDI_CALL request } + DAdapter. Only IDI clients with buffer, that is huge enough to + get all descriptors will receive information about DAdapter + { byte type, byte channels, word features, IDI_CALL request } -------------------------------------------------------------------------- */ -static void IDI_CALL_LINK_T diva_dadapter_request (ENTITY IDI_CALL_ENTITY_T *); +static void IDI_CALL_LINK_T diva_dadapter_request(ENTITY IDI_CALL_ENTITY_T *); static DESCRIPTOR DAdapter = {IDI_DADAPTER, /* Adapter Type */ - 0x00, /* Channels */ - 0x0000, /* Features */ - diva_dadapter_request }; + 0x00, /* Channels */ + 0x0000, /* Features */ + diva_dadapter_request }; /* -------------------------------------------------------------------------- - LOCALS + LOCALS -------------------------------------------------------------------------- */ -static dword diva_register_adapter_callback (\ - didd_adapter_change_callback_t callback, - void IDI_CALL_ENTITY_T* context); -static void diva_remove_adapter_callback (dword handle); -static void diva_notify_adapter_change (DESCRIPTOR* d, int removal); +static dword diva_register_adapter_callback(\ + didd_adapter_change_callback_t callback, + void IDI_CALL_ENTITY_T *context); +static void diva_remove_adapter_callback(dword handle); +static void diva_notify_adapter_change(DESCRIPTOR *d, int removal); static diva_os_spin_lock_t didd_spin; /* -------------------------------------------------------------------------- - Should be called as first step, after driver init - -------------------------------------------------------------------------- */ -void diva_didd_load_time_init (void) { - memset (&HandleTable[0], 0x00, sizeof(HandleTable)); - memset (&NotificationTable[0], 0x00, sizeof(NotificationTable)); - diva_os_initialize_spin_lock (&didd_spin, "didd"); + Should be called as first step, after driver init + -------------------------------------------------------------------------- */ +void diva_didd_load_time_init(void) { + memset(&HandleTable[0], 0x00, sizeof(HandleTable)); + memset(&NotificationTable[0], 0x00, sizeof(NotificationTable)); + diva_os_initialize_spin_lock(&didd_spin, "didd"); } /* -------------------------------------------------------------------------- - Should be called as last step, if driver does unload - -------------------------------------------------------------------------- */ -void diva_didd_load_time_finit (void) { - diva_os_destroy_spin_lock (&didd_spin, "didd"); + Should be called as last step, if driver does unload + -------------------------------------------------------------------------- */ +void diva_didd_load_time_finit(void) { + diva_os_destroy_spin_lock(&didd_spin, "didd"); } /* -------------------------------------------------------------------------- - Called in order to register new adapter in adapter array - return adapter handle (> 0) on success - return -1 adapter array overflow - -------------------------------------------------------------------------- */ -static int diva_didd_add_descriptor (DESCRIPTOR* d) { - diva_os_spin_lock_magic_t irql; - int i; - if (d->type == IDI_DIMAINT) { - if (d->request) { - MAdapter.request = d->request; - dprintf = (DIVA_DI_PRINTF)d->request; - diva_notify_adapter_change (&MAdapter, 0); /* Inserted */ - DBG_TRC (("DIMAINT registered, dprintf=%08x", d->request)) - } else { - DBG_TRC (("DIMAINT removed")) - diva_notify_adapter_change (&MAdapter, 1); /* About to remove */ - MAdapter.request = (IDI_CALL)no_printf; - dprintf = no_printf; - } - return (NEW_MAX_DESCRIPTORS); - } - for (i = 0; i < NEW_MAX_DESCRIPTORS; i++) { - diva_os_enter_spin_lock (&didd_spin, &irql, "didd_add"); - if (HandleTable[i].type == 0) { - memcpy (&HandleTable[i], d, sizeof(*d)); - Adapters++; - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_add"); - diva_notify_adapter_change (d, 0); /* we have new adapter */ - DBG_TRC (("Add adapter[%d], request=%08x", (i+1), d->request)) - return (i+1); - } - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_add"); - } - DBG_ERR (("Can't add adapter, out of resources")) - return (-1); + Called in order to register new adapter in adapter array + return adapter handle (> 0) on success + return -1 adapter array overflow + -------------------------------------------------------------------------- */ +static int diva_didd_add_descriptor(DESCRIPTOR *d) { + diva_os_spin_lock_magic_t irql; + int i; + if (d->type == IDI_DIMAINT) { + if (d->request) { + MAdapter.request = d->request; + dprintf = (DIVA_DI_PRINTF)d->request; + diva_notify_adapter_change(&MAdapter, 0); /* Inserted */ + DBG_TRC(("DIMAINT registered, dprintf=%08x", d->request)) + } else { + DBG_TRC(("DIMAINT removed")) + diva_notify_adapter_change(&MAdapter, 1); /* About to remove */ + MAdapter.request = (IDI_CALL)no_printf; + dprintf = no_printf; + } + return (NEW_MAX_DESCRIPTORS); + } + for (i = 0; i < NEW_MAX_DESCRIPTORS; i++) { + diva_os_enter_spin_lock(&didd_spin, &irql, "didd_add"); + if (HandleTable[i].type == 0) { + memcpy(&HandleTable[i], d, sizeof(*d)); + Adapters++; + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_add"); + diva_notify_adapter_change(d, 0); /* we have new adapter */ + DBG_TRC(("Add adapter[%d], request=%08x", (i + 1), d->request)) + return (i + 1); + } + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_add"); + } + DBG_ERR(("Can't add adapter, out of resources")) + return (-1); } /* -------------------------------------------------------------------------- - Called in order to remove one registered adapter from array - return adapter handle (> 0) on success - return 0 on success - -------------------------------------------------------------------------- */ -static int diva_didd_remove_descriptor (IDI_CALL request) { - diva_os_spin_lock_magic_t irql; - int i; - if (request == MAdapter.request) { - DBG_TRC(("DIMAINT removed")) - dprintf = no_printf; - diva_notify_adapter_change (&MAdapter, 1); /* About to remove */ - MAdapter.request = (IDI_CALL)no_printf; - return (0); - } - for (i = 0; (Adapters && (i < NEW_MAX_DESCRIPTORS)); i++) { - if (HandleTable[i].request == request) { - diva_notify_adapter_change (&HandleTable[i], 1); /* About to remove */ - diva_os_enter_spin_lock (&didd_spin, &irql, "didd_rm"); - memset (&HandleTable[i], 0x00, sizeof(HandleTable[0])); - Adapters--; - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_rm"); - DBG_TRC (("Remove adapter[%d], request=%08x", (i+1), request)) - return (0); - } - } - DBG_ERR (("Invalid request=%08x, can't remove adapter", request)) - return (-1); + Called in order to remove one registered adapter from array + return adapter handle (> 0) on success + return 0 on success + -------------------------------------------------------------------------- */ +static int diva_didd_remove_descriptor(IDI_CALL request) { + diva_os_spin_lock_magic_t irql; + int i; + if (request == MAdapter.request) { + DBG_TRC(("DIMAINT removed")) + dprintf = no_printf; + diva_notify_adapter_change(&MAdapter, 1); /* About to remove */ + MAdapter.request = (IDI_CALL)no_printf; + return (0); + } + for (i = 0; (Adapters && (i < NEW_MAX_DESCRIPTORS)); i++) { + if (HandleTable[i].request == request) { + diva_notify_adapter_change(&HandleTable[i], 1); /* About to remove */ + diva_os_enter_spin_lock(&didd_spin, &irql, "didd_rm"); + memset(&HandleTable[i], 0x00, sizeof(HandleTable[0])); + Adapters--; + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_rm"); + DBG_TRC(("Remove adapter[%d], request=%08x", (i + 1), request)) + return (0); + } + } + DBG_ERR(("Invalid request=%08x, can't remove adapter", request)) + return (-1); } /* -------------------------------------------------------------------------- - Read adapter array - return 1 if not enough space to save all available adapters + Read adapter array + return 1 if not enough space to save all available adapters -------------------------------------------------------------------------- */ -static int diva_didd_read_adapter_array (DESCRIPTOR* buffer, int length) { - diva_os_spin_lock_magic_t irql; - int src, dst; - memset (buffer, 0x00, length); - length /= sizeof(DESCRIPTOR); - DBG_TRC (("DIDD_Read, space = %d, Adapters = %d", length, Adapters+2)) - - diva_os_enter_spin_lock (&didd_spin, &irql, "didd_read"); - for (src = 0, dst = 0; - (Adapters && (src < NEW_MAX_DESCRIPTORS) && (dst < length)); - src++) { - if (HandleTable[src].type) { - memcpy (&buffer[dst], &HandleTable[src], sizeof(DESCRIPTOR)); - dst++; - } - } - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_read"); - if (dst < length) { - memcpy (&buffer[dst], &MAdapter, sizeof(DESCRIPTOR)); - dst++; - } else { - DBG_ERR (("Can't write DIMAINT. Array too small")) - } - if (dst < length) { - memcpy (&buffer[dst], &DAdapter, sizeof(DESCRIPTOR)); - dst++; - } else { - DBG_ERR (("Can't write DADAPTER. Array too small")) - } - DBG_TRC (("Read %d adapters", dst)) - return (dst == length); +static int diva_didd_read_adapter_array(DESCRIPTOR *buffer, int length) { + diva_os_spin_lock_magic_t irql; + int src, dst; + memset(buffer, 0x00, length); + length /= sizeof(DESCRIPTOR); + DBG_TRC(("DIDD_Read, space = %d, Adapters = %d", length, Adapters + 2)) + + diva_os_enter_spin_lock(&didd_spin, &irql, "didd_read"); + for (src = 0, dst = 0; + (Adapters && (src < NEW_MAX_DESCRIPTORS) && (dst < length)); + src++) { + if (HandleTable[src].type) { + memcpy(&buffer[dst], &HandleTable[src], sizeof(DESCRIPTOR)); + dst++; + } + } + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_read"); + if (dst < length) { + memcpy(&buffer[dst], &MAdapter, sizeof(DESCRIPTOR)); + dst++; + } else { + DBG_ERR(("Can't write DIMAINT. Array too small")) + } + if (dst < length) { + memcpy(&buffer[dst], &DAdapter, sizeof(DESCRIPTOR)); + dst++; + } else { + DBG_ERR(("Can't write DADAPTER. Array too small")) + } + DBG_TRC(("Read %d adapters", dst)) + return (dst == length); } /* -------------------------------------------------------------------------- - DAdapter request function. - This function does process only synchronous requests, and is used - for reception/registration of new interfaces + DAdapter request function. + This function does process only synchronous requests, and is used + for reception/registration of new interfaces -------------------------------------------------------------------------- */ -static void IDI_CALL_LINK_T diva_dadapter_request (\ - ENTITY IDI_CALL_ENTITY_T *e) { - IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e ; - if (e->Req) { /* We do not process it, also return error */ - e->Rc = OUT_OF_RESOURCES; - DBG_ERR (("Can't process async request, Req=%02x", e->Req)) - return; - } - /* - So, we process sync request - */ - switch (e->Rc) { - case IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY: { - diva_didd_adapter_notify_t* pinfo = &syncReq->didd_notify.info; - pinfo->handle = diva_register_adapter_callback (\ - (didd_adapter_change_callback_t)pinfo->callback, - (void IDI_CALL_ENTITY_T *)pinfo->context); - e->Rc = 0xff; - } break; - case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY: { - diva_didd_adapter_notify_t* pinfo = &syncReq->didd_notify.info; - diva_remove_adapter_callback (pinfo->handle); - e->Rc = 0xff; - } break; - case IDI_SYNC_REQ_DIDD_ADD_ADAPTER: { - diva_didd_add_adapter_t* pinfo = &syncReq->didd_add_adapter.info; - if (diva_didd_add_descriptor ((DESCRIPTOR*)pinfo->descriptor) < 0) { - e->Rc = OUT_OF_RESOURCES; - } else { - e->Rc = 0xff; - } - } break; - case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER: { - diva_didd_remove_adapter_t* pinfo = &syncReq->didd_remove_adapter.info; - if (diva_didd_remove_descriptor ((IDI_CALL)pinfo->p_request) < 0) { - e->Rc = OUT_OF_RESOURCES; - } else { - e->Rc = 0xff; - } - } break; - case IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY: { - diva_didd_read_adapter_array_t* pinfo =\ - &syncReq->didd_read_adapter_array.info; - if (diva_didd_read_adapter_array ((DESCRIPTOR*)pinfo->buffer, - (int)pinfo->length)) { - e->Rc = OUT_OF_RESOURCES; - } else { - e->Rc = 0xff; - } - } break; - default: - DBG_ERR (("Can't process sync request, Req=%02x", e->Rc)) - e->Rc = OUT_OF_RESOURCES; - } +static void IDI_CALL_LINK_T diva_dadapter_request( \ + ENTITY IDI_CALL_ENTITY_T *e) { + IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e; + if (e->Req) { /* We do not process it, also return error */ + e->Rc = OUT_OF_RESOURCES; + DBG_ERR(("Can't process async request, Req=%02x", e->Req)) + return; + } + /* + So, we process sync request + */ + switch (e->Rc) { + case IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY: { + diva_didd_adapter_notify_t *pinfo = &syncReq->didd_notify.info; + pinfo->handle = diva_register_adapter_callback( \ + (didd_adapter_change_callback_t)pinfo->callback, + (void IDI_CALL_ENTITY_T *)pinfo->context); + e->Rc = 0xff; + } break; + case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY: { + diva_didd_adapter_notify_t *pinfo = &syncReq->didd_notify.info; + diva_remove_adapter_callback(pinfo->handle); + e->Rc = 0xff; + } break; + case IDI_SYNC_REQ_DIDD_ADD_ADAPTER: { + diva_didd_add_adapter_t *pinfo = &syncReq->didd_add_adapter.info; + if (diva_didd_add_descriptor((DESCRIPTOR *)pinfo->descriptor) < 0) { + e->Rc = OUT_OF_RESOURCES; + } else { + e->Rc = 0xff; + } + } break; + case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER: { + diva_didd_remove_adapter_t *pinfo = &syncReq->didd_remove_adapter.info; + if (diva_didd_remove_descriptor((IDI_CALL)pinfo->p_request) < 0) { + e->Rc = OUT_OF_RESOURCES; + } else { + e->Rc = 0xff; + } + } break; + case IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY: { + diva_didd_read_adapter_array_t *pinfo =\ + &syncReq->didd_read_adapter_array.info; + if (diva_didd_read_adapter_array((DESCRIPTOR *)pinfo->buffer, + (int)pinfo->length)) { + e->Rc = OUT_OF_RESOURCES; + } else { + e->Rc = 0xff; + } + } break; + default: + DBG_ERR(("Can't process sync request, Req=%02x", e->Rc)) + e->Rc = OUT_OF_RESOURCES; + } } /* -------------------------------------------------------------------------- - IDI client does register his notification function - -------------------------------------------------------------------------- */ -static dword diva_register_adapter_callback (\ - didd_adapter_change_callback_t callback, - void IDI_CALL_ENTITY_T* context) { - diva_os_spin_lock_magic_t irql; - dword i; - - for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) { - diva_os_enter_spin_lock (&didd_spin, &irql, "didd_nfy_add"); - if (!NotificationTable[i].callback) { - NotificationTable[i].callback = callback; - NotificationTable[i].context = context; - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy_add"); - DBG_TRC(("Register adapter notification[%d]=%08x", i+1, callback)) - return (i+1); - } - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy_add"); - } - DBG_ERR (("Can't register adapter notification, overflow")) - return (0); + IDI client does register his notification function + -------------------------------------------------------------------------- */ +static dword diva_register_adapter_callback( \ + didd_adapter_change_callback_t callback, + void IDI_CALL_ENTITY_T *context) { + diva_os_spin_lock_magic_t irql; + dword i; + + for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) { + diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy_add"); + if (!NotificationTable[i].callback) { + NotificationTable[i].callback = callback; + NotificationTable[i].context = context; + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_add"); + DBG_TRC(("Register adapter notification[%d]=%08x", i + 1, callback)) + return (i + 1); + } + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_add"); + } + DBG_ERR(("Can't register adapter notification, overflow")) + return (0); } /* -------------------------------------------------------------------------- - IDI client does register his notification function - -------------------------------------------------------------------------- */ -static void diva_remove_adapter_callback (dword handle) { - diva_os_spin_lock_magic_t irql; - if (handle && ((--handle) < DIVA_DIDD_MAX_NOTIFICATIONS)) { - diva_os_enter_spin_lock (&didd_spin, &irql, "didd_nfy_rm"); - NotificationTable[handle].callback = NULL; - NotificationTable[handle].context = NULL; - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy_rm"); - DBG_TRC(("Remove adapter notification[%d]", (int)(handle+1))) - return; - } - DBG_ERR(("Can't remove adapter notification, handle=%d", handle)) -} + IDI client does register his notification function + -------------------------------------------------------------------------- */ +static void diva_remove_adapter_callback(dword handle) { + diva_os_spin_lock_magic_t irql; + if (handle && ((--handle) < DIVA_DIDD_MAX_NOTIFICATIONS)) { + diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy_rm"); + NotificationTable[handle].callback = NULL; + NotificationTable[handle].context = NULL; + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_rm"); + DBG_TRC(("Remove adapter notification[%d]", (int)(handle + 1))) + return; + } + DBG_ERR(("Can't remove adapter notification, handle=%d", handle)) + } /* -------------------------------------------------------------------------- - Notify all client about adapter array change - Does suppose following behavior in the client side: - Step 1: Redister Notification - Step 2: Read Adapter Array - -------------------------------------------------------------------------- */ -static void diva_notify_adapter_change (DESCRIPTOR* d, int removal) { - int i, do_notify; - didd_adapter_change_notification_t nfy; - diva_os_spin_lock_magic_t irql; - for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) { - do_notify = 0; - diva_os_enter_spin_lock (&didd_spin, &irql, "didd_nfy"); - if (NotificationTable[i].callback) { - memcpy (&nfy, &NotificationTable[i], sizeof(nfy)); - do_notify = 1; - } - diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy"); - if (do_notify) { - (*(nfy.callback))(nfy.context, d, removal); - } - } + Notify all client about adapter array change + Does suppose following behavior in the client side: + Step 1: Redister Notification + Step 2: Read Adapter Array + -------------------------------------------------------------------------- */ +static void diva_notify_adapter_change(DESCRIPTOR *d, int removal) { + int i, do_notify; + didd_adapter_change_notification_t nfy; + diva_os_spin_lock_magic_t irql; + for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) { + do_notify = 0; + diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy"); + if (NotificationTable[i].callback) { + memcpy(&nfy, &NotificationTable[i], sizeof(nfy)); + do_notify = 1; + } + diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy"); + if (do_notify) { + (*(nfy.callback))(nfy.context, d, removal); + } + } } /* -------------------------------------------------------------------------- - For all systems, that are linked by Kernel Mode Linker this is ONLY one - function thet should be exported by this device driver - IDI clients should look for IDI_DADAPTER, and use request function - of this adapter (sync request) in order to receive appropriate services: - - add new adapter - - remove existing adapter - - add adapter array notification - - remove adapter array notification - (read adapter is redundant in this case) - INPUT: + For all systems, that are linked by Kernel Mode Linker this is ONLY one + function thet should be exported by this device driver + IDI clients should look for IDI_DADAPTER, and use request function + of this adapter (sync request) in order to receive appropriate services: + - add new adapter + - remove existing adapter + - add adapter array notification + - remove adapter array notification + (read adapter is redundant in this case) + INPUT: buffer - pointer to buffer that will receive adapter array length - length (in bytes) of space in buffer - OUTPUT: + OUTPUT: Adapter array will be written to memory described by 'buffer' If the last adapter seen in the returned adapter array is IDI_DADAPTER or if last adapter in array does have type '0', then it was enougth space in buffer to accommodate all available adapter descriptors - *NOTE 1 (debug interface): + *NOTE 1 (debug interface): The IDI adapter of type 'IDI_DIMAINT' does register as 'request' famous 'dprintf' function (of type DI_PRINTF, please look include/debuglib.c and include/debuglib.h) for details. So dprintf is not exported from module debug module directly, instead of this IDI_DIMAINT is registered. Module load order will receive in this case: - 1. DIDD (this file) - 2. DIMAINT does load and register 'IDI_DIMAINT', at this step - DIDD should be able to get 'dprintf', save it, and - register with DIDD by means of 'dprintf' function. - 3. any other driver is loaded and is able to access adapter array - and debug interface + 1. DIDD (this file) + 2. DIMAINT does load and register 'IDI_DIMAINT', at this step + DIDD should be able to get 'dprintf', save it, and + register with DIDD by means of 'dprintf' function. + 3. any other driver is loaded and is able to access adapter array + and debug interface This approach does allow to load/unload debug interface on demand, and save memory, it it is necessary. - -------------------------------------------------------------------------- */ -void IDI_CALL_LINK_T DIVA_DIDD_Read (void IDI_CALL_ENTITY_T * buffer, - int length) { - diva_didd_read_adapter_array (buffer, length); + -------------------------------------------------------------------------- */ +void IDI_CALL_LINK_T DIVA_DIDD_Read(void IDI_CALL_ENTITY_T *buffer, + int length) { + diva_didd_read_adapter_array(buffer, length); } - diff --git a/drivers/isdn/hardware/eicon/dadapter.h b/drivers/isdn/hardware/eicon/dadapter.h index 3575ac912e6..5540f46a5be 100644 --- a/drivers/isdn/hardware/eicon/dadapter.h +++ b/drivers/isdn/hardware/eicon/dadapter.h @@ -1,33 +1,33 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_DIDD_DADAPTER_INC__ #define __DIVA_DIDD_DADAPTER_INC__ - -void diva_didd_load_time_init (void); -void diva_didd_load_time_finit (void); + +void diva_didd_load_time_init(void); +void diva_didd_load_time_finit(void); #define NEW_MAX_DESCRIPTORS 64 diff --git a/drivers/isdn/hardware/eicon/dbgioctl.h b/drivers/isdn/hardware/eicon/dbgioctl.h deleted file mode 100644 index 0fb6f5e88b6..00000000000 --- a/drivers/isdn/hardware/eicon/dbgioctl.h +++ /dev/null @@ -1,198 +0,0 @@ - -/* - * - Copyright (c) Eicon Technology Corporation, 2000. - * - This source file is supplied for the use with Eicon - Technology Corporation's range of DIVA Server Adapters. - * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -/*------------------------------------------------------------------*/ -/* file: dbgioctl.h */ -/*------------------------------------------------------------------*/ - -#if !defined(__DBGIOCTL_H__) - -#define __DBGIOCTL_H__ - -#ifdef NOT_YET_NEEDED -/* - * The requested operation is passed in arg0 of DbgIoctlArgs, - * additional arguments (if any) in arg1, arg2 and arg3. - */ - -typedef struct -{ ULONG arg0 ; - ULONG arg1 ; - ULONG arg2 ; - ULONG arg3 ; -} DbgIoctlArgs ; - -#define DBG_COPY_LOGS 0 /* copy debugs to user until buffer full */ - /* arg1: size threshold */ - /* arg2: timeout in milliseconds */ - -#define DBG_FLUSH_LOGS 1 /* flush pending debugs to user buffer */ - /* arg1: internal driver id */ - -#define DBG_LIST_DRVS 2 /* return the list of registered drivers */ - -#define DBG_GET_MASK 3 /* get current debug mask of driver */ - /* arg1: internal driver id */ - -#define DBG_SET_MASK 4 /* set/change debug mask of driver */ - /* arg1: internal driver id */ - /* arg2: new debug mask */ - -#define DBG_GET_BUFSIZE 5 /* get current buffer size of driver */ - /* arg1: internal driver id */ - /* arg2: new debug mask */ - -#define DBG_SET_BUFSIZE 6 /* set new buffer size of driver */ - /* arg1: new buffer size */ - -/* - * common internal debug message structure - */ - -typedef struct -{ unsigned short id ; /* virtual driver id */ - unsigned short type ; /* special message type */ - unsigned long seq ; /* sequence number of message */ - unsigned long size ; /* size of message in bytes */ - unsigned long next ; /* offset to next buffered message */ - LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */ - unsigned char data[4] ;/* message data */ -} OldDbgMessage ; - -typedef struct -{ LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */ - unsigned short size ; /* size of message in bytes */ - unsigned short ffff ; /* always 0xffff to indicate new msg */ - unsigned short id ; /* virtual driver id */ - unsigned short type ; /* special message type */ - unsigned long seq ; /* sequence number of message */ - unsigned char data[4] ;/* message data */ -} DbgMessage ; - -#endif - -#define DRV_ID_UNKNOWN 0x0C /* for messages via prtComp() */ - -#define MSG_PROC_FLAG 0x80 -#define MSG_PROC_NO_GET(x) (((x) & MSG_PROC_FLAG) ? (((x) >> 4) & 7) : -1) -#define MSG_PROC_NO_SET(x) (MSG_PROC_FLAG | (((x) & 7) << 4)) - -#define MSG_TYPE_DRV_ID 0x0001 -#define MSG_TYPE_FLAGS 0x0002 -#define MSG_TYPE_STRING 0x0003 -#define MSG_TYPE_BINARY 0x0004 - -#define MSG_HEAD_SIZE ((unsigned long)&(((DbgMessage *)0)->data[0])) -#define MSG_ALIGN(len) (((unsigned long)(len) + MSG_HEAD_SIZE + 3) & ~3) -#define MSG_SIZE(pMsg) MSG_ALIGN((pMsg)->size) -#define MSG_NEXT(pMsg) ((DbgMessage *)( ((char *)(pMsg)) + MSG_SIZE(pMsg) )) - -#define OLD_MSG_HEAD_SIZE ((unsigned long)&(((OldDbgMessage *)0)->data[0])) -#define OLD_MSG_ALIGN(len) (((unsigned long)(len)+OLD_MSG_HEAD_SIZE+3) & ~3) - -/* - * manifest constants - */ - -#define MSG_FRAME_MAX_SIZE 2150 /* maximum size of B1 frame */ -#define MSG_TEXT_MAX_SIZE 1024 /* maximum size of msg text */ -#define MSG_MAX_SIZE MSG_ALIGN(MSG_FRAME_MAX_SIZE) -#define DBG_MIN_BUFFER_SIZE 0x00008000 /* minimal total buffer size 32 KB */ -#define DBG_DEF_BUFFER_SIZE 0x00020000 /* default total buffer size 128 KB */ -#define DBG_MAX_BUFFER_SIZE 0x00400000 /* maximal total buffer size 4 MB */ - -#define DBGDRV_NAME "Diehl_DIMAINT" -#define UNIDBG_DRIVER L"\\Device\\Diehl_DIMAINT" /* UNICODE name for kernel */ -#define DEBUG_DRIVER "\\\\.\\" DBGDRV_NAME /* traditional string for apps */ -#define DBGVXD_NAME "DIMAINT" -#define DEBUG_VXD "\\\\.\\" DBGVXD_NAME /* traditional string for apps */ - -/* - * Special IDI interface debug construction - */ - -#define DBG_IDI_SIG_REQ (unsigned long)0xF479C402 -#define DBG_IDI_SIG_IND (unsigned long)0xF479C403 -#define DBG_IDI_NL_REQ (unsigned long)0xF479C404 -#define DBG_IDI_NL_IND (unsigned long)0xF479C405 - -typedef struct -{ unsigned long magic_type ; - unsigned short data_len ; - unsigned char layer_ID ; - unsigned char entity_ID ; - unsigned char request ; - unsigned char ret_code ; - unsigned char indication ; - unsigned char complete ; - unsigned char data[4] ; -} DbgIdiAct, *DbgIdiAction ; - -/* - * We want to use the same IOCTL codes in Win95 and WinNT. - * The official constructor for IOCTL codes is the CTL_CODE macro - * from <winoctl.h> (<devioctl.h> in WinNT DDK environment). - * The problem here is that we don't know how to get <winioctl.h> - * working in a Win95 DDK environment! - */ - -# ifdef CTL_CODE /*{*/ - -/* Assert that we have the same idea of the CTL_CODE macro. */ - -#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ - ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ -) - -# else /* !CTL_CODE */ /*}{*/ - -/* Use the definitions stolen from <winioctl.h>. */ - -#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ - ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ -) - -#define METHOD_BUFFERED 0 -#define METHOD_IN_DIRECT 1 -#define METHOD_OUT_DIRECT 2 -#define METHOD_NEITHER 3 - -#define FILE_ANY_ACCESS 0 -#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe -#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe - -# endif /* CTL_CODE */ /*}*/ - -/* - * Now we can define WinNT/Win95 DeviceIoControl codes. - * - * These codes are defined in di_defs.h too, a possible mismatch will be - * detected when the dbgtool is compiled. - */ - -#define IOCTL_DRIVER_LNK \ - CTL_CODE(0x8001U,0x701,METHOD_OUT_DIRECT,FILE_ANY_ACCESS) -#define IOCTL_DRIVER_DBG \ - CTL_CODE(0x8001U,0x702,METHOD_OUT_DIRECT,FILE_ANY_ACCESS) - -#endif /* __DBGIOCTL_H__ */ diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c index 6851c6270ce..b5226af6dde 100644 --- a/drivers/isdn/hardware/eicon/debug.c +++ b/drivers/isdn/hardware/eicon/debug.c @@ -9,67 +9,67 @@ /* LOCALS - */ +*/ #define DBG_MAGIC (0x47114711L) -static void DI_register (void *arg); -static void DI_deregister (pDbgHandle hDbg); -static void DI_format (int do_lock, word id, int type, char *format, va_list argument_list); -static void DI_format_locked (word id, int type, char *format, va_list argument_list); -static void DI_format_old (word id, char *format, va_list ap) { } -static void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap) { } -static void single_p (byte * P, word * PLength, byte Id); -static void diva_maint_xdi_cb (ENTITY* e); -static word SuperTraceCreateReadReq (byte* P, const char* path); -static int diva_mnt_cmp_nmbr (const char* nmbr); -static void diva_free_dma_descriptor (IDI_CALL request, int nr); -static int diva_get_dma_descriptor (IDI_CALL request, dword *dma_magic); -void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...); - -static dword MaxDumpSize = 256 ; -static dword MaxXlogSize = 2 + 128 ; -static char TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH+1]; +static void DI_register(void *arg); +static void DI_deregister(pDbgHandle hDbg); +static void DI_format(int do_lock, word id, int type, char *format, va_list argument_list); +static void DI_format_locked(word id, int type, char *format, va_list argument_list); +static void DI_format_old(word id, char *format, va_list ap) { } +static void DiProcessEventLog(unsigned short id, unsigned long msgID, va_list ap) { } +static void single_p(byte *P, word *PLength, byte Id); +static void diva_maint_xdi_cb(ENTITY *e); +static word SuperTraceCreateReadReq(byte *P, const char *path); +static int diva_mnt_cmp_nmbr(const char *nmbr); +static void diva_free_dma_descriptor(IDI_CALL request, int nr); +static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic); +void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...); + +static dword MaxDumpSize = 256; +static dword MaxXlogSize = 2 + 128; +static char TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH + 1]; static int TraceFilterIdent = -1; static int TraceFilterChannel = -1; typedef struct _diva_maint_client { - dword sec; - dword usec; - pDbgHandle hDbg; - char drvName[128]; - dword dbgMask; - dword last_dbgMask; - IDI_CALL request; - _DbgHandle_ Dbg; - int logical; - int channels; - diva_strace_library_interface_t* pIdiLib; - BUFFERS XData; - char xbuffer[2048+512]; - byte* pmem; - int request_pending; - int dma_handle; + dword sec; + dword usec; + pDbgHandle hDbg; + char drvName[128]; + dword dbgMask; + dword last_dbgMask; + IDI_CALL request; + _DbgHandle_ Dbg; + int logical; + int channels; + diva_strace_library_interface_t *pIdiLib; + BUFFERS XData; + char xbuffer[2048 + 512]; + byte *pmem; + int request_pending; + int dma_handle; } diva_maint_client_t; static diva_maint_client_t clients[MAX_DESCRIPTORS]; -static void diva_change_management_debug_mask (diva_maint_client_t* pC, dword old_mask); +static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask); -static void diva_maint_error (void* user_context, - diva_strace_library_interface_t* hLib, - int Adapter, - int error, - const char* file, - int line); -static void diva_maint_state_change_notify (void* user_context, - diva_strace_library_interface_t* hLib, - int Adapter, - diva_trace_line_state_t* channel, - int notify_subject); -static void diva_maint_trace_notify (void* user_context, - diva_strace_library_interface_t* hLib, - int Adapter, - void* xlog_buffer, - int length); +static void diva_maint_error(void *user_context, + diva_strace_library_interface_t *hLib, + int Adapter, + int error, + const char *file, + int line); +static void diva_maint_state_change_notify(void *user_context, + diva_strace_library_interface_t *hLib, + int Adapter, + diva_trace_line_state_t *channel, + int notify_subject); +static void diva_maint_trace_notify(void *user_context, + diva_strace_library_interface_t *hLib, + int Adapter, + void *xlog_buffer, + int length); @@ -79,36 +79,36 @@ typedef struct MSG_QUEUE { byte *High; /* Base + Size (constant) */ byte *Head; /* first message in queue (if any) */ byte *Tail; /* first free position */ - byte *Wrap; /* current wraparound position */ + byte *Wrap; /* current wraparound position */ dword Count; /* current no of bytes in queue */ } MSG_QUEUE; typedef struct MSG_HEAD { volatile dword Size; /* size of data following MSG_HEAD */ -#define MSG_INCOMPLETE 0x8000 /* ored to Size until queueCompleteMsg */ +#define MSG_INCOMPLETE 0x8000 /* ored to Size until queueCompleteMsg */ } MSG_HEAD; -#define queueCompleteMsg(p) do{ ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; }while(0) +#define queueCompleteMsg(p) do { ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; } while (0) #define queueCount(q) ((q)->Count) -#define MSG_NEED(size) \ - ( (sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1) ) +#define MSG_NEED(size) \ + ((sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1)) -static void queueInit (MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) { +static void queueInit(MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) { Q->Size = sizeBuffer; Q->Base = Q->Head = Q->Tail = Buffer; Q->High = Buffer + sizeBuffer; Q->Wrap = NULL; - Q->Count= 0; + Q->Count = 0; } -static byte *queueAllocMsg (MSG_QUEUE *Q, word size) { +static byte *queueAllocMsg(MSG_QUEUE *Q, word size) { /* Allocate 'size' bytes at tail of queue which will be filled later - * directly with callers own message header info and/or message. - * An 'alloced' message is marked incomplete by oring the 'Size' field - * with MSG_INCOMPLETE. - * This must be reset via queueCompleteMsg() after the message is filled. - * As long as a message is marked incomplete queuePeekMsg() will return - * a 'queue empty' condition when it reaches such a message. */ + * directly with callers own message header info and/or message. + * An 'alloced' message is marked incomplete by oring the 'Size' field + * with MSG_INCOMPLETE. + * This must be reset via queueCompleteMsg() after the message is filled. + * As long as a message is marked incomplete queuePeekMsg() will return + * a 'queue empty' condition when it reaches such a message. */ MSG_HEAD *Msg; word need = MSG_NEED(size); @@ -119,7 +119,7 @@ static byte *queueAllocMsg (MSG_QUEUE *Q, word size) { } goto alloc; /* empty */ } - + if (Q->Tail > Q->Head) { if (Q->Tail + need <= Q->High) goto alloc; /* append */ if (Q->Base + need > Q->Head) { @@ -145,10 +145,10 @@ alloc: - return ((byte*)(Msg + 1)); + return ((byte *)(Msg + 1)); } -static void queueFreeMsg (MSG_QUEUE *Q) { +static void queueFreeMsg(MSG_QUEUE *Q) { /* Free the message at head of queue */ word size = ((MSG_HEAD *)Q->Head)->Size & ~MSG_INCOMPLETE; @@ -166,10 +166,10 @@ static void queueFreeMsg (MSG_QUEUE *Q) { } } -static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) { +static byte *queuePeekMsg(MSG_QUEUE *Q, word *size) { /* Show the first valid message in queue BUT DON'T free the message. - * After looking on the message contents it can be freed queueFreeMsg() - * or simply remain in message queue. */ + * After looking on the message contents it can be freed queueFreeMsg() + * or simply remain in message queue. */ MSG_HEAD *Msg = (MSG_HEAD *)Q->Head; @@ -184,9 +184,9 @@ static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) { /* Message queue header - */ -static MSG_QUEUE* dbg_queue; -static byte* dbg_base; +*/ +static MSG_QUEUE *dbg_queue; +static byte *dbg_base; static int external_dbg_queue; static diva_os_spin_lock_t dbg_q_lock; static diva_os_spin_lock_t dbg_adapter_lock; @@ -196,1148 +196,1147 @@ static dword start_sec; static dword start_usec; /* - INTERFACE: - Initialize run time queue structures. - base: base of the message queue - length: length of the message queue - do_init: perfor queue reset - - return: zero on success, -1 on error - */ -int diva_maint_init (byte* base, unsigned long length, int do_init) { - if (dbg_queue || (!base) || (length < (4096*4))) { - return (-1); - } + INTERFACE: + Initialize run time queue structures. + base: base of the message queue + length: length of the message queue + do_init: perfor queue reset + + return: zero on success, -1 on error +*/ +int diva_maint_init(byte *base, unsigned long length, int do_init) { + if (dbg_queue || (!base) || (length < (4096 * 4))) { + return (-1); + } - TraceFilter[0] = 0; - TraceFilterIdent = -1; - TraceFilterChannel = -1; + TraceFilter[0] = 0; + TraceFilterIdent = -1; + TraceFilterChannel = -1; - dbg_base = base; + dbg_base = base; - diva_os_get_time (&start_sec, &start_usec); + diva_os_get_time(&start_sec, &start_usec); - *(dword*)base = (dword)DBG_MAGIC; /* Store Magic */ - base += sizeof(dword); - length -= sizeof(dword); + *(dword *)base = (dword)DBG_MAGIC; /* Store Magic */ + base += sizeof(dword); + length -= sizeof(dword); - *(dword*)base = 2048; /* Extension Field Length */ - base += sizeof(dword); - length -= sizeof(dword); + *(dword *)base = 2048; /* Extension Field Length */ + base += sizeof(dword); + length -= sizeof(dword); - strcpy (base, "KERNEL MODE BUFFER\n"); - base += 2048; - length -= 2048; + strcpy(base, "KERNEL MODE BUFFER\n"); + base += 2048; + length -= 2048; - *(dword*)base = 0; /* Terminate extension */ - base += sizeof(dword); - length -= sizeof(dword); + *(dword *)base = 0; /* Terminate extension */ + base += sizeof(dword); + length -= sizeof(dword); - *(void**)base = (void*)(base+sizeof(void*)); /* Store Base */ - base += sizeof(void*); - length -= sizeof(void*); + *(void **)base = (void *)(base + sizeof(void *)); /* Store Base */ + base += sizeof(void *); + length -= sizeof(void *); - dbg_queue = (MSG_QUEUE*)base; - queueInit (dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512); - external_dbg_queue = 0; + dbg_queue = (MSG_QUEUE *)base; + queueInit(dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512); + external_dbg_queue = 0; - if (!do_init) { - external_dbg_queue = 1; /* memory was located on the external device */ - } + if (!do_init) { + external_dbg_queue = 1; /* memory was located on the external device */ + } - if (diva_os_initialize_spin_lock (&dbg_q_lock, "dbg_init")) { - dbg_queue = NULL; - dbg_base = NULL; - external_dbg_queue = 0; + if (diva_os_initialize_spin_lock(&dbg_q_lock, "dbg_init")) { + dbg_queue = NULL; + dbg_base = NULL; + external_dbg_queue = 0; return (-1); - } + } - if (diva_os_initialize_spin_lock (&dbg_adapter_lock, "dbg_init")) { - diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init"); - dbg_queue = NULL; - dbg_base = NULL; - external_dbg_queue = 0; + if (diva_os_initialize_spin_lock(&dbg_adapter_lock, "dbg_init")) { + diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init"); + dbg_queue = NULL; + dbg_base = NULL; + external_dbg_queue = 0; return (-1); - } + } - return (0); + return (0); } /* INTERFACE: - Finit at unload time - return address of internal queue or zero if queue - was external - */ -void* diva_maint_finit (void) { - void* ret = (void*)dbg_base; - int i; - - dbg_queue = NULL; - dbg_base = NULL; - - if (ret) { - diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit"); - diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit"); - } - - if (external_dbg_queue) { - ret = NULL; - } - external_dbg_queue = 0; - - for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) { - if (clients[i].pmem) { - diva_os_free (0, clients[i].pmem); - } - } - - return (ret); + Finit at unload time + return address of internal queue or zero if queue + was external +*/ +void *diva_maint_finit(void) { + void *ret = (void *)dbg_base; + int i; + + dbg_queue = NULL; + dbg_base = NULL; + + if (ret) { + diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit"); + diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit"); + } + + if (external_dbg_queue) { + ret = NULL; + } + external_dbg_queue = 0; + + for (i = 1; i < ARRAY_SIZE(clients); i++) { + if (clients[i].pmem) { + diva_os_free(0, clients[i].pmem); + } + } + + return (ret); } /* INTERFACE: - Return amount of messages in debug queue - */ -dword diva_dbg_q_length (void) { + Return amount of messages in debug queue +*/ +dword diva_dbg_q_length(void) { return (dbg_queue ? queueCount(dbg_queue) : 0); } /* INTERFACE: - Lock message queue and return the pointer to the first - entry. - */ -diva_dbg_entry_head_t* diva_maint_get_message (word* size, - diva_os_spin_lock_magic_t* old_irql) { - diva_dbg_entry_head_t* pmsg = NULL; - - diva_os_enter_spin_lock (&dbg_q_lock, old_irql, "read"); - if (dbg_q_busy) { - diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_busy"); - return NULL; - } - dbg_q_busy = 1; - - if (!(pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, size))) { - dbg_q_busy = 0; - diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_empty"); - } - - return (pmsg); + Lock message queue and return the pointer to the first + entry. +*/ +diva_dbg_entry_head_t *diva_maint_get_message(word *size, + diva_os_spin_lock_magic_t *old_irql) { + diva_dbg_entry_head_t *pmsg = NULL; + + diva_os_enter_spin_lock(&dbg_q_lock, old_irql, "read"); + if (dbg_q_busy) { + diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_busy"); + return NULL; + } + dbg_q_busy = 1; + + if (!(pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, size))) { + dbg_q_busy = 0; + diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_empty"); + } + + return (pmsg); } /* INTERFACE: - acknowledge last message and unlock queue - */ -void diva_maint_ack_message (int do_release, - diva_os_spin_lock_magic_t* old_irql) { + acknowledge last message and unlock queue +*/ +void diva_maint_ack_message(int do_release, + diva_os_spin_lock_magic_t *old_irql) { if (!dbg_q_busy) { return; } if (do_release) { - queueFreeMsg (dbg_queue); + queueFreeMsg(dbg_queue); } dbg_q_busy = 0; - diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_ack"); + diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_ack"); } /* INTERFACE: - PRT COMP function used to register - with MAINT adapter or log in compatibility - mode in case older driver version is connected too - */ -void diva_maint_prtComp (char *format, ...) { - void *hDbg; - va_list ap; - - if (!format) - return; - - va_start(ap, format); - - /* - register to new log driver functions - */ - if ((format[0] == 0) && ((unsigned char)format[1] == 255)) { - hDbg = va_arg(ap, void *); /* ptr to DbgHandle */ - DI_register (hDbg); - } - - va_end (ap); + PRT COMP function used to register + with MAINT adapter or log in compatibility + mode in case older driver version is connected too +*/ +void diva_maint_prtComp(char *format, ...) { + void *hDbg; + va_list ap; + + if (!format) + return; + + va_start(ap, format); + + /* + register to new log driver functions + */ + if ((format[0] == 0) && ((unsigned char)format[1] == 255)) { + hDbg = va_arg(ap, void *); /* ptr to DbgHandle */ + DI_register(hDbg); + } + + va_end(ap); } -static void DI_register (void *arg) { - diva_os_spin_lock_magic_t old_irql; - dword sec, usec; - pDbgHandle hDbg ; - int id, free_id = -1, best_id = 0; - - diva_os_get_time (&sec, &usec); - - hDbg = (pDbgHandle)arg ; - /* - Check for bad args, specially for the old obsolete debug handle - */ - if ((hDbg == NULL) || - ((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) || - (hDbg->Registered != 0)) { - return ; - } - - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register"); - - for (id = 1; id < (sizeof(clients)/sizeof(clients[0])); id++) { - if (clients[id].hDbg == hDbg) { - /* - driver already registered - */ - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register"); - return; - } - if (clients[id].hDbg) { /* slot is busy */ - continue; - } - free_id = id; - if (!strcmp (clients[id].drvName, hDbg->drvName)) { - /* - This driver was already registered with this name - and slot is still free - reuse it - */ - best_id = 1; - break; - } - if (!clients[id].hDbg) { /* slot is busy */ - break; - } - } - - if (free_id != -1) { - diva_dbg_entry_head_t* pmsg = NULL; - int len; - char tmp[256]; - word size; - - /* - Register new driver with id == free_id - */ - clients[free_id].hDbg = hDbg; - clients[free_id].sec = sec; - clients[free_id].usec = usec; - strcpy (clients[free_id].drvName, hDbg->drvName); - - clients[free_id].dbgMask = hDbg->dbgMask; - if (best_id) { - hDbg->dbgMask |= clients[free_id].last_dbgMask; - } else { - clients[free_id].last_dbgMask = 0; - } - - hDbg->Registered = DBG_HANDLE_REG_NEW ; - hDbg->id = (byte)free_id; - hDbg->dbg_end = DI_deregister; - hDbg->dbg_prt = DI_format_locked; - hDbg->dbg_ev = DiProcessEventLog; - hDbg->dbg_irq = DI_format_locked; - if (hDbg->Version > 0) { - hDbg->dbg_old = DI_format_old; - } - hDbg->next = (pDbgHandle)DBG_MAGIC; - - /* - Log driver register, MAINT driver ID is '0' - */ - len = sprintf (tmp, "DIMAINT - drv # %d = '%s' registered", - free_id, hDbg->drvName); - - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)(len+1+sizeof(*pmsg))))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - - if (pmsg) { - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_STRING; - pmsg->dli = DLI_REG; - pmsg->drv_id = 0; /* id 0 - DIMAINT */ - pmsg->di_cpu = 0; - pmsg->data_length = len+1; - - memcpy (&pmsg[1], tmp, len+1); - queueCompleteMsg (pmsg); - diva_maint_wakeup_read(); - } - } - - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register"); +static void DI_register(void *arg) { + diva_os_spin_lock_magic_t old_irql; + dword sec, usec; + pDbgHandle hDbg; + int id, free_id = -1, best_id = 0; + + diva_os_get_time(&sec, &usec); + + hDbg = (pDbgHandle)arg; + /* + Check for bad args, specially for the old obsolete debug handle + */ + if ((hDbg == NULL) || + ((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) || + (hDbg->Registered != 0)) { + return; + } + + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register"); + + for (id = 1; id < ARRAY_SIZE(clients); id++) { + if (clients[id].hDbg == hDbg) { + /* + driver already registered + */ + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register"); + return; + } + if (clients[id].hDbg) { /* slot is busy */ + continue; + } + free_id = id; + if (!strcmp(clients[id].drvName, hDbg->drvName)) { + /* + This driver was already registered with this name + and slot is still free - reuse it + */ + best_id = 1; + break; + } + if (!clients[id].hDbg) { /* slot is busy */ + break; + } + } + + if (free_id != -1) { + diva_dbg_entry_head_t *pmsg = NULL; + int len; + char tmp[256]; + word size; + + /* + Register new driver with id == free_id + */ + clients[free_id].hDbg = hDbg; + clients[free_id].sec = sec; + clients[free_id].usec = usec; + strcpy(clients[free_id].drvName, hDbg->drvName); + + clients[free_id].dbgMask = hDbg->dbgMask; + if (best_id) { + hDbg->dbgMask |= clients[free_id].last_dbgMask; + } else { + clients[free_id].last_dbgMask = 0; + } + + hDbg->Registered = DBG_HANDLE_REG_NEW; + hDbg->id = (byte)free_id; + hDbg->dbg_end = DI_deregister; + hDbg->dbg_prt = DI_format_locked; + hDbg->dbg_ev = DiProcessEventLog; + hDbg->dbg_irq = DI_format_locked; + if (hDbg->Version > 0) { + hDbg->dbg_old = DI_format_old; + } + hDbg->next = (pDbgHandle)DBG_MAGIC; + + /* + Log driver register, MAINT driver ID is '0' + */ + len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered", + free_id, hDbg->drvName); + + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)(len + 1 + sizeof(*pmsg))))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + + if (pmsg) { + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_STRING; + pmsg->dli = DLI_REG; + pmsg->drv_id = 0; /* id 0 - DIMAINT */ + pmsg->di_cpu = 0; + pmsg->data_length = len + 1; + + memcpy(&pmsg[1], tmp, len + 1); + queueCompleteMsg(pmsg); + diva_maint_wakeup_read(); + } + } + + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register"); } -static void DI_deregister (pDbgHandle hDbg) { - diva_os_spin_lock_magic_t old_irql, old_irql1; - dword sec, usec; - int i; - word size; - byte* pmem = NULL; - - diva_os_get_time (&sec, &usec); - - diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read"); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read"); - - for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) { - if (clients[i].hDbg == hDbg) { - diva_dbg_entry_head_t* pmsg; - char tmp[256]; - int len; - - clients[i].hDbg = NULL; - - hDbg->id = -1; - hDbg->dbgMask = 0; - hDbg->dbg_end = NULL; - hDbg->dbg_prt = NULL; - hDbg->dbg_irq = NULL; - if (hDbg->Version > 0) - hDbg->dbg_old = NULL; - hDbg->Registered = 0; - hDbg->next = NULL; - - if (clients[i].pIdiLib) { - (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib); - clients[i].pIdiLib = NULL; - - pmem = clients[i].pmem; - clients[i].pmem = NULL; - } - - /* - Log driver register, MAINT driver ID is '0' - */ - len = sprintf (tmp, "DIMAINT - drv # %d = '%s' de-registered", - i, hDbg->drvName); - - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)(len+1+sizeof(*pmsg))))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - - if (pmsg) { - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_STRING; - pmsg->dli = DLI_REG; - pmsg->drv_id = 0; /* id 0 - DIMAINT */ - pmsg->di_cpu = 0; - pmsg->data_length = len+1; - - memcpy (&pmsg[1], tmp, len+1); - queueCompleteMsg (pmsg); - diva_maint_wakeup_read(); - } - - break; - } - } - - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_ack"); - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "read_ack"); - - if (pmem) { - diva_os_free (0, pmem); - } +static void DI_deregister(pDbgHandle hDbg) { + diva_os_spin_lock_magic_t old_irql, old_irql1; + dword sec, usec; + int i; + word size; + byte *pmem = NULL; + + diva_os_get_time(&sec, &usec); + + diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read"); + + for (i = 1; i < ARRAY_SIZE(clients); i++) { + if (clients[i].hDbg == hDbg) { + diva_dbg_entry_head_t *pmsg; + char tmp[256]; + int len; + + clients[i].hDbg = NULL; + + hDbg->id = -1; + hDbg->dbgMask = 0; + hDbg->dbg_end = NULL; + hDbg->dbg_prt = NULL; + hDbg->dbg_irq = NULL; + if (hDbg->Version > 0) + hDbg->dbg_old = NULL; + hDbg->Registered = 0; + hDbg->next = NULL; + + if (clients[i].pIdiLib) { + (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib); + clients[i].pIdiLib = NULL; + + pmem = clients[i].pmem; + clients[i].pmem = NULL; + } + + /* + Log driver register, MAINT driver ID is '0' + */ + len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered", + i, hDbg->drvName); + + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)(len + 1 + sizeof(*pmsg))))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + + if (pmsg) { + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_STRING; + pmsg->dli = DLI_REG; + pmsg->drv_id = 0; /* id 0 - DIMAINT */ + pmsg->di_cpu = 0; + pmsg->data_length = len + 1; + + memcpy(&pmsg[1], tmp, len + 1); + queueCompleteMsg(pmsg); + diva_maint_wakeup_read(); + } + + break; + } + } + + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack"); + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack"); + + if (pmem) { + diva_os_free(0, pmem); + } } -static void DI_format_locked (unsigned short id, - int type, - char *format, - va_list argument_list) { - DI_format (1, id, type, format, argument_list); +static void DI_format_locked(unsigned short id, + int type, + char *format, + va_list argument_list) { + DI_format(1, id, type, format, argument_list); } -static void DI_format (int do_lock, - unsigned short id, - int type, - char *format, - va_list ap) { - diva_os_spin_lock_magic_t old_irql; - dword sec, usec; - diva_dbg_entry_head_t* pmsg = NULL; - dword length; - word size; - static char fmtBuf[MSG_FRAME_MAX_SIZE+sizeof(*pmsg)+1]; - char *data; - unsigned short code; - - if (diva_os_in_irq()) { - dbg_sequence++; - return; - } +static void DI_format(int do_lock, + unsigned short id, + int type, + char *format, + va_list ap) { + diva_os_spin_lock_magic_t old_irql; + dword sec, usec; + diva_dbg_entry_head_t *pmsg = NULL; + dword length; + word size; + static char fmtBuf[MSG_FRAME_MAX_SIZE + sizeof(*pmsg) + 1]; + char *data; + unsigned short code; + + if (diva_os_in_irq()) { + dbg_sequence++; + return; + } if ((!format) || - ((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) { + ((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) { return; } - - diva_os_get_time (&sec, &usec); - - if (do_lock) { - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "format"); - } - - switch (type) { - case DLI_MXLOG : - case DLI_BLK : - case DLI_SEND: - case DLI_RECV: - if (!(length = va_arg(ap, unsigned long))) { - break; - } - if (length > MaxDumpSize) { - length = MaxDumpSize; - } - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)length+sizeof(*pmsg)))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - if (pmsg) { - memcpy (&pmsg[1], format, length); - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_BINARY ; - pmsg->dli = type; /* DLI_XXX */ - pmsg->drv_id = id; /* driver MAINT id */ - pmsg->di_cpu = 0; - pmsg->data_length = length; - queueCompleteMsg (pmsg); - } + + diva_os_get_time(&sec, &usec); + + if (do_lock) { + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "format"); + } + + switch (type) { + case DLI_MXLOG: + case DLI_BLK: + case DLI_SEND: + case DLI_RECV: + if (!(length = va_arg(ap, unsigned long))) { + break; + } + if (length > MaxDumpSize) { + length = MaxDumpSize; + } + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)length + sizeof(*pmsg)))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + if (pmsg) { + memcpy(&pmsg[1], format, length); + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_BINARY; + pmsg->dli = type; /* DLI_XXX */ + pmsg->drv_id = id; /* driver MAINT id */ + pmsg->di_cpu = 0; + pmsg->data_length = length; + queueCompleteMsg(pmsg); + } break; - case DLI_XLOG: { - byte* p; - data = va_arg(ap, char*); - code = (unsigned short)va_arg(ap, unsigned int); - length = (unsigned long) va_arg(ap, unsigned int); - - if (length > MaxXlogSize) - length = MaxXlogSize; - - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)length+sizeof(*pmsg)+2))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - if (pmsg) { - p = (byte*)&pmsg[1]; - p[0] = (char)(code) ; - p[1] = (char)(code >> 8) ; - if (data && length) { - memcpy (&p[2], &data[0], length) ; - } - length += 2 ; - - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_BINARY ; - pmsg->dli = type; /* DLI_XXX */ - pmsg->drv_id = id; /* driver MAINT id */ - pmsg->di_cpu = 0; - pmsg->data_length = length; - queueCompleteMsg (pmsg); - } - } break; - - case DLI_LOG : - case DLI_FTL : - case DLI_ERR : - case DLI_TRC : - case DLI_REG : - case DLI_MEM : - case DLI_SPL : - case DLI_IRP : - case DLI_TIM : - case DLI_TAPI: - case DLI_NDIS: - case DLI_CONN: - case DLI_STAT: - case DLI_PRV0: - case DLI_PRV1: - case DLI_PRV2: - case DLI_PRV3: - if ((length = (unsigned long)vsprintf (&fmtBuf[0], format, ap)) > 0) { - length += (sizeof(*pmsg)+1); - - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)length))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_STRING; - pmsg->dli = type; /* DLI_XXX */ - pmsg->drv_id = id; /* driver MAINT id */ - pmsg->di_cpu = 0; - pmsg->data_length = length - sizeof(*pmsg); - - memcpy (&pmsg[1], fmtBuf, pmsg->data_length); - queueCompleteMsg (pmsg); - } - break; - - } /* switch type */ - - - if (queueCount(dbg_queue)) { - diva_maint_wakeup_read(); - } - - if (do_lock) { - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "format"); - } + case DLI_XLOG: { + byte *p; + data = va_arg(ap, char *); + code = (unsigned short)va_arg(ap, unsigned int); + length = (unsigned long)va_arg(ap, unsigned int); + + if (length > MaxXlogSize) + length = MaxXlogSize; + + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)length + sizeof(*pmsg) + 2))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + if (pmsg) { + p = (byte *)&pmsg[1]; + p[0] = (char)(code); + p[1] = (char)(code >> 8); + if (data && length) { + memcpy(&p[2], &data[0], length); + } + length += 2; + + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_BINARY; + pmsg->dli = type; /* DLI_XXX */ + pmsg->drv_id = id; /* driver MAINT id */ + pmsg->di_cpu = 0; + pmsg->data_length = length; + queueCompleteMsg(pmsg); + } + } break; + + case DLI_LOG: + case DLI_FTL: + case DLI_ERR: + case DLI_TRC: + case DLI_REG: + case DLI_MEM: + case DLI_SPL: + case DLI_IRP: + case DLI_TIM: + case DLI_TAPI: + case DLI_NDIS: + case DLI_CONN: + case DLI_STAT: + case DLI_PRV0: + case DLI_PRV1: + case DLI_PRV2: + case DLI_PRV3: + if ((length = (unsigned long)vsprintf(&fmtBuf[0], format, ap)) > 0) { + length += (sizeof(*pmsg) + 1); + + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)length))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_STRING; + pmsg->dli = type; /* DLI_XXX */ + pmsg->drv_id = id; /* driver MAINT id */ + pmsg->di_cpu = 0; + pmsg->data_length = length - sizeof(*pmsg); + + memcpy(&pmsg[1], fmtBuf, pmsg->data_length); + queueCompleteMsg(pmsg); + } + break; + + } /* switch type */ + + + if (queueCount(dbg_queue)) { + diva_maint_wakeup_read(); + } + + if (do_lock) { + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "format"); + } } /* Write driver ID and driver revision to callers buffer - */ -int diva_get_driver_info (dword id, byte* data, int data_length) { - diva_os_spin_lock_magic_t old_irql; - byte* p = data; - int to_copy; - - if (!data || !id || (data_length < 17) || - (id >= (sizeof(clients)/sizeof(clients[0])))) { - return (-1); - } - - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "driver info"); - - if (clients[id].hDbg) { - *p++ = 1; - *p++ = (byte)clients[id].sec; /* save seconds */ - *p++ = (byte)(clients[id].sec >> 8); - *p++ = (byte)(clients[id].sec >> 16); - *p++ = (byte)(clients[id].sec >> 24); - - *p++ = (byte)(clients[id].usec/1000); /* save mseconds */ - *p++ = (byte)((clients[id].usec/1000) >> 8); - *p++ = (byte)((clients[id].usec/1000) >> 16); - *p++ = (byte)((clients[id].usec/1000) >> 24); - - data_length -= 9; - - if ((to_copy = MIN(strlen(clients[id].drvName), data_length-1))) { - memcpy (p, clients[id].drvName, to_copy); - p += to_copy; - data_length -= to_copy; - if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) { - *p++ = '('; - data_length -= 1; - if ((to_copy = MIN(strlen(clients[id].hDbg->drvTag), data_length-2))) { - memcpy (p, clients[id].hDbg->drvTag, to_copy); - p += to_copy; - data_length -= to_copy; - if (data_length >= 2) { - *p++ = ')'; - data_length--; - } - } - } - } - } - *p++ = 0; - - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "driver info"); - - return (p - data); -} +*/ +int diva_get_driver_info(dword id, byte *data, int data_length) { + diva_os_spin_lock_magic_t old_irql; + byte *p = data; + int to_copy; + + if (!data || !id || (data_length < 17) || + (id >= ARRAY_SIZE(clients))) { + return (-1); + } -int diva_get_driver_dbg_mask (dword id, byte* data) { - diva_os_spin_lock_magic_t old_irql; - int ret = -1; + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info"); + + if (clients[id].hDbg) { + *p++ = 1; + *p++ = (byte)clients[id].sec; /* save seconds */ + *p++ = (byte)(clients[id].sec >> 8); + *p++ = (byte)(clients[id].sec >> 16); + *p++ = (byte)(clients[id].sec >> 24); + + *p++ = (byte)(clients[id].usec / 1000); /* save mseconds */ + *p++ = (byte)((clients[id].usec / 1000) >> 8); + *p++ = (byte)((clients[id].usec / 1000) >> 16); + *p++ = (byte)((clients[id].usec / 1000) >> 24); + + data_length -= 9; + + if ((to_copy = min(strlen(clients[id].drvName), (size_t)(data_length - 1)))) { + memcpy(p, clients[id].drvName, to_copy); + p += to_copy; + data_length -= to_copy; + if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) { + *p++ = '('; + data_length -= 1; + if ((to_copy = min(strlen(clients[id].hDbg->drvTag), (size_t)(data_length - 2)))) { + memcpy(p, clients[id].hDbg->drvTag, to_copy); + p += to_copy; + data_length -= to_copy; + if (data_length >= 2) { + *p++ = ')'; + data_length--; + } + } + } + } + } + *p++ = 0; - if (!data || !id || (id >= (sizeof(clients)/sizeof(clients[0])))) { - return (-1); - } - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "driver info"); + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info"); - if (clients[id].hDbg) { - ret = 4; - *data++= (byte)(clients[id].hDbg->dbgMask); - *data++= (byte)(clients[id].hDbg->dbgMask >> 8); - *data++= (byte)(clients[id].hDbg->dbgMask >> 16); - *data++= (byte)(clients[id].hDbg->dbgMask >> 24); - } + return (p - data); +} + +int diva_get_driver_dbg_mask(dword id, byte *data) { + diva_os_spin_lock_magic_t old_irql; + int ret = -1; + + if (!data || !id || (id >= ARRAY_SIZE(clients))) { + return (-1); + } + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info"); + + if (clients[id].hDbg) { + ret = 4; + *data++ = (byte)(clients[id].hDbg->dbgMask); + *data++ = (byte)(clients[id].hDbg->dbgMask >> 8); + *data++ = (byte)(clients[id].hDbg->dbgMask >> 16); + *data++ = (byte)(clients[id].hDbg->dbgMask >> 24); + } - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "driver info"); + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info"); - return (ret); + return (ret); } -int diva_set_driver_dbg_mask (dword id, dword mask) { - diva_os_spin_lock_magic_t old_irql, old_irql1; - int ret = -1; - +int diva_set_driver_dbg_mask(dword id, dword mask) { + diva_os_spin_lock_magic_t old_irql, old_irql1; + int ret = -1; - if (!id || (id >= (sizeof(clients)/sizeof(clients[0])))) { - return (-1); - } - diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask"); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "dbg mask"); + if (!id || (id >= ARRAY_SIZE(clients))) { + return (-1); + } - if (clients[id].hDbg) { - dword old_mask = clients[id].hDbg->dbgMask; - mask &= 0x7fffffff; - clients[id].hDbg->dbgMask = mask; - clients[id].last_dbgMask = (clients[id].hDbg->dbgMask | clients[id].dbgMask); - ret = 4; - diva_change_management_debug_mask (&clients[id], old_mask); - } + diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "dbg mask"); + if (clients[id].hDbg) { + dword old_mask = clients[id].hDbg->dbgMask; + mask &= 0x7fffffff; + clients[id].hDbg->dbgMask = mask; + clients[id].last_dbgMask = (clients[id].hDbg->dbgMask | clients[id].dbgMask); + ret = 4; + diva_change_management_debug_mask(&clients[id], old_mask); + } - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "dbg mask"); - if (clients[id].request_pending) { - clients[id].request_pending = 0; - (*(clients[id].request))((ENTITY*)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib)); - } + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "dbg mask"); - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask"); + if (clients[id].request_pending) { + clients[id].request_pending = 0; + (*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib)); + } + + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask"); - return (ret); + return (ret); } -static int diva_get_idi_adapter_info (IDI_CALL request, dword* serial, dword* logical) { - IDI_SYNC_REQ sync_req; +static int diva_get_idi_adapter_info(IDI_CALL request, dword *serial, dword *logical) { + IDI_SYNC_REQ sync_req; - sync_req.xdi_logical_adapter_number.Req = 0; - sync_req.xdi_logical_adapter_number.Rc = IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER; - (*request)((ENTITY *)&sync_req); - *logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number; + sync_req.xdi_logical_adapter_number.Req = 0; + sync_req.xdi_logical_adapter_number.Rc = IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER; + (*request)((ENTITY *)&sync_req); + *logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number; - sync_req.GetSerial.Req = 0; - sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL; - sync_req.GetSerial.serial = 0; - (*request)((ENTITY *)&sync_req); + sync_req.GetSerial.Req = 0; + sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL; + sync_req.GetSerial.serial = 0; + (*request)((ENTITY *)&sync_req); *serial = sync_req.GetSerial.serial; - return (0); + return (0); } /* Register XDI adapter as MAINT compatible driver - */ -void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) { - diva_os_spin_lock_magic_t old_irql, old_irql1; - dword sec, usec, logical, serial, org_mask; - int id, best_id = 0, free_id = -1; - char tmp[256]; - diva_dbg_entry_head_t* pmsg = NULL; - int len; - word size; - byte* pmem; - - diva_os_get_time (&sec, &usec); - diva_get_idi_adapter_info (d->request, &serial, &logical); - if (serial & 0xff000000) { - sprintf (tmp, "ADAPTER:%d SN:%u-%d", - (int)logical, - serial & 0x00ffffff, - (byte)(((serial & 0xff000000) >> 24) + 1)); - } else { - sprintf (tmp, "ADAPTER:%d SN:%u", (int)logical, serial); - } - - if (!(pmem = diva_os_malloc (0, DivaSTraceGetMemotyRequirement (d->channels)))) { - return; - } - memset (pmem, 0x00, DivaSTraceGetMemotyRequirement (d->channels)); - - diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "register"); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register"); - - for (id = 1; id < (sizeof(clients)/sizeof(clients[0])); id++) { - if (clients[id].hDbg && (clients[id].request == d->request)) { - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register"); - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register"); - diva_os_free(0, pmem); - return; - } - if (clients[id].hDbg) { /* slot is busy */ - continue; - } - if (free_id < 0) { - free_id = id; - } - if (!strcmp (clients[id].drvName, tmp)) { - /* - This driver was already registered with this name - and slot is still free - reuse it - */ - free_id = id; - best_id = 1; - break; - } - } - - if (free_id < 0) { - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register"); - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register"); - diva_os_free (0, pmem); - return; - } - - id = free_id; - clients[id].request = d->request; - clients[id].request_pending = 0; - clients[id].hDbg = &clients[id].Dbg; - clients[id].sec = sec; - clients[id].usec = usec; - strcpy (clients[id].drvName, tmp); - strcpy (clients[id].Dbg.drvName, tmp); - clients[id].Dbg.drvTag[0] = 0; - clients[id].logical = (int)logical; - clients[id].channels = (int)d->channels; - clients[id].dma_handle = -1; - - clients[id].Dbg.dbgMask = 0; - clients[id].dbgMask = clients[id].Dbg.dbgMask; - if (id) { - clients[id].Dbg.dbgMask |= clients[free_id].last_dbgMask; - } else { - clients[id].last_dbgMask = 0; - } - clients[id].Dbg.Registered = DBG_HANDLE_REG_NEW; - clients[id].Dbg.id = (byte)id; - clients[id].Dbg.dbg_end = DI_deregister; - clients[id].Dbg.dbg_prt = DI_format_locked; - clients[id].Dbg.dbg_ev = DiProcessEventLog; - clients[id].Dbg.dbg_irq = DI_format_locked; - clients[id].Dbg.next = (pDbgHandle)DBG_MAGIC; - - { - diva_trace_library_user_interface_t diva_maint_user_ifc = { &clients[id], - diva_maint_state_change_notify, - diva_maint_trace_notify, - diva_maint_error }; - - /* - Attach to adapter management interface - */ - if ((clients[id].pIdiLib = - DivaSTraceLibraryCreateInstance ((int)logical, &diva_maint_user_ifc, pmem))) { - if (((*(clients[id].pIdiLib->DivaSTraceLibraryStart))(clients[id].pIdiLib->hLib))) { - diva_mnt_internal_dprintf (0, DLI_ERR, "Adapter(%d) Start failed", (int)logical); - (*(clients[id].pIdiLib->DivaSTraceLibraryFinit))(clients[id].pIdiLib->hLib); - clients[id].pIdiLib = NULL; - } - } else { - diva_mnt_internal_dprintf (0, DLI_ERR, "A(%d) management init failed", (int)logical); - } - } - - if (!clients[id].pIdiLib) { - clients[id].request = NULL; - clients[id].request_pending = 0; - clients[id].hDbg = NULL; - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register"); - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register"); - diva_os_free (0, pmem); - return; - } - - /* - Log driver register, MAINT driver ID is '0' - */ - len = sprintf (tmp, "DIMAINT - drv # %d = '%s' registered", - id, clients[id].Dbg.drvName); - - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)(len+1+sizeof(*pmsg))))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - - if (pmsg) { - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_STRING; - pmsg->dli = DLI_REG; - pmsg->drv_id = 0; /* id 0 - DIMAINT */ - pmsg->di_cpu = 0; - pmsg->data_length = len+1; - - memcpy (&pmsg[1], tmp, len+1); - queueCompleteMsg (pmsg); - diva_maint_wakeup_read(); - } - - org_mask = clients[id].Dbg.dbgMask; - clients[id].Dbg.dbgMask = 0; - - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register"); - - if (clients[id].request_pending) { - clients[id].request_pending = 0; - (*(clients[id].request))((ENTITY*)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib)); - } - - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register"); - - diva_set_driver_dbg_mask (id, org_mask); +*/ +void diva_mnt_add_xdi_adapter(const DESCRIPTOR *d) { + diva_os_spin_lock_magic_t old_irql, old_irql1; + dword sec, usec, logical, serial, org_mask; + int id, free_id = -1; + char tmp[128]; + diva_dbg_entry_head_t *pmsg = NULL; + int len; + word size; + byte *pmem; + + diva_os_get_time(&sec, &usec); + diva_get_idi_adapter_info(d->request, &serial, &logical); + if (serial & 0xff000000) { + sprintf(tmp, "ADAPTER:%d SN:%u-%d", + (int)logical, + serial & 0x00ffffff, + (byte)(((serial & 0xff000000) >> 24) + 1)); + } else { + sprintf(tmp, "ADAPTER:%d SN:%u", (int)logical, serial); + } + + if (!(pmem = diva_os_malloc(0, DivaSTraceGetMemotyRequirement(d->channels)))) { + return; + } + memset(pmem, 0x00, DivaSTraceGetMemotyRequirement(d->channels)); + + diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "register"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register"); + + for (id = 1; id < ARRAY_SIZE(clients); id++) { + if (clients[id].hDbg && (clients[id].request == d->request)) { + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register"); + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register"); + diva_os_free(0, pmem); + return; + } + if (clients[id].hDbg) { /* slot is busy */ + continue; + } + if (free_id < 0) { + free_id = id; + } + if (!strcmp(clients[id].drvName, tmp)) { + /* + This driver was already registered with this name + and slot is still free - reuse it + */ + free_id = id; + break; + } + } + + if (free_id < 0) { + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register"); + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register"); + diva_os_free(0, pmem); + return; + } + + id = free_id; + clients[id].request = d->request; + clients[id].request_pending = 0; + clients[id].hDbg = &clients[id].Dbg; + clients[id].sec = sec; + clients[id].usec = usec; + strcpy(clients[id].drvName, tmp); + strcpy(clients[id].Dbg.drvName, tmp); + clients[id].Dbg.drvTag[0] = 0; + clients[id].logical = (int)logical; + clients[id].channels = (int)d->channels; + clients[id].dma_handle = -1; + + clients[id].Dbg.dbgMask = 0; + clients[id].dbgMask = clients[id].Dbg.dbgMask; + if (id) { + clients[id].Dbg.dbgMask |= clients[free_id].last_dbgMask; + } else { + clients[id].last_dbgMask = 0; + } + clients[id].Dbg.Registered = DBG_HANDLE_REG_NEW; + clients[id].Dbg.id = (byte)id; + clients[id].Dbg.dbg_end = DI_deregister; + clients[id].Dbg.dbg_prt = DI_format_locked; + clients[id].Dbg.dbg_ev = DiProcessEventLog; + clients[id].Dbg.dbg_irq = DI_format_locked; + clients[id].Dbg.next = (pDbgHandle)DBG_MAGIC; + + { + diva_trace_library_user_interface_t diva_maint_user_ifc = { &clients[id], + diva_maint_state_change_notify, + diva_maint_trace_notify, + diva_maint_error }; + + /* + Attach to adapter management interface + */ + if ((clients[id].pIdiLib = + DivaSTraceLibraryCreateInstance((int)logical, &diva_maint_user_ifc, pmem))) { + if (((*(clients[id].pIdiLib->DivaSTraceLibraryStart))(clients[id].pIdiLib->hLib))) { + diva_mnt_internal_dprintf(0, DLI_ERR, "Adapter(%d) Start failed", (int)logical); + (*(clients[id].pIdiLib->DivaSTraceLibraryFinit))(clients[id].pIdiLib->hLib); + clients[id].pIdiLib = NULL; + } + } else { + diva_mnt_internal_dprintf(0, DLI_ERR, "A(%d) management init failed", (int)logical); + } + } + + if (!clients[id].pIdiLib) { + clients[id].request = NULL; + clients[id].request_pending = 0; + clients[id].hDbg = NULL; + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register"); + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register"); + diva_os_free(0, pmem); + return; + } + + /* + Log driver register, MAINT driver ID is '0' + */ + len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered", + id, clients[id].Dbg.drvName); + + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)(len + 1 + sizeof(*pmsg))))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + + if (pmsg) { + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_STRING; + pmsg->dli = DLI_REG; + pmsg->drv_id = 0; /* id 0 - DIMAINT */ + pmsg->di_cpu = 0; + pmsg->data_length = len + 1; + + memcpy(&pmsg[1], tmp, len + 1); + queueCompleteMsg(pmsg); + diva_maint_wakeup_read(); + } + + org_mask = clients[id].Dbg.dbgMask; + clients[id].Dbg.dbgMask = 0; + + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register"); + + if (clients[id].request_pending) { + clients[id].request_pending = 0; + (*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib)); + } + + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register"); + + diva_set_driver_dbg_mask(id, org_mask); } /* De-Register XDI adapter - */ -void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d) { - diva_os_spin_lock_magic_t old_irql, old_irql1; - dword sec, usec; - int i; - word size; - byte* pmem = NULL; - - diva_os_get_time (&sec, &usec); - - diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read"); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read"); - - for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) { - if (clients[i].hDbg && (clients[i].request == d->request)) { - diva_dbg_entry_head_t* pmsg; - char tmp[256]; - int len; - - if (clients[i].pIdiLib) { - (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib); - clients[i].pIdiLib = NULL; - - pmem = clients[i].pmem; - clients[i].pmem = NULL; - } - - clients[i].hDbg = NULL; - clients[i].request_pending = 0; - if (clients[i].dma_handle >= 0) { - /* - Free DMA handle - */ - diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle); - clients[i].dma_handle = -1; - } - clients[i].request = NULL; - - /* - Log driver register, MAINT driver ID is '0' - */ - len = sprintf (tmp, "DIMAINT - drv # %d = '%s' de-registered", - i, clients[i].Dbg.drvName); - - memset (&clients[i].Dbg, 0x00, sizeof(clients[i].Dbg)); - - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)(len+1+sizeof(*pmsg))))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - - if (pmsg) { - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_STRING; - pmsg->dli = DLI_REG; - pmsg->drv_id = 0; /* id 0 - DIMAINT */ - pmsg->di_cpu = 0; - pmsg->data_length = len+1; - - memcpy (&pmsg[1], tmp, len+1); - queueCompleteMsg (pmsg); - diva_maint_wakeup_read(); - } - - break; - } - } - - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_ack"); - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "read_ack"); - - if (pmem) { - diva_os_free (0, pmem); - } +*/ +void diva_mnt_remove_xdi_adapter(const DESCRIPTOR *d) { + diva_os_spin_lock_magic_t old_irql, old_irql1; + dword sec, usec; + int i; + word size; + byte *pmem = NULL; + + diva_os_get_time(&sec, &usec); + + diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read"); + + for (i = 1; i < ARRAY_SIZE(clients); i++) { + if (clients[i].hDbg && (clients[i].request == d->request)) { + diva_dbg_entry_head_t *pmsg; + char tmp[256]; + int len; + + if (clients[i].pIdiLib) { + (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib); + clients[i].pIdiLib = NULL; + + pmem = clients[i].pmem; + clients[i].pmem = NULL; + } + + clients[i].hDbg = NULL; + clients[i].request_pending = 0; + if (clients[i].dma_handle >= 0) { + /* + Free DMA handle + */ + diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle); + clients[i].dma_handle = -1; + } + clients[i].request = NULL; + + /* + Log driver register, MAINT driver ID is '0' + */ + len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered", + i, clients[i].Dbg.drvName); + + memset(&clients[i].Dbg, 0x00, sizeof(clients[i].Dbg)); + + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)(len + 1 + sizeof(*pmsg))))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + + if (pmsg) { + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_STRING; + pmsg->dli = DLI_REG; + pmsg->drv_id = 0; /* id 0 - DIMAINT */ + pmsg->di_cpu = 0; + pmsg->data_length = len + 1; + + memcpy(&pmsg[1], tmp, len + 1); + queueCompleteMsg(pmsg); + diva_maint_wakeup_read(); + } + + break; + } + } + + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack"); + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack"); + + if (pmem) { + diva_os_free(0, pmem); + } } /* ---------------------------------------------------------------- - Low level interface for management interface client + Low level interface for management interface client ---------------------------------------------------------------- */ /* Return handle to client structure - */ -void* SuperTraceOpenAdapter (int AdapterNumber) { - int i; +*/ +void *SuperTraceOpenAdapter(int AdapterNumber) { + int i; - for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) { - if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) { - return (&clients[i]); - } - } + for (i = 1; i < ARRAY_SIZE(clients); i++) { + if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) { + return (&clients[i]); + } + } - return NULL; + return NULL; } -int SuperTraceCloseAdapter (void* AdapterHandle) { - return (0); +int SuperTraceCloseAdapter(void *AdapterHandle) { + return (0); } -int SuperTraceReadRequest (void* AdapterHandle, const char* name, byte* data) { - diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle; +int SuperTraceReadRequest(void *AdapterHandle, const char *name, byte *data) { + diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle; - if (pC && pC->pIdiLib && pC->request) { - ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); - byte* xdata = (byte*)&pC->xbuffer[0]; - char tmp = 0; - word length; + if (pC && pC->pIdiLib && pC->request) { + ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); + byte *xdata = (byte *)&pC->xbuffer[0]; + char tmp = 0; + word length; - if (!strcmp(name, "\\")) { /* Read ROOT */ - name = &tmp; - } - length = SuperTraceCreateReadReq (xdata, name); - single_p (xdata, &length, 0); /* End Of Message */ + if (!strcmp(name, "\\")) { /* Read ROOT */ + name = &tmp; + } + length = SuperTraceCreateReadReq(xdata, name); + single_p(xdata, &length, 0); /* End Of Message */ - e->Req = MAN_READ; - e->ReqCh = 0; - e->X->PLength = length; - e->X->P = (byte*)xdata; + e->Req = MAN_READ; + e->ReqCh = 0; + e->X->PLength = length; + e->X->P = (byte *)xdata; - pC->request_pending = 1; + pC->request_pending = 1; - return (0); - } + return (0); + } - return (-1); + return (-1); } -int SuperTraceGetNumberOfChannels (void* AdapterHandle) { - if (AdapterHandle) { - diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle; +int SuperTraceGetNumberOfChannels(void *AdapterHandle) { + if (AdapterHandle) { + diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle; - return (pC->channels); - } + return (pC->channels); + } - return (0); + return (0); } -int SuperTraceASSIGN (void* AdapterHandle, byte* data) { - diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle; - - if (pC && pC->pIdiLib && pC->request) { - ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); - IDI_SYNC_REQ* preq; - char buffer[((sizeof(preq->xdi_extended_features)+4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features)+4) : sizeof(ENTITY)]; - char features[4]; - word assign_data_length = 1; - - features[0] = 0; - pC->xbuffer[0] = 0; - preq = (IDI_SYNC_REQ*)&buffer[0]; - preq->xdi_extended_features.Req = 0; - preq->xdi_extended_features.Rc = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES; - preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features); - preq->xdi_extended_features.info.features = &features[0]; - - (*(pC->request))((ENTITY*)preq); - - if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) && - (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) { - dword rx_dma_magic; - if ((pC->dma_handle = diva_get_dma_descriptor (pC->request, &rx_dma_magic)) >= 0) { - pC->xbuffer[0] = LLI; - pC->xbuffer[1] = 8; - pC->xbuffer[2] = 0x40; - pC->xbuffer[3] = (byte)pC->dma_handle; - pC->xbuffer[4] = (byte)rx_dma_magic; - pC->xbuffer[5] = (byte)(rx_dma_magic >> 8); - pC->xbuffer[6] = (byte)(rx_dma_magic >> 16); - pC->xbuffer[7] = (byte)(rx_dma_magic >> 24); - pC->xbuffer[8] = (byte)DIVA_MAX_MANAGEMENT_TRANSFER_SIZE; - pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8); - pC->xbuffer[10] = 0; - - assign_data_length = 11; - } - } else { - pC->dma_handle = -1; - } - - e->Id = MAN_ID; - e->callback = diva_maint_xdi_cb; - e->XNum = 1; - e->X = &pC->XData; - e->Req = ASSIGN; - e->ReqCh = 0; - e->X->PLength = assign_data_length; - e->X->P = (byte*)&pC->xbuffer[0]; - - pC->request_pending = 1; - - return (0); - } - - return (-1); +int SuperTraceASSIGN(void *AdapterHandle, byte *data) { + diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle; + + if (pC && pC->pIdiLib && pC->request) { + ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); + IDI_SYNC_REQ *preq; + char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)]; + char features[4]; + word assign_data_length = 1; + + features[0] = 0; + pC->xbuffer[0] = 0; + preq = (IDI_SYNC_REQ *)&buffer[0]; + preq->xdi_extended_features.Req = 0; + preq->xdi_extended_features.Rc = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES; + preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features); + preq->xdi_extended_features.info.features = &features[0]; + + (*(pC->request))((ENTITY *)preq); + + if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) && + (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) { + dword uninitialized_var(rx_dma_magic); + if ((pC->dma_handle = diva_get_dma_descriptor(pC->request, &rx_dma_magic)) >= 0) { + pC->xbuffer[0] = LLI; + pC->xbuffer[1] = 8; + pC->xbuffer[2] = 0x40; + pC->xbuffer[3] = (byte)pC->dma_handle; + pC->xbuffer[4] = (byte)rx_dma_magic; + pC->xbuffer[5] = (byte)(rx_dma_magic >> 8); + pC->xbuffer[6] = (byte)(rx_dma_magic >> 16); + pC->xbuffer[7] = (byte)(rx_dma_magic >> 24); + pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF); + pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8); + pC->xbuffer[10] = 0; + + assign_data_length = 11; + } + } else { + pC->dma_handle = -1; + } + + e->Id = MAN_ID; + e->callback = diva_maint_xdi_cb; + e->XNum = 1; + e->X = &pC->XData; + e->Req = ASSIGN; + e->ReqCh = 0; + e->X->PLength = assign_data_length; + e->X->P = (byte *)&pC->xbuffer[0]; + + pC->request_pending = 1; + + return (0); + } + + return (-1); } -int SuperTraceREMOVE (void* AdapterHandle) { - diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle; +int SuperTraceREMOVE(void *AdapterHandle) { + diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle; - if (pC && pC->pIdiLib && pC->request) { - ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); + if (pC && pC->pIdiLib && pC->request) { + ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); - e->XNum = 1; - e->X = &pC->XData; - e->Req = REMOVE; - e->ReqCh = 0; - e->X->PLength = 1; - e->X->P = (byte*)&pC->xbuffer[0]; - pC->xbuffer[0] = 0; + e->XNum = 1; + e->X = &pC->XData; + e->Req = REMOVE; + e->ReqCh = 0; + e->X->PLength = 1; + e->X->P = (byte *)&pC->xbuffer[0]; + pC->xbuffer[0] = 0; - pC->request_pending = 1; + pC->request_pending = 1; - return (0); - } + return (0); + } - return (-1); + return (-1); } -int SuperTraceTraceOnRequest(void* hAdapter, const char* name, byte* data) { - diva_maint_client_t* pC = (diva_maint_client_t*)hAdapter; +int SuperTraceTraceOnRequest(void *hAdapter, const char *name, byte *data) { + diva_maint_client_t *pC = (diva_maint_client_t *)hAdapter; - if (pC && pC->pIdiLib && pC->request) { - ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); - byte* xdata = (byte*)&pC->xbuffer[0]; - char tmp = 0; - word length; + if (pC && pC->pIdiLib && pC->request) { + ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); + byte *xdata = (byte *)&pC->xbuffer[0]; + char tmp = 0; + word length; - if (!strcmp(name, "\\")) { /* Read ROOT */ - name = &tmp; - } - length = SuperTraceCreateReadReq (xdata, name); - single_p (xdata, &length, 0); /* End Of Message */ - e->Req = MAN_EVENT_ON; - e->ReqCh = 0; - e->X->PLength = length; - e->X->P = (byte*)xdata; + if (!strcmp(name, "\\")) { /* Read ROOT */ + name = &tmp; + } + length = SuperTraceCreateReadReq(xdata, name); + single_p(xdata, &length, 0); /* End Of Message */ + e->Req = MAN_EVENT_ON; + e->ReqCh = 0; + e->X->PLength = length; + e->X->P = (byte *)xdata; - pC->request_pending = 1; + pC->request_pending = 1; - return (0); - } + return (0); + } - return (-1); + return (-1); } -int SuperTraceWriteVar (void* AdapterHandle, - byte* data, - const char* name, - void* var, - byte type, - byte var_length) { - diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle; - - if (pC && pC->pIdiLib && pC->request) { - ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); - diva_man_var_header_t* pVar = (diva_man_var_header_t*)&pC->xbuffer[0]; - word length = SuperTraceCreateReadReq ((byte*)pVar, name); - - memcpy (&pC->xbuffer[length], var, var_length); - length += var_length; - pVar->length += var_length; - pVar->value_length = var_length; - pVar->type = type; - single_p ((byte*)pVar, &length, 0); /* End Of Message */ - - e->Req = MAN_WRITE; - e->ReqCh = 0; - e->X->PLength = length; - e->X->P = (byte*)pVar; - - pC->request_pending = 1; - - return (0); - } - - return (-1); +int SuperTraceWriteVar(void *AdapterHandle, + byte *data, + const char *name, + void *var, + byte type, + byte var_length) { + diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle; + + if (pC && pC->pIdiLib && pC->request) { + ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); + diva_man_var_header_t *pVar = (diva_man_var_header_t *)&pC->xbuffer[0]; + word length = SuperTraceCreateReadReq((byte *)pVar, name); + + memcpy(&pC->xbuffer[length], var, var_length); + length += var_length; + pVar->length += var_length; + pVar->value_length = var_length; + pVar->type = type; + single_p((byte *)pVar, &length, 0); /* End Of Message */ + + e->Req = MAN_WRITE; + e->ReqCh = 0; + e->X->PLength = length; + e->X->P = (byte *)pVar; + + pC->request_pending = 1; + + return (0); + } + + return (-1); } -int SuperTraceExecuteRequest (void* AdapterHandle, - const char* name, - byte* data) { - diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle; +int SuperTraceExecuteRequest(void *AdapterHandle, + const char *name, + byte *data) { + diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle; - if (pC && pC->pIdiLib && pC->request) { - ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); - byte* xdata = (byte*)&pC->xbuffer[0]; - word length; + if (pC && pC->pIdiLib && pC->request) { + ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib); + byte *xdata = (byte *)&pC->xbuffer[0]; + word length; - length = SuperTraceCreateReadReq (xdata, name); - single_p (xdata, &length, 0); /* End Of Message */ + length = SuperTraceCreateReadReq(xdata, name); + single_p(xdata, &length, 0); /* End Of Message */ - e->Req = MAN_EXECUTE; - e->ReqCh = 0; - e->X->PLength = length; - e->X->P = (byte*)xdata; + e->Req = MAN_EXECUTE; + e->ReqCh = 0; + e->X->PLength = length; + e->X->P = (byte *)xdata; - pC->request_pending = 1; + pC->request_pending = 1; - return (0); - } + return (0); + } - return (-1); + return (-1); } -static word SuperTraceCreateReadReq (byte* P, const char* path) { +static word SuperTraceCreateReadReq(byte *P, const char *path) { byte var_length; - byte* plen; + byte *plen; - var_length = (byte)strlen (path); + var_length = (byte)strlen(path); *P++ = ESC; plen = P++; @@ -1347,708 +1346,708 @@ static word SuperTraceCreateReadReq (byte* P, const char* path) { *P++ = 0x00; /* Status */ *P++ = 0x00; /* Variable Length */ *P++ = var_length; - memcpy (P, path, var_length); + memcpy(P, path, var_length); P += var_length; *plen = var_length + 0x06; return ((word)(var_length + 0x08)); } -static void single_p (byte * P, word * PLength, byte Id) { - P[(*PLength)++] = Id; +static void single_p(byte *P, word *PLength, byte Id) { + P[(*PLength)++] = Id; } -static void diva_maint_xdi_cb (ENTITY* e) { - diva_strace_context_t* pLib = DIVAS_CONTAINING_RECORD(e,diva_strace_context_t,e); - diva_maint_client_t* pC; - diva_os_spin_lock_magic_t old_irql, old_irql1; +static void diva_maint_xdi_cb(ENTITY *e) { + diva_strace_context_t *pLib = DIVAS_CONTAINING_RECORD(e, diva_strace_context_t, e); + diva_maint_client_t *pC; + diva_os_spin_lock_magic_t old_irql, old_irql1; - diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "xdi_cb"); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "xdi_cb"); + diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb"); - pC = (diva_maint_client_t*)pLib->hAdapter; + pC = (diva_maint_client_t *)pLib->hAdapter; - if ((e->complete == 255) || (pC->dma_handle < 0)) { - if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) { - diva_mnt_internal_dprintf (0, DLI_ERR, "Trace internal library error"); - } - } else { - /* - Process combined management interface indication - */ - if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) { - diva_mnt_internal_dprintf (0, DLI_ERR, "Trace internal library error (DMA mode)"); - } - } + if ((e->complete == 255) || (pC->dma_handle < 0)) { + if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) { + diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error"); + } + } else { + /* + Process combined management interface indication + */ + if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) { + diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error (DMA mode)"); + } + } - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "xdi_cb"); + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb"); if (pC->request_pending) { - pC->request_pending = 0; - (*(pC->request))(e); + pC->request_pending = 0; + (*(pC->request))(e); } - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "xdi_cb"); + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb"); } -static void diva_maint_error (void* user_context, - diva_strace_library_interface_t* hLib, - int Adapter, - int error, - const char* file, - int line) { - diva_mnt_internal_dprintf (0, DLI_ERR, - "Trace library error(%d) A(%d) %s %d", error, Adapter, file, line); +static void diva_maint_error(void *user_context, + diva_strace_library_interface_t *hLib, + int Adapter, + int error, + const char *file, + int line) { + diva_mnt_internal_dprintf(0, DLI_ERR, + "Trace library error(%d) A(%d) %s %d", error, Adapter, file, line); } -static void print_ie (diva_trace_ie_t* ie, char* buffer, int length) { +static void print_ie(diva_trace_ie_t *ie, char *buffer, int length) { int i; - buffer[0] = 0; - - if (length > 32) { - for (i = 0; ((i < ie->length) && (length > 3)); i++) { - sprintf (buffer, "%02x", ie->data[i]); - buffer += 2; - length -= 2; - if (i < (ie->length-1)) { - strcpy (buffer, " "); - buffer++; - length--; - } - } - } + buffer[0] = 0; + + if (length > 32) { + for (i = 0; ((i < ie->length) && (length > 3)); i++) { + sprintf(buffer, "%02x", ie->data[i]); + buffer += 2; + length -= 2; + if (i < (ie->length - 1)) { + strcpy(buffer, " "); + buffer++; + length--; + } + } + } } -static void diva_maint_state_change_notify (void* user_context, - diva_strace_library_interface_t* hLib, - int Adapter, - diva_trace_line_state_t* channel, - int notify_subject) { - diva_maint_client_t* pC = (diva_maint_client_t*)user_context; - diva_trace_fax_state_t* fax = &channel->fax; - diva_trace_modem_state_t* modem = &channel->modem; - char tmp[256]; - - if (!pC->hDbg) { - return; - } - - switch (notify_subject) { - case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE: { - int view = (TraceFilter[0] == 0); - /* - Process selective Trace - */ - if (channel->Line[0] == 'I' && channel->Line[1] == 'd' && - channel->Line[2] == 'l' && channel->Line[3] == 'e') { - if ((TraceFilterIdent == pC->hDbg->id) && (TraceFilterChannel == (int)channel->ChannelNumber)) { - (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 0); - (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 0); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, "Selective Trace OFF for Ch=%d", - (int)channel->ChannelNumber); - TraceFilterIdent = -1; - TraceFilterChannel = -1; - view = 1; - } - } else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr (&channel->RemoteAddress[0]) && - diva_mnt_cmp_nmbr (&channel->LocalAddress[0]))) { - - if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0) { /* Activate B-channel trace */ - (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 1); - } - if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0) { /* Activate AudioTap Trace */ - (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 1); - } - - TraceFilterIdent = pC->hDbg->id; - TraceFilterChannel = (int)channel->ChannelNumber; - - if (TraceFilterIdent >= 0) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, "Selective Trace ON for Ch=%d", - (int)channel->ChannelNumber); - view = 1; - } - } - if (view && (pC->hDbg->dbgMask & DIVA_MGT_DBG_LINE_EVENTS)) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Ch = %d", - (int)channel->ChannelNumber); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Status = <%s>", &channel->Line[0]); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer1 = <%s>", &channel->Framing[0]); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer2 = <%s>", &channel->Layer2[0]); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer3 = <%s>", &channel->Layer3[0]); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L RAddr = <%s>", - &channel->RemoteAddress[0]); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L RSAddr = <%s>", - &channel->RemoteSubAddress[0]); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LAddr = <%s>", - &channel->LocalAddress[0]); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LSAddr = <%s>", - &channel->LocalSubAddress[0]); - print_ie(&channel->call_BC, tmp, sizeof(tmp)); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L BC = <%s>", tmp); - print_ie(&channel->call_HLC, tmp, sizeof(tmp)); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L HLC = <%s>", tmp); - print_ie(&channel->call_LLC, tmp, sizeof(tmp)); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LLC = <%s>", tmp); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L CR = 0x%x", channel->CallReference); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Disc = 0x%x", - channel->LastDisconnecCause); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Owner = <%s>", &channel->UserID[0]); - } - - } break; - - case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE: - if (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_PROGRESS) { - { - int ch = TraceFilterChannel; - int id = TraceFilterIdent; - - if ((id >= 0) && (ch >= 0) && (id < sizeof(clients)/sizeof(clients[0])) && - (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) { - if (ch != (int)modem->ChannelNumber) { - break; - } - } else if (TraceFilter[0] != 0) { +static void diva_maint_state_change_notify(void *user_context, + diva_strace_library_interface_t *hLib, + int Adapter, + diva_trace_line_state_t *channel, + int notify_subject) { + diva_maint_client_t *pC = (diva_maint_client_t *)user_context; + diva_trace_fax_state_t *fax = &channel->fax; + diva_trace_modem_state_t *modem = &channel->modem; + char tmp[256]; + + if (!pC->hDbg) { + return; + } + + switch (notify_subject) { + case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE: { + int view = (TraceFilter[0] == 0); + /* + Process selective Trace + */ + if (channel->Line[0] == 'I' && channel->Line[1] == 'd' && + channel->Line[2] == 'l' && channel->Line[3] == 'e') { + if ((TraceFilterIdent == pC->hDbg->id) && (TraceFilterChannel == (int)channel->ChannelNumber)) { + (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 0); + (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 0); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace OFF for Ch=%d", + (int)channel->ChannelNumber); + TraceFilterIdent = -1; + TraceFilterChannel = -1; + view = 1; + } + } else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr(&channel->RemoteAddress[0]) && + diva_mnt_cmp_nmbr(&channel->LocalAddress[0]))) { + + if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0) { /* Activate B-channel trace */ + (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 1); + } + if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0) { /* Activate AudioTap Trace */ + (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 1); + } + + TraceFilterIdent = pC->hDbg->id; + TraceFilterChannel = (int)channel->ChannelNumber; + + if (TraceFilterIdent >= 0) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace ON for Ch=%d", + (int)channel->ChannelNumber); + view = 1; + } + } + if (view && (pC->hDbg->dbgMask & DIVA_MGT_DBG_LINE_EVENTS)) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Ch = %d", + (int)channel->ChannelNumber); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Status = <%s>", &channel->Line[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer1 = <%s>", &channel->Framing[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer2 = <%s>", &channel->Layer2[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer3 = <%s>", &channel->Layer3[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RAddr = <%s>", + &channel->RemoteAddress[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RSAddr = <%s>", + &channel->RemoteSubAddress[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LAddr = <%s>", + &channel->LocalAddress[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LSAddr = <%s>", + &channel->LocalSubAddress[0]); + print_ie(&channel->call_BC, tmp, sizeof(tmp)); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L BC = <%s>", tmp); + print_ie(&channel->call_HLC, tmp, sizeof(tmp)); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L HLC = <%s>", tmp); + print_ie(&channel->call_LLC, tmp, sizeof(tmp)); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LLC = <%s>", tmp); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L CR = 0x%x", channel->CallReference); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Disc = 0x%x", + channel->LastDisconnecCause); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Owner = <%s>", &channel->UserID[0]); + } + + } break; + + case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE: + if (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_PROGRESS) { + { + int ch = TraceFilterChannel; + int id = TraceFilterIdent; + + if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) && + (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) { + if (ch != (int)modem->ChannelNumber) { break; } + } else if (TraceFilter[0] != 0) { + break; } + } + + + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Ch = %lu", + (int)modem->ChannelNumber); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Event = %lu", modem->Event); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Norm = %lu", modem->Norm); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Opts. = 0x%08x", modem->Options); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Tx = %lu Bps", modem->TxSpeed); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rx = %lu Bps", modem->RxSpeed); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RT = %lu mSec", + modem->RoundtripMsec); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Sr = %lu", modem->SymbolRate); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rxl = %d dBm", modem->RxLeveldBm); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM El = %d dBm", modem->EchoLeveldBm); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM SNR = %lu dB", modem->SNRdb); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM MAE = %lu", modem->MAE); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRet = %lu", + modem->LocalRetrains); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRet = %lu", + modem->RemoteRetrains); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRes = %lu", modem->LocalResyncs); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRes = %lu", + modem->RemoteResyncs); + if (modem->Event == 3) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Disc = %lu", modem->DiscReason); + } + } + if ((modem->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_STATISTICS)) { + (*(pC->pIdiLib->DivaSTraceGetModemStatistics))(pC->pIdiLib); + } + break; + case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE: + if (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_PROGRESS) { + { + int ch = TraceFilterChannel; + int id = TraceFilterIdent; - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Ch = %lu", - (int)modem->ChannelNumber); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Event = %lu", modem->Event); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Norm = %lu", modem->Norm); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Opts. = 0x%08x", modem->Options); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Tx = %lu Bps", modem->TxSpeed); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rx = %lu Bps", modem->RxSpeed); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RT = %lu mSec", - modem->RoundtripMsec); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Sr = %lu", modem->SymbolRate); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rxl = %d dBm", modem->RxLeveldBm); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM El = %d dBm", modem->EchoLeveldBm); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM SNR = %lu dB", modem->SNRdb); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM MAE = %lu", modem->MAE); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRet = %lu", - modem->LocalRetrains); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRet = %lu", - modem->RemoteRetrains); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRes = %lu", modem->LocalResyncs); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRes = %lu", - modem->RemoteResyncs); - if (modem->Event == 3) { - diva_mnt_internal_dprintf(pC->hDbg->id,DLI_STAT,"MDM Disc = %lu", modem->DiscReason); - } - } - if ((modem->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_STATISTICS)) { - (*(pC->pIdiLib->DivaSTraceGetModemStatistics))(pC->pIdiLib); - } - break; - - case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE: - if (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_PROGRESS) { - { - int ch = TraceFilterChannel; - int id = TraceFilterIdent; - - if ((id >= 0) && (ch >= 0) && (id < sizeof(clients)/sizeof(clients[0])) && - (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) { - if (ch != (int)fax->ChannelNumber) { - break; - } - } else if (TraceFilter[0] != 0) { + if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) && + (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) { + if (ch != (int)fax->ChannelNumber) { break; } + } else if (TraceFilter[0] != 0) { + break; } + } + + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Ch = %lu", (int)fax->ChannelNumber); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Event = %lu", fax->Event); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pages = %lu", fax->Page_Counter); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Feat. = 0x%08x", fax->Features); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX ID = <%s>", &fax->Station_ID[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Saddr = <%s>", &fax->Subaddress[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pwd = <%s>", &fax->Password[0]); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Speed = %lu", fax->Speed); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Res. = 0x%08x", fax->Resolution); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Width = %lu", fax->Paper_Width); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Length= %lu", fax->Paper_Length); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX SLT = %lu", fax->Scanline_Time); + if (fax->Event == 3) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Disc = %lu", fax->Disc_Reason); + } + } + if ((fax->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_STATISTICS)) { + (*(pC->pIdiLib->DivaSTraceGetFaxStatistics))(pC->pIdiLib); + } + break; + + case DIVA_SUPER_TRACE_INTERFACE_CHANGE: + if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_EVENTS) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, + "Layer 1 -> [%s]", channel->pInterface->Layer1); + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, + "Layer 2 -> [%s]", channel->pInterface->Layer2); + } + break; + + case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE: + if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) { + /* + Incoming Statistics + */ + if (channel->pInterfaceStat->inc.Calls) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Calls =%lu", channel->pInterfaceStat->inc.Calls); + } + if (channel->pInterfaceStat->inc.Connected) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Connected =%lu", channel->pInterfaceStat->inc.Connected); + } + if (channel->pInterfaceStat->inc.User_Busy) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Busy =%lu", channel->pInterfaceStat->inc.User_Busy); + } + if (channel->pInterfaceStat->inc.Call_Rejected) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Rejected =%lu", channel->pInterfaceStat->inc.Call_Rejected); + } + if (channel->pInterfaceStat->inc.Wrong_Number) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Wrong Nr =%lu", channel->pInterfaceStat->inc.Wrong_Number); + } + if (channel->pInterfaceStat->inc.Incompatible_Dst) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Incomp. Dest =%lu", channel->pInterfaceStat->inc.Incompatible_Dst); + } + if (channel->pInterfaceStat->inc.Out_of_Order) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Out of Order =%lu", channel->pInterfaceStat->inc.Out_of_Order); + } + if (channel->pInterfaceStat->inc.Ignored) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Inc Ignored =%lu", channel->pInterfaceStat->inc.Ignored); + } + + /* + Outgoing Statistics + */ + if (channel->pInterfaceStat->outg.Calls) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Outg Calls =%lu", channel->pInterfaceStat->outg.Calls); + } + if (channel->pInterfaceStat->outg.Connected) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Outg Connected =%lu", channel->pInterfaceStat->outg.Connected); + } + if (channel->pInterfaceStat->outg.User_Busy) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Outg Busy =%lu", channel->pInterfaceStat->outg.User_Busy); + } + if (channel->pInterfaceStat->outg.No_Answer) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Outg No Answer =%lu", channel->pInterfaceStat->outg.No_Answer); + } + if (channel->pInterfaceStat->outg.Wrong_Number) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Outg Wrong Nr =%lu", channel->pInterfaceStat->outg.Wrong_Number); + } + if (channel->pInterfaceStat->outg.Call_Rejected) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Outg Rejected =%lu", channel->pInterfaceStat->outg.Call_Rejected); + } + if (channel->pInterfaceStat->outg.Other_Failures) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "Outg Other Failures =%lu", channel->pInterfaceStat->outg.Other_Failures); + } + } + break; + + case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE: + if (channel->pInterfaceStat->mdm.Disc_Normal) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Normal = %lu", channel->pInterfaceStat->mdm.Disc_Normal); + } + if (channel->pInterfaceStat->mdm.Disc_Unspecified) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Unsp. = %lu", channel->pInterfaceStat->mdm.Disc_Unspecified); + } + if (channel->pInterfaceStat->mdm.Disc_Busy_Tone) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Busy Tone = %lu", channel->pInterfaceStat->mdm.Disc_Busy_Tone); + } + if (channel->pInterfaceStat->mdm.Disc_Congestion) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Congestion = %lu", channel->pInterfaceStat->mdm.Disc_Congestion); + } + if (channel->pInterfaceStat->mdm.Disc_Carr_Wait) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Carrier Wait = %lu", channel->pInterfaceStat->mdm.Disc_Carr_Wait); + } + if (channel->pInterfaceStat->mdm.Disc_Trn_Timeout) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Trn. T.o. = %lu", channel->pInterfaceStat->mdm.Disc_Trn_Timeout); + } + if (channel->pInterfaceStat->mdm.Disc_Incompat) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Incompatible = %lu", channel->pInterfaceStat->mdm.Disc_Incompat); + } + if (channel->pInterfaceStat->mdm.Disc_Frame_Rej) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc Frame Reject = %lu", channel->pInterfaceStat->mdm.Disc_Frame_Rej); + } + if (channel->pInterfaceStat->mdm.Disc_V42bis) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "MDM Disc V.42bis = %lu", channel->pInterfaceStat->mdm.Disc_V42bis); + } + break; - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Ch = %lu",(int)fax->ChannelNumber); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Event = %lu", fax->Event); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pages = %lu", fax->Page_Counter); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Feat. = 0x%08x", fax->Features); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX ID = <%s>", &fax->Station_ID[0]); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Saddr = <%s>", &fax->Subaddress[0]); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pwd = <%s>", &fax->Password[0]); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Speed = %lu", fax->Speed); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Res. = 0x%08x", fax->Resolution); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Width = %lu", fax->Paper_Width); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Length= %lu", fax->Paper_Length); - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX SLT = %lu", fax->Scanline_Time); - if (fax->Event == 3) { - diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Disc = %lu", fax->Disc_Reason); - } - } - if ((fax->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_STATISTICS)) { - (*(pC->pIdiLib->DivaSTraceGetFaxStatistics))(pC->pIdiLib); - } - break; - - case DIVA_SUPER_TRACE_INTERFACE_CHANGE: - if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_EVENTS) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, - "Layer 1 -> [%s]", channel->pInterface->Layer1); - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, - "Layer 2 -> [%s]", channel->pInterface->Layer2); - } - break; - - case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE: - if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) { - /* - Incoming Statistics - */ - if (channel->pInterfaceStat->inc.Calls) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Calls =%lu", channel->pInterfaceStat->inc.Calls); - } - if (channel->pInterfaceStat->inc.Connected) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Connected =%lu", channel->pInterfaceStat->inc.Connected); - } - if (channel->pInterfaceStat->inc.User_Busy) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Busy =%lu", channel->pInterfaceStat->inc.User_Busy); - } - if (channel->pInterfaceStat->inc.Call_Rejected) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Rejected =%lu", channel->pInterfaceStat->inc.Call_Rejected); - } - if (channel->pInterfaceStat->inc.Wrong_Number) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Wrong Nr =%lu", channel->pInterfaceStat->inc.Wrong_Number); - } - if (channel->pInterfaceStat->inc.Incompatible_Dst) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Incomp. Dest =%lu", channel->pInterfaceStat->inc.Incompatible_Dst); - } - if (channel->pInterfaceStat->inc.Out_of_Order) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Out of Order =%lu", channel->pInterfaceStat->inc.Out_of_Order); - } - if (channel->pInterfaceStat->inc.Ignored) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Inc Ignored =%lu", channel->pInterfaceStat->inc.Ignored); - } - - /* - Outgoing Statistics - */ - if (channel->pInterfaceStat->outg.Calls) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Outg Calls =%lu", channel->pInterfaceStat->outg.Calls); - } - if (channel->pInterfaceStat->outg.Connected) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Outg Connected =%lu", channel->pInterfaceStat->outg.Connected); - } - if (channel->pInterfaceStat->outg.User_Busy) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Outg Busy =%lu", channel->pInterfaceStat->outg.User_Busy); - } - if (channel->pInterfaceStat->outg.No_Answer) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Outg No Answer =%lu", channel->pInterfaceStat->outg.No_Answer); - } - if (channel->pInterfaceStat->outg.Wrong_Number) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Outg Wrong Nr =%lu", channel->pInterfaceStat->outg.Wrong_Number); - } - if (channel->pInterfaceStat->outg.Call_Rejected) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Outg Rejected =%lu", channel->pInterfaceStat->outg.Call_Rejected); - } - if (channel->pInterfaceStat->outg.Other_Failures) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "Outg Other Failures =%lu", channel->pInterfaceStat->outg.Other_Failures); - } - } - break; - - case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE: - if (channel->pInterfaceStat->mdm.Disc_Normal) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Normal = %lu", channel->pInterfaceStat->mdm.Disc_Normal); - } - if (channel->pInterfaceStat->mdm.Disc_Unspecified) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Unsp. = %lu", channel->pInterfaceStat->mdm.Disc_Unspecified); - } - if (channel->pInterfaceStat->mdm.Disc_Busy_Tone) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Busy Tone = %lu", channel->pInterfaceStat->mdm.Disc_Busy_Tone); - } - if (channel->pInterfaceStat->mdm.Disc_Congestion) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Congestion = %lu", channel->pInterfaceStat->mdm.Disc_Congestion); - } - if (channel->pInterfaceStat->mdm.Disc_Carr_Wait) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Carrier Wait = %lu", channel->pInterfaceStat->mdm.Disc_Carr_Wait); - } - if (channel->pInterfaceStat->mdm.Disc_Trn_Timeout) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Trn. T.o. = %lu", channel->pInterfaceStat->mdm.Disc_Trn_Timeout); - } - if (channel->pInterfaceStat->mdm.Disc_Incompat) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Incompatible = %lu", channel->pInterfaceStat->mdm.Disc_Incompat); - } - if (channel->pInterfaceStat->mdm.Disc_Frame_Rej) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc Frame Reject = %lu", channel->pInterfaceStat->mdm.Disc_Frame_Rej); - } - if (channel->pInterfaceStat->mdm.Disc_V42bis) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "MDM Disc V.42bis = %lu", channel->pInterfaceStat->mdm.Disc_V42bis); - } - break; - - case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE: - if (channel->pInterfaceStat->fax.Disc_Normal) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Normal = %lu", channel->pInterfaceStat->fax.Disc_Normal); - } - if (channel->pInterfaceStat->fax.Disc_Not_Ident) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Not Ident. = %lu", channel->pInterfaceStat->fax.Disc_Not_Ident); - } - if (channel->pInterfaceStat->fax.Disc_No_Response) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc No Response = %lu", channel->pInterfaceStat->fax.Disc_No_Response); - } - if (channel->pInterfaceStat->fax.Disc_Retries) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Max Retries = %lu", channel->pInterfaceStat->fax.Disc_Retries); - } - if (channel->pInterfaceStat->fax.Disc_Unexp_Msg) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Unexp. Msg. = %lu", channel->pInterfaceStat->fax.Disc_Unexp_Msg); - } - if (channel->pInterfaceStat->fax.Disc_No_Polling) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc No Polling = %lu", channel->pInterfaceStat->fax.Disc_No_Polling); - } - if (channel->pInterfaceStat->fax.Disc_Training) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Training = %lu", channel->pInterfaceStat->fax.Disc_Training); - } - if (channel->pInterfaceStat->fax.Disc_Unexpected) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Unexpected = %lu", channel->pInterfaceStat->fax.Disc_Unexpected); - } - if (channel->pInterfaceStat->fax.Disc_Application) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Application = %lu", channel->pInterfaceStat->fax.Disc_Application); - } - if (channel->pInterfaceStat->fax.Disc_Incompat) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Incompatible = %lu", channel->pInterfaceStat->fax.Disc_Incompat); - } - if (channel->pInterfaceStat->fax.Disc_No_Command) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc No Command = %lu", channel->pInterfaceStat->fax.Disc_No_Command); - } - if (channel->pInterfaceStat->fax.Disc_Long_Msg) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Long Msg. = %lu", channel->pInterfaceStat->fax.Disc_Long_Msg); - } - if (channel->pInterfaceStat->fax.Disc_Supervisor) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Supervisor = %lu", channel->pInterfaceStat->fax.Disc_Supervisor); - } - if (channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc SUP SEP PWD = %lu", channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD); - } - if (channel->pInterfaceStat->fax.Disc_Invalid_Msg) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Invalid Msg. = %lu", channel->pInterfaceStat->fax.Disc_Invalid_Msg); - } - if (channel->pInterfaceStat->fax.Disc_Page_Coding) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Page Coding = %lu", channel->pInterfaceStat->fax.Disc_Page_Coding); - } - if (channel->pInterfaceStat->fax.Disc_App_Timeout) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Appl. T.o. = %lu", channel->pInterfaceStat->fax.Disc_App_Timeout); - } - if (channel->pInterfaceStat->fax.Disc_Unspecified) { - diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, - "FAX Disc Unspec. = %lu", channel->pInterfaceStat->fax.Disc_Unspecified); - } - break; - } + case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE: + if (channel->pInterfaceStat->fax.Disc_Normal) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Normal = %lu", channel->pInterfaceStat->fax.Disc_Normal); + } + if (channel->pInterfaceStat->fax.Disc_Not_Ident) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Not Ident. = %lu", channel->pInterfaceStat->fax.Disc_Not_Ident); + } + if (channel->pInterfaceStat->fax.Disc_No_Response) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc No Response = %lu", channel->pInterfaceStat->fax.Disc_No_Response); + } + if (channel->pInterfaceStat->fax.Disc_Retries) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Max Retries = %lu", channel->pInterfaceStat->fax.Disc_Retries); + } + if (channel->pInterfaceStat->fax.Disc_Unexp_Msg) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Unexp. Msg. = %lu", channel->pInterfaceStat->fax.Disc_Unexp_Msg); + } + if (channel->pInterfaceStat->fax.Disc_No_Polling) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc No Polling = %lu", channel->pInterfaceStat->fax.Disc_No_Polling); + } + if (channel->pInterfaceStat->fax.Disc_Training) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Training = %lu", channel->pInterfaceStat->fax.Disc_Training); + } + if (channel->pInterfaceStat->fax.Disc_Unexpected) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Unexpected = %lu", channel->pInterfaceStat->fax.Disc_Unexpected); + } + if (channel->pInterfaceStat->fax.Disc_Application) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Application = %lu", channel->pInterfaceStat->fax.Disc_Application); + } + if (channel->pInterfaceStat->fax.Disc_Incompat) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Incompatible = %lu", channel->pInterfaceStat->fax.Disc_Incompat); + } + if (channel->pInterfaceStat->fax.Disc_No_Command) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc No Command = %lu", channel->pInterfaceStat->fax.Disc_No_Command); + } + if (channel->pInterfaceStat->fax.Disc_Long_Msg) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Long Msg. = %lu", channel->pInterfaceStat->fax.Disc_Long_Msg); + } + if (channel->pInterfaceStat->fax.Disc_Supervisor) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Supervisor = %lu", channel->pInterfaceStat->fax.Disc_Supervisor); + } + if (channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc SUP SEP PWD = %lu", channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD); + } + if (channel->pInterfaceStat->fax.Disc_Invalid_Msg) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Invalid Msg. = %lu", channel->pInterfaceStat->fax.Disc_Invalid_Msg); + } + if (channel->pInterfaceStat->fax.Disc_Page_Coding) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Page Coding = %lu", channel->pInterfaceStat->fax.Disc_Page_Coding); + } + if (channel->pInterfaceStat->fax.Disc_App_Timeout) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Appl. T.o. = %lu", channel->pInterfaceStat->fax.Disc_App_Timeout); + } + if (channel->pInterfaceStat->fax.Disc_Unspecified) { + diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, + "FAX Disc Unspec. = %lu", channel->pInterfaceStat->fax.Disc_Unspecified); + } + break; + } } /* Receive trace information from the Management Interface and store it in the internal trace buffer with MSG_TYPE_MLOG as is, without any filtering. Event Filtering and formatting is done in Management Interface self. - */ -static void diva_maint_trace_notify (void* user_context, - diva_strace_library_interface_t* hLib, - int Adapter, - void* xlog_buffer, - int length) { - diva_maint_client_t* pC = (diva_maint_client_t*)user_context; - diva_dbg_entry_head_t* pmsg; - word size; - dword sec, usec; - int ch = TraceFilterChannel; - int id = TraceFilterIdent; - - /* - Selective trace - */ - if ((id >= 0) && (ch >= 0) && (id < sizeof(clients)/sizeof(clients[0])) && - (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) { - const char* p = NULL; - int ch_value = -1; - MI_XLOG_HDR *TrcData = (MI_XLOG_HDR *)xlog_buffer; - - if (Adapter != clients[id].logical) { - return; /* Ignore all trace messages from other adapters */ - } - - if (TrcData->code == 24) { - p = (char*)&TrcData->code; - p += 2; - } - - /* - All L1 messages start as [dsp,ch], so we can filter this information - and filter out all messages that use different channel - */ - if (p && p[0] == '[') { - if (p[2] == ',') { - p += 3; - ch_value = *p - '0'; - } else if (p[3] == ',') { - p += 4; - ch_value = *p - '0'; - } - if (ch_value >= 0) { - if (p[2] == ']') { - ch_value = ch_value * 10 + p[1] - '0'; - } - if (ch_value != ch) { - return; /* Ignore other channels */ - } - } - } +*/ +static void diva_maint_trace_notify(void *user_context, + diva_strace_library_interface_t *hLib, + int Adapter, + void *xlog_buffer, + int length) { + diva_maint_client_t *pC = (diva_maint_client_t *)user_context; + diva_dbg_entry_head_t *pmsg; + word size; + dword sec, usec; + int ch = TraceFilterChannel; + int id = TraceFilterIdent; + + /* + Selective trace + */ + if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) && + (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) { + const char *p = NULL; + int ch_value = -1; + MI_XLOG_HDR *TrcData = (MI_XLOG_HDR *)xlog_buffer; + + if (Adapter != clients[id].logical) { + return; /* Ignore all trace messages from other adapters */ + } + + if (TrcData->code == 24) { + p = (char *)&TrcData->code; + p += 2; + } + + /* + All L1 messages start as [dsp,ch], so we can filter this information + and filter out all messages that use different channel + */ + if (p && p[0] == '[') { + if (p[2] == ',') { + p += 3; + ch_value = *p - '0'; + } else if (p[3] == ',') { + p += 4; + ch_value = *p - '0'; + } + if (ch_value >= 0) { + if (p[2] == ']') { + ch_value = ch_value * 10 + p[1] - '0'; + } + if (ch_value != ch) { + return; /* Ignore other channels */ + } + } + } } else if (TraceFilter[0] != 0) { - return; /* Ignore trace if trace filter is activated, but idle */ - } - - diva_os_get_time (&sec, &usec); - - while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue, - (word)length+sizeof(*pmsg)))) { - if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) { - queueFreeMsg (dbg_queue); - } else { - break; - } - } - if (pmsg) { - memcpy (&pmsg[1], xlog_buffer, length); - pmsg->sequence = dbg_sequence++; - pmsg->time_sec = sec; - pmsg->time_usec = usec; - pmsg->facility = MSG_TYPE_MLOG; - pmsg->dli = pC->logical; - pmsg->drv_id = pC->hDbg->id; - pmsg->di_cpu = 0; - pmsg->data_length = length; - queueCompleteMsg (pmsg); - if (queueCount(dbg_queue)) { - diva_maint_wakeup_read(); - } - } + return; /* Ignore trace if trace filter is activated, but idle */ + } + + diva_os_get_time(&sec, &usec); + + while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue, + (word)length + sizeof(*pmsg)))) { + if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) { + queueFreeMsg(dbg_queue); + } else { + break; + } + } + if (pmsg) { + memcpy(&pmsg[1], xlog_buffer, length); + pmsg->sequence = dbg_sequence++; + pmsg->time_sec = sec; + pmsg->time_usec = usec; + pmsg->facility = MSG_TYPE_MLOG; + pmsg->dli = pC->logical; + pmsg->drv_id = pC->hDbg->id; + pmsg->di_cpu = 0; + pmsg->data_length = length; + queueCompleteMsg(pmsg); + if (queueCount(dbg_queue)) { + diva_maint_wakeup_read(); + } + } } /* Convert MAINT trace mask to management interface trace mask/work/facility and issue command to management interface - */ -static void diva_change_management_debug_mask (diva_maint_client_t* pC, dword old_mask) { - if (pC->request && pC->hDbg && pC->pIdiLib) { - dword changed = pC->hDbg->dbgMask ^ old_mask; - - if (changed & DIVA_MGT_DBG_TRACE) { - (*(pC->pIdiLib->DivaSTraceSetInfo))(pC->pIdiLib, - (pC->hDbg->dbgMask & DIVA_MGT_DBG_TRACE) != 0); - } - if (changed & DIVA_MGT_DBG_DCHAN) { - (*(pC->pIdiLib->DivaSTraceSetDChannel))(pC->pIdiLib, - (pC->hDbg->dbgMask & DIVA_MGT_DBG_DCHAN) != 0); - } - if (!TraceFilter[0]) { - if (changed & DIVA_MGT_DBG_IFC_BCHANNEL) { - int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0); - - for (i = 0; i < pC->channels; i++) { - (*(pC->pIdiLib->DivaSTraceSetBChannel))(pC->pIdiLib, i+1, state); - } - } - if (changed & DIVA_MGT_DBG_IFC_AUDIO) { - int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0); - - for (i = 0; i < pC->channels; i++) { - (*(pC->pIdiLib->DivaSTraceSetAudioTap))(pC->pIdiLib, i+1, state); - } - } - } - } +*/ +static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask) { + if (pC->request && pC->hDbg && pC->pIdiLib) { + dword changed = pC->hDbg->dbgMask ^ old_mask; + + if (changed & DIVA_MGT_DBG_TRACE) { + (*(pC->pIdiLib->DivaSTraceSetInfo))(pC->pIdiLib, + (pC->hDbg->dbgMask & DIVA_MGT_DBG_TRACE) != 0); + } + if (changed & DIVA_MGT_DBG_DCHAN) { + (*(pC->pIdiLib->DivaSTraceSetDChannel))(pC->pIdiLib, + (pC->hDbg->dbgMask & DIVA_MGT_DBG_DCHAN) != 0); + } + if (!TraceFilter[0]) { + if (changed & DIVA_MGT_DBG_IFC_BCHANNEL) { + int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0); + + for (i = 0; i < pC->channels; i++) { + (*(pC->pIdiLib->DivaSTraceSetBChannel))(pC->pIdiLib, i + 1, state); + } + } + if (changed & DIVA_MGT_DBG_IFC_AUDIO) { + int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0); + + for (i = 0; i < pC->channels; i++) { + (*(pC->pIdiLib->DivaSTraceSetAudioTap))(pC->pIdiLib, i + 1, state); + } + } + } + } } -void diva_mnt_internal_dprintf (dword drv_id, dword type, char* fmt, ...) { - va_list ap; +void diva_mnt_internal_dprintf(dword drv_id, dword type, char *fmt, ...) { + va_list ap; va_start(ap, fmt); - DI_format (0, (word)drv_id, (int)type, fmt, ap); + DI_format(0, (word)drv_id, (int)type, fmt, ap); va_end(ap); } /* Shutdown all adapters before driver removal - */ -int diva_mnt_shutdown_xdi_adapters (void) { - diva_os_spin_lock_magic_t old_irql, old_irql1; - int i, fret = 0; - byte * pmem; - - - for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) { - pmem = NULL; - - diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "unload"); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "unload"); - - if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) { - if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].pIdiLib) == 1) { - /* - Adapter removal complete - */ - if (clients[i].pIdiLib) { - (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib); - clients[i].pIdiLib = NULL; - - pmem = clients[i].pmem; - clients[i].pmem = NULL; - } - clients[i].hDbg = NULL; - clients[i].request_pending = 0; - - if (clients[i].dma_handle >= 0) { - /* - Free DMA handle - */ - diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle); - clients[i].dma_handle = -1; +*/ +int diva_mnt_shutdown_xdi_adapters(void) { + diva_os_spin_lock_magic_t old_irql, old_irql1; + int i, fret = 0; + byte *pmem; + + + for (i = 1; i < ARRAY_SIZE(clients); i++) { + pmem = NULL; + + diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "unload"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "unload"); + + if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) { + if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].pIdiLib) == 1) { + /* + Adapter removal complete + */ + if (clients[i].pIdiLib) { + (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib); + clients[i].pIdiLib = NULL; + + pmem = clients[i].pmem; + clients[i].pmem = NULL; } - clients[i].request = NULL; - } else { - fret = -1; - } - } - - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "unload"); - if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) { - clients[i].request_pending = 0; - (*(clients[i].request))((ENTITY*)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib)); - if (clients[i].dma_handle >= 0) { - diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle); - clients[i].dma_handle = -1; - } - } - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "unload"); - - if (pmem) { - diva_os_free (0, pmem); - } - } - - return (fret); + clients[i].hDbg = NULL; + clients[i].request_pending = 0; + + if (clients[i].dma_handle >= 0) { + /* + Free DMA handle + */ + diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle); + clients[i].dma_handle = -1; + } + clients[i].request = NULL; + } else { + fret = -1; + } + } + + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "unload"); + if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) { + clients[i].request_pending = 0; + (*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib)); + if (clients[i].dma_handle >= 0) { + diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle); + clients[i].dma_handle = -1; + } + } + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "unload"); + + if (pmem) { + diva_os_free(0, pmem); + } + } + + return (fret); } /* Set/Read the trace filter used for selective tracing. Affects B- and Audio Tap trace mask at run time - */ -int diva_set_trace_filter (int filter_length, const char* filter) { - diva_os_spin_lock_magic_t old_irql, old_irql1; - int i, ch, on, client_b_on, client_atap_on; - - diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask"); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "write_filter"); - - if (filter_length <= DIVA_MAX_SELECTIVE_FILTER_LENGTH) { - memcpy (&TraceFilter[0], filter, filter_length); - if (TraceFilter[filter_length]) { - TraceFilter[filter_length] = 0; - } - if (TraceFilter[0] == '*') { - TraceFilter[0] = 0; - } - } else { - filter_length = -1; - } - - TraceFilterIdent = -1; - TraceFilterChannel = -1; - - on = (TraceFilter[0] == 0); - - for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) { - if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) { - client_b_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0); - client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0); - for (ch = 0; ch < clients[i].channels; ch++) { - (*(clients[i].pIdiLib->DivaSTraceSetBChannel))(clients[i].pIdiLib->hLib, ch+1, client_b_on); - (*(clients[i].pIdiLib->DivaSTraceSetAudioTap))(clients[i].pIdiLib->hLib, ch+1, client_atap_on); - } - } - } - - for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) { - if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) { - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "write_filter"); - clients[i].request_pending = 0; - (*(clients[i].request))((ENTITY*)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib)); - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "write_filter"); - } - } - - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "write_filter"); - diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask"); - - return (filter_length); +*/ +int diva_set_trace_filter(int filter_length, const char *filter) { + diva_os_spin_lock_magic_t old_irql, old_irql1; + int i, ch, on, client_b_on, client_atap_on; + + diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter"); + + if (filter_length <= DIVA_MAX_SELECTIVE_FILTER_LENGTH) { + memcpy(&TraceFilter[0], filter, filter_length); + if (TraceFilter[filter_length]) { + TraceFilter[filter_length] = 0; + } + if (TraceFilter[0] == '*') { + TraceFilter[0] = 0; + } + } else { + filter_length = -1; + } + + TraceFilterIdent = -1; + TraceFilterChannel = -1; + + on = (TraceFilter[0] == 0); + + for (i = 1; i < ARRAY_SIZE(clients); i++) { + if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) { + client_b_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0); + client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0); + for (ch = 0; ch < clients[i].channels; ch++) { + (*(clients[i].pIdiLib->DivaSTraceSetBChannel))(clients[i].pIdiLib->hLib, ch + 1, client_b_on); + (*(clients[i].pIdiLib->DivaSTraceSetAudioTap))(clients[i].pIdiLib->hLib, ch + 1, client_atap_on); + } + } + } + + for (i = 1; i < ARRAY_SIZE(clients); i++) { + if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) { + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter"); + clients[i].request_pending = 0; + (*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib)); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter"); + } + } + + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter"); + diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask"); + + return (filter_length); } -int diva_get_trace_filter (int max_length, char* filter) { - diva_os_spin_lock_magic_t old_irql; - int len; +int diva_get_trace_filter(int max_length, char *filter) { + diva_os_spin_lock_magic_t old_irql; + int len; - diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read_filter"); - len = strlen (&TraceFilter[0]) + 1; - if (max_length >= len) { - memcpy (filter, &TraceFilter[0], len); - } - diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_filter"); + diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read_filter"); + len = strlen(&TraceFilter[0]) + 1; + if (max_length >= len) { + memcpy(filter, &TraceFilter[0], len); + } + diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_filter"); - return (len); + return (len); } -static int diva_dbg_cmp_key (const char* ref, const char* key) { +static int diva_dbg_cmp_key(const char *ref, const char *key) { while (*key && (*ref++ == *key++)); - return (!*key && !*ref); + return (!*key && !*ref); } /* @@ -2056,78 +2055,77 @@ static int diva_dbg_cmp_key (const char* ref, const char* key) { all following characters are interpreted as command. Followings commands are available: - single, trace single call at time, independent from CPN/CiPN - */ -static int diva_mnt_cmp_nmbr (const char* nmbr) { - const char* ref = &TraceFilter[0]; - int ref_len = strlen(&TraceFilter[0]), nmbr_len = strlen(nmbr); - - if (ref[0] == 'C') { - if (diva_dbg_cmp_key (&ref[1], "single")) { - return (0); - } - return (-1); - } - - if (!ref_len || (ref_len > nmbr_len)) { - return (-1); - } - - nmbr = nmbr + nmbr_len - 1; - ref = ref + ref_len - 1; - - while (ref_len--) { - if (*nmbr-- != *ref--) { - return (-1); - } - } - - return (0); +*/ +static int diva_mnt_cmp_nmbr(const char *nmbr) { + const char *ref = &TraceFilter[0]; + int ref_len = strlen(&TraceFilter[0]), nmbr_len = strlen(nmbr); + + if (ref[0] == 'C') { + if (diva_dbg_cmp_key(&ref[1], "single")) { + return (0); + } + return (-1); + } + + if (!ref_len || (ref_len > nmbr_len)) { + return (-1); + } + + nmbr = nmbr + nmbr_len - 1; + ref = ref + ref_len - 1; + + while (ref_len--) { + if (*nmbr-- != *ref--) { + return (-1); + } + } + + return (0); } -static int diva_get_dma_descriptor (IDI_CALL request, dword *dma_magic) { - ENTITY e; - IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e; +static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic) { + ENTITY e; + IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e; - if (!request) { - return (-1); - } + if (!request) { + return (-1); + } - pReq->xdi_dma_descriptor_operation.Req = 0; - pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; + pReq->xdi_dma_descriptor_operation.Req = 0; + pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; - pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC; - pReq->xdi_dma_descriptor_operation.info.descriptor_number = -1; - pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; - pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; + pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC; + pReq->xdi_dma_descriptor_operation.info.descriptor_number = -1; + pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; + pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; - (*request)((ENTITY*)pReq); + (*request)((ENTITY *)pReq); - if (!pReq->xdi_dma_descriptor_operation.info.operation && - (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) && - pReq->xdi_dma_descriptor_operation.info.descriptor_magic) { - *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic; - return (pReq->xdi_dma_descriptor_operation.info.descriptor_number); - } else { - return (-1); - } + if (!pReq->xdi_dma_descriptor_operation.info.operation && + (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) && + pReq->xdi_dma_descriptor_operation.info.descriptor_magic) { + *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic; + return (pReq->xdi_dma_descriptor_operation.info.descriptor_number); + } else { + return (-1); + } } -static void diva_free_dma_descriptor (IDI_CALL request, int nr) { - ENTITY e; - IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e; +static void diva_free_dma_descriptor(IDI_CALL request, int nr) { + ENTITY e; + IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e; - if (!request || (nr < 0)) { - return; - } + if (!request || (nr < 0)) { + return; + } - pReq->xdi_dma_descriptor_operation.Req = 0; - pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; + pReq->xdi_dma_descriptor_operation.Req = 0; + pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; - pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE; - pReq->xdi_dma_descriptor_operation.info.descriptor_number = nr; - pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; - pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; + pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE; + pReq->xdi_dma_descriptor_operation.info.descriptor_number = nr; + pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; + pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; - (*request)((ENTITY*)pReq); + (*request)((ENTITY *)pReq); } - diff --git a/drivers/isdn/hardware/eicon/debug_if.h b/drivers/isdn/hardware/eicon/debug_if.h index 4db739d5803..fc5953a35ff 100644 --- a/drivers/isdn/hardware/eicon/debug_if.h +++ b/drivers/isdn/hardware/eicon/debug_if.h @@ -1,23 +1,23 @@ /* * - Copyright (c) Eicon Technology Corporation, 2000. + Copyright (c) Eicon Technology Corporation, 2000. * - This source file is supplied for the use with Eicon - Technology Corporation's range of DIVA Server Adapters. + This source file is supplied for the use with Eicon + Technology Corporation's range of DIVA Server Adapters. * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_DEBUG_IF_H__ @@ -31,35 +31,35 @@ #define MSG_FRAME_MAX_SIZE 2150 typedef struct _diva_dbg_entry_head { - dword sequence; - dword time_sec; - dword time_usec; - dword facility; - dword dli; - dword drv_id; - dword di_cpu; - dword data_length; + dword sequence; + dword time_sec; + dword time_usec; + dword facility; + dword dli; + dword drv_id; + dword di_cpu; + dword data_length; } diva_dbg_entry_head_t; -int diva_maint_init (byte* base, unsigned long length, int do_init); -void* diva_maint_finit (void); -dword diva_dbg_q_length (void); -diva_dbg_entry_head_t* diva_maint_get_message (word* size, - diva_os_spin_lock_magic_t* old_irql); -void diva_maint_ack_message (int do_release, - diva_os_spin_lock_magic_t* old_irql); -void diva_maint_prtComp (char *format, ...); -void diva_maint_wakeup_read (void); -int diva_get_driver_info (dword id, byte* data, int data_length); -int diva_get_driver_dbg_mask (dword id, byte* data); -int diva_set_driver_dbg_mask (dword id, dword mask); -void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d); -void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d); -int diva_mnt_shutdown_xdi_adapters (void); +int diva_maint_init(byte *base, unsigned long length, int do_init); +void *diva_maint_finit(void); +dword diva_dbg_q_length(void); +diva_dbg_entry_head_t *diva_maint_get_message(word *size, + diva_os_spin_lock_magic_t *old_irql); +void diva_maint_ack_message(int do_release, + diva_os_spin_lock_magic_t *old_irql); +void diva_maint_prtComp(char *format, ...); +void diva_maint_wakeup_read(void); +int diva_get_driver_info(dword id, byte *data, int data_length); +int diva_get_driver_dbg_mask(dword id, byte *data); +int diva_set_driver_dbg_mask(dword id, dword mask); +void diva_mnt_remove_xdi_adapter(const DESCRIPTOR *d); +void diva_mnt_add_xdi_adapter(const DESCRIPTOR *d); +int diva_mnt_shutdown_xdi_adapters(void); #define DIVA_MAX_SELECTIVE_FILTER_LENGTH 127 -int diva_set_trace_filter (int filter_length, const char* filter); -int diva_get_trace_filter (int max_length, char* filter); +int diva_set_trace_filter(int filter_length, const char *filter); +int diva_get_trace_filter(int max_length, char *filter); #define DITRACE_CMD_GET_DRIVER_INFO 1 @@ -72,7 +72,7 @@ int diva_get_trace_filter (int max_length, char* filter); /* Trace lavels for debug via management interface - */ +*/ #define DIVA_MGT_DBG_TRACE 0x00000001 /* All trace messages from the card */ #define DIVA_MGT_DBG_DCHAN 0x00000002 /* All D-channel relater trace messages */ #define DIVA_MGT_DBG_MDM_PROGRESS 0x00000004 /* Modem progress events */ @@ -86,5 +86,3 @@ int diva_get_trace_filter (int max_length, char* filter); #define DIVA_MGT_DBG_IFC_AUDIO 0x00000400 /* Audio Tap trace for all channels */ # endif /* DEBUG_IF___H */ - - diff --git a/drivers/isdn/hardware/eicon/debuglib.c b/drivers/isdn/hardware/eicon/debuglib.c index a19b7ffe9ac..d5b1092a54f 100644 --- a/drivers/isdn/hardware/eicon/debuglib.c +++ b/drivers/isdn/hardware/eicon/debuglib.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -29,35 +29,35 @@ #ifdef DIVA_NO_DEBUGLIB static DIVA_DI_PRINTF dprintf; #else /* DIVA_NO_DEBUGLIB */ - + _DbgHandle_ myDriverDebugHandle = { 0 /*!Registered*/, DBG_HANDLE_VERSION }; DIVA_DI_PRINTF dprintf = no_printf; /*****************************************************************************/ -#define DBG_FUNC(name) \ -void \ -myDbgPrint_##name (char *format, ...) \ -{ va_list ap ; \ - if ( myDriverDebugHandle.dbg_prt ) \ - { va_start (ap, format) ; \ - (myDriverDebugHandle.dbg_prt) \ - (myDriverDebugHandle.id, DLI_##name, format, ap) ; \ - va_end (ap) ; \ -} } +#define DBG_FUNC(name) \ + void \ + myDbgPrint_##name(char *format, ...) \ + { va_list ap; \ + if (myDriverDebugHandle.dbg_prt) \ + { va_start(ap, format); \ + (myDriverDebugHandle.dbg_prt) \ + (myDriverDebugHandle.id, DLI_##name, format, ap); \ + va_end(ap); \ + } } DBG_FUNC(LOG) DBG_FUNC(FTL) DBG_FUNC(ERR) DBG_FUNC(TRC) DBG_FUNC(MXLOG) DBG_FUNC(FTL_MXLOG) -void -myDbgPrint_EVL (long msgID, ...) -{ va_list ap ; - if ( myDriverDebugHandle.dbg_ev ) - { va_start (ap, msgID) ; - (myDriverDebugHandle.dbg_ev) - (myDriverDebugHandle.id, (unsigned long)msgID, ap) ; - va_end (ap) ; -} } +void +myDbgPrint_EVL(long msgID, ...) +{ va_list ap; + if (myDriverDebugHandle.dbg_ev) + { va_start(ap, msgID); + (myDriverDebugHandle.dbg_ev) + (myDriverDebugHandle.id, (unsigned long)msgID, ap); + va_end(ap); + } } DBG_FUNC(REG) DBG_FUNC(MEM) DBG_FUNC(SPL) @@ -76,81 +76,81 @@ DBG_FUNC(PRV2) DBG_FUNC(PRV3) /*****************************************************************************/ int -DbgRegister (char *drvName, char *drvTag, unsigned long dbgMask) +DbgRegister(char *drvName, char *drvTag, unsigned long dbgMask) { - int len; + int len; /* * deregister (if already registered) and zero out myDriverDebugHandle */ - DbgDeregister () ; + DbgDeregister(); /* * initialize the debug handle */ - myDriverDebugHandle.Version = DBG_HANDLE_VERSION ; - myDriverDebugHandle.id = -1 ; - myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG) ; - len = strlen (drvName) ; - memcpy (myDriverDebugHandle.drvName, drvName, - (len < sizeof(myDriverDebugHandle.drvName)) ? - len : sizeof(myDriverDebugHandle.drvName) - 1) ; - len = strlen (drvTag) ; - memcpy (myDriverDebugHandle.drvTag, drvTag, - (len < sizeof(myDriverDebugHandle.drvTag)) ? - len : sizeof(myDriverDebugHandle.drvTag) - 1) ; + myDriverDebugHandle.Version = DBG_HANDLE_VERSION; + myDriverDebugHandle.id = -1; + myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG); + len = strlen(drvName); + memcpy(myDriverDebugHandle.drvName, drvName, + (len < sizeof(myDriverDebugHandle.drvName)) ? + len : sizeof(myDriverDebugHandle.drvName) - 1); + len = strlen(drvTag); + memcpy(myDriverDebugHandle.drvTag, drvTag, + (len < sizeof(myDriverDebugHandle.drvTag)) ? + len : sizeof(myDriverDebugHandle.drvTag) - 1); /* * Try to register debugging via old (and only) interface */ - dprintf("\000\377", &myDriverDebugHandle) ; - if ( myDriverDebugHandle.dbg_prt ) - { - return (1) ; - } + dprintf("\000\377", &myDriverDebugHandle); + if (myDriverDebugHandle.dbg_prt) + { + return (1); + } /* - * Check if we registered whith an old maint driver (see debuglib.h) + * Check if we registered with an old maint driver (see debuglib.h) */ - if ( myDriverDebugHandle.dbg_end != NULL - /* location of 'dbg_prt' in _OldDbgHandle_ struct */ - && (myDriverDebugHandle.regTime.LowPart || - myDriverDebugHandle.regTime.HighPart ) ) - /* same location as in _OldDbgHandle_ struct */ - { - dprintf("%s: Cannot log to old maint driver !", drvName) ; - myDriverDebugHandle.dbg_end = - ((_OldDbgHandle_ *)&myDriverDebugHandle)->dbg_end ; - DbgDeregister () ; - } - return (0) ; + if (myDriverDebugHandle.dbg_end != NULL + /* location of 'dbg_prt' in _OldDbgHandle_ struct */ + && (myDriverDebugHandle.regTime.LowPart || + myDriverDebugHandle.regTime.HighPart)) + /* same location as in _OldDbgHandle_ struct */ + { + dprintf("%s: Cannot log to old maint driver !", drvName); + myDriverDebugHandle.dbg_end = + ((_OldDbgHandle_ *)&myDriverDebugHandle)->dbg_end; + DbgDeregister(); + } + return (0); } /*****************************************************************************/ void -DbgSetLevel (unsigned long dbgMask) +DbgSetLevel(unsigned long dbgMask) { - myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG) ; + myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG); } /*****************************************************************************/ void -DbgDeregister (void) +DbgDeregister(void) { - if ( myDriverDebugHandle.dbg_end ) - { - (myDriverDebugHandle.dbg_end)(&myDriverDebugHandle) ; - } - memset (&myDriverDebugHandle, 0, sizeof(myDriverDebugHandle)) ; + if (myDriverDebugHandle.dbg_end) + { + (myDriverDebugHandle.dbg_end)(&myDriverDebugHandle); + } + memset(&myDriverDebugHandle, 0, sizeof(myDriverDebugHandle)); } -void xdi_dbg_xlog (char* x, ...) { - va_list ap; - va_start (ap, x); - if (myDriverDebugHandle.dbg_end && - (myDriverDebugHandle.dbg_irq || myDriverDebugHandle.dbg_old) && - (myDriverDebugHandle.dbgMask & DL_STAT)) { - if (myDriverDebugHandle.dbg_irq) { - (*(myDriverDebugHandle.dbg_irq))(myDriverDebugHandle.id, - (x[0] != 0) ? DLI_TRC : DLI_XLOG, x, ap); - } else { - (*(myDriverDebugHandle.dbg_old))(myDriverDebugHandle.id, x, ap); - } - } - va_end(ap); +void xdi_dbg_xlog(char *x, ...) { + va_list ap; + va_start(ap, x); + if (myDriverDebugHandle.dbg_end && + (myDriverDebugHandle.dbg_irq || myDriverDebugHandle.dbg_old) && + (myDriverDebugHandle.dbgMask & DL_STAT)) { + if (myDriverDebugHandle.dbg_irq) { + (*(myDriverDebugHandle.dbg_irq))(myDriverDebugHandle.id, + (x[0] != 0) ? DLI_TRC : DLI_XLOG, x, ap); + } else { + (*(myDriverDebugHandle.dbg_old))(myDriverDebugHandle.id, x, ap); + } + } + va_end(ap); } /*****************************************************************************/ #endif /* DIVA_NO_DEBUGLIB */ diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h index 11b3b9edd1d..6dcbf6afb8f 100644 --- a/drivers/isdn/hardware/eicon/debuglib.h +++ b/drivers/isdn/hardware/eicon/debuglib.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #if !defined(__DEBUGLIB_H__) @@ -103,43 +103,43 @@ #define DL_TO_KERNEL 0x40000000 #ifdef DIVA_NO_DEBUGLIB -#define myDbgPrint_LOG(x...) do { } while(0); -#define myDbgPrint_FTL(x...) do { } while(0); -#define myDbgPrint_ERR(x...) do { } while(0); -#define myDbgPrint_TRC(x...) do { } while(0); -#define myDbgPrint_MXLOG(x...) do { } while(0); -#define myDbgPrint_EVL(x...) do { } while(0); -#define myDbgPrint_REG(x...) do { } while(0); -#define myDbgPrint_MEM(x...) do { } while(0); -#define myDbgPrint_SPL(x...) do { } while(0); -#define myDbgPrint_IRP(x...) do { } while(0); -#define myDbgPrint_TIM(x...) do { } while(0); -#define myDbgPrint_BLK(x...) do { } while(0); -#define myDbgPrint_TAPI(x...) do { } while(0); -#define myDbgPrint_NDIS(x...) do { } while(0); -#define myDbgPrint_CONN(x...) do { } while(0); -#define myDbgPrint_STAT(x...) do { } while(0); -#define myDbgPrint_SEND(x...) do { } while(0); -#define myDbgPrint_RECV(x...) do { } while(0); -#define myDbgPrint_PRV0(x...) do { } while(0); -#define myDbgPrint_PRV1(x...) do { } while(0); -#define myDbgPrint_PRV2(x...) do { } while(0); -#define myDbgPrint_PRV3(x...) do { } while(0); -#define DBG_TEST(func,args) do { } while(0); -#define DBG_EVL_ID(args) do { } while(0); +#define myDbgPrint_LOG(x...) do { } while (0); +#define myDbgPrint_FTL(x...) do { } while (0); +#define myDbgPrint_ERR(x...) do { } while (0); +#define myDbgPrint_TRC(x...) do { } while (0); +#define myDbgPrint_MXLOG(x...) do { } while (0); +#define myDbgPrint_EVL(x...) do { } while (0); +#define myDbgPrint_REG(x...) do { } while (0); +#define myDbgPrint_MEM(x...) do { } while (0); +#define myDbgPrint_SPL(x...) do { } while (0); +#define myDbgPrint_IRP(x...) do { } while (0); +#define myDbgPrint_TIM(x...) do { } while (0); +#define myDbgPrint_BLK(x...) do { } while (0); +#define myDbgPrint_TAPI(x...) do { } while (0); +#define myDbgPrint_NDIS(x...) do { } while (0); +#define myDbgPrint_CONN(x...) do { } while (0); +#define myDbgPrint_STAT(x...) do { } while (0); +#define myDbgPrint_SEND(x...) do { } while (0); +#define myDbgPrint_RECV(x...) do { } while (0); +#define myDbgPrint_PRV0(x...) do { } while (0); +#define myDbgPrint_PRV1(x...) do { } while (0); +#define myDbgPrint_PRV2(x...) do { } while (0); +#define myDbgPrint_PRV3(x...) do { } while (0); +#define DBG_TEST(func, args) do { } while (0); +#define DBG_EVL_ID(args) do { } while (0); #else /* DIVA_NO_DEBUGLIB */ /* * define low level macros for formatted & raw debugging */ -#define DBG_DECL(func) extern void myDbgPrint_##func (char *, ...) ; +#define DBG_DECL(func) extern void myDbgPrint_##func(char *, ...); DBG_DECL(LOG) DBG_DECL(FTL) DBG_DECL(ERR) DBG_DECL(TRC) DBG_DECL(MXLOG) DBG_DECL(FTL_MXLOG) -extern void myDbgPrint_EVL (long, ...) ; +extern void myDbgPrint_EVL(long, ...); DBG_DECL(REG) DBG_DECL(MEM) DBG_DECL(SPL) @@ -156,34 +156,34 @@ DBG_DECL(PRV0) DBG_DECL(PRV1) DBG_DECL(PRV2) DBG_DECL(PRV3) -#ifdef _KERNEL_DBG_PRINT_ +#ifdef _KERNEL_DBG_PRINT_ /* * tracing to maint and kernel if selected in the trace mask. */ -#define DBG_TEST(func,args) \ -{ if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func ) \ - { \ - if ( (myDriverDebugHandle.dbgMask) & DL_TO_KERNEL ) \ - {DbgPrint args; DbgPrint ("\r\n");} \ - myDbgPrint_##func args ; \ -} } +#define DBG_TEST(func, args) \ + { if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func) \ + { \ + if ((myDriverDebugHandle.dbgMask) & DL_TO_KERNEL) \ + { DbgPrint args; DbgPrint("\r\n"); } \ + myDbgPrint_##func args; \ + } } #else /* * Standard tracing to maint driver. */ -#define DBG_TEST(func,args) \ -{ if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func ) \ - { myDbgPrint_##func args ; \ -} } +#define DBG_TEST(func, args) \ + { if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func) \ + { myDbgPrint_##func args; \ + } } #endif /* - * For event level debug use a separate define, the paramete are + * For event level debug use a separate define, the parameter are * different and cause compiler errors on some systems. */ -#define DBG_EVL_ID(args) \ -{ if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL ) \ - { myDbgPrint_EVL args ; \ -} } +#define DBG_EVL_ID(args) \ + { if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL) \ + { myDbgPrint_EVL args; \ + } } #endif /* DIVA_NO_DEBUGLIB */ @@ -214,109 +214,109 @@ DBG_DECL(PRV3) * prototypes for debug register/deregister functions in "debuglib.c" */ #ifdef DIVA_NO_DEBUGLIB -#define DbgRegister(name,tag, mask) do { } while(0) -#define DbgDeregister() do { } while(0) -#define DbgSetLevel(mask) do { } while(0) +#define DbgRegister(name, tag, mask) do { } while (0) +#define DbgDeregister() do { } while (0) +#define DbgSetLevel(mask) do { } while (0) #else extern DIVA_DI_PRINTF dprintf; -extern int DbgRegister (char *drvName, char *drvTag, unsigned long dbgMask) ; -extern void DbgDeregister (void) ; -extern void DbgSetLevel (unsigned long dbgMask) ; +extern int DbgRegister(char *drvName, char *drvTag, unsigned long dbgMask); +extern void DbgDeregister(void); +extern void DbgSetLevel(unsigned long dbgMask); #endif /* * driver internal structure for debug handling; * in client drivers this structure is maintained in "debuglib.c", * in the debug driver "debug.c" maintains a chain of such structs. */ -typedef struct _DbgHandle_ *pDbgHandle ; -typedef void ( * DbgEnd) (pDbgHandle) ; -typedef void ( * DbgLog) (unsigned short, int, char *, va_list) ; -typedef void ( * DbgOld) (unsigned short, char *, va_list) ; -typedef void ( * DbgEv) (unsigned short, unsigned long, va_list) ; -typedef void ( * DbgIrq) (unsigned short, int, char *, va_list) ; +typedef struct _DbgHandle_ *pDbgHandle; +typedef void (*DbgEnd)(pDbgHandle); +typedef void (*DbgLog)(unsigned short, int, char *, va_list); +typedef void (*DbgOld)(unsigned short, char *, va_list); +typedef void (*DbgEv)(unsigned short, unsigned long, va_list); +typedef void (*DbgIrq)(unsigned short, int, char *, va_list); typedef struct _DbgHandle_ -{ char Registered ; /* driver successfull registered */ +{ char Registered; /* driver successfully registered */ #define DBG_HANDLE_REG_NEW 0x01 /* this (new) structure */ #define DBG_HANDLE_REG_OLD 0x7f /* old structure (see below) */ - char Version; /* version of this structure */ + char Version; /* version of this structure */ #define DBG_HANDLE_VERSION 1 /* contains dbg_old function now */ #define DBG_HANDLE_VER_EXT 2 /* pReserved points to extended info*/ - short id ; /* internal id of registered driver */ - struct _DbgHandle_ *next ; /* ptr to next registered driver */ - struct /*LARGE_INTEGER*/ { - unsigned long LowPart; - long HighPart; - } regTime ; /* timestamp for registration */ - void *pIrp ; /* ptr to pending i/o request */ - unsigned long dbgMask ; /* current debug mask */ - char drvName[16] ; /* ASCII name of registered driver */ - char drvTag[64] ; /* revision string */ - DbgEnd dbg_end ; /* function for debug closing */ - DbgLog dbg_prt ; /* function for debug appending */ - DbgOld dbg_old ; /* function for old debug appending */ - DbgEv dbg_ev ; /* function for Windows NT Eventlog */ - DbgIrq dbg_irq ; /* function for irql checked debug */ - void *pReserved3 ; -} _DbgHandle_ ; -extern _DbgHandle_ myDriverDebugHandle ; + short id; /* internal id of registered driver */ + struct _DbgHandle_ *next; /* ptr to next registered driver */ + struct /*LARGE_INTEGER*/ { + unsigned long LowPart; + long HighPart; + } regTime; /* timestamp for registration */ + void *pIrp; /* ptr to pending i/o request */ + unsigned long dbgMask; /* current debug mask */ + char drvName[128]; /* ASCII name of registered driver */ + char drvTag[64]; /* revision string */ + DbgEnd dbg_end; /* function for debug closing */ + DbgLog dbg_prt; /* function for debug appending */ + DbgOld dbg_old; /* function for old debug appending */ + DbgEv dbg_ev; /* function for Windows NT Eventlog */ + DbgIrq dbg_irq; /* function for irql checked debug */ + void *pReserved3; +} _DbgHandle_; +extern _DbgHandle_ myDriverDebugHandle; typedef struct _OldDbgHandle_ -{ struct _OldDbgHandle_ *next ; - void *pIrp ; - long regTime[2] ; - unsigned long dbgMask ; - short id ; - char drvName[78] ; - DbgEnd dbg_end ; - DbgLog dbg_prt ; -} _OldDbgHandle_ ; +{ struct _OldDbgHandle_ *next; + void *pIrp; + long regTime[2]; + unsigned long dbgMask; + short id; + char drvName[78]; + DbgEnd dbg_end; + DbgLog dbg_prt; +} _OldDbgHandle_; /* the differences in DbgHandles old: tmp: new: - 0 long next char Registered char Registered - char filler char Version - short id short id - 4 long pIrp long regTime.lo long next - 8 long regTime.lo long regTime.hi long regTime.lo - 12 long regTime.hi long next long regTime.hi - 16 long dbgMask long pIrp long pIrp - 20 short id long dbgMask long dbgMask - 22 char drvName[78] .. - 24 .. char drvName[16] char drvName[16] - 40 .. char drvTag[64] char drvTag[64] - 100 void *dbg_end .. .. - 104 void *dbg_prt void *dbg_end void *dbg_end - 108 .. void *dbg_prt void *dbg_prt - 112 .. .. void *dbg_old - 116 .. .. void *dbg_ev - 120 .. .. void *dbg_irq - 124 .. .. void *pReserved3 - ( new->id == 0 && *((short *)&new->dbgMask) == -1 ) identifies "old", - new->Registered and new->Version overlay old->next, - new->next overlays old->pIrp, new->regTime matches old->regTime and - thus these fields can be maintained in new struct whithout trouble; - id, dbgMask, drvName, dbg_end and dbg_prt need special handling ! + 0 long next char Registered char Registered + char filler char Version + short id short id + 4 long pIrp long regTime.lo long next + 8 long regTime.lo long regTime.hi long regTime.lo + 12 long regTime.hi long next long regTime.hi + 16 long dbgMask long pIrp long pIrp + 20 short id long dbgMask long dbgMask + 22 char drvName[78] .. + 24 .. char drvName[16] char drvName[16] + 40 .. char drvTag[64] char drvTag[64] + 100 void *dbg_end .. .. + 104 void *dbg_prt void *dbg_end void *dbg_end + 108 .. void *dbg_prt void *dbg_prt + 112 .. .. void *dbg_old + 116 .. .. void *dbg_ev + 120 .. .. void *dbg_irq + 124 .. .. void *pReserved3 + ( new->id == 0 && *((short *)&new->dbgMask) == -1 ) identifies "old", + new->Registered and new->Version overlay old->next, + new->next overlays old->pIrp, new->regTime matches old->regTime and + thus these fields can be maintained in new struct whithout trouble; + id, dbgMask, drvName, dbg_end and dbg_prt need special handling ! */ #define DBG_EXT_TYPE_CARD_TRACE 0x00000001 typedef struct { - unsigned long ExtendedType; - union - { - /* DBG_EXT_TYPE_CARD_TRACE */ - struct - { - void ( * MaskChangedNotify) (void *pContext); - unsigned long ModuleTxtMask; - unsigned long DebugLevel; - unsigned long B_ChannelMask; - unsigned long LogBufferSize; - } CardTrace; - }Data; + unsigned long ExtendedType; + union + { + /* DBG_EXT_TYPE_CARD_TRACE */ + struct + { + void (*MaskChangedNotify)(void *pContext); + unsigned long ModuleTxtMask; + unsigned long DebugLevel; + unsigned long B_ChannelMask; + unsigned long LogBufferSize; + } CardTrace; + } Data; } _DbgExtendedInfo_; #ifndef DIVA_NO_DEBUGLIB /* ------------------------------------------------------------- - Function used for xlog-style debug + Function used for xlog-style debug ------------------------------------------------------------- */ #define XDI_USE_XLOG 1 -void xdi_dbg_xlog (char* x, ...); +void xdi_dbg_xlog(char *x, ...); #endif /* DIVA_NO_DEBUGLIB */ #endif /* __DEBUGLIB_H__ */ diff --git a/drivers/isdn/hardware/eicon/dfifo.h b/drivers/isdn/hardware/eicon/dfifo.h index 9a109c71e93..6a1d3337f99 100644 --- a/drivers/isdn/hardware/eicon/dfifo.h +++ b/drivers/isdn/hardware/eicon/dfifo.h @@ -1,54 +1,54 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_IDI_DFIFO_INC__ #define __DIVA_IDI_DFIFO_INC__ #define DIVA_DFIFO_CACHE_SZ 64 /* Used to isolate pipe from - rest of the world - should be divisible by 4 - */ -#define DIVA_DFIFO_RAW_SZ (2512*8) + rest of the world + should be divisible by 4 + */ +#define DIVA_DFIFO_RAW_SZ (2512 * 8) #define DIVA_DFIFO_DATA_SZ 68 #define DIVA_DFIFO_HDR_SZ 4 -#define DIVA_DFIFO_SEGMENT_SZ (DIVA_DFIFO_DATA_SZ+DIVA_DFIFO_HDR_SZ) -#define DIVA_DFIFO_SEGMENTS ((DIVA_DFIFO_RAW_SZ)/(DIVA_DFIFO_SEGMENT_SZ)+1) -#define DIVA_DFIFO_MEM_SZ (\ - (DIVA_DFIFO_SEGMENT_SZ)*(DIVA_DFIFO_SEGMENTS)+\ - (DIVA_DFIFO_CACHE_SZ)*2\ - ) +#define DIVA_DFIFO_SEGMENT_SZ (DIVA_DFIFO_DATA_SZ + DIVA_DFIFO_HDR_SZ) +#define DIVA_DFIFO_SEGMENTS ((DIVA_DFIFO_RAW_SZ) / (DIVA_DFIFO_SEGMENT_SZ) + 1) +#define DIVA_DFIFO_MEM_SZ ( \ + (DIVA_DFIFO_SEGMENT_SZ) * (DIVA_DFIFO_SEGMENTS) + \ + (DIVA_DFIFO_CACHE_SZ) * 2 \ + ) #define DIVA_DFIFO_STEP DIVA_DFIFO_SEGMENT_SZ /* ------------------------------------------------------------------------- - Block header layout is: + Block header layout is: byte[0] -> flags byte[1] -> length of data in block byte[2] -> reserved byte[4] -> reserved - ------------------------------------------------------------------------- */ + ------------------------------------------------------------------------- */ #define DIVA_DFIFO_WRAP 0x80 /* This is the last block in fifo */ #define DIVA_DFIFO_READY 0x40 /* This block is ready for processing */ #define DIVA_DFIFO_LAST 0x20 /* This block is last in message */ #define DIVA_DFIFO_AUTO 0x10 /* Don't look for 'ready', don't ack */ -int diva_dfifo_create (void* start, int length); +int diva_dfifo_create(void *start, int length); #endif diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c index 0617d7cabf0..cd3fba1add1 100644 --- a/drivers/isdn/hardware/eicon/di.c +++ b/drivers/isdn/hardware/eicon/di.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -29,9 +29,9 @@ #include "di_defs.h" #include "di.h" #if !defined USE_EXTENDED_DEBUGS - #include "dimaint.h" +#include "dimaint.h" #else - #define dprintf +#define dprintf #endif #include "io.h" #include "dfifo.h" @@ -40,796 +40,796 @@ /*------------------------------------------------------------------*/ /* local function prototypes */ /*------------------------------------------------------------------*/ -void pr_out(ADAPTER * a); -byte pr_dpc(ADAPTER * a); -static byte pr_ready(ADAPTER * a); +void pr_out(ADAPTER *a); +byte pr_dpc(ADAPTER *a); +static byte pr_ready(ADAPTER *a); static byte isdn_rc(ADAPTER *, byte, byte, byte, word, dword, dword); static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word); /* ----------------------------------------------------------------- - Functions used for the extended XDI Debug - macros - global convergence counter (used by all adapters) - Look by the implementation part of the functions - about the parameters. - If you change the dubugging parameters, then you should update - the aididbg.doc in the IDI doc's. + Functions used for the extended XDI Debug + macros + global convergence counter (used by all adapters) + Look by the implementation part of the functions + about the parameters. + If you change the dubugging parameters, then you should update + the aididbg.doc in the IDI doc's. ----------------------------------------------------------------- */ #if defined(XDI_USE_XLOG) #define XDI_A_NR(_x_) ((byte)(((ISDN_ADAPTER *)(_x_->io))->ANum)) -static void xdi_xlog (byte *msg, word code, int length); +static void xdi_xlog(byte *msg, word code, int length); static byte xdi_xlog_sec = 0; #else #define XDI_A_NR(_x_) ((byte)0) #endif -static void xdi_xlog_rc_event (byte Adapter, - byte Id, byte Ch, byte Rc, byte cb, byte type); -static void xdi_xlog_request (byte Adapter, byte Id, - byte Ch, byte Req, byte type); -static void xdi_xlog_ind (byte Adapter, - byte Id, - byte Ch, - byte Ind, - byte rnr_valid, - byte rnr, - byte type); +static void xdi_xlog_rc_event(byte Adapter, + byte Id, byte Ch, byte Rc, byte cb, byte type); +static void xdi_xlog_request(byte Adapter, byte Id, + byte Ch, byte Req, byte type); +static void xdi_xlog_ind(byte Adapter, + byte Id, + byte Ch, + byte Ind, + byte rnr_valid, + byte rnr, + byte type); /*------------------------------------------------------------------*/ /* output function */ /*------------------------------------------------------------------*/ -void pr_out(ADAPTER * a) +void pr_out(ADAPTER *a) { - byte e_no; - ENTITY * this = NULL; - BUFFERS *X; - word length; - word i; - word clength; - REQ * ReqOut; - byte more; - byte ReadyCount; - byte ReqCount; - byte Id; - dtrc(dprintf("pr_out")); - /* while a request is pending ... */ - e_no = look_req(a); - if(!e_no) - { - dtrc(dprintf("no_req")); - return; - } - ReadyCount = pr_ready(a); - if(!ReadyCount) - { - dtrc(dprintf("not_ready")); - return; - } - ReqCount = 0; - while(e_no && ReadyCount) { - next_req(a); - this = entity_ptr(a, e_no); + byte e_no; + ENTITY *this = NULL; + BUFFERS *X; + word length; + word i; + word clength; + REQ *ReqOut; + byte more; + byte ReadyCount; + byte ReqCount; + byte Id; + dtrc(dprintf("pr_out")); + /* while a request is pending ... */ + e_no = look_req(a); + if (!e_no) + { + dtrc(dprintf("no_req")); + return; + } + ReadyCount = pr_ready(a); + if (!ReadyCount) + { + dtrc(dprintf("not_ready")); + return; + } + ReqCount = 0; + while (e_no && ReadyCount) { + next_req(a); + this = entity_ptr(a, e_no); #ifdef USE_EXTENDED_DEBUGS - if ( !this ) - { - DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore", - xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum)) - e_no = look_req(a) ; - ReadyCount-- ; - continue ; - } - { - DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req)) - } + if (!this) + { + DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore", + xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum)) + e_no = look_req(a); + ReadyCount--; + continue; + } + { + DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req)) + } #else - dbug(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh)); + dbug(dprintf("out:Req=%x,Id=%x,Ch=%x", this->Req, this->Id, this->ReqCh)); #endif - /* get address of next available request buffer */ - ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)]; + /* get address of next available request buffer */ + ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)]; #if defined(DIVA_ISTREAM) - if (!(a->tx_stream[this->Id] && - this->Req == N_DATA)) { + if (!(a->tx_stream[this->Id] && + this->Req == N_DATA)) { #endif - /* now copy the data from the current data buffer into the */ - /* adapters request buffer */ - length = 0; - i = this->XCurrent; - X = PTR_X(a,this); - while(i<this->XNum && length<270) { - clength = MIN((word)(270-length),X[i].PLength-this->XOffset); - a->ram_out_buffer(a, - &ReqOut->XBuffer.P[length], - PTR_P(a,this,&X[i].P[this->XOffset]), - clength); - length +=clength; - this->XOffset +=clength; - if(this->XOffset==X[i].PLength) { - this->XCurrent = (byte)++i; - this->XOffset = 0; - } - } + /* now copy the data from the current data buffer into the */ + /* adapters request buffer */ + length = 0; + i = this->XCurrent; + X = PTR_X(a, this); + while (i < this->XNum && length < 270) { + clength = min((word)(270 - length), (word)(X[i].PLength-this->XOffset)); + a->ram_out_buffer(a, + &ReqOut->XBuffer.P[length], + PTR_P(a, this, &X[i].P[this->XOffset]), + clength); + length += clength; + this->XOffset += clength; + if (this->XOffset == X[i].PLength) { + this->XCurrent = (byte)++i; + this->XOffset = 0; + } + } #if defined(DIVA_ISTREAM) - } else { /* Use CMA extension in order to transfer data to the card */ - i = this->XCurrent; - X = PTR_X(a,this); - while (i < this->XNum) { - diva_istream_write (a, - this->Id, - PTR_P(a,this,&X[i].P[0]), - X[i].PLength, - ((i+1) == this->XNum), - 0, 0); - this->XCurrent = (byte)++i; - } - length = 0; - } + } else { /* Use CMA extension in order to transfer data to the card */ + i = this->XCurrent; + X = PTR_X(a, this); + while (i < this->XNum) { + diva_istream_write(a, + this->Id, + PTR_P(a, this, &X[i].P[0]), + X[i].PLength, + ((i + 1) == this->XNum), + 0, 0); + this->XCurrent = (byte)++i; + } + length = 0; + } #endif - a->ram_outw(a, &ReqOut->XBuffer.length, length); - a->ram_out(a, &ReqOut->ReqId, this->Id); - a->ram_out(a, &ReqOut->ReqCh, this->ReqCh); - /* if it's a specific request (no ASSIGN) ... */ - if(this->Id &0x1f) { - /* if buffers are left in the list of data buffers do */ - /* do chaining (LL_MDATA, N_MDATA) */ - this->More++; - if(i<this->XNum && this->MInd) { - xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->MInd, - a->IdTypeTable[this->No]); - a->ram_out(a, &ReqOut->Req, this->MInd); - more = TRUE; - } - else { - xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->Req, - a->IdTypeTable[this->No]); - this->More |=XMOREF; - a->ram_out(a, &ReqOut->Req, this->Req); - more = FALSE; - if (a->FlowControlIdTable[this->ReqCh] == this->Id) - a->FlowControlSkipTable[this->ReqCh] = TRUE; - /* - Note that remove request was sent to the card - */ - if (this->Req == REMOVE) { - a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING; - } - } - /* if we did chaining, this entity is put back into the */ - /* request queue */ - if(more) { - req_queue(a,this->No); - } - } - /* else it's a ASSIGN */ - else { - /* save the request code used for buffer chaining */ - this->MInd = 0; - if (this->Id==BLLC_ID) this->MInd = LL_MDATA; - if (this->Id==NL_ID || - this->Id==TASK_ID || - this->Id==MAN_ID - ) this->MInd = N_MDATA; - /* send the ASSIGN */ - a->IdTypeTable[this->No] = this->Id; - xdi_xlog_request (XDI_A_NR(a),this->Id,this->ReqCh,this->Req, this->Id); - this->More |=XMOREF; - a->ram_out(a, &ReqOut->Req, this->Req); - /* save the reference of the ASSIGN */ - assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference)); - } - a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next)); - ReadyCount--; - ReqCount++; - e_no = look_req(a); - } - /* send the filled request buffers to the ISDN adapter */ - a->ram_out(a, &PR_RAM->ReqInput, - (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount)); - /* if it is a 'unreturncoded' UREMOVE request, remove the */ - /* Id from our table after sending the request */ - if(this && (this->Req==UREMOVE) && this->Id) { - Id = this->Id; - e_no = a->IdTable[Id]; - free_entity(a, e_no); - for (i = 0; i < 256; i++) - { - if (a->FlowControlIdTable[i] == Id) - a->FlowControlIdTable[i] = 0; - } - a->IdTable[Id] = 0; - this->Id = 0; - } + a->ram_outw(a, &ReqOut->XBuffer.length, length); + a->ram_out(a, &ReqOut->ReqId, this->Id); + a->ram_out(a, &ReqOut->ReqCh, this->ReqCh); + /* if it's a specific request (no ASSIGN) ... */ + if (this->Id & 0x1f) { + /* if buffers are left in the list of data buffers do */ + /* do chaining (LL_MDATA, N_MDATA) */ + this->More++; + if (i < this->XNum && this->MInd) { + xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->MInd, + a->IdTypeTable[this->No]); + a->ram_out(a, &ReqOut->Req, this->MInd); + more = true; + } + else { + xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req, + a->IdTypeTable[this->No]); + this->More |= XMOREF; + a->ram_out(a, &ReqOut->Req, this->Req); + more = false; + if (a->FlowControlIdTable[this->ReqCh] == this->Id) + a->FlowControlSkipTable[this->ReqCh] = true; + /* + Note that remove request was sent to the card + */ + if (this->Req == REMOVE) { + a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING; + } + } + /* if we did chaining, this entity is put back into the */ + /* request queue */ + if (more) { + req_queue(a, this->No); + } + } + /* else it's a ASSIGN */ + else { + /* save the request code used for buffer chaining */ + this->MInd = 0; + if (this->Id == BLLC_ID) this->MInd = LL_MDATA; + if (this->Id == NL_ID || + this->Id == TASK_ID || + this->Id == MAN_ID + ) this->MInd = N_MDATA; + /* send the ASSIGN */ + a->IdTypeTable[this->No] = this->Id; + xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req, this->Id); + this->More |= XMOREF; + a->ram_out(a, &ReqOut->Req, this->Req); + /* save the reference of the ASSIGN */ + assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference)); + } + a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next)); + ReadyCount--; + ReqCount++; + e_no = look_req(a); + } + /* send the filled request buffers to the ISDN adapter */ + a->ram_out(a, &PR_RAM->ReqInput, + (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount)); + /* if it is a 'unreturncoded' UREMOVE request, remove the */ + /* Id from our table after sending the request */ + if (this && (this->Req == UREMOVE) && this->Id) { + Id = this->Id; + e_no = a->IdTable[Id]; + free_entity(a, e_no); + for (i = 0; i < 256; i++) + { + if (a->FlowControlIdTable[i] == Id) + a->FlowControlIdTable[i] = 0; + } + a->IdTable[Id] = 0; + this->Id = 0; + } } -static byte pr_ready(ADAPTER * a) +static byte pr_ready(ADAPTER *a) { - byte ReadyCount; - ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) - - a->ram_in(a, &PR_RAM->ReqInput)); - if(!ReadyCount) { - if(!a->ReadyInt) { - a->ram_inc(a, &PR_RAM->ReadyInt); - a->ReadyInt++; - } - } - return ReadyCount; + byte ReadyCount; + ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) - + a->ram_in(a, &PR_RAM->ReqInput)); + if (!ReadyCount) { + if (!a->ReadyInt) { + a->ram_inc(a, &PR_RAM->ReadyInt); + a->ReadyInt++; + } + } + return ReadyCount; } /*------------------------------------------------------------------*/ /* isdn interrupt handler */ /*------------------------------------------------------------------*/ -byte pr_dpc(ADAPTER * a) +byte pr_dpc(ADAPTER *a) { - byte Count; - RC * RcIn; - IND * IndIn; - byte c; - byte RNRId; - byte Rc; - byte Ind; - /* if return codes are available ... */ - if((Count = a->ram_in(a, &PR_RAM->RcOutput)) != 0) { - dtrc(dprintf("#Rc=%x",Count)); - /* get the buffer address of the first return code */ - RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)]; - /* for all return codes do ... */ - while(Count--) { - if((Rc=a->ram_in(a, &RcIn->Rc)) != 0) { - dword tmp[2]; - /* - Get extended information, associated with return code - */ - a->ram_in_buffer(a, - &RcIn->Reserved2[0], - (byte*)&tmp[0], - 8); - /* call return code handler, if it is not our return code */ - /* the handler returns 2 */ - /* for all return codes we process, we clear the Rc field */ - isdn_rc(a, - Rc, - a->ram_in(a, &RcIn->RcId), - a->ram_in(a, &RcIn->RcCh), - a->ram_inw(a, &RcIn->Reference), - tmp[0], /* type of extended informtion */ - tmp[1]); /* extended information */ - a->ram_out(a, &RcIn->Rc, 0); - } - /* get buffer address of next return code */ - RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)]; - } - /* clear all return codes (no chaining!) */ - a->ram_out(a, &PR_RAM->RcOutput ,0); - /* call output function */ - pr_out(a); - } - /* clear RNR flag */ - RNRId = 0; - /* if indications are available ... */ - if((Count = a->ram_in(a, &PR_RAM->IndOutput)) != 0) { - dtrc(dprintf("#Ind=%x",Count)); - /* get the buffer address of the first indication */ - IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)]; - /* for all indications do ... */ - while(Count--) { - /* if the application marks an indication as RNR, all */ - /* indications from the same Id delivered in this interrupt */ - /* are marked RNR */ - if(RNRId && RNRId==a->ram_in(a, &IndIn->IndId)) { - a->ram_out(a, &IndIn->Ind, 0); - a->ram_out(a, &IndIn->RNR, TRUE); - } - else { - Ind = a->ram_in(a, &IndIn->Ind); - if(Ind) { - RNRId = 0; - /* call indication handler, a return value of 2 means chain */ - /* a return value of 1 means RNR */ - /* for all indications we process, we clear the Ind field */ - c = isdn_ind(a, - Ind, - a->ram_in(a, &IndIn->IndId), - a->ram_in(a, &IndIn->IndCh), - &IndIn->RBuffer, - a->ram_in(a, &IndIn->MInd), - a->ram_inw(a, &IndIn->MLength)); - if(c==1) { - dtrc(dprintf("RNR")); - a->ram_out(a, &IndIn->Ind, 0); - RNRId = a->ram_in(a, &IndIn->IndId); - a->ram_out(a, &IndIn->RNR, TRUE); - } - } - } - /* get buffer address of next indication */ - IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)]; - } - a->ram_out(a, &PR_RAM->IndOutput, 0); - } - return FALSE; + byte Count; + RC *RcIn; + IND *IndIn; + byte c; + byte RNRId; + byte Rc; + byte Ind; + /* if return codes are available ... */ + if ((Count = a->ram_in(a, &PR_RAM->RcOutput)) != 0) { + dtrc(dprintf("#Rc=%x", Count)); + /* get the buffer address of the first return code */ + RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)]; + /* for all return codes do ... */ + while (Count--) { + if ((Rc = a->ram_in(a, &RcIn->Rc)) != 0) { + dword tmp[2]; + /* + Get extended information, associated with return code + */ + a->ram_in_buffer(a, + &RcIn->Reserved2[0], + (byte *)&tmp[0], + 8); + /* call return code handler, if it is not our return code */ + /* the handler returns 2 */ + /* for all return codes we process, we clear the Rc field */ + isdn_rc(a, + Rc, + a->ram_in(a, &RcIn->RcId), + a->ram_in(a, &RcIn->RcCh), + a->ram_inw(a, &RcIn->Reference), + tmp[0], /* type of extended information */ + tmp[1]); /* extended information */ + a->ram_out(a, &RcIn->Rc, 0); + } + /* get buffer address of next return code */ + RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)]; + } + /* clear all return codes (no chaining!) */ + a->ram_out(a, &PR_RAM->RcOutput, 0); + /* call output function */ + pr_out(a); + } + /* clear RNR flag */ + RNRId = 0; + /* if indications are available ... */ + if ((Count = a->ram_in(a, &PR_RAM->IndOutput)) != 0) { + dtrc(dprintf("#Ind=%x", Count)); + /* get the buffer address of the first indication */ + IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)]; + /* for all indications do ... */ + while (Count--) { + /* if the application marks an indication as RNR, all */ + /* indications from the same Id delivered in this interrupt */ + /* are marked RNR */ + if (RNRId && RNRId == a->ram_in(a, &IndIn->IndId)) { + a->ram_out(a, &IndIn->Ind, 0); + a->ram_out(a, &IndIn->RNR, true); + } + else { + Ind = a->ram_in(a, &IndIn->Ind); + if (Ind) { + RNRId = 0; + /* call indication handler, a return value of 2 means chain */ + /* a return value of 1 means RNR */ + /* for all indications we process, we clear the Ind field */ + c = isdn_ind(a, + Ind, + a->ram_in(a, &IndIn->IndId), + a->ram_in(a, &IndIn->IndCh), + &IndIn->RBuffer, + a->ram_in(a, &IndIn->MInd), + a->ram_inw(a, &IndIn->MLength)); + if (c == 1) { + dtrc(dprintf("RNR")); + a->ram_out(a, &IndIn->Ind, 0); + RNRId = a->ram_in(a, &IndIn->IndId); + a->ram_out(a, &IndIn->RNR, true); + } + } + } + /* get buffer address of next indication */ + IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)]; + } + a->ram_out(a, &PR_RAM->IndOutput, 0); + } + return false; } -byte scom_test_int(ADAPTER * a) +byte scom_test_int(ADAPTER *a) { - return a->ram_in(a,(void *)0x3fe); + return a->ram_in(a, (void *)0x3fe); } -void scom_clear_int(ADAPTER * a) +void scom_clear_int(ADAPTER *a) { - a->ram_out(a,(void *)0x3fe,0); + a->ram_out(a, (void *)0x3fe, 0); } /*------------------------------------------------------------------*/ /* return code handler */ /*------------------------------------------------------------------*/ -byte isdn_rc(ADAPTER * a, - byte Rc, - byte Id, - byte Ch, - word Ref, - dword extended_info_type, - dword extended_info) +static byte isdn_rc(ADAPTER *a, + byte Rc, + byte Id, + byte Ch, + word Ref, + dword extended_info_type, + dword extended_info) { - ENTITY * this; - byte e_no; - word i; - int cancel_rc; + ENTITY *this; + byte e_no; + word i; + int cancel_rc; #ifdef USE_EXTENDED_DEBUGS - { - DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc)) - } + { + DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc)) + } #else - dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch)); + dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)", Rc, Id, Ch)); #endif - /* check for ready interrupt */ - if(Rc==READY_INT) { - xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, 0); - if(a->ReadyInt) { - a->ReadyInt--; - return 0; - } - return 2; - } - /* if we know this Id ... */ - e_no = a->IdTable[Id]; - if(e_no) { - this = entity_ptr(a,e_no); - xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, a->IdTypeTable[this->No]); - this->RcCh = Ch; - /* if it is a return code to a REMOVE request, remove the */ - /* Id from our table */ - if ((a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_REMOVE_PENDING) && - (Rc==OK)) { - if (a->IdTypeTable[e_no] == NL_ID) { - if (a->RcExtensionSupported && - (extended_info_type != DIVA_RC_TYPE_REMOVE_COMPLETE)) { - dtrc(dprintf("XDI: N-REMOVE, A(%02x) Id:%02x, ignore RC=OK", - XDI_A_NR(a),Id)); - return (0); - } - if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE) - a->RcExtensionSupported = TRUE; - } - a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING; - a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING; - free_entity(a, e_no); - for (i = 0; i < 256; i++) - { - if (a->FlowControlIdTable[i] == Id) - a->FlowControlIdTable[i] = 0; - } - a->IdTable[Id] = 0; - this->Id = 0; - /* --------------------------------------------------------------- - If we send N_DISC or N_DISK_ACK after we have received OK_FC - then the card will respond with OK_FC and later with RC==OK. - If we send N_REMOVE in this state we will receive only RC==OK - This will create the state in that the XDI is waiting for the - additional RC and does not delivery the RC to the client. This - code corrects the counter of outstanding RC's in this case. - --------------------------------------------------------------- */ - if ((this->More & XMOREC) > 1) { - this->More &= ~XMOREC; - this->More |= 1; - dtrc(dprintf("XDI: correct MORE on REMOVE A(%02x) Id:%02x", - XDI_A_NR(a),Id)); - } - } - if (Rc==OK_FC) { - a->FlowControlIdTable[Ch] = Id; - a->FlowControlSkipTable[Ch] = FALSE; - this->Rc = Rc; - this->More &= ~(XBUSY | XMOREC); - this->complete=0xff; - xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); - CALLBACK(a, this); - return 0; - } - /* - New protocol code sends return codes that comes from release - of flow control condition marked with DIVA_RC_TYPE_OK_FC extended - information element type. - If like return code arrives then application is able to process - all return codes self and XDI should not cances return codes. - This return code does not decrement XMOREC partial return code - counter due to fact that it was no request for this return code, - also XMOREC was not incremented. - */ - if (extended_info_type == DIVA_RC_TYPE_OK_FC) { - a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_NO_RC_CANCELLING; - this->Rc = Rc; - this->complete=0xff; - xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); - DBG_TRC(("XDI OK_FC A(%02x) Id:%02x Ch:%02x Rc:%02x", - XDI_A_NR(a), Id, Ch, Rc)) - CALLBACK(a, this); - return 0; - } - cancel_rc = !(a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_NO_RC_CANCELLING); - if (cancel_rc && (a->FlowControlIdTable[Ch] == Id)) - { - a->FlowControlIdTable[Ch] = 0; - if ((Rc != OK) || !a->FlowControlSkipTable[Ch]) - { - this->Rc = Rc; - if (Ch == this->ReqCh) - { - this->More &=~(XBUSY | XMOREC); - this->complete=0xff; - } - xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); - CALLBACK(a, this); - } - return 0; - } - if (this->More &XMOREC) - this->More--; - /* call the application callback function */ - if (((!cancel_rc) || (this->More & XMOREF)) && !(this->More & XMOREC)) { - this->Rc = Rc; - this->More &=~XBUSY; - this->complete=0xff; - xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); - CALLBACK(a, this); - } - return 0; - } - /* if it's an ASSIGN return code check if it's a return */ - /* code to an ASSIGN request from us */ - if((Rc &0xf0)==ASSIGN_RC) { - e_no = get_assign(a, Ref); - if(e_no) { - this = entity_ptr(a,e_no); - this->Id = Id; - xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 2, a->IdTypeTable[this->No]); - /* call the application callback function */ - this->Rc = Rc; - this->More &=~XBUSY; - this->complete=0xff; + /* check for ready interrupt */ + if (Rc == READY_INT) { + xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 0, 0); + if (a->ReadyInt) { + a->ReadyInt--; + return 0; + } + return 2; + } + /* if we know this Id ... */ + e_no = a->IdTable[Id]; + if (e_no) { + this = entity_ptr(a, e_no); + xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 0, a->IdTypeTable[this->No]); + this->RcCh = Ch; + /* if it is a return code to a REMOVE request, remove the */ + /* Id from our table */ + if ((a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_REMOVE_PENDING) && + (Rc == OK)) { + if (a->IdTypeTable[e_no] == NL_ID) { + if (a->RcExtensionSupported && + (extended_info_type != DIVA_RC_TYPE_REMOVE_COMPLETE)) { + dtrc(dprintf("XDI: N-REMOVE, A(%02x) Id:%02x, ignore RC=OK", + XDI_A_NR(a), Id)); + return (0); + } + if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE) + a->RcExtensionSupported = true; + } + a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING; + a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING; + free_entity(a, e_no); + for (i = 0; i < 256; i++) + { + if (a->FlowControlIdTable[i] == Id) + a->FlowControlIdTable[i] = 0; + } + a->IdTable[Id] = 0; + this->Id = 0; + /* --------------------------------------------------------------- + If we send N_DISC or N_DISK_ACK after we have received OK_FC + then the card will respond with OK_FC and later with RC==OK. + If we send N_REMOVE in this state we will receive only RC==OK + This will create the state in that the XDI is waiting for the + additional RC and does not delivery the RC to the client. This + code corrects the counter of outstanding RC's in this case. + --------------------------------------------------------------- */ + if ((this->More & XMOREC) > 1) { + this->More &= ~XMOREC; + this->More |= 1; + dtrc(dprintf("XDI: correct MORE on REMOVE A(%02x) Id:%02x", + XDI_A_NR(a), Id)); + } + } + if (Rc == OK_FC) { + a->FlowControlIdTable[Ch] = Id; + a->FlowControlSkipTable[Ch] = false; + this->Rc = Rc; + this->More &= ~(XBUSY | XMOREC); + this->complete = 0xff; + xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); + CALLBACK(a, this); + return 0; + } + /* + New protocol code sends return codes that comes from release + of flow control condition marked with DIVA_RC_TYPE_OK_FC extended + information element type. + If like return code arrives then application is able to process + all return codes self and XDI should not cances return codes. + This return code does not decrement XMOREC partial return code + counter due to fact that it was no request for this return code, + also XMOREC was not incremented. + */ + if (extended_info_type == DIVA_RC_TYPE_OK_FC) { + a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_NO_RC_CANCELLING; + this->Rc = Rc; + this->complete = 0xff; + xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); + DBG_TRC(("XDI OK_FC A(%02x) Id:%02x Ch:%02x Rc:%02x", + XDI_A_NR(a), Id, Ch, Rc)) + CALLBACK(a, this); + return 0; + } + cancel_rc = !(a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_NO_RC_CANCELLING); + if (cancel_rc && (a->FlowControlIdTable[Ch] == Id)) + { + a->FlowControlIdTable[Ch] = 0; + if ((Rc != OK) || !a->FlowControlSkipTable[Ch]) + { + this->Rc = Rc; + if (Ch == this->ReqCh) + { + this->More &= ~(XBUSY | XMOREC); + this->complete = 0xff; + } + xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); + CALLBACK(a, this); + } + return 0; + } + if (this->More & XMOREC) + this->More--; + /* call the application callback function */ + if (((!cancel_rc) || (this->More & XMOREF)) && !(this->More & XMOREC)) { + this->Rc = Rc; + this->More &= ~XBUSY; + this->complete = 0xff; + xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]); + CALLBACK(a, this); + } + return 0; + } + /* if it's an ASSIGN return code check if it's a return */ + /* code to an ASSIGN request from us */ + if ((Rc & 0xf0) == ASSIGN_RC) { + e_no = get_assign(a, Ref); + if (e_no) { + this = entity_ptr(a, e_no); + this->Id = Id; + xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 2, a->IdTypeTable[this->No]); + /* call the application callback function */ + this->Rc = Rc; + this->More &= ~XBUSY; + this->complete = 0xff; #if defined(DIVA_ISTREAM) /* { */ - if ((Rc == ASSIGN_OK) && a->ram_offset && - (a->IdTypeTable[this->No] == NL_ID) && - ((extended_info_type == DIVA_RC_TYPE_RX_DMA) || - (extended_info_type == DIVA_RC_TYPE_CMA_PTR)) && - extended_info) { - dword offset = (*(a->ram_offset)) (a); - dword tmp[2]; - extended_info -= offset; + if ((Rc == ASSIGN_OK) && a->ram_offset && + (a->IdTypeTable[this->No] == NL_ID) && + ((extended_info_type == DIVA_RC_TYPE_RX_DMA) || + (extended_info_type == DIVA_RC_TYPE_CMA_PTR)) && + extended_info) { + dword offset = (*(a->ram_offset)) (a); + dword tmp[2]; + extended_info -= offset; #ifdef PLATFORM_GT_32BIT - a->ram_in_dw(a, (void*)ULongToPtr(extended_info), (dword*)&tmp[0], 2); + a->ram_in_dw(a, (void *)ULongToPtr(extended_info), (dword *)&tmp[0], 2); #else - a->ram_in_dw(a, (void*)extended_info, (dword*)&tmp[0], 2); + a->ram_in_dw(a, (void *)extended_info, (dword *)&tmp[0], 2); #endif - a->tx_stream[Id] = tmp[0]; - a->rx_stream[Id] = tmp[1]; - if (extended_info_type == DIVA_RC_TYPE_RX_DMA) { - DBG_TRC(("Id=0x%x RxDMA=%08x:%08x", - Id, a->tx_stream[Id], a->rx_stream[Id])) - a->misc_flags_table[this->No] |= DIVA_MISC_FLAGS_RX_DMA; - } else { - DBG_TRC(("Id=0x%x CMA=%08x:%08x", - Id, a->tx_stream[Id], a->rx_stream[Id])) - a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA; - a->rx_pos[Id] = 0; - a->rx_stream[Id] -= offset; - } - a->tx_pos[Id] = 0; - a->tx_stream[Id] -= offset; - } else { - a->tx_stream[Id] = 0; - a->rx_stream[Id] = 0; - a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA; - } + a->tx_stream[Id] = tmp[0]; + a->rx_stream[Id] = tmp[1]; + if (extended_info_type == DIVA_RC_TYPE_RX_DMA) { + DBG_TRC(("Id=0x%x RxDMA=%08x:%08x", + Id, a->tx_stream[Id], a->rx_stream[Id])) + a->misc_flags_table[this->No] |= DIVA_MISC_FLAGS_RX_DMA; + } else { + DBG_TRC(("Id=0x%x CMA=%08x:%08x", + Id, a->tx_stream[Id], a->rx_stream[Id])) + a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA; + a->rx_pos[Id] = 0; + a->rx_stream[Id] -= offset; + } + a->tx_pos[Id] = 0; + a->tx_stream[Id] -= offset; + } else { + a->tx_stream[Id] = 0; + a->rx_stream[Id] = 0; + a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA; + } #endif /* } */ - CALLBACK(a, this); - if(Rc==ASSIGN_OK) { - a->IdTable[Id] = e_no; - } - else - { - free_entity(a, e_no); - for (i = 0; i < 256; i++) - { - if (a->FlowControlIdTable[i] == Id) - a->FlowControlIdTable[i] = 0; - } - a->IdTable[Id] = 0; - this->Id = 0; - } - return 1; - } - } - return 2; + CALLBACK(a, this); + if (Rc == ASSIGN_OK) { + a->IdTable[Id] = e_no; + } + else + { + free_entity(a, e_no); + for (i = 0; i < 256; i++) + { + if (a->FlowControlIdTable[i] == Id) + a->FlowControlIdTable[i] = 0; + } + a->IdTable[Id] = 0; + this->Id = 0; + } + return 1; + } + } + return 2; } /*------------------------------------------------------------------*/ /* indication handler */ /*------------------------------------------------------------------*/ -byte isdn_ind(ADAPTER * a, - byte Ind, - byte Id, - byte Ch, - PBUFFER * RBuffer, - byte MInd, - word MLength) +static byte isdn_ind(ADAPTER *a, + byte Ind, + byte Id, + byte Ch, + PBUFFER *RBuffer, + byte MInd, + word MLength) { - ENTITY * this; - word clength; - word offset; - BUFFERS *R; - byte* cma = NULL; + ENTITY *this; + word clength; + word offset; + BUFFERS *R; + byte *cma = NULL; #ifdef USE_EXTENDED_DEBUGS - { - DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind)) - } + { + DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind)) + } #else - dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch)); + dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)", Ind, Id, Ch)); #endif - if(a->IdTable[Id]) { - this = entity_ptr(a,a->IdTable[Id]); - this->IndCh = Ch; - xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind, - 0/* rnr_valid */, 0 /* rnr */, a->IdTypeTable[this->No]); - /* if the Receive More flag is not yet set, this is the */ - /* first buffer of the packet */ - if(this->RCurrent==0xff) { - /* check for receive buffer chaining */ - if(Ind==this->MInd) { - this->complete = 0; - this->Ind = MInd; - } - else { - this->complete = 1; - this->Ind = Ind; - } - /* call the application callback function for the receive */ - /* look ahead */ - this->RLength = MLength; + if (a->IdTable[Id]) { + this = entity_ptr(a, a->IdTable[Id]); + this->IndCh = Ch; + xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind, + 0/* rnr_valid */, 0 /* rnr */, a->IdTypeTable[this->No]); + /* if the Receive More flag is not yet set, this is the */ + /* first buffer of the packet */ + if (this->RCurrent == 0xff) { + /* check for receive buffer chaining */ + if (Ind == this->MInd) { + this->complete = 0; + this->Ind = MInd; + } + else { + this->complete = 1; + this->Ind = Ind; + } + /* call the application callback function for the receive */ + /* look ahead */ + this->RLength = MLength; #if defined(DIVA_ISTREAM) - if ((a->rx_stream[this->Id] || - (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA)) && - ((Ind == N_DATA) || - (a->protocol_capabilities & PROTCAP_CMA_ALLPR))) { - PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io ; - if (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA) { + if ((a->rx_stream[this->Id] || + (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA)) && + ((Ind == N_DATA) || + (a->protocol_capabilities & PROTCAP_CMA_ALLPR))) { + PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io; + if (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA) { #if defined(DIVA_IDI_RX_DMA) - dword d; - diva_get_dma_map_entry (\ - (struct _diva_dma_map_entry*)IoAdapter->dma_map, - (int)a->rx_stream[this->Id], (void**)&cma, &d); + dword d; + diva_get_dma_map_entry(\ + (struct _diva_dma_map_entry *)IoAdapter->dma_map, + (int)a->rx_stream[this->Id], (void **)&cma, &d); #else - cma = &a->stream_buffer[0]; - cma[0] = cma[1] = cma[2] = cma[3] = 0; + cma = &a->stream_buffer[0]; + cma[0] = cma[1] = cma[2] = cma[3] = 0; #endif - this->RLength = MLength = (word)*(dword*)cma; - cma += 4; - } else { - int final = 0; - cma = &a->stream_buffer[0]; - this->RLength = MLength = (word)diva_istream_read (a, - Id, - cma, - sizeof(a->stream_buffer), - &final, NULL, NULL); - } - IoAdapter->RBuffer.length = MIN(MLength, 270); - if (IoAdapter->RBuffer.length != MLength) { - this->complete = 0; - } else { - this->complete = 1; - } - memcpy (IoAdapter->RBuffer.P, cma, IoAdapter->RBuffer.length) ; - this->RBuffer = (DBUFFER *)&IoAdapter->RBuffer ; - } + this->RLength = MLength = (word)*(dword *)cma; + cma += 4; + } else { + int final = 0; + cma = &a->stream_buffer[0]; + this->RLength = MLength = (word)diva_istream_read(a, + Id, + cma, + sizeof(a->stream_buffer), + &final, NULL, NULL); + } + IoAdapter->RBuffer.length = min(MLength, (word)270); + if (IoAdapter->RBuffer.length != MLength) { + this->complete = 0; + } else { + this->complete = 1; + } + memcpy(IoAdapter->RBuffer.P, cma, IoAdapter->RBuffer.length); + this->RBuffer = (DBUFFER *)&IoAdapter->RBuffer; + } #endif - if (!cma) { - a->ram_look_ahead(a, RBuffer, this); - } - this->RNum = 0; - CALLBACK(a, this); - /* map entity ptr, selector could be re-mapped by call to */ - /* IDI from within callback */ - this = entity_ptr(a,a->IdTable[Id]); - xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind, - 1/* rnr_valid */, this->RNR/* rnr */, a->IdTypeTable[this->No]); - /* check for RNR */ - if(this->RNR==1) { - this->RNR = 0; - return 1; - } - /* if no buffers are provided by the application, the */ - /* application want to copy the data itself including */ - /* N_MDATA/LL_MDATA chaining */ - if(!this->RNR && !this->RNum) { - xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind, - 2/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]); - return 0; - } - /* if there is no RNR, set the More flag */ - this->RCurrent = 0; - this->ROffset = 0; - } - if(this->RNR==2) { - if(Ind!=this->MInd) { - this->RCurrent = 0xff; - this->RNR = 0; - } - return 0; - } - /* if we have received buffers from the application, copy */ - /* the data into these buffers */ - offset = 0; - R = PTR_R(a,this); - do { - if(this->ROffset==R[this->RCurrent].PLength) { - this->ROffset = 0; - this->RCurrent++; - } - if (cma) { - clength = MIN(MLength, R[this->RCurrent].PLength-this->ROffset); - } else { - clength = MIN(a->ram_inw(a, &RBuffer->length)-offset, - R[this->RCurrent].PLength-this->ROffset); - } - if(R[this->RCurrent].P) { - if (cma) { - memcpy (PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]), - &cma[offset], - clength); - } else { - a->ram_in_buffer(a, - &RBuffer->P[offset], - PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]), - clength); - } - } - offset +=clength; - this->ROffset +=clength; - if (cma) { - if (offset >= MLength) { - break; - } - continue; - } - } while(offset<(a->ram_inw(a, &RBuffer->length))); - /* if it's the last buffer of the packet, call the */ - /* application callback function for the receive complete */ - /* call */ - if(Ind!=this->MInd) { - R[this->RCurrent].PLength = this->ROffset; - if(this->ROffset) this->RCurrent++; - this->RNum = this->RCurrent; - this->RCurrent = 0xff; - this->Ind = Ind; - this->complete = 2; - xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind, - 3/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]); - CALLBACK(a, this); - } - return 0; - } - return 2; + if (!cma) { + a->ram_look_ahead(a, RBuffer, this); + } + this->RNum = 0; + CALLBACK(a, this); + /* map entity ptr, selector could be re-mapped by call to */ + /* IDI from within callback */ + this = entity_ptr(a, a->IdTable[Id]); + xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind, + 1/* rnr_valid */, this->RNR/* rnr */, a->IdTypeTable[this->No]); + /* check for RNR */ + if (this->RNR == 1) { + this->RNR = 0; + return 1; + } + /* if no buffers are provided by the application, the */ + /* application want to copy the data itself including */ + /* N_MDATA/LL_MDATA chaining */ + if (!this->RNR && !this->RNum) { + xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind, + 2/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]); + return 0; + } + /* if there is no RNR, set the More flag */ + this->RCurrent = 0; + this->ROffset = 0; + } + if (this->RNR == 2) { + if (Ind != this->MInd) { + this->RCurrent = 0xff; + this->RNR = 0; + } + return 0; + } + /* if we have received buffers from the application, copy */ + /* the data into these buffers */ + offset = 0; + R = PTR_R(a, this); + do { + if (this->ROffset == R[this->RCurrent].PLength) { + this->ROffset = 0; + this->RCurrent++; + } + if (cma) { + clength = min(MLength, (word)(R[this->RCurrent].PLength-this->ROffset)); + } else { + clength = min(a->ram_inw(a, &RBuffer->length)-offset, + R[this->RCurrent].PLength-this->ROffset); + } + if (R[this->RCurrent].P) { + if (cma) { + memcpy(PTR_P(a, this, &R[this->RCurrent].P[this->ROffset]), + &cma[offset], + clength); + } else { + a->ram_in_buffer(a, + &RBuffer->P[offset], + PTR_P(a, this, &R[this->RCurrent].P[this->ROffset]), + clength); + } + } + offset += clength; + this->ROffset += clength; + if (cma) { + if (offset >= MLength) { + break; + } + continue; + } + } while (offset < (a->ram_inw(a, &RBuffer->length))); + /* if it's the last buffer of the packet, call the */ + /* application callback function for the receive complete */ + /* call */ + if (Ind != this->MInd) { + R[this->RCurrent].PLength = this->ROffset; + if (this->ROffset) this->RCurrent++; + this->RNum = this->RCurrent; + this->RCurrent = 0xff; + this->Ind = Ind; + this->complete = 2; + xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind, + 3/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]); + CALLBACK(a, this); + } + return 0; + } + return 2; } #if defined(XDI_USE_XLOG) /* ----------------------------------------------------------- This function works in the same way as xlog on the active board ----------------------------------------------------------- */ -static void xdi_xlog (byte *msg, word code, int length) { - xdi_dbg_xlog ("\x00\x02", msg, code, length); +static void xdi_xlog(byte *msg, word code, int length) { + xdi_dbg_xlog("\x00\x02", msg, code, length); } #endif /* ----------------------------------------------------------- - This function writes the information about the Return Code - processing in the trace buffer. Trace ID is 221. - INPUT: - Adapter - system unicue adapter number (0 ... 255) - Id - Id of the entity that had sent this return code - Ch - Channel of the entity that had sent this return code - Rc - return code value - cb: (0...2) - switch (cb) { - case 0: printf ("DELIVERY"); break; - case 1: printf ("CALLBACK"); break; - case 2: printf ("ASSIGN"); break; - } - DELIVERY - have entered isdn_rc with this RC - CALLBACK - about to make callback to the application - for this RC - ASSIGN - about to make callback for RC that is result - of ASSIGN request. It is no DELIVERY message - before of this message - type - the Id that was sent by the ASSIGN of this entity. - This should be global Id like NL_ID, DSIG_ID, MAN_ID. - An unknown Id will cause "?-" in the front of the request. - In this case the log.c is to be extended. + This function writes the information about the Return Code + processing in the trace buffer. Trace ID is 221. + INPUT: + Adapter - system unicue adapter number (0 ... 255) + Id - Id of the entity that had sent this return code + Ch - Channel of the entity that had sent this return code + Rc - return code value + cb: (0...2) + switch (cb) { + case 0: printf ("DELIVERY"); break; + case 1: printf ("CALLBACK"); break; + case 2: printf ("ASSIGN"); break; + } + DELIVERY - have entered isdn_rc with this RC + CALLBACK - about to make callback to the application + for this RC + ASSIGN - about to make callback for RC that is result + of ASSIGN request. It is no DELIVERY message + before of this message + type - the Id that was sent by the ASSIGN of this entity. + This should be global Id like NL_ID, DSIG_ID, MAN_ID. + An unknown Id will cause "?-" in the front of the request. + In this case the log.c is to be extended. ----------------------------------------------------------- */ -static void xdi_xlog_rc_event (byte Adapter, - byte Id, byte Ch, byte Rc, byte cb, byte type) { +static void xdi_xlog_rc_event(byte Adapter, + byte Id, byte Ch, byte Rc, byte cb, byte type) { #if defined(XDI_USE_XLOG) - word LogInfo[4]; - PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8))); - PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8))); - PUT_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8))); - PUT_WORD(&LogInfo[3], cb); - xdi_xlog ((byte*)&LogInfo[0], 221, sizeof(LogInfo)); + word LogInfo[4]; + PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8))); + PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8))); + PUT_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8))); + PUT_WORD(&LogInfo[3], cb); + xdi_xlog((byte *)&LogInfo[0], 221, sizeof(LogInfo)); #endif } /* ------------------------------------------------------------------------ - This function writes the information about the request processing - in the trace buffer. Trace ID is 220. - INPUT: - Adapter - system unicue adapter number (0 ... 255) - Id - Id of the entity that had sent this request - Ch - Channel of the entity that had sent this request - Req - Code of the request - type - the Id that was sent by the ASSIGN of this entity. - This should be global Id like NL_ID, DSIG_ID, MAN_ID. - An unknown Id will cause "?-" in the front of the request. - In this case the log.c is to be extended. + This function writes the information about the request processing + in the trace buffer. Trace ID is 220. + INPUT: + Adapter - system unicue adapter number (0 ... 255) + Id - Id of the entity that had sent this request + Ch - Channel of the entity that had sent this request + Req - Code of the request + type - the Id that was sent by the ASSIGN of this entity. + This should be global Id like NL_ID, DSIG_ID, MAN_ID. + An unknown Id will cause "?-" in the front of the request. + In this case the log.c is to be extended. ------------------------------------------------------------------------ */ -static void xdi_xlog_request (byte Adapter, byte Id, - byte Ch, byte Req, byte type) { +static void xdi_xlog_request(byte Adapter, byte Id, + byte Ch, byte Req, byte type) { #if defined(XDI_USE_XLOG) - word LogInfo[3]; - PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8))); - PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8))); - PUT_WORD(&LogInfo[2], ((word)Req | (word)(type << 8))); - xdi_xlog ((byte*)&LogInfo[0], 220, sizeof(LogInfo)); + word LogInfo[3]; + PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8))); + PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8))); + PUT_WORD(&LogInfo[2], ((word)Req | (word)(type << 8))); + xdi_xlog((byte *)&LogInfo[0], 220, sizeof(LogInfo)); #endif } /* ------------------------------------------------------------------------ - This function writes the information about the indication processing - in the trace buffer. Trace ID is 222. - INPUT: - Adapter - system unicue adapter number (0 ... 255) - Id - Id of the entity that had sent this indication - Ch - Channel of the entity that had sent this indication - Ind - Code of the indication - rnr_valid: (0 .. 3) supported - switch (rnr_valid) { - case 0: printf ("DELIVERY"); break; - case 1: printf ("RNR=%d", rnr); - case 2: printf ("RNum=0"); - case 3: printf ("COMPLETE"); - } - DELIVERY - indication entered isdn_rc function - RNR=... - application had returned RNR=... after the - look ahead callback - RNum=0 - aplication had not returned any buffer to copy - this indication and will copy it self - COMPLETE - XDI had copied the data to the buffers provided - bu the application and is about to issue the - final callback - rnr: Look case 1 of the rnr_valid - type: the Id that was sent by the ASSIGN of this entity. This should - be global Id like NL_ID, DSIG_ID, MAN_ID. An unknown Id will - cause "?-" in the front of the request. In this case the - log.c is to be extended. + This function writes the information about the indication processing + in the trace buffer. Trace ID is 222. + INPUT: + Adapter - system unicue adapter number (0 ... 255) + Id - Id of the entity that had sent this indication + Ch - Channel of the entity that had sent this indication + Ind - Code of the indication + rnr_valid: (0 .. 3) supported + switch (rnr_valid) { + case 0: printf ("DELIVERY"); break; + case 1: printf ("RNR=%d", rnr); + case 2: printf ("RNum=0"); + case 3: printf ("COMPLETE"); + } + DELIVERY - indication entered isdn_rc function + RNR=... - application had returned RNR=... after the + look ahead callback + RNum=0 - application had not returned any buffer to copy + this indication and will copy it self + COMPLETE - XDI had copied the data to the buffers provided + bu the application and is about to issue the + final callback + rnr: Look case 1 of the rnr_valid + type: the Id that was sent by the ASSIGN of this entity. This should + be global Id like NL_ID, DSIG_ID, MAN_ID. An unknown Id will + cause "?-" in the front of the request. In this case the + log.c is to be extended. ------------------------------------------------------------------------ */ -static void xdi_xlog_ind (byte Adapter, - byte Id, - byte Ch, - byte Ind, - byte rnr_valid, - byte rnr, - byte type) { +static void xdi_xlog_ind(byte Adapter, + byte Id, + byte Ch, + byte Ind, + byte rnr_valid, + byte rnr, + byte type) { #if defined(XDI_USE_XLOG) - word LogInfo[4]; - PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8))); - PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8))); - PUT_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8))); - PUT_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8))); - xdi_xlog ((byte*)&LogInfo[0], 222, sizeof(LogInfo)); + word LogInfo[4]; + PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8))); + PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8))); + PUT_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8))); + PUT_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8))); + xdi_xlog((byte *)&LogInfo[0], 222, sizeof(LogInfo)); #endif } diff --git a/drivers/isdn/hardware/eicon/di.h b/drivers/isdn/hardware/eicon/di.h index dcf37b10f5d..ff26c65631d 100644 --- a/drivers/isdn/hardware/eicon/di.h +++ b/drivers/isdn/hardware/eicon/di.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* @@ -35,83 +35,83 @@ #define DIVA_MISC_FLAGS_REMOVE_PENDING 0x01 #define DIVA_MISC_FLAGS_NO_RC_CANCELLING 0x02 #define DIVA_MISC_FLAGS_RX_DMA 0x04 - /* structure for all information we have to keep on a per */ - /* adapater basis */ +/* structure for all information we have to keep on a per */ +/* adapater basis */ typedef struct adapter_s ADAPTER; struct adapter_s { - void * io; - byte IdTable[256]; - byte IdTypeTable[256]; - byte FlowControlIdTable[256]; - byte FlowControlSkipTable[256]; - byte ReadyInt; - byte RcExtensionSupported; - byte misc_flags_table[256]; - dword protocol_capabilities; - byte ( * ram_in)(ADAPTER * a, void * adr); - word ( * ram_inw)(ADAPTER * a, void * adr); - void (* ram_in_buffer)(ADAPTER * a, void * adr, void * P, word length); - void (* ram_look_ahead)(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e); - void ( * ram_out)(ADAPTER * a, void * adr, byte data); - void ( * ram_outw)(ADAPTER * a, void * adr, word data); - void (* ram_out_buffer)(ADAPTER * a, void * adr, void * P, word length); - void ( * ram_inc)(ADAPTER * a, void * adr); + void *io; + byte IdTable[256]; + byte IdTypeTable[256]; + byte FlowControlIdTable[256]; + byte FlowControlSkipTable[256]; + byte ReadyInt; + byte RcExtensionSupported; + byte misc_flags_table[256]; + dword protocol_capabilities; + byte (*ram_in)(ADAPTER *a, void *adr); + word (*ram_inw)(ADAPTER *a, void *adr); + void (*ram_in_buffer)(ADAPTER *a, void *adr, void *P, word length); + void (*ram_look_ahead)(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e); + void (*ram_out)(ADAPTER *a, void *adr, byte data); + void (*ram_outw)(ADAPTER *a, void *adr, word data); + void (*ram_out_buffer)(ADAPTER *a, void *adr, void *P, word length); + void (*ram_inc)(ADAPTER *a, void *adr); #if defined(DIVA_ISTREAM) - dword rx_stream[256]; - dword tx_stream[256]; - word tx_pos[256]; - word rx_pos[256]; - byte stream_buffer[2512]; - dword ( * ram_offset)(ADAPTER * a); - void ( * ram_out_dw) (ADAPTER *a, - void *addr, - const dword* data, - int dwords); - void ( * ram_in_dw) (ADAPTER *a, - void *addr, - dword* data, - int dwords); - void ( * istream_wakeup)(ADAPTER* a); + dword rx_stream[256]; + dword tx_stream[256]; + word tx_pos[256]; + word rx_pos[256]; + byte stream_buffer[2512]; + dword (*ram_offset)(ADAPTER *a); + void (*ram_out_dw)(ADAPTER *a, + void *addr, + const dword *data, + int dwords); + void (*ram_in_dw)(ADAPTER *a, + void *addr, + dword *data, + int dwords); + void (*istream_wakeup)(ADAPTER *a); #else - byte stream_buffer[4]; + byte stream_buffer[4]; #endif }; /*------------------------------------------------------------------*/ /* public functions of IDI common code */ /*------------------------------------------------------------------*/ -void pr_out(ADAPTER * a); -byte pr_dpc(ADAPTER * a); -byte scom_test_int(ADAPTER * a); -void scom_clear_int(ADAPTER * a); +void pr_out(ADAPTER *a); +byte pr_dpc(ADAPTER *a); +byte scom_test_int(ADAPTER *a); +void scom_clear_int(ADAPTER *a); /*------------------------------------------------------------------*/ /* OS specific functions used by IDI common code */ /*------------------------------------------------------------------*/ -void free_entity(ADAPTER * a, byte e_no); -void assign_queue(ADAPTER * a, byte e_no, word ref); -byte get_assign(ADAPTER * a, word ref); -void req_queue(ADAPTER * a, byte e_no); -byte look_req(ADAPTER * a); -void next_req(ADAPTER * a); -ENTITY * entity_ptr(ADAPTER * a, byte e_no); +void free_entity(ADAPTER *a, byte e_no); +void assign_queue(ADAPTER *a, byte e_no, word ref); +byte get_assign(ADAPTER *a, word ref); +void req_queue(ADAPTER *a, byte e_no); +byte look_req(ADAPTER *a); +void next_req(ADAPTER *a); +ENTITY *entity_ptr(ADAPTER *a, byte e_no); #if defined(DIVA_ISTREAM) struct _diva_xdi_stream_interface; -void diva_xdi_provide_istream_info (ADAPTER* a, - struct _diva_xdi_stream_interface* pI); -void pr_stream (ADAPTER * a); -int diva_istream_write (void* context, - int Id, - void* data, - int length, - int final, - byte usr1, - byte usr2); -int diva_istream_read (void* context, - int Id, - void* data, - int max_length, - int* final, - byte* usr1, - byte* usr2); +void diva_xdi_provide_istream_info(ADAPTER *a, + struct _diva_xdi_stream_interface *pI); +void pr_stream(ADAPTER *a); +int diva_istream_write(void *context, + int Id, + void *data, + int length, + int final, + byte usr1, + byte usr2); +int diva_istream_read(void *context, + int Id, + void *data, + int max_length, + int *final, + byte *usr1, + byte *usr2); #if defined(DIVA_IDI_RX_DMA) #include "diva_dma.h" #endif diff --git a/drivers/isdn/hardware/eicon/di_dbg.h b/drivers/isdn/hardware/eicon/di_dbg.h index d576ff31d44..1380b60e526 100644 --- a/drivers/isdn/hardware/eicon/di_dbg.h +++ b/drivers/isdn/hardware/eicon/di_dbg.h @@ -1,34 +1,34 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_DI_DBG_INC__ #define __DIVA_DI_DBG_INC__ -#if !defined (dtrc) +#if !defined(dtrc) #define dtrc(a) #endif -#if !defined (dbug) +#if !defined(dbug) #define dbug(a) #endif #if !defined USE_EXTENDED_DEBUGS diff --git a/drivers/isdn/hardware/eicon/di_defs.h b/drivers/isdn/hardware/eicon/di_defs.h index 4c2f61267df..a5094d22108 100644 --- a/drivers/isdn/hardware/eicon/di_defs.h +++ b/drivers/isdn/hardware/eicon/di_defs.h @@ -1,31 +1,31 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -#ifndef _DI_DEFS_ +#ifndef _DI_DEFS_ #define _DI_DEFS_ - /* typedefs for our data structures */ +/* typedefs for our data structures */ typedef struct get_name_s GET_NAME; /* The entity_s structure is used to pass all parameters between application and IDI */ @@ -38,72 +38,72 @@ typedef struct get_para_s GET_PARA; #define IDI_CALL_ENTITY_T /* typedef void ( * IDI_CALL)(ENTITY *); */ /* -------------------------------------------------------- - IDI_CALL + IDI_CALL -------------------------------------------------------- */ -typedef void (IDI_CALL_LINK_T * IDI_CALL)(ENTITY IDI_CALL_ENTITY_T *); +typedef void (IDI_CALL_LINK_T *IDI_CALL)(ENTITY IDI_CALL_ENTITY_T *); typedef struct { - word length; /* length of data/parameter field */ - byte P[270]; /* data/parameter field */ + word length; /* length of data/parameter field */ + byte P[270]; /* data/parameter field */ } DBUFFER; struct get_name_s { - word command; /* command = 0x0100 */ - byte name[BOARD_NAME_LENGTH]; + word command; /* command = 0x0100 */ + byte name[BOARD_NAME_LENGTH]; }; struct postcall_s { - word command; /* command = 0x0300 */ - word dummy; /* not used */ - void ( * callback)(void *); /* call back */ - void *context; /* context pointer */ + word command; /* command = 0x0300 */ + word dummy; /* not used */ + void (*callback)(void *); /* call back */ + void *context; /* context pointer */ }; #define REQ_PARA 0x0600 /* request command line parameters */ #define REQ_PARA_LEN 1 /* number of data bytes */ #define L1_STARTUP_DOWN_POS 0 /* '-y' command line parameter in......*/ #define L1_STARTUP_DOWN_MSK 0x01 /* first byte position (index 0) with value 0x01 */ struct get_para_s { - word command; /* command = 0x0600 */ - byte len; /* max length of para field in bytes */ - byte para[REQ_PARA_LEN]; /* parameter field */ + word command; /* command = 0x0600 */ + byte len; /* max length of para field in bytes */ + byte para[REQ_PARA_LEN]; /* parameter field */ }; struct buffers_s { - word PLength; - byte * P; + word PLength; + byte *P; }; struct entity_s { - byte Req; /* pending request */ - byte Rc; /* return code received */ - byte Ind; /* indication received */ - byte ReqCh; /* channel of current Req */ - byte RcCh; /* channel of current Rc */ - byte IndCh; /* channel of current Ind */ - byte Id; /* ID used by this entity */ - byte GlobalId; /* reserved field */ - byte XNum; /* number of X-buffers */ - byte RNum; /* number of R-buffers */ - BUFFERS * X; /* pointer to X-buffer list */ - BUFFERS * R; /* pointer to R-buffer list */ - word RLength; /* length of current R-data */ - DBUFFER * RBuffer; /* buffer of current R-data */ - byte RNR; /* receive not ready flag */ - byte complete; /* receive complete status */ - IDI_CALL callback; - word user[2]; - /* fields used by the driver internally */ - byte No; /* entity number */ - byte reserved2; /* reserved field */ - byte More; /* R/X More flags */ - byte MInd; /* MDATA coding for this ID */ - byte XCurrent; /* current transmit buffer */ - byte RCurrent; /* current receive buffer */ - word XOffset; /* offset in x-buffer */ - word ROffset; /* offset in r-buffer */ + byte Req; /* pending request */ + byte Rc; /* return code received */ + byte Ind; /* indication received */ + byte ReqCh; /* channel of current Req */ + byte RcCh; /* channel of current Rc */ + byte IndCh; /* channel of current Ind */ + byte Id; /* ID used by this entity */ + byte GlobalId; /* reserved field */ + byte XNum; /* number of X-buffers */ + byte RNum; /* number of R-buffers */ + BUFFERS *X; /* pointer to X-buffer list */ + BUFFERS *R; /* pointer to R-buffer list */ + word RLength; /* length of current R-data */ + DBUFFER *RBuffer; /* buffer of current R-data */ + byte RNR; /* receive not ready flag */ + byte complete; /* receive complete status */ + IDI_CALL callback; + word user[2]; + /* fields used by the driver internally */ + byte No; /* entity number */ + byte reserved2; /* reserved field */ + byte More; /* R/X More flags */ + byte MInd; /* MDATA coding for this ID */ + byte XCurrent; /* current transmit buffer */ + byte RCurrent; /* current receive buffer */ + word XOffset; /* offset in x-buffer */ + word ROffset; /* offset in r-buffer */ }; typedef struct { - byte type; - byte channels; - word features; - IDI_CALL request; + byte type; + byte channels; + word features; + IDI_CALL request; } DESCRIPTOR; - /* descriptor type field coding */ +/* descriptor type field coding */ #define IDI_ADAPTER_S 1 #define IDI_ADAPTER_PR 2 #define IDI_ADAPTER_DIVA 3 @@ -113,7 +113,7 @@ typedef struct { #define IDI_DADAPTER 0xfd #define IDI_DIDDPNP 0xfe #define IDI_DIMAINT 0xff - /* Hardware IDs ISA PNP */ +/* Hardware IDs ISA PNP */ #define HW_ID_DIVA_PRO 3 /* same as IDI_ADAPTER_DIVA */ #define HW_ID_MAESTRA 4 /* same as IDI_ADAPTER_MAESTRA */ #define HW_ID_PICCOLA 5 @@ -123,7 +123,7 @@ typedef struct { #define HW_ID_DIVA20_U 9 #define HW_ID_DIVA30 10 #define HW_ID_DIVA30_U 11 - /* Hardware IDs PCI */ +/* Hardware IDs PCI */ #define HW_ID_EICON_PCI 0x1133 #define HW_ID_SIEMENS_PCI 0x8001 /* unused SubVendor ID for Siemens Cornet-N cards */ #define HW_ID_PROTTYPE_CORNETN 0x0014 /* SubDevice ID for Siemens Cornet-N cards */ @@ -153,16 +153,16 @@ typedef struct { #define HW_ID_DSRV_VOICE_P30M_V2_PCI 0xe019 #define HW_ID_DSRV_B2F_PCI 0xe01a #define HW_ID_DSRV_VOICE_B2M_V2_PCI 0xe01b - /* Hardware IDs USB */ +/* Hardware IDs USB */ #define EICON_USB_VENDOR_ID 0x071D #define HW_ID_DIVA_USB_REV1 0x1000 #define HW_ID_DIVA_USB_REV2 0x1003 #define HW_ID_TELEDAT_SURF_USB_REV2 0x1004 #define HW_ID_TELEDAT_SURF_USB_REV1 0x2000 /* -------------------------------------------------------------------------- - Adapter array change notification framework - -------------------------------------------------------------------------- */ -typedef void (IDI_CALL_LINK_T* didd_adapter_change_callback_t)( void IDI_CALL_ENTITY_T * context, DESCRIPTOR* adapter, int removal); + Adapter array change notification framework + -------------------------------------------------------------------------- */ +typedef void (IDI_CALL_LINK_T *didd_adapter_change_callback_t)(void IDI_CALL_ENTITY_T *context, DESCRIPTOR *adapter, int removal); /* -------------------------------------------------------------------------- */ #define DI_VOICE 0x0 /* obsolete define */ #define DI_FAX3 0x1 @@ -177,5 +177,5 @@ typedef void (IDI_CALL_LINK_T* didd_adapter_change_callback_t)( void IDI_CAL #define DI_EXTD_FAX 0x0200 /* Extended FAX (ECM, 2D, T.6, Polling) */ #define DI_AT_PARSER 0x0400 /* Build-in AT Parser in the L2 */ #define DI_VOICE_OVER_IP 0x0800 /* Voice over IP support */ -typedef void (IDI_CALL_LINK_T* _IDI_CALL)(void*, ENTITY*); -#endif +typedef void (IDI_CALL_LINK_T *_IDI_CALL)(void *, ENTITY *); +#endif diff --git a/drivers/isdn/hardware/eicon/did_vers.h b/drivers/isdn/hardware/eicon/did_vers.h index 538c590fdf4..fa8db824923 100644 --- a/drivers/isdn/hardware/eicon/did_vers.h +++ b/drivers/isdn/hardware/eicon/did_vers.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -static char diva_didd_common_code_build[] = "102-51"; +static char diva_didd_common_code_build[] = "102-51"; diff --git a/drivers/isdn/hardware/eicon/diddfunc.c b/drivers/isdn/hardware/eicon/diddfunc.c index 3029234178d..b0b23ed8b37 100644 --- a/drivers/isdn/hardware/eicon/diddfunc.c +++ b/drivers/isdn/hardware/eicon/diddfunc.c @@ -1,12 +1,12 @@ /* $Id: diddfunc.c,v 1.14.6.2 2004/08/28 20:03:53 armin Exp $ * * DIDD Interface module for Eicon active cards. - * - * Functions are in dadapter.c - * - * Copyright 2002-2003 by Armin Schindler (mac@melware.de) + * + * Functions are in dadapter.c + * + * Copyright 2002-2003 by Armin Schindler (mac@melware.de) * Copyright 2002-2003 Cytronics & Melware (info@melware.de) - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. */ @@ -28,12 +28,12 @@ static DESCRIPTOR _DAdapter; /* * didd callback function */ -static void *didd_callback(void *context, DESCRIPTOR * adapter, +static void *didd_callback(void *context, DESCRIPTOR *adapter, int removal) { if (adapter->type == IDI_DADAPTER) { DBG_ERR(("Notification about IDI_DADAPTER change ! Oops.")) - return (NULL); + return (NULL); } else if (adapter->type == IDI_DIMAINT) { if (removal) { DbgDeregister(); @@ -47,7 +47,7 @@ static void *didd_callback(void *context, DESCRIPTOR * adapter, /* * connect to didd */ -static int DIVA_INIT_FUNCTION connect_didd(void) +static int __init connect_didd(void) { int x = 0; int dadapter = 0; @@ -62,10 +62,10 @@ static int DIVA_INIT_FUNCTION connect_didd(void) 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; + 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); + _DAdapter.request((ENTITY *)&req); if (req.didd_notify.e.Rc != 0xff) return (0); notify_handle = req.didd_notify.info.handle; @@ -79,26 +79,26 @@ static int DIVA_INIT_FUNCTION connect_didd(void) /* * disconnect from didd */ -static void DIVA_EXIT_FUNCTION disconnect_didd(void) +static void __exit disconnect_didd(void) { IDI_SYNC_REQ req; 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); + _DAdapter.request((ENTITY *)&req); } /* * init */ -int DIVA_INIT_FUNCTION diddfunc_init(void) +int __init diddfunc_init(void) { diva_didd_load_time_init(); if (!connect_didd()) { DBG_ERR(("init: failed to connect to DIDD.")) - diva_didd_load_time_finit(); + diva_didd_load_time_finit(); return (0); } return (1); @@ -107,7 +107,7 @@ int DIVA_INIT_FUNCTION diddfunc_init(void) /* * finit */ -void DIVA_EXIT_FUNCTION diddfunc_finit(void) +void __exit diddfunc_finit(void) { DbgDeregister(); disconnect_didd(); diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c index 8ab8027f33c..d91dd580e97 100644 --- a/drivers/isdn/hardware/eicon/diva.c +++ b/drivers/isdn/hardware/eicon/diva.c @@ -28,12 +28,12 @@ PISDN_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); +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) ; } +#define DivaIdiReqFunc(N) \ + static void DivaIdiRequest##N(ENTITY *e) \ + { if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); } /* ** Create own 32 Adapters @@ -71,8 +71,6 @@ DivaIdiReqFunc(29) DivaIdiReqFunc(30) DivaIdiReqFunc(31) -struct pt_regs; - /* ** LOCALS */ @@ -93,44 +91,44 @@ typedef struct _diva_supported_cards_info { static diva_supported_cards_info_t divas_supported_cards[] = { #ifdef CONFIG_ISDN_DIVAS_PRIPCI /* - PRI Cards - */ + PRI Cards + */ {CARDTYPE_DIVASRV_P_30M_PCI, diva_pri_init_card}, /* - PRI Rev.2 Cards - */ + PRI Rev.2 Cards + */ {CARDTYPE_DIVASRV_P_30M_V2_PCI, diva_pri_init_card}, /* - PRI Rev.2 VoIP Cards - */ + 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 - */ + 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 - */ + 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 - */ + 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 - */ + BRI + */ {CARDTYPE_MAESTRA_PCI, diva_bri_init_card}, #endif /* - EOL - */ + EOL + */ {-1} }; @@ -152,18 +150,18 @@ static int diva_find_free_adapters(int base, int nr) return (0); } -static diva_os_xdi_adapter_t *diva_q_get_next(struct list_head * what) +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); + return (a); } /* -------------------------------------------------------------------------- - Add card to the card list + Add card to the card list -------------------------------------------------------------------------- */ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal) { @@ -205,7 +203,7 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal) [CardOrdinal].Name, pdiva->controller)) - diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card"); + 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); @@ -216,11 +214,11 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal) 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 */ + 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; + break; } } @@ -232,10 +230,10 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal) diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card"); /* - Not able to add adapter - remove it and return error - */ + Not able to add adapter - remove it and return error + */ DBG_ERR(("can not alloc request array")) - diva_driver_remove_card(pdiva); + diva_driver_remove_card(pdiva); return NULL; } @@ -245,7 +243,7 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal) } /* -------------------------------------------------------------------------- - Called on driver load, MAIN, main, DriverEntry + Called on driver load, MAIN, main, DriverEntry -------------------------------------------------------------------------- */ int divasa_xdi_driver_entry(void) { @@ -257,7 +255,7 @@ int divasa_xdi_driver_entry(void) } /* -------------------------------------------------------------------------- - Remove adapter from list + Remove adapter from list -------------------------------------------------------------------------- */ static diva_os_xdi_adapter_t *get_and_remove_from_queue(void) { @@ -276,7 +274,7 @@ static diva_os_xdi_adapter_t *get_and_remove_from_queue(void) } /* -------------------------------------------------------------------------- - Remove card from the card list + Remove card from the card list -------------------------------------------------------------------------- */ void diva_driver_remove_card(void *pdiva) { @@ -320,7 +318,7 @@ void diva_driver_remove_card(void *pdiva) } /* -------------------------------------------------------------------------- - Create diva PCI adapter and init internal adapter structures + Create diva PCI adapter and init internal adapter structures -------------------------------------------------------------------------- */ static void *divas_create_pci_card(int handle, void *pci_dev_handle) { @@ -330,10 +328,10 @@ static void *divas_create_pci_card(int handle, void *pci_dev_handle) DBG_LOG(("found %d-%s", pI->CardOrdinal, CardProperties[pI->CardOrdinal].Name)) - if (!(a = (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) { - DBG_ERR(("A: can't alloc adapter")); - return NULL; - } + if (!(a = (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) { + DBG_ERR(("A: can't alloc adapter")); + return NULL; + } memset(a, 0x00, sizeof(*a)); @@ -346,9 +344,9 @@ static void *divas_create_pci_card(int handle, void *pci_dev_handle) a->resources.pci.hdev = pci_dev_handle; /* - Add master adapter first, so slave adapters will receive higher - numbers as master adapter - */ + Add master adapter first, so slave adapters will receive higher + numbers as master adapter + */ diva_os_enter_spin_lock(&adapter_lock, &old_irql, "found_pci_card"); list_add_tail(&a->link, &adapter_queue); diva_os_leave_spin_lock(&adapter_lock, &old_irql, "found_pci_card"); @@ -366,7 +364,7 @@ static void *divas_create_pci_card(int handle, void *pci_dev_handle) } /* -------------------------------------------------------------------------- - Called on driver unload FINIT, finit, Unload + Called on driver unload FINIT, finit, Unload -------------------------------------------------------------------------- */ void divasa_xdi_driver_unload(void) { @@ -400,11 +398,11 @@ void *diva_xdi_open_adapter(void *os_handle, const void __user *src, if (length < sizeof(diva_xdi_um_cfg_cmd_t)) { DBG_ERR(("A: A(?) open, msg too small (%d < %d)", length, sizeof(diva_xdi_um_cfg_cmd_t))) - return NULL; + return NULL; } if ((*cp_fn) (os_handle, &msg, src, sizeof(msg)) <= 0) { DBG_ERR(("A: A(?) open, write error")) - return NULL; + return NULL; } diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter"); list_for_each(tmp, &adapter_queue) { @@ -417,7 +415,7 @@ void *diva_xdi_open_adapter(void *os_handle, const void __user *src, if (!a) { DBG_ERR(("A: A(%d) open, adapter not found", msg.adapter)) - } + } return (a); } @@ -445,19 +443,19 @@ diva_xdi_write(void *adapter, void *os_handle, const void __user *src, if (a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY) { DBG_ERR(("A: A(%d) write, mbox busy", a->controller)) - return (-1); + return (-1); } if (length < sizeof(diva_xdi_um_cfg_cmd_t)) { DBG_ERR(("A: A(%d) write, message too small (%d < %d)", a->controller, length, sizeof(diva_xdi_um_cfg_cmd_t))) - return (-3); + return (-3); } if (!(data = diva_os_malloc(0, length))) { DBG_ERR(("A: A(%d) write, ENOMEM", a->controller)) - return (-2); + return (-2); } length = (*cp_fn) (os_handle, data, src, length); @@ -469,7 +467,7 @@ diva_xdi_write(void *adapter, void *os_handle, const void __user *src, } else { DBG_ERR(("A: A(%d) write error (%d)", a->controller, length)) - } + } diva_os_free(0, data); @@ -488,23 +486,23 @@ diva_xdi_read(void *adapter, void *os_handle, void __user *dst, if (!(a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY)) { DBG_ERR(("A: A(%d) rx mbox empty", a->controller)) - return (-1); + return (-1); } if (!a->xdi_mbox.data) { a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY; DBG_ERR(("A: A(%d) rx ENOMEM", a->controller)) - return (-2); + return (-2); } if (max_length < a->xdi_mbox.data_length) { DBG_ERR(("A: A(%d) rx buffer too short(%d < %d)", a->controller, max_length, a->xdi_mbox.data_length)) - return (-3); + return (-3); } ret = (*cp_fn) (os_handle, dst, a->xdi_mbox.data, - a->xdi_mbox.data_length); + a->xdi_mbox.data_length); if (ret > 0) { diva_os_free(0, a->xdi_mbox.data); a->xdi_mbox.data = NULL; @@ -515,14 +513,13 @@ diva_xdi_read(void *adapter, void *os_handle, void __user *dst, } -irqreturn_t diva_os_irq_wrapper(int irq, void *context, struct pt_regs *regs) +irqreturn_t diva_os_irq_wrapper(int irq, void *context) { - diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) context; + diva_os_xdi_adapter_t *a = context; diva_xdi_clear_interrupts_proc_t clear_int_proc; - if (!a || !a->xdi_adapter.diva_isr_handler) { + if (!a || !a->xdi_adapter.diva_isr_handler) return IRQ_NONE; - } if ((clear_int_proc = a->clear_interrupts_proc)) { (*clear_int_proc) (a); @@ -580,33 +577,33 @@ void diva_xdi_display_adapter_features(int card) features = IoAdapters[card]->Properties.Features; DBG_LOG(("FEATURES FOR ADAPTER: %d", card + 1)) - DBG_LOG((" DI_FAX3 : %s", - (features & DI_FAX3) ? "Y" : "N")) - DBG_LOG((" DI_MODEM : %s", - (features & DI_MODEM) ? "Y" : "N")) - DBG_LOG((" DI_POST : %s", - (features & DI_POST) ? "Y" : "N")) - DBG_LOG((" DI_V110 : %s", - (features & DI_V110) ? "Y" : "N")) - DBG_LOG((" DI_V120 : %s", - (features & DI_V120) ? "Y" : "N")) - DBG_LOG((" DI_POTS : %s", - (features & DI_POTS) ? "Y" : "N")) - DBG_LOG((" DI_CODEC : %s", - (features & DI_CODEC) ? "Y" : "N")) - DBG_LOG((" DI_MANAGE : %s", - (features & DI_MANAGE) ? "Y" : "N")) - DBG_LOG((" DI_V_42 : %s", - (features & DI_V_42) ? "Y" : "N")) - DBG_LOG((" DI_EXTD_FAX : %s", - (features & DI_EXTD_FAX) ? "Y" : "N")) - DBG_LOG((" DI_AT_PARSER : %s", - (features & DI_AT_PARSER) ? "Y" : "N")) - DBG_LOG((" DI_VOICE_OVER_IP : %s", - (features & DI_VOICE_OVER_IP) ? "Y" : "N")) -} + DBG_LOG((" DI_FAX3 : %s", + (features & DI_FAX3) ? "Y" : "N")) + DBG_LOG((" DI_MODEM : %s", + (features & DI_MODEM) ? "Y" : "N")) + DBG_LOG((" DI_POST : %s", + (features & DI_POST) ? "Y" : "N")) + DBG_LOG((" DI_V110 : %s", + (features & DI_V110) ? "Y" : "N")) + DBG_LOG((" DI_V120 : %s", + (features & DI_V120) ? "Y" : "N")) + DBG_LOG((" DI_POTS : %s", + (features & DI_POTS) ? "Y" : "N")) + DBG_LOG((" DI_CODEC : %s", + (features & DI_CODEC) ? "Y" : "N")) + DBG_LOG((" DI_MANAGE : %s", + (features & DI_MANAGE) ? "Y" : "N")) + DBG_LOG((" DI_V_42 : %s", + (features & DI_V_42) ? "Y" : "N")) + DBG_LOG((" DI_EXTD_FAX : %s", + (features & DI_EXTD_FAX) ? "Y" : "N")) + DBG_LOG((" DI_AT_PARSER : %s", + (features & DI_AT_PARSER) ? "Y" : "N")) + DBG_LOG((" DI_VOICE_OVER_IP : %s", + (features & DI_VOICE_OVER_IP) ? "Y" : "N")) + } -void diva_add_slave_adapter(diva_os_xdi_adapter_t * a) +void diva_add_slave_adapter(diva_os_xdi_adapter_t *a) { diva_os_spin_lock_magic_t old_irql; @@ -615,7 +612,7 @@ void diva_add_slave_adapter(diva_os_xdi_adapter_t * a) diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add_slave"); } -int diva_card_read_xlog(diva_os_xdi_adapter_t * a) +int diva_card_read_xlog(diva_os_xdi_adapter_t *a) { diva_get_xlog_t *req; byte *data; diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c index 27204f4b111..fab6ccfb00d 100644 --- a/drivers/isdn/hardware/eicon/diva_didd.c +++ b/drivers/isdn/hardware/eicon/diva_didd.c @@ -1,21 +1,22 @@ /* $Id: diva_didd.c,v 1.13.6.4 2005/02/11 19:40:25 armin Exp $ * * DIDD Interface module for Eicon active cards. - * - * Functions are in dadapter.c - * - * Copyright 2002-2003 by Armin Schindler (mac@melware.de) + * + * Functions are in dadapter.c + * + * Copyright 2002-2003 by Armin Schindler (mac@melware.de) * Copyright 2002-2003 Cytronics & Melware (info@melware.de) - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> +#include <net/net_namespace.h> #include "platform.h" #include "di_defs.h" @@ -26,7 +27,7 @@ static char *main_revision = "$Revision: 1.13.6.4 $"; static char *DRIVERNAME = - "Eicon DIVA - DIDD table (http://www.melware.net)"; + "Eicon DIVA - DIDD table (http://www.melware.net)"; static char *DRIVERLNAME = "divadidd"; char *DRIVERRELEASE_DIDD = "2.0"; @@ -62,51 +63,53 @@ static char *getrev(const char *revision) return rev; } -static int -proc_read(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int divadidd_proc_show(struct seq_file *m, void *v) { - int len = 0; char tmprev[32]; strcpy(tmprev, main_revision); - len += sprintf(page + len, "%s\n", DRIVERNAME); - len += sprintf(page + len, "name : %s\n", DRIVERLNAME); - len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_DIDD); - len += sprintf(page + len, "build : %s(%s)\n", - diva_didd_common_code_build, DIVA_BUILD); - len += sprintf(page + len, "revision : %s\n", getrev(tmprev)); - - if (off + count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len - off) ? count : len - off); + seq_printf(m, "%s\n", DRIVERNAME); + seq_printf(m, "name : %s\n", DRIVERLNAME); + seq_printf(m, "release : %s\n", DRIVERRELEASE_DIDD); + seq_printf(m, "build : %s(%s)\n", + diva_didd_common_code_build, DIVA_BUILD); + seq_printf(m, "revision : %s\n", getrev(tmprev)); + + return 0; } -static int DIVA_INIT_FUNCTION create_proc(void) +static int divadidd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, divadidd_proc_show, NULL); +} + +static const struct file_operations divadidd_proc_fops = { + .owner = THIS_MODULE, + .open = divadidd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init create_proc(void) { - proc_net_eicon = proc_mkdir("net/eicon", NULL); + proc_net_eicon = proc_mkdir("eicon", init_net.proc_net); if (proc_net_eicon) { - if ((proc_didd = - create_proc_entry(DRIVERLNAME, S_IFREG | S_IRUGO, - proc_net_eicon))) { - proc_didd->read_proc = proc_read; - } + proc_didd = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon, + &divadidd_proc_fops); return (1); } return (0); } -static void DIVA_EXIT_FUNCTION remove_proc(void) +static void remove_proc(void) { remove_proc_entry(DRIVERLNAME, proc_net_eicon); - remove_proc_entry("net/eicon", NULL); + remove_proc_entry("eicon", init_net.proc_net); } -static int DIVA_INIT_FUNCTION divadidd_init(void) +static int __init divadidd_init(void) { char tmprev[32]; int ret = 0; @@ -134,11 +137,11 @@ static int DIVA_INIT_FUNCTION divadidd_init(void) goto out; } - out: +out: return (ret); } -static void DIVA_EXIT_FUNCTION divadidd_exit(void) +static void __exit divadidd_exit(void) { diddfunc_finit(); remove_proc(); diff --git a/drivers/isdn/hardware/eicon/diva_dma.c b/drivers/isdn/hardware/eicon/diva_dma.c index f53a7407605..217b6aa9f61 100644 --- a/drivers/isdn/hardware/eicon/diva_dma.c +++ b/drivers/isdn/hardware/eicon/diva_dma.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -28,67 +28,67 @@ /* Every entry has length of PAGE_SIZE and represents one single physical page - */ +*/ struct _diva_dma_map_entry { - int busy; - dword phys_bus_addr; /* 32bit address as seen by the card */ - void* local_ram_addr; /* local address as seen by the host */ - void* addr_handle; /* handle uset to free allocated memory */ + int busy; + dword phys_bus_addr; /* 32bit address as seen by the card */ + void *local_ram_addr; /* local address as seen by the host */ + void *addr_handle; /* handle uset to free allocated memory */ }; /* Create local mapping structure and init it to default state - */ -struct _diva_dma_map_entry* diva_alloc_dma_map (void* os_context, int nentries) { - diva_dma_map_entry_t* pmap = diva_os_malloc(0, sizeof(*pmap)*(nentries+1)); - if (pmap) - memset (pmap, 0, sizeof(*pmap)*(nentries+1)); - return pmap; +*/ +struct _diva_dma_map_entry *diva_alloc_dma_map(void *os_context, int nentries) { + diva_dma_map_entry_t *pmap = diva_os_malloc(0, sizeof(*pmap) * (nentries + 1)); + if (pmap) + memset(pmap, 0, sizeof(*pmap) * (nentries + 1)); + return pmap; } /* Free local map (context should be freed before) if any - */ -void diva_free_dma_mapping (struct _diva_dma_map_entry* pmap) { - if (pmap) { - diva_os_free (0, pmap); - } +*/ +void diva_free_dma_mapping(struct _diva_dma_map_entry *pmap) { + if (pmap) { + diva_os_free(0, pmap); + } } /* Set information saved on the map entry - */ -void diva_init_dma_map_entry (struct _diva_dma_map_entry* pmap, - int nr, void* virt, dword phys, - void* addr_handle) { - pmap[nr].phys_bus_addr = phys; - pmap[nr].local_ram_addr = virt; - pmap[nr].addr_handle = addr_handle; +*/ +void diva_init_dma_map_entry(struct _diva_dma_map_entry *pmap, + int nr, void *virt, dword phys, + void *addr_handle) { + pmap[nr].phys_bus_addr = phys; + pmap[nr].local_ram_addr = virt; + pmap[nr].addr_handle = addr_handle; } /* Allocate one single entry in the map - */ -int diva_alloc_dma_map_entry (struct _diva_dma_map_entry* pmap) { - int i; - for (i = 0; (pmap && pmap[i].local_ram_addr); i++) { - if (!pmap[i].busy) { - pmap[i].busy = 1; - return (i); - } - } - return (-1); +*/ +int diva_alloc_dma_map_entry(struct _diva_dma_map_entry *pmap) { + int i; + for (i = 0; (pmap && pmap[i].local_ram_addr); i++) { + if (!pmap[i].busy) { + pmap[i].busy = 1; + return (i); + } + } + return (-1); } /* Free one single entry in the map - */ -void diva_free_dma_map_entry (struct _diva_dma_map_entry* pmap, int nr) { - pmap[nr].busy = 0; +*/ +void diva_free_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr) { + pmap[nr].busy = 0; } /* Get information saved on the map entry - */ -void diva_get_dma_map_entry (struct _diva_dma_map_entry* pmap, int nr, - void** pvirt, dword* pphys) { - *pphys = pmap[nr].phys_bus_addr; - *pvirt = pmap[nr].local_ram_addr; +*/ +void diva_get_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr, + void **pvirt, dword *pphys) { + *pphys = pmap[nr].phys_bus_addr; + *pvirt = pmap[nr].local_ram_addr; } -void* diva_get_entry_handle (struct _diva_dma_map_entry* pmap, int nr) { - return (pmap[nr].addr_handle); +void *diva_get_entry_handle(struct _diva_dma_map_entry *pmap, int nr) { + return (pmap[nr].addr_handle); } diff --git a/drivers/isdn/hardware/eicon/diva_dma.h b/drivers/isdn/hardware/eicon/diva_dma.h index dff80724cdb..d32c91be562 100644 --- a/drivers/isdn/hardware/eicon/diva_dma.h +++ b/drivers/isdn/hardware/eicon/diva_dma.h @@ -1,48 +1,48 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_DMA_MAPPING_IFC_H__ #define __DIVA_DMA_MAPPING_IFC_H__ typedef struct _diva_dma_map_entry diva_dma_map_entry_t; -struct _diva_dma_map_entry* diva_alloc_dma_map (void* os_context, int nentries); -void diva_init_dma_map_entry (struct _diva_dma_map_entry* pmap, - int nr, void* virt, dword phys, - void* addr_handle); -int diva_alloc_dma_map_entry (struct _diva_dma_map_entry* pmap); -void diva_free_dma_map_entry (struct _diva_dma_map_entry* pmap, int entry); -void diva_get_dma_map_entry (struct _diva_dma_map_entry* pmap, int nr, - void** pvirt, dword* pphys); -void diva_free_dma_mapping (struct _diva_dma_map_entry* pmap); +struct _diva_dma_map_entry *diva_alloc_dma_map(void *os_context, int nentries); +void diva_init_dma_map_entry(struct _diva_dma_map_entry *pmap, + int nr, void *virt, dword phys, + void *addr_handle); +int diva_alloc_dma_map_entry(struct _diva_dma_map_entry *pmap); +void diva_free_dma_map_entry(struct _diva_dma_map_entry *pmap, int entry); +void diva_get_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr, + void **pvirt, dword *pphys); +void diva_free_dma_mapping(struct _diva_dma_map_entry *pmap); /* Functionality to be implemented by OS wrapper and running in process context - */ -void diva_init_dma_map (void* hdev, - struct _diva_dma_map_entry** ppmap, - int nentries); -void diva_free_dma_map (void* hdev, - struct _diva_dma_map_entry* pmap); -void* diva_get_entry_handle (struct _diva_dma_map_entry* pmap, int nr); +*/ +void diva_init_dma_map(void *hdev, + struct _diva_dma_map_entry **ppmap, + int nentries); +void diva_free_dma_map(void *hdev, + struct _diva_dma_map_entry *pmap); +void *diva_get_entry_handle(struct _diva_dma_map_entry *pmap, int nr); #endif diff --git a/drivers/isdn/hardware/eicon/diva_pci.h b/drivers/isdn/hardware/eicon/diva_pci.h index cc0d5102723..bb4b562050f 100644 --- a/drivers/isdn/hardware/eicon/diva_pci.h +++ b/drivers/isdn/hardware/eicon/diva_pci.h @@ -4,9 +4,9 @@ #define __DIVA_PCI_INTERFACE_H__ void __iomem *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a, - int id, - unsigned long bar, - unsigned long area_length); + int id, + unsigned long bar, + unsigned long area_length); void divasa_unmap_pci_bar(void __iomem *bar); unsigned long divasa_get_pci_irq(unsigned char bus, unsigned char func, void *pci_dev_handle); diff --git a/drivers/isdn/hardware/eicon/divacapi.h b/drivers/isdn/hardware/eicon/divacapi.h index 9f5b68037a2..a315a2914d7 100644 --- a/drivers/isdn/hardware/eicon/divacapi.h +++ b/drivers/isdn/hardware/eicon/divacapi.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -29,8 +29,8 @@ - - + + @@ -82,7 +82,7 @@ #define CODEC_PERMANENT 0x02 #define ADV_VOICE 0x03 #define MAX_CIP_TYPES 5 /* kind of CIP types for group optimization */ -#define C_IND_MASK_DWORDS ((MAX_APPL+32) >> 5) +#define C_IND_MASK_DWORDS ((MAX_APPL + 32) >> 5) #define FAX_CONNECT_INFO_BUFFER_SIZE 256 @@ -116,289 +116,289 @@ typedef struct msn_config_max_s MSN_CONFIG_MAX; typedef struct msn_ld_s MSN_LD; struct manufacturer_profile_s { - dword private_options; - dword rtp_primary_payloads; - dword rtp_additional_payloads; + dword private_options; + dword rtp_primary_payloads; + dword rtp_additional_payloads; }; struct fax_ncpi_s { - word options; - word format; + word options; + word format; }; struct msn_config_s { - byte msn[MAX_CPN_MASK_SIZE]; + byte msn[MAX_CPN_MASK_SIZE]; }; struct msn_config_max_s { - MSN_CONFIG msn_conf[MAX_MSN_CONFIG]; + MSN_CONFIG msn_conf[MAX_MSN_CONFIG]; }; struct msn_ld_s { - dword low; - dword high; + dword low; + dword high; }; struct api_parse_s { - word length; - byte * info; + word length; + byte *info; }; struct api_save_s { - API_PARSE parms[MAX_MSG_PARMS+1]; - byte info[MAX_MSG_SIZE]; + API_PARSE parms[MAX_MSG_PARMS + 1]; + byte info[MAX_MSG_SIZE]; }; struct _DATA_B3_DESC { - word Handle; - word Number; - word Flags; - word Length; - void * P; + word Handle; + word Number; + word Flags; + word Length; + void *P; }; struct _DATA_ACK_DESC { - word Handle; - word Number; + word Handle; + word Number; }; -typedef void (* t_std_internal_command)(dword Id, PLCI *plci, byte Rc); +typedef void (*t_std_internal_command)(dword Id, PLCI *plci, byte Rc); /************************************************************************/ /* Don't forget to adapt dos.asm after changing the _APPL structure!!!! */ struct _APPL { - word Id; - word NullCREnable; - word CDEnable; - dword S_Handle; + word Id; + word NullCREnable; + word CDEnable; + dword S_Handle; - LIST_ENTRY s_function; - dword s_context; - word s_count; - APPL * s_next; - byte * xbuffer_used; - void ** xbuffer_internal; - void ** xbuffer_ptr; + LIST_ENTRY s_function; + dword s_context; + word s_count; + APPL *s_next; + byte *xbuffer_used; + void **xbuffer_internal; + void **xbuffer_ptr; - byte * queue; - word queue_size; - word queue_free; - word queue_read; - word queue_write; - word queue_signal; - byte msg_lost; - byte appl_flags; - word Number; + byte *queue; + word queue_size; + word queue_free; + word queue_read; + word queue_write; + word queue_signal; + byte msg_lost; + byte appl_flags; + word Number; - word MaxBuffer; - byte MaxNCCI; - byte MaxNCCIData; - word MaxDataLength; - word NCCIDataFlowCtrlTimer; - byte * ReceiveBuffer; - word * DataNCCI; - word * DataFlags; + word MaxBuffer; + byte MaxNCCI; + byte MaxNCCIData; + word MaxDataLength; + word NCCIDataFlowCtrlTimer; + byte *ReceiveBuffer; + word *DataNCCI; + word *DataFlags; }; struct _PLCI { - ENTITY Sig; - ENTITY NL; - word RNum; - word RFlags; - BUFFERS RData[2]; - BUFFERS XData[1]; - BUFFERS NData[2]; - - DIVA_CAPI_ADAPTER *adapter; - APPL *appl; - PLCI *relatedPTYPLCI; - byte Id; - byte State; - byte sig_req; - byte nl_req; - byte SuppState; - byte channels; - byte tel; - byte B1_resource; - byte B2_prot; - byte B3_prot; - - word command; - word m_command; - word internal_command; - word number; - word req_in_start; - word req_in; - word req_out; - word msg_in_write_pos; - word msg_in_read_pos; - word msg_in_wrap_pos; - - void * data_sent_ptr; - byte data_sent; - byte send_disc; - byte sig_global_req; - byte sig_remove_id; - byte nl_global_req; - byte nl_remove_id; - byte b_channel; - byte adv_nl; - byte manufacturer; - byte call_dir; - byte hook_state; - byte spoofed_msg; - byte ptyState; - byte cr_enquiry; - word hangup_flow_ctrl_timer; - - word ncci_ring_list; - byte inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI]; - t_std_internal_command internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS]; - dword c_ind_mask_table[C_IND_MASK_DWORDS]; - dword group_optimization_mask_table[C_IND_MASK_DWORDS]; - byte RBuffer[200]; - dword msg_in_queue[MSG_IN_QUEUE_SIZE/sizeof(dword)]; - API_SAVE saved_msg; - API_SAVE B_protocol; - byte fax_connect_info_length; - byte fax_connect_info_buffer[FAX_CONNECT_INFO_BUFFER_SIZE]; - byte fax_edata_ack_length; - word nsf_control_bits; - byte ncpi_state; - byte ncpi_buffer[NCPI_BUFFER_SIZE]; - - byte internal_req_buffer[INTERNAL_REQ_BUFFER_SIZE]; - byte internal_ind_buffer[INTERNAL_IND_BUFFER_SIZE + 3]; - dword requested_options_conn; - dword requested_options; - word B1_facilities; - API_SAVE *adjust_b_parms_msg; - word adjust_b_facilities; - word adjust_b_command; - word adjust_b_ncci; - word adjust_b_mode; - word adjust_b_state; - byte adjust_b_restore; - - byte dtmf_rec_active; - word dtmf_rec_pulse_ms; - word dtmf_rec_pause_ms; - byte dtmf_send_requests; - word dtmf_send_pulse_ms; - word dtmf_send_pause_ms; - word dtmf_cmd; - word dtmf_msg_number_queue[8]; - byte dtmf_parameter_length; - byte dtmf_parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE]; - - - t_capidtmf_state capidtmf_state; - - - byte li_bchannel_id; /* BRI: 1..2, PRI: 1..32 */ - byte li_channel_bits; - byte li_notify_update; - word li_cmd; - word li_write_command; - word li_write_channel; - word li_plci_b_write_pos; - word li_plci_b_read_pos; - word li_plci_b_req_pos; - dword li_plci_b_queue[LI_PLCI_B_QUEUE_ENTRIES]; - - - word ec_cmd; - word ec_idi_options; - word ec_tail_length; - - - byte tone_last_indication_code; - - byte vswitchstate; - byte vsprot; - byte vsprotdialect; - byte notifiedcall; /* Flag if it is a spoofed call */ - - int rx_dma_descriptor; - dword rx_dma_magic; + ENTITY Sig; + ENTITY NL; + word RNum; + word RFlags; + BUFFERS RData[2]; + BUFFERS XData[1]; + BUFFERS NData[2]; + + DIVA_CAPI_ADAPTER *adapter; + APPL *appl; + PLCI *relatedPTYPLCI; + byte Id; + byte State; + byte sig_req; + byte nl_req; + byte SuppState; + byte channels; + byte tel; + byte B1_resource; + byte B2_prot; + byte B3_prot; + + word command; + word m_command; + word internal_command; + word number; + word req_in_start; + word req_in; + word req_out; + word msg_in_write_pos; + word msg_in_read_pos; + word msg_in_wrap_pos; + + void *data_sent_ptr; + byte data_sent; + byte send_disc; + byte sig_global_req; + byte sig_remove_id; + byte nl_global_req; + byte nl_remove_id; + byte b_channel; + byte adv_nl; + byte manufacturer; + byte call_dir; + byte hook_state; + byte spoofed_msg; + byte ptyState; + byte cr_enquiry; + word hangup_flow_ctrl_timer; + + word ncci_ring_list; + byte inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI]; + t_std_internal_command internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS]; + dword c_ind_mask_table[C_IND_MASK_DWORDS]; + dword group_optimization_mask_table[C_IND_MASK_DWORDS]; + byte RBuffer[200]; + dword msg_in_queue[MSG_IN_QUEUE_SIZE/sizeof(dword)]; + API_SAVE saved_msg; + API_SAVE B_protocol; + byte fax_connect_info_length; + byte fax_connect_info_buffer[FAX_CONNECT_INFO_BUFFER_SIZE]; + byte fax_edata_ack_length; + word nsf_control_bits; + byte ncpi_state; + byte ncpi_buffer[NCPI_BUFFER_SIZE]; + + byte internal_req_buffer[INTERNAL_REQ_BUFFER_SIZE]; + byte internal_ind_buffer[INTERNAL_IND_BUFFER_SIZE + 3]; + dword requested_options_conn; + dword requested_options; + word B1_facilities; + API_SAVE *adjust_b_parms_msg; + word adjust_b_facilities; + word adjust_b_command; + word adjust_b_ncci; + word adjust_b_mode; + word adjust_b_state; + byte adjust_b_restore; + + byte dtmf_rec_active; + word dtmf_rec_pulse_ms; + word dtmf_rec_pause_ms; + byte dtmf_send_requests; + word dtmf_send_pulse_ms; + word dtmf_send_pause_ms; + word dtmf_cmd; + word dtmf_msg_number_queue[8]; + byte dtmf_parameter_length; + byte dtmf_parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE]; + + + t_capidtmf_state capidtmf_state; + + + byte li_bchannel_id; /* BRI: 1..2, PRI: 1..32 */ + byte li_channel_bits; + byte li_notify_update; + word li_cmd; + word li_write_command; + word li_write_channel; + word li_plci_b_write_pos; + word li_plci_b_read_pos; + word li_plci_b_req_pos; + dword li_plci_b_queue[LI_PLCI_B_QUEUE_ENTRIES]; + + + word ec_cmd; + word ec_idi_options; + word ec_tail_length; + + + byte tone_last_indication_code; + + byte vswitchstate; + byte vsprot; + byte vsprotdialect; + byte notifiedcall; /* Flag if it is a spoofed call */ + + int rx_dma_descriptor; + dword rx_dma_magic; }; struct _NCCI { - byte data_out; - byte data_pending; - byte data_ack_out; - byte data_ack_pending; - DATA_B3_DESC DBuffer[MAX_DATA_B3]; - DATA_ACK_DESC DataAck[MAX_DATA_ACK]; + byte data_out; + byte data_pending; + byte data_ack_out; + byte data_ack_pending; + DATA_B3_DESC DBuffer[MAX_DATA_B3]; + DATA_ACK_DESC DataAck[MAX_DATA_ACK]; }; struct _DIVA_CAPI_ADAPTER { - IDI_CALL request; - byte Id; - byte max_plci; - byte max_listen; - byte listen_active; - PLCI *plci; - byte ch_ncci[MAX_NL_CHANNEL+1]; - byte ncci_ch[MAX_NCCI+1]; - byte ncci_plci[MAX_NCCI+1]; - byte ncci_state[MAX_NCCI+1]; - byte ncci_next[MAX_NCCI+1]; - NCCI ncci[MAX_NCCI+1]; - - byte ch_flow_control[MAX_NL_CHANNEL+1]; /* Used by XON protocol */ - byte ch_flow_control_pending; - byte ch_flow_plci[MAX_NL_CHANNEL+1]; - int last_flow_control_ch; - - dword Info_Mask[MAX_APPL]; - dword CIP_Mask[MAX_APPL]; - - dword Notification_Mask[MAX_APPL]; - PLCI *codec_listen[MAX_APPL]; - dword requested_options_table[MAX_APPL]; - API_PROFILE profile; - MANUFACTURER_PROFILE man_profile; - dword manufacturer_features; - - byte AdvCodecFLAG; - PLCI *AdvCodecPLCI; - PLCI *AdvSignalPLCI; - APPL *AdvSignalAppl; - byte TelOAD[23]; - byte TelOSA[23]; - byte scom_appl_disable; - PLCI *automatic_lawPLCI; - byte automatic_law; - byte u_law; - - byte adv_voice_coef_length; - byte adv_voice_coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE]; - - byte li_pri; - byte li_channels; - word li_base; - - byte adapter_disabled; - byte group_optimization_enabled; /* use application groups if enabled */ - dword sdram_bar; - byte flag_dynamic_l1_down; /* for hunt groups:down layer 1 if no appl present*/ - byte FlowControlIdTable[256]; - byte FlowControlSkipTable[256]; - void* os_card; /* pointer to associated OS dependent adapter structure */ + IDI_CALL request; + byte Id; + byte max_plci; + byte max_listen; + byte listen_active; + PLCI *plci; + byte ch_ncci[MAX_NL_CHANNEL + 1]; + byte ncci_ch[MAX_NCCI + 1]; + byte ncci_plci[MAX_NCCI + 1]; + byte ncci_state[MAX_NCCI + 1]; + byte ncci_next[MAX_NCCI + 1]; + NCCI ncci[MAX_NCCI + 1]; + + byte ch_flow_control[MAX_NL_CHANNEL + 1]; /* Used by XON protocol */ + byte ch_flow_control_pending; + byte ch_flow_plci[MAX_NL_CHANNEL + 1]; + int last_flow_control_ch; + + dword Info_Mask[MAX_APPL]; + dword CIP_Mask[MAX_APPL]; + + dword Notification_Mask[MAX_APPL]; + PLCI *codec_listen[MAX_APPL]; + dword requested_options_table[MAX_APPL]; + API_PROFILE profile; + MANUFACTURER_PROFILE man_profile; + dword manufacturer_features; + + byte AdvCodecFLAG; + PLCI *AdvCodecPLCI; + PLCI *AdvSignalPLCI; + APPL *AdvSignalAppl; + byte TelOAD[23]; + byte TelOSA[23]; + byte scom_appl_disable; + PLCI *automatic_lawPLCI; + byte automatic_law; + byte u_law; + + byte adv_voice_coef_length; + byte adv_voice_coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE]; + + byte li_pri; + byte li_channels; + word li_base; + + byte adapter_disabled; + byte group_optimization_enabled; /* use application groups if enabled */ + dword sdram_bar; + byte flag_dynamic_l1_down; /* for hunt groups:down layer 1 if no appl present*/ + byte FlowControlIdTable[256]; + byte FlowControlSkipTable[256]; + void *os_card; /* pointer to associated OS dependent adapter structure */ }; @@ -422,11 +422,11 @@ struct _DIVA_CAPI_ADAPTER { #define LAPD 6 /* lapd (Q.921) */ #define X25_L2 7 /* x.25 layer-2 */ #define V120_L2 8 /* V.120 layer-2 protocol */ -#define V42_IN 9 /* V.42 layer-2 protocol, incomming */ +#define V42_IN 9 /* V.42 layer-2 protocol, incoming */ #define V42 10 /* V.42 layer-2 protocol */ #define MDM_ATP 11 /* AT Parser built in the L2 */ #define X75_V42BIS 12 /* ISO7776 (X.75 SLP) modified to support V.42 bis compression */ -#define RTPL2_IN 13 /* RTP layer-2 protocol, incomming */ +#define RTPL2_IN 13 /* RTP layer-2 protocol, incoming */ #define RTPL2 14 /* RTP layer-2 protocol */ #define V120_V42BIS 15 /* V.120 layer-2 protocol supporting V.42 bis compression */ @@ -451,23 +451,23 @@ struct _DIVA_CAPI_ADAPTER { typedef struct t30_info_s T30_INFO; struct t30_info_s { - byte code; - byte rate_div_2400; - byte resolution; - byte data_format; - byte pages_low; - byte pages_high; - byte operating_mode; - byte control_bits_low; - byte control_bits_high; - byte feature_bits_low; - byte feature_bits_high; - byte recording_properties; - byte universal_6; - byte universal_7; - byte station_id_len; - byte head_line_len; - byte station_id[T30_MAX_STATION_ID_LENGTH]; + byte code; + byte rate_div_2400; + byte resolution; + byte data_format; + byte pages_low; + byte pages_high; + byte operating_mode; + byte control_bits_low; + byte control_bits_high; + byte feature_bits_low; + byte feature_bits_high; + byte recording_properties; + byte universal_6; + byte universal_7; + byte station_id_len; + byte head_line_len; + byte station_id[T30_MAX_STATION_ID_LENGTH]; /* byte head_line[]; */ /* byte sub_sep_length; */ /* byte sub_sep_field[]; */ @@ -528,13 +528,13 @@ struct t30_info_s { #define T30_OPERATING_MODE_CAPI_NEG 4 #define T30_OPERATING_MODE_COUNT 5 - /* EDATA transmit messages */ +/* EDATA transmit messages */ #define EDATA_T30_DIS 0x01 #define EDATA_T30_FTT 0x02 #define EDATA_T30_MCF 0x03 #define EDATA_T30_PARAMETERS 0x04 - /* EDATA receive messages */ +/* EDATA receive messages */ #define EDATA_T30_DCS 0x81 #define EDATA_T30_TRAIN_OK 0x82 #define EDATA_T30_EOP 0x83 @@ -639,11 +639,11 @@ struct t30_info_s { typedef struct async_s ASYNC_FORMAT; struct async_s { - unsigned pe: 1; - unsigned parity:2; - unsigned spare: 2; - unsigned stp: 1; - unsigned ch_len:2; /* 3th octett in CAI */ + unsigned pe:1; + unsigned parity:2; + unsigned spare:2; + unsigned stp:1; + unsigned ch_len:2; /* 3th octett in CAI */ }; @@ -673,7 +673,7 @@ struct async_s { /*------------------------------------------------------------------*/ -/* auxilliary states for supplementary services */ +/* auxiliary states for supplementary services */ /*------------------------------------------------------------------*/ #define IDLE 0 @@ -686,14 +686,14 @@ struct async_s { /*------------------------------------------------------------------*/ /* Capi IE + Msg types */ /*------------------------------------------------------------------*/ -#define ESC_CAUSE 0x800|CAU /* Escape cause element */ -#define ESC_MSGTYPE 0x800|MSGTYPEIE /* Escape message type */ -#define ESC_CHI 0x800|CHI /* Escape channel id */ -#define ESC_LAW 0x800|BC /* Escape law info */ -#define ESC_CR 0x800|CRIE /* Escape CallReference */ -#define ESC_PROFILE 0x800|PROFILEIE /* Escape profile */ -#define ESC_SSEXT 0x800|SSEXTIE /* Escape Supplem. Serv.*/ -#define ESC_VSWITCH 0x800|VSWITCHIE /* Escape VSwitch */ +#define ESC_CAUSE 0x800 | CAU /* Escape cause element */ +#define ESC_MSGTYPE 0x800 | MSGTYPEIE /* Escape message type */ +#define ESC_CHI 0x800 | CHI /* Escape channel id */ +#define ESC_LAW 0x800 | BC /* Escape law info */ +#define ESC_CR 0x800 | CRIE /* Escape CallReference */ +#define ESC_PROFILE 0x800 | PROFILEIE /* Escape profile */ +#define ESC_SSEXT 0x800 | SSEXTIE /* Escape Supplem. Serv.*/ +#define ESC_VSWITCH 0x800 | VSWITCHIE /* Escape VSwitch */ #define CST 0x14 /* Call State i.e. */ #define PI 0x1E /* Progress Indicator */ #define NI 0x27 /* Notification Ind */ @@ -903,25 +903,25 @@ struct async_s { typedef struct li_config_s LI_CONFIG; struct xconnect_card_address_s { - dword low; - dword high; + dword low; + dword high; }; struct xconnect_transfer_address_s { - struct xconnect_card_address_s card_address; - dword offset; + struct xconnect_card_address_s card_address; + dword offset; }; struct li_config_s { - DIVA_CAPI_ADAPTER *adapter; - PLCI *plci; - struct xconnect_transfer_address_s send_b; - struct xconnect_transfer_address_s send_pc; - byte *flag_table; /* dword aligned and sized */ - byte *coef_table; /* dword aligned and sized */ - byte channel; - byte curchnl; - byte chflags; + DIVA_CAPI_ADAPTER *adapter; + PLCI *plci; + struct xconnect_transfer_address_s send_b; + struct xconnect_transfer_address_s send_pc; + byte *flag_table; /* dword aligned and sized */ + byte *coef_table; /* dword aligned and sized */ + byte channel; + byte curchnl; + byte chflags; }; extern LI_CONFIG *li_config_table; @@ -1110,33 +1110,33 @@ extern word li_total_channels; #define B1_PIAFS 29 #define B2_PIAFS 29 -#define PRIVATE_PIAFS 29 +#define PRIVATE_PIAFS 29 /* B2 configuration for PIAFS: -+---------------------+------+-----------------------------------------+ -| PIAFS Protocol | byte | Bit 1 - Protocol Speed | -| Speed configuration | | 0 - 32K | -| | | 1 - 64K (default) | -| | | Bit 2 - Variable Protocol Speed | -| | | 0 - Speed is fix | -| | | 1 - Speed is variable (default) | -+---------------------+------+-----------------------------------------+ -| Direction | word | Enable compression/decompression for | -| | | 0: All direction | -| | | 1: disable outgoing data | -| | | 2: disable incomming data | -| | | 3: disable both direction (default) | -+---------------------+------+-----------------------------------------+ -| Number of code | word | Parameter P1 of V.42bis in accordance | -| words | | with V.42bis | -+---------------------+------+-----------------------------------------+ -| Maximum String | word | Parameter P2 of V.42bis in accordance | -| Length | | with V.42bis | -+---------------------+------+-----------------------------------------+ -| control (UDATA) | byte | enable PIAFS control communication | -| abilities | | | -+---------------------+------+-----------------------------------------+ + +---------------------+------+-----------------------------------------+ + | PIAFS Protocol | byte | Bit 1 - Protocol Speed | + | Speed configuration | | 0 - 32K | + | | | 1 - 64K (default) | + | | | Bit 2 - Variable Protocol Speed | + | | | 0 - Speed is fix | + | | | 1 - Speed is variable (default) | + +---------------------+------+-----------------------------------------+ + | Direction | word | Enable compression/decompression for | + | | | 0: All direction | + | | | 1: disable outgoing data | + | | | 2: disable incoming data | + | | | 3: disable both direction (default) | + +---------------------+------+-----------------------------------------+ + | Number of code | word | Parameter P1 of V.42bis in accordance | + | words | | with V.42bis | + +---------------------+------+-----------------------------------------+ + | Maximum String | word | Parameter P2 of V.42bis in accordance | + | Length | | with V.42bis | + +---------------------+------+-----------------------------------------+ + | control (UDATA) | byte | enable PIAFS control communication | + | abilities | | | + +---------------------+------+-----------------------------------------+ */ #define PIAFS_UDATA_ABILITIES 0x80 diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c index 6146f7633be..48db08d0bb3 100644 --- a/drivers/isdn/hardware/eicon/divamnt.c +++ b/drivers/isdn/hardware/eicon/divamnt.c @@ -10,14 +10,11 @@ * of the GNU General Public License, incorporated herein by reference. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/smp_lock.h> #include <linux/poll.h> -#include <linux/devfs_fs_kernel.h> +#include <linux/mutex.h> #include <asm/uaccess.h> #include "platform.h" @@ -25,6 +22,7 @@ #include "divasync.h" #include "debug_if.h" +static DEFINE_MUTEX(maint_mutex); static char *main_revision = "$Revision: 1.32.6.10 $"; static int major; @@ -40,7 +38,7 @@ static unsigned long diva_dbg_mem = 0; module_param(diva_dbg_mem, ulong, 0); static char *DRIVERNAME = - "Eicon DIVA - MAINT module (http://www.melware.net)"; + "Eicon DIVA - MAINT module (http://www.melware.net)"; static char *DRIVERLNAME = "diva_mnt"; static char *DEVNAME = "DivasMAINT"; char *DRIVERRELEASE_MNT = "2.0"; @@ -88,7 +86,7 @@ int diva_os_copy_from_user(void *os_handle, void *dst, const void __user *src, /* * get time */ -void diva_os_get_time(dword * sec, dword * usec) +void diva_os_get_time(dword *sec, dword *usec) { struct timeval tv; @@ -117,7 +115,7 @@ void diva_os_get_time(dword * sec, dword * usec) /* * device node operations */ -static unsigned int maint_poll(struct file *file, poll_table * wait) +static unsigned int maint_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; @@ -131,14 +129,19 @@ static unsigned int maint_poll(struct file *file, poll_table * wait) static int maint_open(struct inode *ino, struct file *filep) { + int ret; + + mutex_lock(&maint_mutex); /* only one open is allowed, so we test it atomically */ if (test_and_set_bit(0, &opened)) - return (-EBUSY); - - filep->private_data = NULL; - - return nonseekable_open(ino, filep); + ret = -EBUSY; + else { + filep->private_data = NULL; + ret = nonseekable_open(ino, filep); + } + mutex_unlock(&maint_mutex); + return ret; } static int maint_close(struct inode *ino, struct file *filep) @@ -150,23 +153,23 @@ static int maint_close(struct inode *ino, struct file *filep) /* clear 'used' flag */ clear_bit(0, &opened); - + return (0); } static ssize_t divas_maint_write(struct file *file, const char __user *buf, - size_t count, loff_t * ppos) + size_t count, loff_t *ppos) { return (maint_read_write((char __user *) buf, (int) count)); } static ssize_t divas_maint_read(struct file *file, char __user *buf, - size_t count, loff_t * ppos) + size_t count, loff_t *ppos) { return (maint_read_write(buf, (int) count)); } -static struct file_operations divas_maint_fops = { +static const struct file_operations divas_maint_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = divas_maint_read, @@ -178,11 +181,10 @@ static struct file_operations divas_maint_fops = { static void divas_maint_unregister_chrdev(void) { - devfs_remove(DEVNAME); unregister_chrdev(major, DEVNAME); } -static int DIVA_INIT_FUNCTION divas_maint_register_chrdev(void) +static int __init divas_maint_register_chrdev(void) { if ((major = register_chrdev(0, DEVNAME, &divas_maint_fops)) < 0) { @@ -190,7 +192,6 @@ static int DIVA_INIT_FUNCTION divas_maint_register_chrdev(void) DRIVERLNAME); return (0); } - devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME); return (1); } @@ -206,7 +207,7 @@ void diva_maint_wakeup_read(void) /* * Driver Load */ -static int DIVA_INIT_FUNCTION maint_init(void) +static int __init maint_init(void) { char tmprev[50]; int ret = 0; @@ -237,14 +238,14 @@ static int DIVA_INIT_FUNCTION maint_init(void) DRIVERLNAME, buffer, (buffer_length / 1024), (diva_dbg_mem == 0) ? "internal" : "external", major); - out: +out: return (ret); } /* ** Driver Unload */ -static void DIVA_EXIT_FUNCTION maint_exit(void) +static void __exit maint_exit(void) { divas_maint_unregister_chrdev(); mntfunc_finit(); @@ -254,4 +255,3 @@ static void DIVA_EXIT_FUNCTION maint_exit(void) module_init(maint_init); module_exit(maint_exit); - diff --git a/drivers/isdn/hardware/eicon/divasfunc.c b/drivers/isdn/hardware/eicon/divasfunc.c index df61e510a28..4be5f881477 100644 --- a/drivers/isdn/hardware/eicon/divasfunc.c +++ b/drivers/isdn/hardware/eicon/divasfunc.c @@ -34,7 +34,7 @@ static DESCRIPTOR DAdapter; static DESCRIPTOR MAdapter; /* -------------------------------------------------------------------------- - MAINT driver connector section + MAINT driver connector section -------------------------------------------------------------------------- */ static void no_printf(unsigned char *x, ...) { @@ -74,17 +74,17 @@ void diva_xdi_didd_register_adapter(int card) d.features = IoAdapters[card - 1]->Properties.Features; DBG_TRC(("DIDD register A(%d) channels=%d", card, d.channels)) - /* workaround for different Name in structure */ - strlcpy(IoAdapters[card - 1]->Name, - IoAdapters[card - 1]->Properties.Name, - sizeof(IoAdapters[card - 1]->Name)); + /* workaround for different Name in structure */ + strlcpy(IoAdapters[card - 1]->Name, + IoAdapters[card - 1]->Properties.Name, + sizeof(IoAdapters[card - 1]->Name)); req.didd_remove_adapter.e.Req = 0; req.didd_add_adapter.e.Rc = IDI_SYNC_REQ_DIDD_ADD_ADAPTER; req.didd_add_adapter.info.descriptor = (void *) &d; - DAdapter.request((ENTITY *) & req); + DAdapter.request((ENTITY *)&req); if (req.didd_add_adapter.e.Rc != 0xff) { DBG_ERR(("DIDD register A(%d) failed !", card)) - } + } IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL; } } @@ -99,11 +99,11 @@ void diva_xdi_didd_remove_adapter(int card) IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL; DBG_TRC(("DIDD de-register A(%d)", card)) - req.didd_remove_adapter.e.Req = 0; + req.didd_remove_adapter.e.Req = 0; req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER; req.didd_remove_adapter.info.p_request = - (IDI_CALL) Requests[card - 1]; - DAdapter.request((ENTITY *) & req); + (IDI_CALL) Requests[card - 1]; + DAdapter.request((ENTITY *)&req); memset(&(a->IdTable), 0x00, 256); } @@ -113,10 +113,9 @@ void diva_xdi_didd_remove_adapter(int card) static void start_dbg(void) { DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT); - DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s]-%s-%s)", - DIVA_BUILD, diva_xdi_common_code_build, __DATE__, - __TIME__)) -} + DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s])", + DIVA_BUILD, diva_xdi_common_code_build)) + } /* * stop debug @@ -131,7 +130,7 @@ static void stop_dbg(void) /* * didd callback function */ -static void *didd_callback(void *context, DESCRIPTOR * adapter, +static void *didd_callback(void *context, DESCRIPTOR *adapter, int removal) { if (adapter->type == IDI_DADAPTER) { @@ -154,7 +153,7 @@ static void *didd_callback(void *context, DESCRIPTOR * adapter, /* * connect to didd */ -static int DIVA_INIT_FUNCTION connect_didd(void) +static int __init connect_didd(void) { int x = 0; int dadapter = 0; @@ -169,10 +168,10 @@ static int DIVA_INIT_FUNCTION connect_didd(void) 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; + 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); + DAdapter.request((ENTITY *)&req); if (req.didd_notify.e.Rc != 0xff) { stop_dbg(); return (0); @@ -195,7 +194,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void) /* * disconnect from didd */ -static void DIVA_EXIT_FUNCTION disconnect_didd(void) +static void disconnect_didd(void) { IDI_SYNC_REQ req; @@ -204,21 +203,21 @@ static void DIVA_EXIT_FUNCTION disconnect_didd(void) 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); + DAdapter.request((ENTITY *)&req); } /* * init */ -int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask) +int __init divasfunc_init(int dbgmask) { char *version; debugmask = dbgmask; - + if (!connect_didd()) { DBG_ERR(("divasfunc: failed to connect to DIDD.")) - return (0); + return (0); } version = diva_xdi_common_code_build; @@ -231,7 +230,7 @@ int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask) /* * exit */ -void DIVA_EXIT_FUNCTION divasfunc_exit(void) +void divasfunc_exit(void) { divasa_xdi_driver_unload(); disconnect_didd(); diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c index df715b47e2b..4103a8c178d 100644 --- a/drivers/isdn/hardware/eicon/divasi.c +++ b/drivers/isdn/hardware/eicon/divasi.c @@ -1,7 +1,7 @@ /* $Id: divasi.c,v 1.25.6.2 2005/01/31 12:22:20 armin Exp $ * * Driver for Eicon DIVA Server ISDN cards. - * User Mode IDI Interface + * User Mode IDI Interface * * Copyright 2000-2003 by Armin Schindler (mac@melware.de) * Copyright 2000-2003 Cytronics & Melware (info@melware.de) @@ -10,16 +10,14 @@ * of the GNU General Public License, incorporated herein by reference. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> -#include <linux/smp_lock.h> #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/skbuff.h> -#include <linux/devfs_fs_kernel.h> +#include <linux/seq_file.h> #include <asm/uaccess.h> #include "platform.h" @@ -73,10 +71,10 @@ static char *getrev(const char *revision) * LOCALS */ static ssize_t um_idi_read(struct file *file, char __user *buf, size_t count, - loff_t * offset); + loff_t *offset); static ssize_t um_idi_write(struct file *file, const char __user *buf, - size_t count, loff_t * offset); -static unsigned int um_idi_poll(struct file *file, poll_table * wait); + size_t count, loff_t *offset); +static unsigned int um_idi_poll(struct file *file, poll_table *wait); static int um_idi_open(struct inode *inode, struct file *file); static int um_idi_release(struct inode *inode, struct file *file); static int remove_entity(void *entity); @@ -88,40 +86,40 @@ static void diva_um_timer_function(unsigned long data); extern struct proc_dir_entry *proc_net_eicon; static struct proc_dir_entry *um_idi_proc_entry = NULL; -static int -um_idi_proc_read(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int um_idi_proc_show(struct seq_file *m, void *v) { - int len = 0; char tmprev[32]; - len += sprintf(page + len, "%s\n", DRIVERNAME); - len += sprintf(page + len, "name : %s\n", DRIVERLNAME); - len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_IDI); + seq_printf(m, "%s\n", DRIVERNAME); + seq_printf(m, "name : %s\n", DRIVERLNAME); + seq_printf(m, "release : %s\n", DRIVERRELEASE_IDI); strcpy(tmprev, main_revision); - len += sprintf(page + len, "revision : %s\n", getrev(tmprev)); - len += sprintf(page + len, "build : %s\n", DIVA_BUILD); - len += sprintf(page + len, "major : %d\n", major); - - if (off + count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len - off) ? count : len - off); + seq_printf(m, "revision : %s\n", getrev(tmprev)); + seq_printf(m, "build : %s\n", DIVA_BUILD); + seq_printf(m, "major : %d\n", major); + + return 0; } -static int DIVA_INIT_FUNCTION create_um_idi_proc(void) +static int um_idi_proc_open(struct inode *inode, struct file *file) { - um_idi_proc_entry = create_proc_entry(DRIVERLNAME, - S_IFREG | S_IRUGO | S_IWUSR, - proc_net_eicon); - if (!um_idi_proc_entry) - return (0); + return single_open(file, um_idi_proc_show, NULL); +} - um_idi_proc_entry->read_proc = um_idi_proc_read; - um_idi_proc_entry->owner = THIS_MODULE; +static const struct file_operations um_idi_proc_fops = { + .owner = THIS_MODULE, + .open = um_idi_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +static int __init create_um_idi_proc(void) +{ + um_idi_proc_entry = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon, + &um_idi_proc_fops); + if (!um_idi_proc_entry) + return (0); return (1); } @@ -133,7 +131,7 @@ static void remove_um_idi_proc(void) } } -static struct file_operations divas_idi_fops = { +static const struct file_operations divas_idi_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = um_idi_read, @@ -145,11 +143,10 @@ static struct file_operations divas_idi_fops = { static void divas_idi_unregister_chrdev(void) { - devfs_remove(DEVNAME); unregister_chrdev(major, DEVNAME); } -static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void) +static int __init divas_idi_register_chrdev(void) { if ((major = register_chrdev(0, DEVNAME, &divas_idi_fops)) < 0) { @@ -157,7 +154,6 @@ static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void) DRIVERLNAME); return (0); } - devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME); return (1); } @@ -165,7 +161,7 @@ static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void) /* ** Driver Load */ -static int DIVA_INIT_FUNCTION divasi_init(void) +static int __init divasi_init(void) { char tmprev[50]; int ret = 0; @@ -198,7 +194,7 @@ static int DIVA_INIT_FUNCTION divasi_init(void) } printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major); - out: +out: return (ret); } @@ -206,7 +202,7 @@ static int DIVA_INIT_FUNCTION divasi_init(void) /* ** Driver Unload */ -static void DIVA_EXIT_FUNCTION divasi_exit(void) +static void __exit divasi_exit(void) { idifunc_finit(); remove_um_idi_proc(); @@ -232,7 +228,7 @@ divas_um_idi_copy_to_user(void *os_handle, void *dst, const void *src, } static ssize_t -um_idi_read(struct file *file, char __user *buf, size_t count, loff_t * offset) +um_idi_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { diva_um_idi_os_context_t *p_os; int ret = -EINVAL; @@ -296,7 +292,7 @@ static int um_idi_open_adapter(struct file *file, int adapter_nr) { diva_um_idi_os_context_t *p_os; void *e = - divas_um_idi_create_entity((dword) adapter_nr, (void *) file); + divas_um_idi_create_entity((dword) adapter_nr, (void *) file); if (!(file->private_data = e)) { return (0); @@ -314,7 +310,7 @@ static int um_idi_open_adapter(struct file *file, int adapter_nr) static ssize_t um_idi_write(struct file *file, const char __user *buf, size_t count, - loff_t * offset) + loff_t *offset) { diva_um_idi_os_context_t *p_os; int ret = -EINVAL; @@ -335,8 +331,8 @@ um_idi_write(struct file *file, const char __user *buf, size_t count, } if (!(p_os = - (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file-> - private_data))) + (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file-> + private_data))) { return (-ENODEV); } @@ -371,7 +367,7 @@ um_idi_write(struct file *file, const char __user *buf, size_t count, return (ret); } -static unsigned int um_idi_poll(struct file *file, poll_table * wait) +static unsigned int um_idi_poll(struct file *file, poll_table *wait) { diva_um_idi_os_context_t *p_os; @@ -421,7 +417,7 @@ static int um_idi_release(struct inode *inode, struct file *file) } if (!(p_os = - (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) { + (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) { ret = -ENODEV; goto out; } @@ -438,7 +434,7 @@ static int um_idi_release(struct inode *inode, struct file *file) goto out; } - out: +out: return (ret); } @@ -450,14 +446,14 @@ int diva_os_get_context_size(void) void diva_os_wakeup_read(void *os_context) { diva_um_idi_os_context_t *p_os = - (diva_um_idi_os_context_t *) os_context; + (diva_um_idi_os_context_t *) os_context; wake_up_interruptible(&p_os->read_wait); } void diva_os_wakeup_close(void *os_context) { diva_um_idi_os_context_t *p_os = - (diva_um_idi_os_context_t *) os_context; + (diva_um_idi_os_context_t *) os_context; wake_up_interruptible(&p_os->close_wait); } @@ -470,7 +466,7 @@ void diva_um_timer_function(unsigned long data) wake_up_interruptible(&p_os->read_wait); wake_up_interruptible(&p_os->close_wait); DBG_ERR(("entity removal watchdog")) -} + } /* ** If application exits without entity removal this function will remove @@ -485,30 +481,30 @@ static int remove_entity(void *entity) if (!entity) { DBG_FTL(("Zero entity on remove")) - return (0); + return (0); } if (!(p_os = - (diva_um_idi_os_context_t *) - diva_um_id_get_os_context(entity))) { + (diva_um_idi_os_context_t *) + diva_um_id_get_os_context(entity))) { DBG_FTL(("Zero entity os context on remove")) - return (0); + return (0); } if (!divas_um_idi_entity_assigned(entity) || p_os->aborted) { /* - Entity is not assigned, also can be removed - */ + Entity is not assigned, also can be removed + */ return (0); } DBG_TRC(("E(%08x) check remove", entity)) - /* - If adapter not answers on remove request inside of - 10 Sec, then adapter is dead - */ - diva_um_idi_start_wdog(entity); + /* + If adapter not answers on remove request inside of + 10 Sec, then adapter is dead + */ + diva_um_idi_start_wdog(entity); { DECLARE_WAITQUEUE(wait, curtask); @@ -546,7 +542,7 @@ static int remove_entity(void *entity) DBG_TRC(("E(%08x) remove complete, aborted:%d", entity, p_os->aborted)) - diva_um_idi_stop_wdog(entity); + diva_um_idi_stop_wdog(entity); p_os->aborted = 0; diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c index c9b26e86d18..a2e0ed6c9a4 100644 --- a/drivers/isdn/hardware/eicon/divasmain.c +++ b/drivers/isdn/hardware/eicon/divasmain.c @@ -9,18 +9,13 @@ * of the GNU General Public License, incorporated herein by reference. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/devfs_fs_kernel.h> #include <asm/uaccess.h> #include <asm/io.h> #include <linux/ioport.h> -#include <linux/workqueue.h> #include <linux/pci.h> -#include <linux/smp_lock.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/poll.h> @@ -55,13 +50,12 @@ module_param(dbgmask, int, 0); MODULE_PARM_DESC(dbgmask, "initial debug mask"); static char *DRIVERNAME = - "Eicon DIVA Server driver (http://www.melware.net)"; + "Eicon DIVA Server driver (http://www.melware.net)"; static char *DRIVERLNAME = "divas"; static char *DEVNAME = "Divas"; char *DRIVERRELEASE_DIVAS = "2.0"; -extern irqreturn_t diva_os_irq_wrapper(int irq, void *context, - struct pt_regs *regs); +extern irqreturn_t diva_os_irq_wrapper(int irq, void *context); extern int create_divas_proc(void); extern void remove_divas_proc(void); extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf); @@ -74,7 +68,7 @@ typedef struct _diva_os_thread_dpc { } diva_os_thread_dpc_t; /* -------------------------------------------------------------------------- - PCI driver interface section + PCI driver interface section -------------------------------------------------------------------------- */ /* vendor, device Vendor and device ID to match (or PCI_ANY_ID) @@ -83,7 +77,7 @@ typedef struct _diva_os_thread_dpc { class, Device class to match. The class_mask tells which bits class_mask of the class are honored during the comparison. driver_data Data private to the driver. - */ +*/ #if !defined(PCI_DEVICE_ID_EICON_MAESTRAP_2) #define PCI_DEVICE_ID_EICON_MAESTRAP_2 0xE015 @@ -115,54 +109,53 @@ typedef struct _diva_os_thread_dpc { /* This table should be sorted by PCI device ID - */ +*/ static struct pci_device_id divas_pci_tbl[] = { -/* Diva Server BRI-2M PCI 0xE010 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_MAESTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_MAESTRA_PCI}, -/* Diva Server 4BRI-8M PCI 0xE012 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_MAESTRAQ, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_Q_8M_PCI}, -/* Diva Server 4BRI-8M 2.0 PCI 0xE013 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_MAESTRAQ_U, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_Q_8M_V2_PCI}, -/* Diva Server PRI-30M PCI 0xE014 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_MAESTRAP, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_P_30M_PCI}, -/* Diva Server PRI 2.0 adapter 0xE015 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_P_30M_V2_PCI}, -/* Diva Server Voice 4BRI-8M PCI 0xE016 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_4BRI_VOIP, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_VOICE_Q_8M_PCI}, -/* Diva Server Voice 4BRI-8M 2.0 PCI 0xE017 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_4BRI_2_VOIP, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI}, -/* Diva Server BRI-2M 2.0 PCI 0xE018 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_BRI2M_2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_B_2M_V2_PCI}, -/* Diva Server Voice PRI 2.0 PCI 0xE019 */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI}, -/* Diva Server 2FX 0xE01A */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_2F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_B_2F_PCI}, -/* Diva Server Voice BRI-2M 2.0 PCI 0xE01B */ - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_BRI2M_2_VOIP, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI}, - {0,} /* 0 terminated list. */ + /* Diva Server BRI-2M PCI 0xE010 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRA), + CARDTYPE_MAESTRA_PCI }, + /* Diva Server 4BRI-8M PCI 0xE012 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ), + CARDTYPE_DIVASRV_Q_8M_PCI }, + /* Diva Server 4BRI-8M 2.0 PCI 0xE013 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ_U), + CARDTYPE_DIVASRV_Q_8M_V2_PCI }, + /* Diva Server PRI-30M PCI 0xE014 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP), + CARDTYPE_DIVASRV_P_30M_PCI }, + /* Diva Server PRI 2.0 adapter 0xE015 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2), + CARDTYPE_DIVASRV_P_30M_V2_PCI }, + /* Diva Server Voice 4BRI-8M PCI 0xE016 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_VOIP), + CARDTYPE_DIVASRV_VOICE_Q_8M_PCI }, + /* Diva Server Voice 4BRI-8M 2.0 PCI 0xE017 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_2_VOIP), + CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI }, + /* Diva Server BRI-2M 2.0 PCI 0xE018 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2), + CARDTYPE_DIVASRV_B_2M_V2_PCI }, + /* Diva Server Voice PRI 2.0 PCI 0xE019 */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP), + CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI }, + /* Diva Server 2FX 0xE01A */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_2F), + CARDTYPE_DIVASRV_B_2F_PCI }, + /* Diva Server Voice BRI-2M 2.0 PCI 0xE01B */ + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2_VOIP), + CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI }, + { 0, } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, divas_pci_tbl); static int divas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void __devexit divas_remove_one(struct pci_dev *pdev); +static void divas_remove_one(struct pci_dev *pdev); static struct pci_driver diva_pci_driver = { .name = "divas", .probe = divas_init_one, - .remove = __devexit_p(divas_remove_one), + .remove = divas_remove_one, .id_table = divas_pci_tbl, }; @@ -188,7 +181,7 @@ void diva_log_info(unsigned char *format, ...) unsigned char line[160]; va_start(args, format); - vsprintf(line, format, args); + vsnprintf(line, sizeof(line), format, args); va_end(args); printk(KERN_INFO "%s: %s\n", DRIVERLNAME, line); @@ -204,7 +197,7 @@ void divas_get_version(char *p) } /* -------------------------------------------------------------------------- - PCI Bus services + PCI Bus services -------------------------------------------------------------------------- */ byte diva_os_get_pci_bus(void *pci_dev_handle) { @@ -339,10 +332,10 @@ void PCIread(byte bus, byte func, int offset, void *data, int length, Init map with DMA pages. It is not problem if some allocations fail - the channels that will not get one DMA page will use standard PIO interface - */ +*/ static void *diva_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t * dma_handle, + dma_addr_t *dma_handle, void **addr_handle) { void *addr = pci_alloc_consistent(hwdev, size, dma_handle); @@ -357,7 +350,7 @@ void diva_init_dma_map(void *hdev, { struct pci_dev *pdev = (struct pci_dev *) hdev; struct _diva_dma_map_entry *pmap = - diva_alloc_dma_map(hdev, nentries); + diva_alloc_dma_map(hdev, nentries); if (pmap) { int i; @@ -388,7 +381,7 @@ void diva_init_dma_map(void *hdev, /* Free all contained in the map entries and memory used by the map Should be always called after adapter removal from DIDD array - */ +*/ void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap) { struct pci_dev *pdev = (struct pci_dev *) hdev; @@ -398,7 +391,7 @@ void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap) dma_addr_t dma_handle; void *addr_handle; - for (i = 0; (pmap != 0); i++) { + for (i = 0; (pmap != NULL); i++) { diva_get_dma_map_entry(pmap, i, &cpu_addr, &phys_addr); if (!cpu_addr) { break; @@ -410,14 +403,14 @@ void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap) DBG_TRC(("dma map free [%d]=(%08lx:%08x:%08lx)", i, (unsigned long) cpu_addr, (dword) dma_handle, (unsigned long) addr_handle)) - } + } diva_free_dma_mapping(pmap); } /********************************************************* - ** I/O port utilities + ** I/O port utilities *********************************************************/ int @@ -427,7 +420,7 @@ diva_os_register_io_port(void *adapter, int on, unsigned long port, if (on) { if (!request_region(port, length, name)) { DBG_ERR(("A: I/O: can't register port=%08x", port)) - return (-1); + return (-1); } } else { release_region(port, length); @@ -450,7 +443,7 @@ void divasa_unmap_pci_bar(void __iomem *bar) } /********************************************************* - ** I/O port access + ** I/O port access *********************************************************/ byte __inline__ inpp(void __iomem *addr) { @@ -483,12 +476,12 @@ void __inline__ outpp(void __iomem *addr, word p) } /* -------------------------------------------------------------------------- - IRQ request / remove + IRQ request / remove -------------------------------------------------------------------------- */ int diva_os_register_irq(void *context, byte irq, const char *name) { int result = request_irq(irq, diva_os_irq_wrapper, - SA_INTERRUPT | SA_SHIRQ, name, context); + IRQF_SHARED, name, context); return (result); } @@ -498,7 +491,7 @@ void diva_os_remove_irq(void *context, byte irq) } /* -------------------------------------------------------------------------- - DPC framework implementation + DPC framework implementation -------------------------------------------------------------------------- */ static void diva_os_dpc_proc(unsigned long context) { @@ -508,7 +501,7 @@ static void diva_os_dpc_proc(unsigned long context) (*(pisr->callback)) (pisr, pisr->callback_context); } -int diva_os_initialize_soft_isr(diva_os_soft_isr_t * psoft_isr, +int diva_os_initialize_soft_isr(diva_os_soft_isr_t *psoft_isr, diva_os_soft_isr_callback_t callback, void *callback_context) { @@ -527,11 +520,11 @@ int diva_os_initialize_soft_isr(diva_os_soft_isr_t * psoft_isr, return (0); } -int diva_os_schedule_soft_isr(diva_os_soft_isr_t * psoft_isr) +int diva_os_schedule_soft_isr(diva_os_soft_isr_t *psoft_isr) { if (psoft_isr && psoft_isr->object) { diva_os_thread_dpc_t *pdpc = - (diva_os_thread_dpc_t *) psoft_isr->object; + (diva_os_thread_dpc_t *) psoft_isr->object; tasklet_schedule(&pdpc->divas_task); } @@ -539,20 +532,19 @@ int diva_os_schedule_soft_isr(diva_os_soft_isr_t * psoft_isr) return (1); } -int diva_os_cancel_soft_isr(diva_os_soft_isr_t * psoft_isr) +int diva_os_cancel_soft_isr(diva_os_soft_isr_t *psoft_isr) { return (0); } -void diva_os_remove_soft_isr(diva_os_soft_isr_t * psoft_isr) +void diva_os_remove_soft_isr(diva_os_soft_isr_t *psoft_isr) { if (psoft_isr && psoft_isr->object) { diva_os_thread_dpc_t *pdpc = - (diva_os_thread_dpc_t *) psoft_isr->object; + (diva_os_thread_dpc_t *) psoft_isr->object; void *mem; tasklet_kill(&pdpc->divas_task); - flush_scheduled_work(); mem = psoft_isr->object; psoft_isr->object = NULL; diva_os_free(0, mem); @@ -597,7 +589,7 @@ static int divas_release(struct inode *inode, struct file *file) } static ssize_t divas_write(struct file *file, const char __user *buf, - size_t count, loff_t * ppos) + size_t count, loff_t *ppos) { int ret = -EINVAL; @@ -628,7 +620,7 @@ static ssize_t divas_write(struct file *file, const char __user *buf, } static ssize_t divas_read(struct file *file, char __user *buf, - size_t count, loff_t * ppos) + size_t count, loff_t *ppos) { int ret = -EINVAL; @@ -658,7 +650,7 @@ static ssize_t divas_read(struct file *file, char __user *buf, return (ret); } -static unsigned int divas_poll(struct file *file, poll_table * wait) +static unsigned int divas_poll(struct file *file, poll_table *wait) { if (!file->private_data) { return (POLLERR); @@ -666,7 +658,7 @@ static unsigned int divas_poll(struct file *file, poll_table * wait) return (POLLIN | POLLRDNORM); } -static struct file_operations divas_fops = { +static const struct file_operations divas_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = divas_read, @@ -678,11 +670,10 @@ static struct file_operations divas_fops = { static void divas_unregister_chrdev(void) { - devfs_remove(DEVNAME); unregister_chrdev(major, DEVNAME); } -static int DIVA_INIT_FUNCTION divas_register_chrdev(void) +static int __init divas_register_chrdev(void) { if ((major = register_chrdev(0, DEVNAME, &divas_fops)) < 0) { @@ -690,16 +681,14 @@ static int DIVA_INIT_FUNCTION divas_register_chrdev(void) DRIVERLNAME); return (0); } - devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME); return (1); } /* -------------------------------------------------------------------------- - PCI driver section + PCI driver section -------------------------------------------------------------------------- */ -static int __devinit divas_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int divas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { void *pdiva = NULL; u8 pci_latency; @@ -708,9 +697,9 @@ static int __devinit divas_init_one(struct pci_dev *pdev, DBG_TRC(("%s bus: %08x fn: %08x insertion.\n", CardProperties[ent->driver_data].Name, pdev->bus->number, pdev->devfn)) - printk(KERN_INFO "%s: %s bus: %08x fn: %08x insertion.\n", - DRIVERLNAME, CardProperties[ent->driver_data].Name, - pdev->bus->number, pdev->devfn); + printk(KERN_INFO "%s: %s bus: %08x fn: %08x insertion.\n", + DRIVERLNAME, CardProperties[ent->driver_data].Name, + pdev->bus->number, pdev->devfn); if (pci_enable_device(pdev)) { DBG_TRC(("%s: %s bus: %08x fn: %08x device init failed.\n", @@ -718,12 +707,12 @@ static int __devinit divas_init_one(struct pci_dev *pdev, CardProperties[ent->driver_data].Name, pdev->bus->number, pdev->devfn)) - printk(KERN_ERR - "%s: %s bus: %08x fn: %08x device init failed.\n", - DRIVERLNAME, - CardProperties[ent->driver_data]. - Name, pdev->bus->number, - pdev->devfn); + printk(KERN_ERR + "%s: %s bus: %08x fn: %08x device init failed.\n", + DRIVERLNAME, + CardProperties[ent->driver_data]. + Name, pdev->bus->number, + pdev->devfn); return (-EIO); } @@ -733,9 +722,9 @@ static int __devinit divas_init_one(struct pci_dev *pdev, if (!pci_latency) { DBG_TRC(("%s: bus: %08x fn: %08x fix latency.\n", DRIVERLNAME, pdev->bus->number, pdev->devfn)) - printk(KERN_INFO - "%s: bus: %08x fn: %08x fix latency.\n", - DRIVERLNAME, pdev->bus->number, pdev->devfn); + printk(KERN_INFO + "%s: bus: %08x fn: %08x fix latency.\n", + DRIVERLNAME, pdev->bus->number, pdev->devfn); pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency); } @@ -745,12 +734,12 @@ static int __devinit divas_init_one(struct pci_dev *pdev, CardProperties[ent->driver_data].Name, pdev->bus->number, pdev->devfn)) - printk(KERN_ERR - "%s: %s bus: %08x fn: %08x card init failed.\n", - DRIVERLNAME, - CardProperties[ent->driver_data]. - Name, pdev->bus->number, - pdev->devfn); + printk(KERN_ERR + "%s: %s bus: %08x fn: %08x card init failed.\n", + DRIVERLNAME, + CardProperties[ent->driver_data]. + Name, pdev->bus->number, + pdev->devfn); return (-EIO); } @@ -759,14 +748,14 @@ static int __devinit divas_init_one(struct pci_dev *pdev, return (0); } -static void __devexit divas_remove_one(struct pci_dev *pdev) +static void divas_remove_one(struct pci_dev *pdev) { void *pdiva = pci_get_drvdata(pdev); DBG_TRC(("bus: %08x fn: %08x removal.\n", pdev->bus->number, pdev->devfn)) - printk(KERN_INFO "%s: bus: %08x fn: %08x removal.\n", - DRIVERLNAME, pdev->bus->number, pdev->devfn); + printk(KERN_INFO "%s: bus: %08x fn: %08x removal.\n", + DRIVERLNAME, pdev->bus->number, pdev->devfn); if (pdiva) { diva_driver_remove_card(pdiva); @@ -775,9 +764,9 @@ static void __devexit divas_remove_one(struct pci_dev *pdev) } /* -------------------------------------------------------------------------- - Driver Load / Startup + Driver Load / Startup -------------------------------------------------------------------------- */ -static int DIVA_INIT_FUNCTION divas_init(void) +static int __init divas_init(void) { char tmprev[50]; int ret = 0; @@ -813,7 +802,6 @@ static int DIVA_INIT_FUNCTION divas_init(void) if (!create_divas_proc()) { #ifdef MODULE - remove_divas_proc(); divas_unregister_chrdev(); divasfunc_exit(); #endif @@ -835,14 +823,14 @@ static int DIVA_INIT_FUNCTION divas_init(void) } printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major); - out: +out: return (ret); } /* -------------------------------------------------------------------------- - Driver Unload + Driver Unload -------------------------------------------------------------------------- */ -static void DIVA_EXIT_FUNCTION divas_exit(void) +static void __exit divas_exit(void) { pci_unregister_driver(&diva_pci_driver); remove_divas_proc(); diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c index c12efa6f842..56ce98a4e24 100644 --- a/drivers/isdn/hardware/eicon/divasproc.c +++ b/drivers/isdn/hardware/eicon/divasproc.c @@ -10,11 +10,11 @@ * of the GNU General Public License, incorporated herein by reference. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/poll.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/list.h> #include <asm/uaccess.h> @@ -55,7 +55,7 @@ extern struct proc_dir_entry *proc_net_eicon; static struct proc_dir_entry *divas_proc_entry = NULL; static ssize_t -divas_read(struct file *file, char __user *buf, size_t count, loff_t * off) +divas_read(struct file *file, char __user *buf, size_t count, loff_t *off) { int len = 0; int cadapter; @@ -94,12 +94,12 @@ divas_read(struct file *file, char __user *buf, size_t count, loff_t * off) } static ssize_t -divas_write(struct file *file, const char __user *buf, size_t count, loff_t * off) +divas_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { return (-ENODEV); } -static unsigned int divas_poll(struct file *file, poll_table * wait) +static unsigned int divas_poll(struct file *file, poll_table *wait) { return (POLLERR); } @@ -114,7 +114,7 @@ static int divas_close(struct inode *inode, struct file *file) return (0); } -static struct file_operations divas_fops = { +static const struct file_operations divas_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = divas_read, @@ -126,15 +126,11 @@ static struct file_operations divas_fops = { int create_divas_proc(void) { - divas_proc_entry = create_proc_entry(divas_proc_name, - S_IFREG | S_IRUGO, - proc_net_eicon); + divas_proc_entry = proc_create(divas_proc_name, S_IFREG | S_IRUGO, + proc_net_eicon, &divas_fops); if (!divas_proc_entry) return (0); - divas_proc_entry->proc_fops = &divas_fops; - divas_proc_entry->owner = THIS_MODULE; - return (1); } @@ -146,14 +142,10 @@ void remove_divas_proc(void) } } -/* -** write group_optimization -*/ -static int -write_grp_opt(struct file *file, const char __user *buffer, unsigned long count, - void *data) +static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; + diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file)); PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; if ((count == 1) || (count == 2)) { @@ -163,11 +155,11 @@ write_grp_opt(struct file *file, const char __user *buffer, unsigned long count, switch (c) { case '0': IoAdapter->capi_cfg.cfg_1 &= - ~DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON; + ~DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON; break; case '1': IoAdapter->capi_cfg.cfg_1 |= - DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON; + DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON; break; default: return (-EINVAL); @@ -177,14 +169,10 @@ write_grp_opt(struct file *file, const char __user *buffer, unsigned long count, return (-EINVAL); } -/* -** write dynamic_l1_down -*/ -static int -write_d_l1_down(struct file *file, const char __user *buffer, unsigned long count, - void *data) +static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; + diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file)); PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; if ((count == 1) || (count == 2)) { @@ -194,11 +182,11 @@ write_d_l1_down(struct file *file, const char __user *buffer, unsigned long coun switch (c) { case '0': IoAdapter->capi_cfg.cfg_1 &= - ~DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON; + ~DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON; break; case '1': IoAdapter->capi_cfg.cfg_1 |= - DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON; + DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON; break; default: return (-EINVAL); @@ -208,63 +196,62 @@ write_d_l1_down(struct file *file, const char __user *buffer, unsigned long coun return (-EINVAL); } - -/* -** read dynamic_l1_down -*/ -static int -read_d_l1_down(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int d_l1_down_proc_show(struct seq_file *m, void *v) { - int len = 0; - diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; + diva_os_xdi_adapter_t *a = m->private; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; - len += sprintf(page + len, "%s\n", - (IoAdapter->capi_cfg. - cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" : - "0"); + seq_printf(m, "%s\n", + (IoAdapter->capi_cfg. + cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" : + "0"); + return 0; +} - if (off + count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len - off) ? count : len - off); +static int d_l1_down_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, d_l1_down_proc_show, PDE_DATA(inode)); } -/* -** read group_optimization -*/ -static int -read_grp_opt(char *page, char **start, off_t off, int count, int *eof, - void *data) +static const struct file_operations d_l1_down_proc_fops = { + .owner = THIS_MODULE, + .open = d_l1_down_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = d_l1_down_proc_write, +}; + +static int grp_opt_proc_show(struct seq_file *m, void *v) { - int len = 0; - diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; + diva_os_xdi_adapter_t *a = m->private; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; - len += sprintf(page + len, "%s\n", - (IoAdapter->capi_cfg. - cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) - ? "1" : "0"); + seq_printf(m, "%s\n", + (IoAdapter->capi_cfg. + cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) + ? "1" : "0"); + return 0; +} - if (off + count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len - off) ? count : len - off); +static int grp_opt_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, grp_opt_proc_show, PDE_DATA(inode)); } -/* -** info write -*/ -static int -info_write(struct file *file, const char __user *buffer, unsigned long count, - void *data) +static const struct file_operations grp_opt_proc_fops = { + .owner = THIS_MODULE, + .open = grp_opt_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = grp_opt_proc_write, +}; + +static ssize_t info_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { - diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; + diva_os_xdi_adapter_t *a = PDE_DATA(file_inode(file)); PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; char c[4]; @@ -282,69 +269,52 @@ info_write(struct file *file, const char __user *buffer, unsigned long count, return (-EINVAL); } -/* -** info read -*/ -static int -info_read(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int info_proc_show(struct seq_file *m, void *v) { int i = 0; - int len = 0; char *p; char tmpser[16]; - diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; + diva_os_xdi_adapter_t *a = m->private; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; - len += - sprintf(page + len, "Name : %s\n", - IoAdapter->Properties.Name); - len += sprintf(page + len, "DSP state : %08x\n", a->dsp_mask); - len += sprintf(page + len, "Channels : %02d\n", - IoAdapter->Properties.Channels); - len += sprintf(page + len, "E. max/used : %03d/%03d\n", - IoAdapter->e_max, IoAdapter->e_count); + seq_printf(m, "Name : %s\n", IoAdapter->Properties.Name); + seq_printf(m, "DSP state : %08x\n", a->dsp_mask); + seq_printf(m, "Channels : %02d\n", IoAdapter->Properties.Channels); + seq_printf(m, "E. max/used : %03d/%03d\n", + IoAdapter->e_max, IoAdapter->e_count); diva_get_vserial_number(IoAdapter, tmpser); - len += sprintf(page + len, "Serial : %s\n", tmpser); - len += - sprintf(page + len, "IRQ : %d\n", - IoAdapter->irq_info.irq_nr); - len += sprintf(page + len, "CardIndex : %d\n", a->CardIndex); - len += sprintf(page + len, "CardOrdinal : %d\n", a->CardOrdinal); - len += sprintf(page + len, "Controller : %d\n", a->controller); - len += sprintf(page + len, "Bus-Type : %s\n", - (a->Bus == - DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI"); - len += sprintf(page + len, "Port-Name : %s\n", a->port_name); + seq_printf(m, "Serial : %s\n", tmpser); + seq_printf(m, "IRQ : %d\n", IoAdapter->irq_info.irq_nr); + seq_printf(m, "CardIndex : %d\n", a->CardIndex); + seq_printf(m, "CardOrdinal : %d\n", a->CardOrdinal); + seq_printf(m, "Controller : %d\n", a->controller); + seq_printf(m, "Bus-Type : %s\n", + (a->Bus == + DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI"); + seq_printf(m, "Port-Name : %s\n", a->port_name); if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) { - len += - sprintf(page + len, "PCI-bus : %d\n", - a->resources.pci.bus); - len += - sprintf(page + len, "PCI-func : %d\n", - a->resources.pci.func); + seq_printf(m, "PCI-bus : %d\n", a->resources.pci.bus); + seq_printf(m, "PCI-func : %d\n", a->resources.pci.func); for (i = 0; i < 8; i++) { if (a->resources.pci.bar[i]) { - len += - sprintf(page + len, - "Mem / I/O %d : 0x%x / mapped : 0x%lx", - i, a->resources.pci.bar[i], - (unsigned long) a->resources. - pci.addr[i]); + seq_printf(m, + "Mem / I/O %d : 0x%x / mapped : 0x%lx", + i, a->resources.pci.bar[i], + (unsigned long) a->resources. + pci.addr[i]); if (a->resources.pci.length[i]) { - len += - sprintf(page + len, - " / length : %d", - a->resources.pci. - length[i]); + seq_printf(m, + " / length : %d", + a->resources.pci. + length[i]); } - len += sprintf(page + len, "\n"); + seq_putc(m, '\n'); } } } if ((!a->xdi_adapter.port) && ((!a->xdi_adapter.ram) || - (!a->xdi_adapter.reset) + (!a->xdi_adapter.reset) || (!a->xdi_adapter.cfg))) { if (!IoAdapter->irq_info.irq_nr) { p = "slave"; @@ -358,24 +328,33 @@ info_read(char *page, char **start, off_t off, int count, int *eof, } else { p = "ready"; } - len += sprintf(page + len, "State : %s\n", p); + seq_printf(m, "State : %s\n", p); - if (off + count >= len) - *eof = 1; - if (len < off) - return 0; - *start = page + off; - return ((count < len - off) ? count : len - off); + return 0; +} + +static int info_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, info_proc_show, PDE_DATA(inode)); } +static const struct file_operations info_proc_fops = { + .owner = THIS_MODULE, + .open = info_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = info_proc_write, +}; + /* ** adapter proc init/de-init */ /* -------------------------------------------------------------------------- - Create adapter directory and files in proc file system + Create adapter directory and files in proc file system -------------------------------------------------------------------------- */ -int create_adapter_proc(diva_os_xdi_adapter_t * a) +int create_adapter_proc(diva_os_xdi_adapter_t *a) { struct proc_dir_entry *de, *pe; char tmp[16]; @@ -385,28 +364,20 @@ int create_adapter_proc(diva_os_xdi_adapter_t * a) return (0); a->proc_adapter_dir = (void *) de; - if (!(pe = - create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR, de))) + pe = proc_create_data(info_proc_name, S_IRUGO | S_IWUSR, de, + &info_proc_fops, a); + if (!pe) return (0); a->proc_info = (void *) pe; - pe->write_proc = info_write; - pe->read_proc = info_read; - pe->data = a; - if ((pe = create_proc_entry(grp_opt_proc_name, - S_IFREG | S_IRUGO | S_IWUSR, de))) { + pe = proc_create_data(grp_opt_proc_name, S_IRUGO | S_IWUSR, de, + &grp_opt_proc_fops, a); + if (pe) a->proc_grp_opt = (void *) pe; - pe->write_proc = write_grp_opt; - pe->read_proc = read_grp_opt; - pe->data = a; - } - if ((pe = create_proc_entry(d_l1_down_proc_name, - S_IFREG | S_IRUGO | S_IWUSR, de))) { + pe = proc_create_data(d_l1_down_proc_name, S_IRUGO | S_IWUSR, de, + &d_l1_down_proc_fops, a); + if (pe) a->proc_d_l1_down = (void *) pe; - pe->write_proc = write_d_l1_down; - pe->read_proc = read_d_l1_down; - pe->data = a; - } DBG_TRC(("proc entry %s created", tmp)); @@ -414,9 +385,9 @@ int create_adapter_proc(diva_os_xdi_adapter_t * a) } /* -------------------------------------------------------------------------- - Remove adapter directory and files in proc file system + Remove adapter directory and files in proc file system -------------------------------------------------------------------------- */ -void remove_adapter_proc(diva_os_xdi_adapter_t * a) +void remove_adapter_proc(diva_os_xdi_adapter_t *a) { char tmp[16]; diff --git a/drivers/isdn/hardware/eicon/divasync.h b/drivers/isdn/hardware/eicon/divasync.h index 0a5be7f969f..dd6b53a2c2c 100644 --- a/drivers/isdn/hardware/eicon/divasync.h +++ b/drivers/isdn/hardware/eicon/divasync.h @@ -1,29 +1,29 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -#ifndef __DIVA_SYNC__H +#ifndef __DIVA_SYNC__H #define __DIVA_SYNC__H #define IDI_SYNC_REQ_REMOVE 0x00 #define IDI_SYNC_REQ_GET_NAME 0x01 @@ -59,26 +59,26 @@ /******************************************************************************/ #define IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES 0x92 /* - To receive XDI features: - 1. set 'buffer_length_in_bytes' to length of you buffer - 2. set 'features' to pointer to your buffer - 3. issue synchronous request to XDI - 4. Check that feature 'DIVA_XDI_EXTENDED_FEATURES_VALID' is present - after call. This feature does indicate that your request - was processed and XDI does support this synchronous request - 5. if on return bit 31 (0x80000000) in 'buffer_length_in_bytes' is - set then provided buffer was too small, and bits 30-0 does - contain necessary length of buffer. - in this case only features that do find place in the buffer - are indicated to caller + To receive XDI features: + 1. set 'buffer_length_in_bytes' to length of you buffer + 2. set 'features' to pointer to your buffer + 3. issue synchronous request to XDI + 4. Check that feature 'DIVA_XDI_EXTENDED_FEATURES_VALID' is present + after call. This feature does indicate that your request + was processed and XDI does support this synchronous request + 5. if on return bit 31 (0x80000000) in 'buffer_length_in_bytes' is + set then provided buffer was too small, and bits 30-0 does + contain necessary length of buffer. + in this case only features that do find place in the buffer + are indicated to caller */ typedef struct _diva_xdi_get_extended_xdi_features { - dword buffer_length_in_bytes; - byte *features; + dword buffer_length_in_bytes; + byte *features; } diva_xdi_get_extended_xdi_features_t; /* - features[0] - */ + features[0] +*/ #define DIVA_XDI_EXTENDED_FEATURES_VALID 0x01 #define DIVA_XDI_EXTENDED_FEATURE_CMA 0x02 #define DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR 0x04 @@ -91,17 +91,17 @@ typedef struct _diva_xdi_get_extended_xdi_features { /******************************************************************************/ #define IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR 0x93 typedef struct _diva_xdi_get_adapter_sdram_bar { - dword bar; + dword bar; } diva_xdi_get_adapter_sdram_bar_t; /******************************************************************************/ #define IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS 0x94 /* CAPI Parameters will be written in the caller's buffer - */ +*/ typedef struct _diva_xdi_get_capi_parameters { - dword structure_length; - byte flag_dynamic_l1_down; - byte group_optimization_enabled; + dword structure_length; + byte flag_dynamic_l1_down; + byte group_optimization_enabled; } diva_xdi_get_capi_parameters_t; /******************************************************************************/ #define IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER 0x95 @@ -111,11 +111,11 @@ typedef struct _diva_xdi_get_capi_parameters { in case of one adapter that supports multiple interfaces 'controller' is zero for Master adapter (and adapter that supports only one interface) - */ +*/ typedef struct _diva_xdi_get_logical_adapter_number { - dword logical_adapter_number; - dword controller; - dword total_controllers; + dword logical_adapter_number; + dword controller; + dword total_controllers; } diva_xdi_get_logical_adapter_number_s_t; /******************************************************************************/ #define IDI_SYNC_REQ_UP1DM_OPERATION 0x96 @@ -124,10 +124,10 @@ typedef struct _diva_xdi_get_logical_adapter_number { #define IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC 0x01 #define IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE 0x02 typedef struct _diva_xdi_dma_descriptor_operation { - int operation; - int descriptor_number; - void* descriptor_address; - dword descriptor_magic; + int operation; + int descriptor_number; + void *descriptor_address; + dword descriptor_magic; } diva_xdi_dma_descriptor_operation_t; /******************************************************************************/ #define IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY 0x01 @@ -137,22 +137,22 @@ typedef struct _diva_xdi_dma_descriptor_operation { #define IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY 0x05 #define IDI_SYNC_REQ_DIDD_GET_CFG_LIB_IFC 0x10 typedef struct _diva_didd_adapter_notify { - dword handle; /* Notification handle */ - void * callback; - void * context; + dword handle; /* Notification handle */ + void *callback; + void *context; } diva_didd_adapter_notify_t; typedef struct _diva_didd_add_adapter { - void * descriptor; + void *descriptor; } diva_didd_add_adapter_t; typedef struct _diva_didd_remove_adapter { - IDI_CALL p_request; + IDI_CALL p_request; } diva_didd_remove_adapter_t; typedef struct _diva_didd_read_adapter_array { - void * buffer; - dword length; + void *buffer; + dword length; } diva_didd_read_adapter_array_t; typedef struct _diva_didd_get_cfg_lib_ifc { - void* ifc; + void *ifc; } diva_didd_get_cfg_lib_ifc_t; /******************************************************************************/ #define IDI_SYNC_REQ_XDI_GET_STREAM 0x91 @@ -163,31 +163,31 @@ typedef struct _diva_didd_get_cfg_lib_ifc { #define DIVA_ISTREAM_COMPLETE_READ 1 #define DIVA_ISTREAM_COMPLETE_WRITE 2 typedef struct _diva_xdi_stream_interface { - unsigned char Id; /* filled by XDI client */ - unsigned char provided_service; /* filled by XDI */ - unsigned char requested_service; /* filled by XDI Client */ - void* xdi_context; /* filled by XDI */ - void* client_context; /* filled by XDI client */ - int (*write)(void* context, - int Id, - void* data, - int length, - int final, - byte usr1, - byte usr2); - int (*read)(void* context, - int Id, - void* data, - int max_length, - int* final, - byte* usr1, - byte* usr2); - int (*complete)(void* client_context, - int Id, - int what, - void* data, - int length, - int* final); + unsigned char Id; /* filled by XDI client */ + unsigned char provided_service; /* filled by XDI */ + unsigned char requested_service; /* filled by XDI Client */ + void *xdi_context; /* filled by XDI */ + void *client_context; /* filled by XDI client */ + int (*write)(void *context, + int Id, + void *data, + int length, + int final, + byte usr1, + byte usr2); + int (*read)(void *context, + int Id, + void *data, + int max_length, + int *final, + byte *usr1, + byte *usr2); + int (*complete)(void *client_context, + int Id, + int what, + void *data, + int length, + int *final); } diva_xdi_stream_interface_t; /******************************************************************************/ /* @@ -196,37 +196,37 @@ typedef struct _diva_xdi_stream_interface { typedef struct { unsigned char LineState; /* Modem line state (STATUS_R) */ #define SERIAL_GSM_CELL 0x01 /* GSM or CELL cable attached */ - unsigned char CardState; /* PCMCIA card state (0 = down) */ - unsigned char IsdnState; /* ISDN layer 1 state (0 = down)*/ - unsigned char HookState; /* current logical hook state */ + unsigned char CardState; /* PCMCIA card state (0 = down) */ + unsigned char IsdnState; /* ISDN layer 1 state (0 = down)*/ + unsigned char HookState; /* current logical hook state */ #define SERIAL_ON_HOOK 0x02 /* set in DIVA CTRL_R register */ } SERIAL_STATE; -typedef int ( * SERIAL_INT_CB) (void *Context) ; -typedef int ( * SERIAL_DPC_CB) (void *Context) ; -typedef unsigned char ( * SERIAL_I_SYNC) (void *Context) ; +typedef int (*SERIAL_INT_CB)(void *Context); +typedef int (*SERIAL_DPC_CB)(void *Context); +typedef unsigned char (*SERIAL_I_SYNC)(void *Context); typedef struct { /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */ - unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (is the request) */ - unsigned char Function; /* private function code */ + unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (is the request) */ + unsigned char Function; /* private function code */ #define SERIAL_HOOK_ATTACH 0x81 #define SERIAL_HOOK_STATUS 0x82 #define SERIAL_HOOK_I_SYNC 0x83 #define SERIAL_HOOK_NOECHO 0x84 #define SERIAL_HOOK_RING 0x85 #define SERIAL_HOOK_DETACH 0x8f - unsigned char Flags; /* function refinements */ - /* parameters passed by the the ATTACH request */ - SERIAL_INT_CB InterruptHandler; /* called on each interrupt */ - SERIAL_DPC_CB DeferredHandler; /* called on hook state changes */ - void *HandlerContext; /* context for both handlers */ - /* return values for both the ATTACH and the STATUS request */ - unsigned long IoBase; /* IO port assigned to UART */ - SERIAL_STATE State; - /* parameters and return values for the I_SYNC function */ - SERIAL_I_SYNC SyncFunction; /* to be called synchronized */ - void *SyncContext; /* context for this function */ - unsigned char SyncResult; /* return value of function */ + unsigned char Flags; /* function refinements */ + /* parameters passed by the ATTACH request */ + SERIAL_INT_CB InterruptHandler; /* called on each interrupt */ + SERIAL_DPC_CB DeferredHandler; /* called on hook state changes */ + void *HandlerContext; /* context for both handlers */ + /* return values for both the ATTACH and the STATUS request */ + unsigned long IoBase; /* IO port assigned to UART */ + SERIAL_STATE State; + /* parameters and return values for the I_SYNC function */ + SERIAL_I_SYNC SyncFunction; /* to be called synchronized */ + void *SyncContext; /* context for this function */ + unsigned char SyncResult; /* return value of function */ } SERIAL_HOOK; /* * IDI_SYNC_REQ_XCHANGE_STATUS - exchange the status between IDI and WMP @@ -234,29 +234,28 @@ typedef struct */ typedef struct { /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */ - unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (is the request) */ + unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (is the request) */ #define DRIVER_STATUS_BOOT 0xA1 #define DRIVER_STATUS_INIT_DEV 0xA2 #define DRIVER_STATUS_RUNNING 0xA3 #define DRIVER_STATUS_SHUTDOWN 0xAF #define DRIVER_STATUS_TRAPPED 0xAE - unsigned char wmpStatus; /* exported by WMP */ - unsigned char idiStatus; /* exported by IDI */ - unsigned long wizProto ; /* from WMP registry to IDI */ - /* the cardtype value is defined by cardtype.h */ - unsigned long cardType ; /* from IDI registry to WMP */ - unsigned long nt2 ; /* from IDI registry to WMP */ - unsigned long permanent ; /* from IDI registry to WMP */ - unsigned long stableL2 ; /* from IDI registry to WMP */ - unsigned long tei ; /* from IDI registry to WMP */ + unsigned char wmpStatus; /* exported by WMP */ + unsigned char idiStatus; /* exported by IDI */ + unsigned long wizProto; /* from WMP registry to IDI */ + /* the cardtype value is defined by cardtype.h */ + unsigned long cardType; /* from IDI registry to WMP */ + unsigned long nt2; /* from IDI registry to WMP */ + unsigned long permanent; /* from IDI registry to WMP */ + unsigned long stableL2; /* from IDI registry to WMP */ + unsigned long tei; /* from IDI registry to WMP */ #define CRC4_MASK 0x00000003 #define L1_TRISTATE_MASK 0x00000004 #define WATCHDOG_MASK 0x00000008 #define NO_ORDER_CHECK_MASK 0x00000010 #define LOW_CHANNEL_MASK 0x00000020 #define NO_HSCX30_MASK 0x00000040 -#define MODE_MASK 0x00000080 #define SET_BOARD 0x00001000 #define SET_CRC4 0x00030000 #define SET_L1_TRISTATE 0x00040000 @@ -272,36 +271,36 @@ typedef struct #define SET_STABLEL2 0x20000000 #define SET_TEI 0x40000000 #define SET_NUMBERLEN 0x80000000 - unsigned long Flag ; /* |31-Type-16|15-Mask-0| */ - unsigned long NumberLen ; /* reconfiguration: union is empty */ - union { - struct { /* possible reconfiguration, but ... ; SET_BOARD */ - unsigned long SerialNumber ; - char *pCardname ; /* di_defs.h: BOARD_NAME_LENGTH */ - } board ; - struct { /* reset: need resources */ - void * pRawResources ; - void * pXlatResources ; - } res ; - struct { /* reconfiguration: wizProto == PROTTYPE_RBSCAS */ + unsigned long Flag; /* |31-Type-16|15-Mask-0| */ + unsigned long NumberLen; /* reconfiguration: union is empty */ + union { + struct { /* possible reconfiguration, but ... ; SET_BOARD */ + unsigned long SerialNumber; + char *pCardname; /* di_defs.h: BOARD_NAME_LENGTH */ + } board; + struct { /* reset: need resources */ + void *pRawResources; + void *pXlatResources; + } res; + struct { /* reconfiguration: wizProto == PROTTYPE_RBSCAS */ #define GLARE_RESOLVE_MASK 0x00000001 #define DID_MASK 0x00000002 #define BEARER_CAP_MASK 0x0000000c #define SET_GLARE_RESOLVE 0x00010000 #define SET_DID 0x00020000 #define SET_BEARER_CAP 0x000c0000 - unsigned long Flag ; /* |31-Type-16|15-VALUE-0| */ - unsigned short DigitTimeout ; - unsigned short AnswerDelay ; - } rbs ; - struct { /* reconfiguration: wizProto == PROTTYPE_QSIG */ + unsigned long Flag; /* |31-Type-16|15-VALUE-0| */ + unsigned short DigitTimeout; + unsigned short AnswerDelay; + } rbs; + struct { /* reconfiguration: wizProto == PROTTYPE_QSIG */ #define CALL_REF_LENGTH1_MASK 0x00000001 #define BRI_CHANNEL_ID_MASK 0x00000002 #define SET_CALL_REF_LENGTH 0x00010000 #define SET_BRI_CHANNEL_ID 0x00020000 - unsigned long Flag ; /* |31-Type-16|15-VALUE-0| */ - } qsig ; - struct { /* reconfiguration: NumberLen != 0 */ + unsigned long Flag; /* |31-Type-16|15-VALUE-0| */ + } qsig; + struct { /* reconfiguration: NumberLen != 0 */ #define SET_SPID1 0x00010000 #define SET_NUMBER1 0x00020000 #define SET_SUBADDRESS1 0x00040000 @@ -309,50 +308,50 @@ typedef struct #define SET_NUMBER2 0x00200000 #define SET_SUBADDRESS2 0x00400000 #define MASK_SET 0xffff0000 - unsigned long Flag ; /* |31-Type-16|15-Channel-0| */ - unsigned char *pBuffer ; /* number value */ - } isdnNo ; - } -parms -; -} isdnProps ; + unsigned long Flag; /* |31-Type-16|15-Channel-0| */ + unsigned char *pBuffer; /* number value */ + } isdnNo; + } + parms + ; +} isdnProps; /* * IDI_SYNC_REQ_PORTDRV_HOOK - signal plug/unplug (Award Cardware only) */ -typedef void ( * PORTDRV_HOOK_CB) (void *Context, int Plug) ; +typedef void (*PORTDRV_HOOK_CB)(void *Context, int Plug); typedef struct { /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */ - unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (is the request) */ - unsigned char Function; /* private function code */ - unsigned char Flags; /* function refinements */ - PORTDRV_HOOK_CB Callback; /* to be called on plug/unplug */ - void *Context; /* context for callback */ - unsigned long Info; /* more info if needed */ -} PORTDRV_HOOK ; + unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (is the request) */ + unsigned char Function; /* private function code */ + unsigned char Flags; /* function refinements */ + PORTDRV_HOOK_CB Callback; /* to be called on plug/unplug */ + void *Context; /* context for callback */ + unsigned long Info; /* more info if needed */ +} PORTDRV_HOOK; /* Codes for the 'Rc' element in structure below. */ #define SLI_INSTALL (0xA1) #define SLI_UNINSTALL (0xA2) -typedef int ( * SLIENTRYPOINT)(void* p3SignalAPI, void* pContext); +typedef int (*SLIENTRYPOINT)(void *p3SignalAPI, void *pContext); typedef struct { /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */ - unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (is the request) */ - unsigned char Function; /* private function code */ - unsigned char Flags; /* function refinements */ - SLIENTRYPOINT Callback; /* to be called on plug/unplug */ - void *Context; /* context for callback */ - unsigned long Info; /* more info if needed */ -} SLIENTRYPOINT_REQ ; + unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (is the request) */ + unsigned char Function; /* private function code */ + unsigned char Flags; /* function refinements */ + SLIENTRYPOINT Callback; /* to be called on plug/unplug */ + void *Context; /* context for callback */ + unsigned long Info; /* more info if needed */ +} SLIENTRYPOINT_REQ; /******************************************************************************/ /* * Definitions for DIVA USB */ -typedef int ( * USB_SEND_REQ) (unsigned char PipeIndex, unsigned char Type,void *Data, int sizeData); -typedef int ( * USB_START_DEV) (void *Adapter, void *Ipac) ; +typedef int (*USB_SEND_REQ)(unsigned char PipeIndex, unsigned char Type, void *Data, int sizeData); +typedef int (*USB_START_DEV)(void *Adapter, void *Ipac); /* called from WDM */ -typedef void ( * USB_RECV_NOTIFY) (void *Ipac, void *msg) ; -typedef void ( * USB_XMIT_NOTIFY) (void *Ipac, unsigned char PipeIndex) ; +typedef void (*USB_RECV_NOTIFY)(void *Ipac, void *msg); +typedef void (*USB_XMIT_NOTIFY)(void *Ipac, unsigned char PipeIndex); /******************************************************************************/ /* * Parameter description for synchronous requests. @@ -362,129 +361,129 @@ typedef void ( * USB_XMIT_NOTIFY) (void *Ipac, unsigned char PipeIndex) ; */ typedef union { ENTITY Entity; - struct - { /* 'Req' and 'Rc' are at the same place as in the ENTITY struct */ - unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (is the request) */ - } Request; - struct - { unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (0x01) */ - unsigned char name[BOARD_NAME_LENGTH]; - } GetName; - struct - { unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (0x02) */ - unsigned long serial; /* serial number */ - } GetSerial; - struct - { unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (0x02) */ - unsigned long lineIdx;/* line, 0 if card has only one */ - } GetLineIdx; - struct - { unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (0x02) */ - unsigned long cardtype;/* card type */ - } GetCardType; - struct - { unsigned short command;/* command = 0x0300 */ - unsigned short dummy; /* not used */ - IDI_CALL callback;/* routine to call back */ - ENTITY *contxt; /* ptr to entity to use */ - } PostCall; - struct - { unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (0x04) */ - unsigned char pcm[1]; /* buffer (a pc_maint struct) */ - } GetXlog; - struct - { unsigned char Req; /* request (must be always 0) */ - unsigned char Rc; /* return code (0x05) */ - unsigned short features;/* feature defines see below */ - } GetFeatures; - SERIAL_HOOK SerialHook; + struct + { /* 'Req' and 'Rc' are at the same place as in the ENTITY struct */ + unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (is the request) */ + } Request; + struct + { unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (0x01) */ + unsigned char name[BOARD_NAME_LENGTH]; + } GetName; + struct + { unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (0x02) */ + unsigned long serial; /* serial number */ + } GetSerial; + struct + { unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (0x02) */ + unsigned long lineIdx;/* line, 0 if card has only one */ + } GetLineIdx; + struct + { unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (0x02) */ + unsigned long cardtype;/* card type */ + } GetCardType; + struct + { unsigned short command;/* command = 0x0300 */ + unsigned short dummy; /* not used */ + IDI_CALL callback;/* routine to call back */ + ENTITY *contxt; /* ptr to entity to use */ + } PostCall; + struct + { unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (0x04) */ + unsigned char pcm[1]; /* buffer (a pc_maint struct) */ + } GetXlog; + struct + { unsigned char Req; /* request (must be always 0) */ + unsigned char Rc; /* return code (0x05) */ + unsigned short features;/* feature defines see below */ + } GetFeatures; + SERIAL_HOOK SerialHook; /* Added for DIVA USB */ - struct - { unsigned char Req; - unsigned char Rc; - USB_SEND_REQ UsbSendRequest; /* function in Diva Usb WDM driver in usb_os.c, */ - /* called from usb_drv.c to send a message to our device */ - /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0) ; */ - USB_RECV_NOTIFY usb_recv; /* called from usb_os.c to pass a received message and ptr to IPAC */ - /* on to usb_drv.c by a call to usb_recv(). */ - USB_XMIT_NOTIFY usb_xmit; /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */ - /* to usb_drv.c by a call to usb_xmit(). */ - USB_START_DEV UsbStartDevice; /* Start the USB Device, in usb_os.c */ - IDI_CALL callback; /* routine to call back */ - ENTITY *contxt; /* ptr to entity to use */ - void ** ipac_ptr; /* pointer to struct IPAC in VxD */ - } Usb_Msg_old; + struct + { unsigned char Req; + unsigned char Rc; + USB_SEND_REQ UsbSendRequest; /* function in Diva Usb WDM driver in usb_os.c, */ + /* called from usb_drv.c to send a message to our device */ + /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0); */ + USB_RECV_NOTIFY usb_recv; /* called from usb_os.c to pass a received message and ptr to IPAC */ + /* on to usb_drv.c by a call to usb_recv(). */ + USB_XMIT_NOTIFY usb_xmit; /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */ + /* to usb_drv.c by a call to usb_xmit(). */ + USB_START_DEV UsbStartDevice; /* Start the USB Device, in usb_os.c */ + IDI_CALL callback; /* routine to call back */ + ENTITY *contxt; /* ptr to entity to use */ + void **ipac_ptr; /* pointer to struct IPAC in VxD */ + } Usb_Msg_old; /* message used by WDM and VXD to pass pointers of function and IPAC* */ - struct - { unsigned char Req; - unsigned char Rc; - USB_SEND_REQ pUsbSendRequest;/* function in Diva Usb WDM driver in usb_os.c, */ - /* called from usb_drv.c to send a message to our device */ - /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0) ; */ - USB_RECV_NOTIFY p_usb_recv; /* called from usb_os.c to pass a received message and ptr to IPAC */ - /* on to usb_drv.c by a call to usb_recv(). */ - USB_XMIT_NOTIFY p_usb_xmit; /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */ - /* to usb_drv.c by a call to usb_xmit().*/ - void *ipac_ptr; /* &Diva.ipac pointer to struct IPAC in VxD */ - } Usb_Msg; - PORTDRV_HOOK PortdrvHook; - SLIENTRYPOINT_REQ sliEntryPointReq; - struct { - unsigned char Req; - unsigned char Rc; - diva_xdi_stream_interface_t info; - } xdi_stream_info; - struct { - unsigned char Req; - unsigned char Rc; - diva_xdi_get_extended_xdi_features_t info; - } xdi_extended_features; - struct { - unsigned char Req; - unsigned char Rc; - diva_xdi_get_adapter_sdram_bar_t info; - } xdi_sdram_bar; - struct { - unsigned char Req; - unsigned char Rc; - diva_xdi_get_capi_parameters_t info; - } xdi_capi_prms; - struct { - ENTITY e; - diva_didd_adapter_notify_t info; - } didd_notify; - struct { - ENTITY e; - diva_didd_add_adapter_t info; - } didd_add_adapter; - struct { - ENTITY e; - diva_didd_remove_adapter_t info; - } didd_remove_adapter; - struct { - ENTITY e; - diva_didd_read_adapter_array_t info; - } didd_read_adapter_array; - struct { - ENTITY e; - diva_didd_get_cfg_lib_ifc_t info; - } didd_get_cfg_lib_ifc; - struct { - unsigned char Req; - unsigned char Rc; - diva_xdi_get_logical_adapter_number_s_t info; - } xdi_logical_adapter_number; - struct { - unsigned char Req; - unsigned char Rc; - diva_xdi_dma_descriptor_operation_t info; - } xdi_dma_descriptor_operation; + struct + { unsigned char Req; + unsigned char Rc; + USB_SEND_REQ pUsbSendRequest;/* function in Diva Usb WDM driver in usb_os.c, */ + /* called from usb_drv.c to send a message to our device */ + /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0); */ + USB_RECV_NOTIFY p_usb_recv; /* called from usb_os.c to pass a received message and ptr to IPAC */ + /* on to usb_drv.c by a call to usb_recv(). */ + USB_XMIT_NOTIFY p_usb_xmit; /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */ + /* to usb_drv.c by a call to usb_xmit().*/ + void *ipac_ptr; /* &Diva.ipac pointer to struct IPAC in VxD */ + } Usb_Msg; + PORTDRV_HOOK PortdrvHook; + SLIENTRYPOINT_REQ sliEntryPointReq; + struct { + unsigned char Req; + unsigned char Rc; + diva_xdi_stream_interface_t info; + } xdi_stream_info; + struct { + unsigned char Req; + unsigned char Rc; + diva_xdi_get_extended_xdi_features_t info; + } xdi_extended_features; + struct { + unsigned char Req; + unsigned char Rc; + diva_xdi_get_adapter_sdram_bar_t info; + } xdi_sdram_bar; + struct { + unsigned char Req; + unsigned char Rc; + diva_xdi_get_capi_parameters_t info; + } xdi_capi_prms; + struct { + ENTITY e; + diva_didd_adapter_notify_t info; + } didd_notify; + struct { + ENTITY e; + diva_didd_add_adapter_t info; + } didd_add_adapter; + struct { + ENTITY e; + diva_didd_remove_adapter_t info; + } didd_remove_adapter; + struct { + ENTITY e; + diva_didd_read_adapter_array_t info; + } didd_read_adapter_array; + struct { + ENTITY e; + diva_didd_get_cfg_lib_ifc_t info; + } didd_get_cfg_lib_ifc; + struct { + unsigned char Req; + unsigned char Rc; + diva_xdi_get_logical_adapter_number_s_t info; + } xdi_logical_adapter_number; + struct { + unsigned char Req; + unsigned char Rc; + diva_xdi_dma_descriptor_operation_t info; + } xdi_dma_descriptor_operation; } IDI_SYNC_REQ; /******************************************************************************/ -#endif /* __DIVA_SYNC__H */ +#endif /* __DIVA_SYNC__H */ diff --git a/drivers/isdn/hardware/eicon/dqueue.c b/drivers/isdn/hardware/eicon/dqueue.c index 98225822517..7958a2536a1 100644 --- a/drivers/isdn/hardware/eicon/dqueue.c +++ b/drivers/isdn/hardware/eicon/dqueue.c @@ -14,7 +14,7 @@ #include "dqueue.h" int -diva_data_q_init(diva_um_idi_data_queue_t * q, +diva_data_q_init(diva_um_idi_data_queue_t *q, int max_length, int max_segments) { int i; @@ -38,7 +38,7 @@ diva_data_q_init(diva_um_idi_data_queue_t * q, return (0); } -int diva_data_q_finit(diva_um_idi_data_queue_t * q) +int diva_data_q_finit(diva_um_idi_data_queue_t *q) { int i; @@ -54,12 +54,12 @@ int diva_data_q_finit(diva_um_idi_data_queue_t * q) return (0); } -int diva_data_q_get_max_length(const diva_um_idi_data_queue_t * q) +int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q) { return (q->max_length); } -void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t * q) +void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q) { if ((!q->segment_pending) && (q->count < q->segments)) { q->segment_pending = 1; @@ -70,7 +70,7 @@ void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t * q) } void -diva_data_q_ack_segment4write(diva_um_idi_data_queue_t * q, int length) +diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q, int length) { if (q->segment_pending) { q->length[q->write] = length; @@ -92,12 +92,12 @@ const void *diva_data_q_get_segment4read(const diva_um_idi_data_queue_t * return NULL; } -int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t * q) +int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q) { return (q->length[q->read]); } -void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t * q) +void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q) { if (q->count) { q->length[q->read] = 0; diff --git a/drivers/isdn/hardware/eicon/dqueue.h b/drivers/isdn/hardware/eicon/dqueue.h index 72d21c96722..6992c45457a 100644 --- a/drivers/isdn/hardware/eicon/dqueue.h +++ b/drivers/isdn/hardware/eicon/dqueue.h @@ -16,16 +16,16 @@ typedef struct _diva_um_idi_data_queue { int length[DIVA_UM_IDI_MAX_MSGS]; } diva_um_idi_data_queue_t; -int diva_data_q_init(diva_um_idi_data_queue_t * q, +int diva_data_q_init(diva_um_idi_data_queue_t *q, int max_length, int max_segments); -int diva_data_q_finit(diva_um_idi_data_queue_t * q); -int diva_data_q_get_max_length(const diva_um_idi_data_queue_t * q); -void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t * q); -void diva_data_q_ack_segment4write(diva_um_idi_data_queue_t * q, +int diva_data_q_finit(diva_um_idi_data_queue_t *q); +int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q); +void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q); +void diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q, int length); const void *diva_data_q_get_segment4read(const diva_um_idi_data_queue_t * q); -int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t * q); -void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t * q); +int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q); +void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q); #endif diff --git a/drivers/isdn/hardware/eicon/dsp_defs.h b/drivers/isdn/hardware/eicon/dsp_defs.h index b44950e06f3..94828c87e2a 100644 --- a/drivers/isdn/hardware/eicon/dsp_defs.h +++ b/drivers/isdn/hardware/eicon/dsp_defs.h @@ -1,62 +1,59 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -#ifndef DSP_DEFS_H_ +#ifndef DSP_DEFS_H_ #define DSP_DEFS_H_ #include "dspdids.h" /*---------------------------------------------------------------------------*/ -#define dsp_download_reserve_space(fp,length) +#define dsp_download_reserve_space(fp, length) /*****************************************************************************/ /* * OS file access abstraction layer * * I/O functions returns -1 on error, 0 on EOF */ -#define OS_SEEK_SET 0 -#define OS_SEEK_CUR 1 -#define OS_SEEK_END 2 struct _OsFileHandle_; -typedef long ( * OsFileIo) (struct _OsFileHandle_ *handle, - void *buffer, - long size) ; -typedef long ( * OsFileSeek)(struct _OsFileHandle_ *handle, - long position, - int mode) ; -typedef long ( * OsCardLoad)(struct _OsFileHandle_ *handle, - long length, - void * *addr) ; +typedef long (*OsFileIo)(struct _OsFileHandle_ *handle, + void *buffer, + long size); +typedef long (*OsFileSeek)(struct _OsFileHandle_ *handle, + long position, + int mode); +typedef long (*OsCardLoad)(struct _OsFileHandle_ *handle, + long length, + void **addr); typedef struct _OsFileHandle_ -{ void *sysFileDesc ; - unsigned long sysFileSize ; - OsFileIo sysFileRead ; - OsFileSeek sysFileSeek ; - void *sysLoadDesc ; - OsCardLoad sysCardLoad ; -} OsFileHandle ; -extern OsFileHandle *OsOpenFile (char *path_name) ; -extern void OsCloseFile (OsFileHandle *fp) ; +{ void *sysFileDesc; + unsigned long sysFileSize; + OsFileIo sysFileRead; + OsFileSeek sysFileSeek; + void *sysLoadDesc; + OsCardLoad sysCardLoad; +} OsFileHandle; +extern OsFileHandle *OsOpenFile(char *path_name); +extern void OsCloseFile(OsFileHandle *fp); /*****************************************************************************/ #define DSP_TELINDUS_FILE "dspdload.bin" /* special DSP file for BRI cards for Qsig and CornetN because of missing memory */ @@ -96,109 +93,109 @@ extern void OsCloseFile (OsFileHandle *fp) ; #define DSP_FILE_FORMAT_VERSION_BCD 0x0100 typedef struct tag_dsp_combifile_header { - char format_identification[DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE]; - word format_version_bcd; - word header_size; - word combifile_description_size; - word directory_entries; - word directory_size; - word download_count; - word usage_mask_size; + char format_identification[DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE]; + word format_version_bcd; + word header_size; + word combifile_description_size; + word directory_entries; + word directory_size; + word download_count; + word usage_mask_size; } t_dsp_combifile_header; typedef struct tag_dsp_combifile_directory_entry { - word card_type_number; - word file_set_number; + word card_type_number; + word file_set_number; } t_dsp_combifile_directory_entry; typedef struct tag_dsp_file_header { - char format_identification[DSP_FILE_FORMAT_IDENTIFICATION_SIZE]; - word format_version_bcd; - word download_id; - word download_flags; - word required_processing_power; - word interface_channel_count; - word header_size; - word download_description_size; - word memory_block_table_size; - word memory_block_count; - word segment_table_size; - word segment_count; - word symbol_table_size; - word symbol_count; - word total_data_size_dm; - word data_block_count_dm; - word total_data_size_pm; - word data_block_count_pm; + char format_identification[DSP_FILE_FORMAT_IDENTIFICATION_SIZE]; + word format_version_bcd; + word download_id; + word download_flags; + word required_processing_power; + word interface_channel_count; + word header_size; + word download_description_size; + word memory_block_table_size; + word memory_block_count; + word segment_table_size; + word segment_count; + word symbol_table_size; + word symbol_count; + word total_data_size_dm; + word data_block_count_dm; + word total_data_size_pm; + word data_block_count_pm; } t_dsp_file_header; typedef struct tag_dsp_memory_block_desc { - word alias_memory_block; - word memory_type; - word address; - word size; /* DSP words */ + word alias_memory_block; + word memory_type; + word address; + word size; /* DSP words */ } t_dsp_memory_block_desc; typedef struct tag_dsp_segment_desc { - word memory_block; - word attributes; - word base; - word size; - word alignment; /* ==0 -> no other legal start address than base */ + word memory_block; + word attributes; + word base; + word size; + word alignment; /* ==0 -> no other legal start address than base */ } t_dsp_segment_desc; typedef struct tag_dsp_symbol_desc { - word symbol_id; - word segment; - word offset; - word size; /* DSP words */ + word symbol_id; + word segment; + word offset; + word size; /* DSP words */ } t_dsp_symbol_desc; typedef struct tag_dsp_data_block_header { - word attributes; - word segment; - word offset; - word size; /* DSP words */ + word attributes; + word segment; + word offset; + word size; /* DSP words */ } t_dsp_data_block_header; typedef struct tag_dsp_download_desc { - word download_id; - word download_flags; - word required_processing_power; - word interface_channel_count; - word excess_header_size; - word memory_block_count; - word segment_count; - word symbol_count; - word data_block_count_dm; - word data_block_count_pm; - byte * p_excess_header_data; - char * p_download_description; - t_dsp_memory_block_desc *p_memory_block_table; - t_dsp_segment_desc *p_segment_table; - t_dsp_symbol_desc *p_symbol_table; - word * p_data_blocks_dm; - word * p_data_blocks_pm; + word download_id; + word download_flags; + word required_processing_power; + word interface_channel_count; + word excess_header_size; + word memory_block_count; + word segment_count; + word symbol_count; + word data_block_count_dm; + word data_block_count_pm; + byte *p_excess_header_data; + char *p_download_description; + t_dsp_memory_block_desc *p_memory_block_table; + t_dsp_segment_desc *p_segment_table; + t_dsp_symbol_desc *p_symbol_table; + word *p_data_blocks_dm; + word *p_data_blocks_pm; } t_dsp_desc; typedef struct tag_dsp_portable_download_desc /* be sure to keep native alignment for MAESTRA's */ { - word download_id; - word download_flags; - word required_processing_power; - word interface_channel_count; - word excess_header_size; - word memory_block_count; - word segment_count; - word symbol_count; - word data_block_count_dm; - word data_block_count_pm; - dword p_excess_header_data; - dword p_download_description; - dword p_memory_block_table; - dword p_segment_table; - dword p_symbol_table; - dword p_data_blocks_dm; - dword p_data_blocks_pm; + word download_id; + word download_flags; + word required_processing_power; + word interface_channel_count; + word excess_header_size; + word memory_block_count; + word segment_count; + word symbol_count; + word data_block_count_dm; + word data_block_count_pm; + dword p_excess_header_data; + dword p_download_description; + dword p_memory_block_table; + dword p_segment_table; + dword p_symbol_table; + dword p_data_blocks_dm; + dword p_data_blocks_pm; } t_dsp_portable_desc; #define DSP_DOWNLOAD_INDEX_KERNEL 0 #define DSP30TX_DOWNLOAD_INDEX_KERNEL 1 @@ -207,7 +204,7 @@ typedef struct tag_dsp_portable_download_desc /* be sure to keep native alignmen #define DSP_DOWNLOAD_MAX_SEGMENTS 16 #define DSP_UDATA_REQUEST_RECONFIGURE 0 /* -parameters: + parameters: <word> reconfigure delay (in 8kHz samples) <word> reconfigure code <byte> reconfigure hdlc preamble flags @@ -232,11 +229,11 @@ parameters: #define DSP_RECONFIGURE_V17_12000 11 #define DSP_RECONFIGURE_V17_14400 12 /* -data indications if transparent framer + data indications if transparent framer <byte> data 0 <byte> data 1 ... -data indications if HDLC framer + data indications if HDLC framer <byte> data 0 <byte> data 1 ... @@ -246,17 +243,17 @@ data indications if HDLC framer */ #define DSP_UDATA_INDICATION_SYNC 0 /* -returns: + returns: <word> time of sync (sampled from counter at 8kHz) */ #define DSP_UDATA_INDICATION_DCD_OFF 1 /* -returns: + returns: <word> time of DCD off (sampled from counter at 8kHz) */ #define DSP_UDATA_INDICATION_DCD_ON 2 /* -returns: + returns: <word> time of DCD on (sampled from counter at 8kHz) <byte> connected norm <word> connected options @@ -264,12 +261,12 @@ returns: */ #define DSP_UDATA_INDICATION_CTS_OFF 3 /* -returns: + returns: <word> time of CTS off (sampled from counter at 8kHz) */ #define DSP_UDATA_INDICATION_CTS_ON 4 /* -returns: + returns: <word> time of CTS on (sampled from counter at 8kHz) <byte> connected norm <word> connected options @@ -295,10 +292,10 @@ returns: #define DSP_CONNECTED_NORM_V17 17 #define DSP_CONNECTED_OPTION_TRELLIS 0x0001 /*---------------------------------------------------------------------------*/ -extern char *dsp_read_file (OsFileHandle *fp, - word card_type_number, - word *p_dsp_download_count, - t_dsp_desc *p_dsp_download_table, - t_dsp_portable_desc *p_dsp_portable_download_table) ; +extern char *dsp_read_file(OsFileHandle *fp, + word card_type_number, + word *p_dsp_download_count, + t_dsp_desc *p_dsp_download_table, + t_dsp_portable_desc *p_dsp_portable_download_table); /*---------------------------------------------------------------------------*/ -#endif /* DSP_DEFS_H_ */ +#endif /* DSP_DEFS_H_ */ diff --git a/drivers/isdn/hardware/eicon/dsp_tst.h b/drivers/isdn/hardware/eicon/dsp_tst.h index a6021e5b1ae..fe36f138be8 100644 --- a/drivers/isdn/hardware/eicon/dsp_tst.h +++ b/drivers/isdn/hardware/eicon/dsp_tst.h @@ -4,8 +4,8 @@ #define __DIVA_PRI_HOST_TEST_DSPS_H__ /* - DSP registers on maestra pri - */ + DSP registers on maestra pri +*/ #define DSP1_PORT (0x00) #define DSP2_PORT (0x8) #define DSP3_PORT (0x800) @@ -39,9 +39,9 @@ #define DSP_ADR_OFFS 0x80 /*------------------------------------------------------------------ - Dsp related definitions + Dsp related definitions ------------------------------------------------------------------ */ #define DSP_SIGNATURE_PROBE_WORD 0x5a5a -#define dsp_make_address_ex(pm,address) ((word)((pm) ? (address) : (address) + 0x4000)) +#define dsp_make_address_ex(pm, address) ((word)((pm) ? (address) : (address) + 0x4000)) #endif diff --git a/drivers/isdn/hardware/eicon/dspdids.h b/drivers/isdn/hardware/eicon/dspdids.h index ebe131a53b9..957b33cc002 100644 --- a/drivers/isdn/hardware/eicon/dspdids.h +++ b/drivers/isdn/hardware/eicon/dspdids.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef DSPDIDS_H_ diff --git a/drivers/isdn/hardware/eicon/dsrv4bri.h b/drivers/isdn/hardware/eicon/dsrv4bri.h index 732d22dfe4a..f353fb6b893 100644 --- a/drivers/isdn/hardware/eicon/dsrv4bri.h +++ b/drivers/isdn/hardware/eicon/dsrv4bri.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_XDI_DSRV_4_BRI_INC__ @@ -35,6 +35,6 @@ #define PLX9054_SOFT_RESET 0x4000 #define PLX9054_RELOAD_EEPROM 0x2000 #define DIVA_4BRI_REVISION(__x__) (((__x__)->cardType == CARDTYPE_DIVASRV_Q_8M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_B_2M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_B_2F_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI)) -void diva_os_set_qBri_functions (PISDN_ADAPTER IoAdapter); -void diva_os_set_qBri2_functions (PISDN_ADAPTER IoAdapter); +void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter); +void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter); #endif diff --git a/drivers/isdn/hardware/eicon/dsrv_bri.h b/drivers/isdn/hardware/eicon/dsrv_bri.h index f38ebbe5333..8a67dbc65be 100644 --- a/drivers/isdn/hardware/eicon/dsrv_bri.h +++ b/drivers/isdn/hardware/eicon/dsrv_bri.h @@ -1,37 +1,37 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_XDI_DSRV_BRI_INC__ #define __DIVA_XDI_DSRV_BRI_INC__ /* - Functions exported from os dependent part of - BRI card configuration and used in - OS independed part - */ + Functions exported from os dependent part of + BRI card configuration and used in + OS independed part +*/ /* - Prepare OS dependent part of BRI functions - */ -void diva_os_prepare_maestra_functions (PISDN_ADAPTER IoAdapter); + Prepare OS dependent part of BRI functions +*/ +void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter); #endif diff --git a/drivers/isdn/hardware/eicon/dsrv_pri.h b/drivers/isdn/hardware/eicon/dsrv_pri.h index 861182666c8..fd1a9ff9f19 100644 --- a/drivers/isdn/hardware/eicon/dsrv_pri.h +++ b/drivers/isdn/hardware/eicon/dsrv_pri.h @@ -1,38 +1,38 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_XDI_DSRV_PRI_INC__ #define __DIVA_XDI_DSRV_PRI_INC__ /* - Functions exported from os dependent part of - PRI card configuration and used in - OS independed part - */ + Functions exported from os dependent part of + PRI card configuration and used in + OS independed part +*/ /* - Prepare OS dependent part of PRI/PRI Rev.2 functions - */ -void diva_os_prepare_pri_functions (PISDN_ADAPTER IoAdapter); -void diva_os_prepare_pri2_functions (PISDN_ADAPTER IoAdapter); + Prepare OS dependent part of PRI/PRI Rev.2 functions +*/ +void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter); +void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter); #endif diff --git a/drivers/isdn/hardware/eicon/entity.h b/drivers/isdn/hardware/eicon/entity.h index 16252cf164b..fdb83416af3 100644 --- a/drivers/isdn/hardware/eicon/entity.h +++ b/drivers/isdn/hardware/eicon/entity.h @@ -11,17 +11,17 @@ typedef struct _divas_um_idi_entity { struct list_head link; - diva_um_idi_adapter_t* adapter; /* Back to adapter */ - ENTITY e; - void* os_ref; - dword status; - void* os_context; - int rc_count; + diva_um_idi_adapter_t *adapter; /* Back to adapter */ + ENTITY e; + void *os_ref; + dword status; + void *os_context; + int rc_count; diva_um_idi_data_queue_t data; /* definad by user 1 ... MAX */ diva_um_idi_data_queue_t rc; /* two entries */ BUFFERS XData; BUFFERS RData; - byte buffer[2048+512]; + byte buffer[2048 + 512]; } divas_um_idi_entity_t; diff --git a/drivers/isdn/hardware/eicon/helpers.h b/drivers/isdn/hardware/eicon/helpers.h index b2123119e43..c9156b0acab 100644 --- a/drivers/isdn/hardware/eicon/helpers.h +++ b/drivers/isdn/hardware/eicon/helpers.h @@ -1,51 +1,51 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_XDI_CARD_CONFIG_HELPERS_INC__ #define __DIVA_XDI_CARD_CONFIG_HELPERS_INC__ -dword diva_get_protocol_file_features (byte* File, - int offset, - char *IdStringBuffer, - dword IdBufferSize); -void diva_configure_protocol (PISDN_ADAPTER IoAdapter); +dword diva_get_protocol_file_features(byte *File, + int offset, + char *IdStringBuffer, + dword IdBufferSize); +void diva_configure_protocol(PISDN_ADAPTER IoAdapter); /* - Low level file access system abstraction - */ + Low level file access system abstraction +*/ /* ------------------------------------------------------------------------- - Access to single file - Return pointer to the image of the requested file, - write image length to 'FileLength' - ------------------------------------------------------------------------- */ -void *xdiLoadFile (char *FileName, dword *FileLength, unsigned long MaxLoadSize) ; + Access to single file + Return pointer to the image of the requested file, + write image length to 'FileLength' + ------------------------------------------------------------------------- */ +void *xdiLoadFile(char *FileName, dword *FileLength, unsigned long MaxLoadSize); /* ------------------------------------------------------------------------- - Dependent on the protocol settings does read return pointer - to the image of appropriate protocol file - ------------------------------------------------------------------------- */ -void *xdiLoadArchive (PISDN_ADAPTER IoAdapter, dword *FileLength, unsigned long MaxLoadSize) ; + Dependent on the protocol settings does read return pointer + to the image of appropriate protocol file + ------------------------------------------------------------------------- */ +void *xdiLoadArchive(PISDN_ADAPTER IoAdapter, dword *FileLength, unsigned long MaxLoadSize); /* -------------------------------------------------------------------------- - Free all system resources accessed by xdiLoadFile and xdiLoadArchive - -------------------------------------------------------------------------- */ -void xdiFreeFile (void* handle); + Free all system resources accessed by xdiLoadFile and xdiLoadArchive + -------------------------------------------------------------------------- */ +void xdiFreeFile(void *handle); #endif diff --git a/drivers/isdn/hardware/eicon/idifunc.c b/drivers/isdn/hardware/eicon/idifunc.c index 4cbc68cf4db..fef6586fe5a 100644 --- a/drivers/isdn/hardware/eicon/idifunc.c +++ b/drivers/isdn/hardware/eicon/idifunc.c @@ -1,7 +1,7 @@ /* $Id: idifunc.c,v 1.14.4.4 2004/08/28 20:03:53 armin Exp $ * * Driver for Eicon DIVA Server ISDN cards. - * User Mode IDI Interface + * User Mode IDI Interface * * Copyright 2000-2003 by Armin Schindler (mac@melware.de) * Copyright 2000-2003 Cytronics & Melware (info@melware.de) @@ -58,7 +58,7 @@ static diva_os_spin_lock_t ll_lock; /* * find card in list */ -static udiva_card *find_card_in_list(DESCRIPTOR * d) +static udiva_card *find_card_in_list(DESCRIPTOR *d) { udiva_card *card; struct list_head *tmp; @@ -80,7 +80,7 @@ static udiva_card *find_card_in_list(DESCRIPTOR * d) /* * new card */ -static void um_new_card(DESCRIPTOR * d) +static void um_new_card(DESCRIPTOR *d) { int adapter_nr = 0; udiva_card *card = NULL; @@ -94,10 +94,10 @@ static void um_new_card(DESCRIPTOR * d) memcpy(&card->d, d, sizeof(DESCRIPTOR)); sync_req.xdi_logical_adapter_number.Req = 0; sync_req.xdi_logical_adapter_number.Rc = - IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER; - card->d.request((ENTITY *) & sync_req); + IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER; + card->d.request((ENTITY *)&sync_req); adapter_nr = - sync_req.xdi_logical_adapter_number.info.logical_adapter_number; + sync_req.xdi_logical_adapter_number.info.logical_adapter_number; card->Id = adapter_nr; if (!(diva_user_mode_idi_create_adapter(d, adapter_nr))) { diva_os_enter_spin_lock(&ll_lock, &old_irql, "add card"); @@ -106,13 +106,14 @@ static void um_new_card(DESCRIPTOR * d) } else { DBG_ERR(("could not create user mode idi card %d", adapter_nr)); + diva_os_free(0, card); } } /* * remove card */ -static void um_remove_card(DESCRIPTOR * d) +static void um_remove_card(DESCRIPTOR *d) { diva_os_spin_lock_magic_t old_irql; udiva_card *card = NULL; @@ -132,7 +133,7 @@ static void um_remove_card(DESCRIPTOR * d) /* * remove all adapter */ -static void DIVA_EXIT_FUNCTION remove_all_idi_proc(void) +static void __exit remove_all_idi_proc(void) { udiva_card *card; diva_os_spin_lock_magic_t old_irql; @@ -153,7 +154,7 @@ rescan: /* * DIDD notify callback */ -static void *didd_callback(void *context, DESCRIPTOR * adapter, +static void *didd_callback(void *context, DESCRIPTOR *adapter, int removal) { if (adapter->type == IDI_DADAPTER) { @@ -180,7 +181,7 @@ static void *didd_callback(void *context, DESCRIPTOR * adapter, /* * connect DIDD */ -static int DIVA_INIT_FUNCTION connect_didd(void) +static int __init connect_didd(void) { int x = 0; int dadapter = 0; @@ -195,10 +196,10 @@ static int DIVA_INIT_FUNCTION connect_didd(void) 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; + 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); + DAdapter.request((ENTITY *)&req); if (req.didd_notify.e.Rc != 0xff) { stop_dbg(); return (0); @@ -224,7 +225,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void) /* * Disconnect from DIDD */ -static void DIVA_EXIT_FUNCTION disconnect_didd(void) +static void __exit disconnect_didd(void) { IDI_SYNC_REQ req; @@ -233,13 +234,13 @@ static void DIVA_EXIT_FUNCTION disconnect_didd(void) 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); + DAdapter.request((ENTITY *)&req); } /* * init */ -int DIVA_INIT_FUNCTION idifunc_init(void) +int __init idifunc_init(void) { diva_os_initialize_spin_lock(&ll_lock, "idifunc"); @@ -259,7 +260,7 @@ int DIVA_INIT_FUNCTION idifunc_init(void) /* * finit */ -void DIVA_EXIT_FUNCTION idifunc_finit(void) +void __exit idifunc_finit(void) { diva_user_mode_idi_finit(); disconnect_didd(); diff --git a/drivers/isdn/hardware/eicon/io.c b/drivers/isdn/hardware/eicon/io.c index 4a27e230b0a..8851ce580c2 100644 --- a/drivers/isdn/hardware/eicon/io.c +++ b/drivers/isdn/hardware/eicon/io.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -33,16 +33,16 @@ #include "di.h" #include "mi_pc.h" #include "io.h" -extern ADAPTER * adapter[MAX_ADAPTER]; +extern ADAPTER *adapter[MAX_ADAPTER]; extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER]; -void request (PISDN_ADAPTER, ENTITY *); -static void pcm_req (PISDN_ADAPTER, ENTITY *); +void request(PISDN_ADAPTER, ENTITY *); +static void pcm_req(PISDN_ADAPTER, ENTITY *); /* -------------------------------------------------------------------------- - local functions - -------------------------------------------------------------------------- */ -#define ReqFunc(N) \ -static void Request##N(ENTITY *e) \ -{ if ( IoAdapters[N] ) (* IoAdapters[N]->DIRequest)(IoAdapters[N], e) ; } + local functions + -------------------------------------------------------------------------- */ +#define ReqFunc(N) \ + static void Request##N(ENTITY *e) \ + { if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); } ReqFunc(0) ReqFunc(1) ReqFunc(2) @@ -61,792 +61,792 @@ ReqFunc(14) ReqFunc(15) IDI_CALL Requests[MAX_ADAPTER] = { &Request0, &Request1, &Request2, &Request3, - &Request4, &Request5, &Request6, &Request7, - &Request8, &Request9, &Request10, &Request11, - &Request12, &Request13, &Request14, &Request15 + &Request4, &Request5, &Request6, &Request7, + &Request8, &Request9, &Request10, &Request11, + &Request12, &Request13, &Request14, &Request15 }; /*****************************************************************************/ /* This array should indicate all new services, that this version of XDI is able to provide to his clients - */ -static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ+1] = { - (DIVA_XDI_EXTENDED_FEATURES_VALID | - DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR | - DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS | +*/ +static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ + 1] = { + (DIVA_XDI_EXTENDED_FEATURES_VALID | + DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR | + DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS | #if defined(DIVA_IDI_RX_DMA) - DIVA_XDI_EXTENDED_FEATURE_CMA | - DIVA_XDI_EXTENDED_FEATURE_RX_DMA | - DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA | + DIVA_XDI_EXTENDED_FEATURE_CMA | + DIVA_XDI_EXTENDED_FEATURE_RX_DMA | + DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA | #endif - DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC), - 0 + DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC), + 0 }; /*****************************************************************************/ void -dump_xlog_buffer (PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc) -{ - dword logLen ; - word *Xlog = xlogDesc->buf ; - word logCnt = xlogDesc->cnt ; - word logOut = xlogDesc->out / sizeof(*Xlog) ; - DBG_FTL(("%s: ************* XLOG recovery (%d) *************", - &IoAdapter->Name[0], (int)logCnt)) - DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0])) - for ( ; logCnt > 0 ; --logCnt ) - { - if ( !GET_WORD(&Xlog[logOut]) ) - { - if ( --logCnt == 0 ) - break ; - logOut = 0 ; - } - if ( GET_WORD(&Xlog[logOut]) <= (logOut * sizeof(*Xlog)) ) - { - if ( logCnt > 2 ) - { - DBG_FTL(("Possibly corrupted XLOG: %d entries left", - (int)logCnt)) - } - break ; - } - logLen = (dword)(GET_WORD(&Xlog[logOut]) - (logOut * sizeof(*Xlog))) ; - DBG_FTL_MXLOG(( (char *)&Xlog[logOut + 1], (dword)(logLen - 2) )) - logOut = (GET_WORD(&Xlog[logOut]) + 1) / sizeof(*Xlog) ; - } - DBG_FTL(("%s: ***************** end of XLOG *****************", - &IoAdapter->Name[0])) -} +dump_xlog_buffer(PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc) +{ + dword logLen; + word *Xlog = xlogDesc->buf; + word logCnt = xlogDesc->cnt; + word logOut = xlogDesc->out / sizeof(*Xlog); + DBG_FTL(("%s: ************* XLOG recovery (%d) *************", + &IoAdapter->Name[0], (int)logCnt)) + DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0])) + for (; logCnt > 0; --logCnt) + { + if (!GET_WORD(&Xlog[logOut])) + { + if (--logCnt == 0) + break; + logOut = 0; + } + if (GET_WORD(&Xlog[logOut]) <= (logOut * sizeof(*Xlog))) + { + if (logCnt > 2) + { + DBG_FTL(("Possibly corrupted XLOG: %d entries left", + (int)logCnt)) + } + break; + } + logLen = (dword)(GET_WORD(&Xlog[logOut]) - (logOut * sizeof(*Xlog))); + DBG_FTL_MXLOG(((char *)&Xlog[logOut + 1], (dword)(logLen - 2))) + logOut = (GET_WORD(&Xlog[logOut]) + 1) / sizeof(*Xlog); + } + DBG_FTL(("%s: ***************** end of XLOG *****************", + &IoAdapter->Name[0])) + } /*****************************************************************************/ #if defined(XDI_USE_XLOG) static char *(ExceptionCauseTable[]) = { - "Interrupt", - "TLB mod /IBOUND", - "TLB load /DBOUND", - "TLB store", - "Address error load", - "Address error store", - "Instruction load bus error", - "Data load/store bus error", - "Syscall", - "Breakpoint", - "Reverd instruction", - "Coprocessor unusable", - "Overflow", - "TRAP", - "VCEI", - "Floating Point Exception", - "CP2", - "Reserved 17", - "Reserved 18", - "Reserved 19", - "Reserved 20", - "Reserved 21", - "Reserved 22", - "WATCH", - "Reserved 24", - "Reserved 25", - "Reserved 26", - "Reserved 27", - "Reserved 28", - "Reserved 29", - "Reserved 30", - "VCED" -} ; + "Interrupt", + "TLB mod /IBOUND", + "TLB load /DBOUND", + "TLB store", + "Address error load", + "Address error store", + "Instruction load bus error", + "Data load/store bus error", + "Syscall", + "Breakpoint", + "Reverd instruction", + "Coprocessor unusable", + "Overflow", + "TRAP", + "VCEI", + "Floating Point Exception", + "CP2", + "Reserved 17", + "Reserved 18", + "Reserved 19", + "Reserved 20", + "Reserved 21", + "Reserved 22", + "WATCH", + "Reserved 24", + "Reserved 25", + "Reserved 26", + "Reserved 27", + "Reserved 28", + "Reserved 29", + "Reserved 30", + "VCED" +}; #endif void -dump_trap_frame (PISDN_ADAPTER IoAdapter, byte __iomem *exceptionFrame) -{ - MP_XCPTC __iomem *xcept = (MP_XCPTC __iomem *)exceptionFrame ; - dword __iomem *regs; - regs = &xcept->regs[0] ; - DBG_FTL(("%s: ***************** CPU TRAPPED *****************", - &IoAdapter->Name[0])) - DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0])) - DBG_FTL(("Cause: %s", - ExceptionCauseTable[(READ_DWORD(&xcept->cr) & 0x0000007c) >> 2])) - DBG_FTL(("sr 0x%08x cr 0x%08x epc 0x%08x vaddr 0x%08x", - READ_DWORD(&xcept->sr), READ_DWORD(&xcept->cr), - READ_DWORD(&xcept->epc), READ_DWORD(&xcept->vaddr))) - DBG_FTL(("zero 0x%08x at 0x%08x v0 0x%08x v1 0x%08x", - READ_DWORD(®s[ 0]), READ_DWORD(®s[ 1]), - READ_DWORD(®s[ 2]), READ_DWORD(®s[ 3]))) - DBG_FTL(("a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x", - READ_DWORD(®s[ 4]), READ_DWORD(®s[ 5]), - READ_DWORD(®s[ 6]), READ_DWORD(®s[ 7]))) - DBG_FTL(("t0 0x%08x t1 0x%08x t2 0x%08x t3 0x%08x", - READ_DWORD(®s[ 8]), READ_DWORD(®s[ 9]), - READ_DWORD(®s[10]), READ_DWORD(®s[11]))) - DBG_FTL(("t4 0x%08x t5 0x%08x t6 0x%08x t7 0x%08x", - READ_DWORD(®s[12]), READ_DWORD(®s[13]), - READ_DWORD(®s[14]), READ_DWORD(®s[15]))) - DBG_FTL(("s0 0x%08x s1 0x%08x s2 0x%08x s3 0x%08x", - READ_DWORD(®s[16]), READ_DWORD(®s[17]), - READ_DWORD(®s[18]), READ_DWORD(®s[19]))) - DBG_FTL(("s4 0x%08x s5 0x%08x s6 0x%08x s7 0x%08x", - READ_DWORD(®s[20]), READ_DWORD(®s[21]), - READ_DWORD(®s[22]), READ_DWORD(®s[23]))) - DBG_FTL(("t8 0x%08x t9 0x%08x k0 0x%08x k1 0x%08x", - READ_DWORD(®s[24]), READ_DWORD(®s[25]), - READ_DWORD(®s[26]), READ_DWORD(®s[27]))) - DBG_FTL(("gp 0x%08x sp 0x%08x s8 0x%08x ra 0x%08x", - READ_DWORD(®s[28]), READ_DWORD(®s[29]), - READ_DWORD(®s[30]), READ_DWORD(®s[31]))) - DBG_FTL(("md 0x%08x|%08x resvd 0x%08x class 0x%08x", - READ_DWORD(&xcept->mdhi), READ_DWORD(&xcept->mdlo), - READ_DWORD(&xcept->reseverd), READ_DWORD(&xcept->xclass))) -} +dump_trap_frame(PISDN_ADAPTER IoAdapter, byte __iomem *exceptionFrame) +{ + MP_XCPTC __iomem *xcept = (MP_XCPTC __iomem *)exceptionFrame; + dword __iomem *regs; + regs = &xcept->regs[0]; + DBG_FTL(("%s: ***************** CPU TRAPPED *****************", + &IoAdapter->Name[0])) + DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0])) + DBG_FTL(("Cause: %s", + ExceptionCauseTable[(READ_DWORD(&xcept->cr) & 0x0000007c) >> 2])) + DBG_FTL(("sr 0x%08x cr 0x%08x epc 0x%08x vaddr 0x%08x", + READ_DWORD(&xcept->sr), READ_DWORD(&xcept->cr), + READ_DWORD(&xcept->epc), READ_DWORD(&xcept->vaddr))) + DBG_FTL(("zero 0x%08x at 0x%08x v0 0x%08x v1 0x%08x", + READ_DWORD(®s[0]), READ_DWORD(®s[1]), + READ_DWORD(®s[2]), READ_DWORD(®s[3]))) + DBG_FTL(("a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x", + READ_DWORD(®s[4]), READ_DWORD(®s[5]), + READ_DWORD(®s[6]), READ_DWORD(®s[7]))) + DBG_FTL(("t0 0x%08x t1 0x%08x t2 0x%08x t3 0x%08x", + READ_DWORD(®s[8]), READ_DWORD(®s[9]), + READ_DWORD(®s[10]), READ_DWORD(®s[11]))) + DBG_FTL(("t4 0x%08x t5 0x%08x t6 0x%08x t7 0x%08x", + READ_DWORD(®s[12]), READ_DWORD(®s[13]), + READ_DWORD(®s[14]), READ_DWORD(®s[15]))) + DBG_FTL(("s0 0x%08x s1 0x%08x s2 0x%08x s3 0x%08x", + READ_DWORD(®s[16]), READ_DWORD(®s[17]), + READ_DWORD(®s[18]), READ_DWORD(®s[19]))) + DBG_FTL(("s4 0x%08x s5 0x%08x s6 0x%08x s7 0x%08x", + READ_DWORD(®s[20]), READ_DWORD(®s[21]), + READ_DWORD(®s[22]), READ_DWORD(®s[23]))) + DBG_FTL(("t8 0x%08x t9 0x%08x k0 0x%08x k1 0x%08x", + READ_DWORD(®s[24]), READ_DWORD(®s[25]), + READ_DWORD(®s[26]), READ_DWORD(®s[27]))) + DBG_FTL(("gp 0x%08x sp 0x%08x s8 0x%08x ra 0x%08x", + READ_DWORD(®s[28]), READ_DWORD(®s[29]), + READ_DWORD(®s[30]), READ_DWORD(®s[31]))) + DBG_FTL(("md 0x%08x|%08x resvd 0x%08x class 0x%08x", + READ_DWORD(&xcept->mdhi), READ_DWORD(&xcept->mdlo), + READ_DWORD(&xcept->reseverd), READ_DWORD(&xcept->xclass))) + } /* -------------------------------------------------------------------------- - Real XDI Request function - -------------------------------------------------------------------------- */ -void request(PISDN_ADAPTER IoAdapter, ENTITY * e) + Real XDI Request function + -------------------------------------------------------------------------- */ +void request(PISDN_ADAPTER IoAdapter, ENTITY *e) { - byte i; - diva_os_spin_lock_magic_t irql; + byte i; + diva_os_spin_lock_magic_t irql; /* * if the Req field in the entity structure is 0, * we treat this request as a special function call */ - if ( !e->Req ) - { - IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e ; - switch (e->Rc) - { + if (!e->Req) + { + IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e; + switch (e->Rc) + { #if defined(DIVA_IDI_RX_DMA) - case IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION: { - diva_xdi_dma_descriptor_operation_t* pI = \ - &syncReq->xdi_dma_descriptor_operation.info; - if (!IoAdapter->dma_map) { - pI->operation = -1; - pI->descriptor_number = -1; - return; - } - diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "dma_op"); - if (pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC) { - pI->descriptor_number = diva_alloc_dma_map_entry (\ - (struct _diva_dma_map_entry*)IoAdapter->dma_map); - if (pI->descriptor_number >= 0) { - dword dma_magic; - void* local_addr; - diva_get_dma_map_entry (\ - (struct _diva_dma_map_entry*)IoAdapter->dma_map, - pI->descriptor_number, - &local_addr, &dma_magic); - pI->descriptor_address = local_addr; - pI->descriptor_magic = dma_magic; - pI->operation = 0; - } else { - pI->operation = -1; - } - } else if ((pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE) && - (pI->descriptor_number >= 0)) { - diva_free_dma_map_entry((struct _diva_dma_map_entry*)IoAdapter->dma_map, - pI->descriptor_number); - pI->descriptor_number = -1; - pI->operation = 0; - } else { - pI->descriptor_number = -1; - pI->operation = -1; - } - diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "dma_op"); - } return; + case IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION: { + diva_xdi_dma_descriptor_operation_t *pI = \ + &syncReq->xdi_dma_descriptor_operation.info; + if (!IoAdapter->dma_map) { + pI->operation = -1; + pI->descriptor_number = -1; + return; + } + diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op"); + if (pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC) { + pI->descriptor_number = diva_alloc_dma_map_entry(\ + (struct _diva_dma_map_entry *)IoAdapter->dma_map); + if (pI->descriptor_number >= 0) { + dword dma_magic; + void *local_addr; + diva_get_dma_map_entry(\ + (struct _diva_dma_map_entry *)IoAdapter->dma_map, + pI->descriptor_number, + &local_addr, &dma_magic); + pI->descriptor_address = local_addr; + pI->descriptor_magic = dma_magic; + pI->operation = 0; + } else { + pI->operation = -1; + } + } else if ((pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE) && + (pI->descriptor_number >= 0)) { + diva_free_dma_map_entry((struct _diva_dma_map_entry *)IoAdapter->dma_map, + pI->descriptor_number); + pI->descriptor_number = -1; + pI->operation = 0; + } else { + pI->descriptor_number = -1; + pI->operation = -1; + } + diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op"); + } return; #endif - case IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER: { - diva_xdi_get_logical_adapter_number_s_t *pI = \ - &syncReq->xdi_logical_adapter_number.info; - pI->logical_adapter_number = IoAdapter->ANum; - pI->controller = IoAdapter->ControllerNumber; - pI->total_controllers = IoAdapter->Properties.Adapters; - } return; - case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS: { - diva_xdi_get_capi_parameters_t prms, *pI = &syncReq->xdi_capi_prms.info; - memset (&prms, 0x00, sizeof(prms)); - prms.structure_length = MIN(sizeof(prms), pI->structure_length); - memset (pI, 0x00, pI->structure_length); - prms.flag_dynamic_l1_down = (IoAdapter->capi_cfg.cfg_1 & \ - DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? 1 : 0; - prms.group_optimization_enabled = (IoAdapter->capi_cfg.cfg_1 & \ - DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) ? 1 : 0; - memcpy (pI, &prms, prms.structure_length); - } return; - case IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR: - syncReq->xdi_sdram_bar.info.bar = IoAdapter->sdram_bar; - return; - case IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES: { - dword i; - diva_xdi_get_extended_xdi_features_t* pI =\ - &syncReq->xdi_extended_features.info; - pI->buffer_length_in_bytes &= ~0x80000000; - if (pI->buffer_length_in_bytes && pI->features) { - memset (pI->features, 0x00, pI->buffer_length_in_bytes); - } - for (i = 0; ((pI->features) && (i < pI->buffer_length_in_bytes) && - (i < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ)); i++) { - pI->features[i] = extended_xdi_features[i]; - } - if ((pI->buffer_length_in_bytes < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ) || - (!pI->features)) { - pI->buffer_length_in_bytes =\ - (0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ); - } - } return; - case IDI_SYNC_REQ_XDI_GET_STREAM: - if (IoAdapter) { - diva_xdi_provide_istream_info (&IoAdapter->a, - &syncReq->xdi_stream_info.info); - } else { - syncReq->xdi_stream_info.info.provided_service = 0; - } - return; - case IDI_SYNC_REQ_GET_NAME: - if ( IoAdapter ) - { - strcpy (&syncReq->GetName.name[0], IoAdapter->Name) ; - DBG_TRC(("xdi: Adapter %d / Name '%s'", - IoAdapter->ANum, IoAdapter->Name)) - return ; - } - syncReq->GetName.name[0] = '\0' ; - break ; - case IDI_SYNC_REQ_GET_SERIAL: - if ( IoAdapter ) - { - syncReq->GetSerial.serial = IoAdapter->serialNo ; - DBG_TRC(("xdi: Adapter %d / SerialNo %ld", - IoAdapter->ANum, IoAdapter->serialNo)) - return ; - } - syncReq->GetSerial.serial = 0 ; - break ; - case IDI_SYNC_REQ_GET_CARDTYPE: - if ( IoAdapter ) - { - syncReq->GetCardType.cardtype = IoAdapter->cardType ; - DBG_TRC(("xdi: Adapter %d / CardType %ld", - IoAdapter->ANum, IoAdapter->cardType)) - return ; - } - syncReq->GetCardType.cardtype = 0 ; - break ; - case IDI_SYNC_REQ_GET_XLOG: - if ( IoAdapter ) - { - pcm_req (IoAdapter, e) ; - return ; - } - e->Ind = 0 ; - break ; - case IDI_SYNC_REQ_GET_DBG_XLOG: - if ( IoAdapter ) - { - pcm_req (IoAdapter, e) ; - return ; - } - e->Ind = 0 ; - break ; - case IDI_SYNC_REQ_GET_FEATURES: - if ( IoAdapter ) - { - syncReq->GetFeatures.features = - (unsigned short)IoAdapter->features ; - return ; - } - syncReq->GetFeatures.features = 0 ; - break ; - case IDI_SYNC_REQ_PORTDRV_HOOK: - if ( IoAdapter ) - { - DBG_TRC(("Xdi:IDI_SYNC_REQ_PORTDRV_HOOK - ignored")) - return ; - } - break; - } - if ( IoAdapter ) - { - return ; - } - } - DBG_TRC(("xdi: Id 0x%x / Req 0x%x / Rc 0x%x", e->Id, e->Req, e->Rc)) - if ( !IoAdapter ) - { - DBG_FTL(("xdi: uninitialized Adapter used - ignore request")) - return ; - } - diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req"); + case IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER: { + diva_xdi_get_logical_adapter_number_s_t *pI = \ + &syncReq->xdi_logical_adapter_number.info; + pI->logical_adapter_number = IoAdapter->ANum; + pI->controller = IoAdapter->ControllerNumber; + pI->total_controllers = IoAdapter->Properties.Adapters; + } return; + case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS: { + diva_xdi_get_capi_parameters_t prms, *pI = &syncReq->xdi_capi_prms.info; + memset(&prms, 0x00, sizeof(prms)); + prms.structure_length = min_t(size_t, sizeof(prms), pI->structure_length); + memset(pI, 0x00, pI->structure_length); + prms.flag_dynamic_l1_down = (IoAdapter->capi_cfg.cfg_1 & \ + DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? 1 : 0; + prms.group_optimization_enabled = (IoAdapter->capi_cfg.cfg_1 & \ + DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) ? 1 : 0; + memcpy(pI, &prms, prms.structure_length); + } return; + case IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR: + syncReq->xdi_sdram_bar.info.bar = IoAdapter->sdram_bar; + return; + case IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES: { + dword i; + diva_xdi_get_extended_xdi_features_t *pI =\ + &syncReq->xdi_extended_features.info; + pI->buffer_length_in_bytes &= ~0x80000000; + if (pI->buffer_length_in_bytes && pI->features) { + memset(pI->features, 0x00, pI->buffer_length_in_bytes); + } + for (i = 0; ((pI->features) && (i < pI->buffer_length_in_bytes) && + (i < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ)); i++) { + pI->features[i] = extended_xdi_features[i]; + } + if ((pI->buffer_length_in_bytes < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ) || + (!pI->features)) { + pI->buffer_length_in_bytes =\ + (0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ); + } + } return; + case IDI_SYNC_REQ_XDI_GET_STREAM: + if (IoAdapter) { + diva_xdi_provide_istream_info(&IoAdapter->a, + &syncReq->xdi_stream_info.info); + } else { + syncReq->xdi_stream_info.info.provided_service = 0; + } + return; + case IDI_SYNC_REQ_GET_NAME: + if (IoAdapter) + { + strcpy(&syncReq->GetName.name[0], IoAdapter->Name); + DBG_TRC(("xdi: Adapter %d / Name '%s'", + IoAdapter->ANum, IoAdapter->Name)) + return; + } + syncReq->GetName.name[0] = '\0'; + break; + case IDI_SYNC_REQ_GET_SERIAL: + if (IoAdapter) + { + syncReq->GetSerial.serial = IoAdapter->serialNo; + DBG_TRC(("xdi: Adapter %d / SerialNo %ld", + IoAdapter->ANum, IoAdapter->serialNo)) + return; + } + syncReq->GetSerial.serial = 0; + break; + case IDI_SYNC_REQ_GET_CARDTYPE: + if (IoAdapter) + { + syncReq->GetCardType.cardtype = IoAdapter->cardType; + DBG_TRC(("xdi: Adapter %d / CardType %ld", + IoAdapter->ANum, IoAdapter->cardType)) + return; + } + syncReq->GetCardType.cardtype = 0; + break; + case IDI_SYNC_REQ_GET_XLOG: + if (IoAdapter) + { + pcm_req(IoAdapter, e); + return; + } + e->Ind = 0; + break; + case IDI_SYNC_REQ_GET_DBG_XLOG: + if (IoAdapter) + { + pcm_req(IoAdapter, e); + return; + } + e->Ind = 0; + break; + case IDI_SYNC_REQ_GET_FEATURES: + if (IoAdapter) + { + syncReq->GetFeatures.features = + (unsigned short)IoAdapter->features; + return; + } + syncReq->GetFeatures.features = 0; + break; + case IDI_SYNC_REQ_PORTDRV_HOOK: + if (IoAdapter) + { + DBG_TRC(("Xdi:IDI_SYNC_REQ_PORTDRV_HOOK - ignored")) + return; + } + break; + } + if (IoAdapter) + { + return; + } + } + DBG_TRC(("xdi: Id 0x%x / Req 0x%x / Rc 0x%x", e->Id, e->Req, e->Rc)) + if (!IoAdapter) + { + DBG_FTL(("xdi: uninitialized Adapter used - ignore request")) + return; + } + diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req"); /* * assign an entity */ - if ( !(e->Id &0x1f) ) - { - if ( IoAdapter->e_count >= IoAdapter->e_max ) - { - DBG_FTL(("xdi: all Ids in use (max=%d) --> Req ignored", - IoAdapter->e_max)) - diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req"); - return ; - } + if (!(e->Id & 0x1f)) + { + if (IoAdapter->e_count >= IoAdapter->e_max) + { + DBG_FTL(("xdi: all Ids in use (max=%d) --> Req ignored", + IoAdapter->e_max)) + diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req"); + return; + } /* * find a new free id */ - for ( i = 1 ; IoAdapter->e_tbl[i].e ; ++i ) ; - IoAdapter->e_tbl[i].e = e ; - IoAdapter->e_count++ ; - e->No = (byte)i ; - e->More = 0 ; - e->RCurrent = 0xff ; - } - else - { - i = e->No ; - } + for (i = 1; IoAdapter->e_tbl[i].e; ++i); + IoAdapter->e_tbl[i].e = e; + IoAdapter->e_count++; + e->No = (byte)i; + e->More = 0; + e->RCurrent = 0xff; + } + else + { + i = e->No; + } /* * if the entity is still busy, ignore the request call */ - if ( e->More & XBUSY ) - { - DBG_FTL(("xdi: Id 0x%x busy --> Req 0x%x ignored", e->Id, e->Req)) - if ( !IoAdapter->trapped && IoAdapter->trapFnc ) - { - IoAdapter->trapFnc (IoAdapter) ; - /* - Firs trap, also notify user if supported - */ - if (IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) { - (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum); - } - } - diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req"); - return ; - } + if (e->More & XBUSY) + { + DBG_FTL(("xdi: Id 0x%x busy --> Req 0x%x ignored", e->Id, e->Req)) + if (!IoAdapter->trapped && IoAdapter->trapFnc) + { + IoAdapter->trapFnc(IoAdapter); + /* + Firs trap, also notify user if supported + */ + if (IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) { + (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum); + } + } + diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req"); + return; + } /* * initialize transmit status variables */ - e->More |= XBUSY ; - e->More &= ~XMOREF ; - e->XCurrent = 0 ; - e->XOffset = 0 ; + e->More |= XBUSY; + e->More &= ~XMOREF; + e->XCurrent = 0; + 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 ; - } + 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"); + diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr); + diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req"); } /* --------------------------------------------------------------------- - Main DPC routine + 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"); - } - /* ---------------------------------------------------------------- */ - } +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 - -------------------------------------------------------------------------- */ + XLOG interface + -------------------------------------------------------------------------- */ static void -pcm_req (PISDN_ADAPTER IoAdapter, ENTITY *e) +pcm_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 ; + 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 ; - } + 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 ; - } - } + 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); - } - } + 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 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); + 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 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); + 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) +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); + 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) +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); + 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) +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 ; + 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) +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); + 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) +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); + 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) +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); + 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) +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); + 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) +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); + 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) { +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); - 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) { +} +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); - 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"); +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) +ENTITY *entity_ptr(ADAPTER *a, byte e_no) { - PISDN_ADAPTER IoAdapter; - IoAdapter = (PISDN_ADAPTER) a->io; - return (IoAdapter->e_tbl[e_no].e); + PISDN_ADAPTER IoAdapter; + IoAdapter = (PISDN_ADAPTER)a->io; + return (IoAdapter->e_tbl[e_no].e); } -void * PTR_X(ADAPTER * a, ENTITY * e) +void *PTR_X(ADAPTER *a, ENTITY *e) { - return ((void *) e->X); + return ((void *) e->X); } -void * PTR_R(ADAPTER * a, ENTITY * e) +void *PTR_R(ADAPTER *a, ENTITY *e) { - return ((void *) e->R); + return ((void *) e->R); } -void * PTR_P(ADAPTER * a, ENTITY * e, void * P) +void *PTR_P(ADAPTER *a, ENTITY *e, void *P) { - return P; + return P; } -void CALLBACK(ADAPTER * a, ENTITY * e) +void CALLBACK(ADAPTER *a, ENTITY *e) { - if ( e && e->callback ) - e->callback (e) ; + if (e && e->callback) + e->callback(e); } diff --git a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h index 0c6c650d76b..01deced18ab 100644 --- a/drivers/isdn/hardware/eicon/io.h +++ b/drivers/isdn/hardware/eicon/io.h @@ -1,308 +1,308 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_XDI_COMMON_IO_H_INC__ /* { */ #define __DIVA_XDI_COMMON_IO_H_INC__ /* - maximum = 16 adapters - */ + maximum = 16 adapters +*/ #define DI_MAX_LINKS MAX_ADAPTER #define ISDN_MAX_NUM_LEN 60 /* -------------------------------------------------------------------------- - structure for quadro card management (obsolete for - systems that do provide per card load event) - -------------------------------------------------------------------------- */ + structure for quadro card management (obsolete for + systems that do provide per card load event) + -------------------------------------------------------------------------- */ typedef struct { - dword Num ; - DEVICE_NAME DeviceName[4] ; - PISDN_ADAPTER QuadroAdapter[4] ; -} ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY ; + dword Num; + DEVICE_NAME DeviceName[4]; + PISDN_ADAPTER QuadroAdapter[4]; +} ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY; /* -------------------------------------------------------------------------- - Special OS memory support structures - -------------------------------------------------------------------------- */ + Special OS memory support structures + -------------------------------------------------------------------------- */ #define MAX_MAPPED_ENTRIES 8 typedef struct { - void * Address; - dword Length; -} ADAPTER_MEMORY ; + void *Address; + dword Length; +} ADAPTER_MEMORY; /* -------------------------------------------------------------------------- - Configuration of XDI clients carried by XDI - -------------------------------------------------------------------------- */ + Configuration of XDI clients carried by XDI + -------------------------------------------------------------------------- */ #define DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON 0x01 #define DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON 0x02 typedef struct _diva_xdi_capi_cfg { - byte cfg_1; + byte cfg_1; } diva_xdi_capi_cfg_t; /* -------------------------------------------------------------------------- - Main data structure kept per adapter - -------------------------------------------------------------------------- */ + Main data structure kept per adapter + -------------------------------------------------------------------------- */ struct _ISDN_ADAPTER { - void (* DIRequest)(PISDN_ADAPTER, ENTITY *) ; - int State ; /* from NT4 1.srv, a good idea, but a poor achievment */ - int Initialized ; - int RegisteredWithDidd ; - int Unavailable ; /* callback function possible? */ - int ResourcesClaimed ; - int PnpBiosConfigUsed ; - dword Logging ; - dword features ; - char ProtocolIdString[80] ; - /* - remember mapped memory areas - */ - ADAPTER_MEMORY MappedMemory[MAX_MAPPED_ENTRIES] ; - CARD_PROPERTIES Properties ; - dword cardType ; - dword protocol_id ; /* configured protocol identifier */ - char protocol_name[8] ; /* readable name of protocol */ - dword BusType ; - dword BusNumber ; - dword slotNumber ; - dword slotId ; - dword ControllerNumber ; /* for QUADRO cards only */ - PISDN_ADAPTER MultiMaster ; /* for 4-BRI card only - use MultiMaster or QuadroList */ - PADAPTER_LIST_ENTRY QuadroList ; /* for QUADRO card only */ - PDEVICE_OBJECT DeviceObject ; - dword DeviceId ; - diva_os_adapter_irq_info_t irq_info; - dword volatile IrqCount ; - int trapped ; - dword DspCodeBaseAddr ; - dword MaxDspCodeSize ; - dword downloadAddr ; - dword DspCodeBaseAddrTable[4] ; /* add. for MultiMaster */ - dword MaxDspCodeSizeTable[4] ; /* add. for MultiMaster */ - dword downloadAddrTable[4] ; /* add. for MultiMaster */ - dword MemoryBase ; - dword MemorySize ; - byte __iomem *Address ; - byte __iomem *Config ; - byte __iomem *Control ; - byte __iomem *reset ; - byte __iomem *port ; - byte __iomem *ram ; - byte __iomem *cfg ; - byte __iomem *prom ; - byte __iomem *ctlReg ; - struct pc_maint *pcm ; - diva_os_dependent_devica_name_t os_name; - byte Name[32] ; - dword serialNo ; - dword ANum ; - dword ArchiveType ; /* ARCHIVE_TYPE_NONE ..._SINGLE ..._USGEN ..._MULTI */ - char *ProtocolSuffix ; /* internal protocolfile table */ - char Archive[32] ; - char Protocol[32] ; - char AddDownload[32] ; /* Dsp- or other additional download files */ - char Oad1[ISDN_MAX_NUM_LEN] ; - char Osa1[ISDN_MAX_NUM_LEN] ; - char Oad2[ISDN_MAX_NUM_LEN] ; - char Osa2[ISDN_MAX_NUM_LEN] ; - char Spid1[ISDN_MAX_NUM_LEN] ; - char Spid2[ISDN_MAX_NUM_LEN] ; - byte nosig ; - byte BriLayer2LinkCount ; /* amount of TEI's that adapter will support in P2MP mode */ - dword Channels ; - dword tei ; - dword nt2 ; - dword TerminalCount ; - dword WatchDog ; - dword Permanent ; - dword BChMask ; /* B channel mask for unchannelized modes */ - dword StableL2 ; - dword DidLen ; - dword NoOrderCheck ; - dword ForceLaw; /* VoiceCoding - default:0, a-law: 1, my-law: 2 */ - dword SigFlags ; - dword LowChannel ; - dword NoHscx30 ; - dword ProtVersion ; - dword crc4 ; - dword L1TristateOrQsig ; /* enable Layer 1 Tristate (bit 2)Or Qsig params (bit 0,1)*/ - dword InitialDspInfo ; - dword ModemGuardTone ; - dword ModemMinSpeed ; - dword ModemMaxSpeed ; - dword ModemOptions ; - dword ModemOptions2 ; - dword ModemNegotiationMode ; - dword ModemModulationsMask ; - dword ModemTransmitLevel ; - dword FaxOptions ; - dword FaxMaxSpeed ; - dword Part68LevelLimiter ; - dword UsEktsNumCallApp ; - byte UsEktsFeatAddConf ; - byte UsEktsFeatRemoveConf ; - byte UsEktsFeatCallTransfer ; - byte UsEktsFeatMsgWaiting ; - byte QsigDialect; - byte ForceVoiceMailAlert; - byte DisableAutoSpid; - byte ModemCarrierWaitTimeSec; - byte ModemCarrierLossWaitTimeTenthSec; - byte PiafsLinkTurnaroundInFrames; - byte DiscAfterProgress; - byte AniDniLimiter[3]; - byte TxAttenuation; /* PRI/E1 only: attenuate TX signal */ - word QsigFeatures; - dword GenerateRingtone ; - dword SupplementaryServicesFeatures; - dword R2Dialect; - dword R2CasOptions; - dword FaxV34Options; - dword DisabledDspMask; - dword AdapterTestMask; - dword DspImageLength; - word AlertToIn20mSecTicks; - word ModemEyeSetup; - byte R2CtryLength; - byte CCBSRelTimer; - byte *PcCfgBufferFile;/* flexible parameter via file */ - byte *PcCfgBuffer ; /* flexible parameter via multistring */ - diva_os_dump_file_t dump_file; /* dump memory to file at lowest irq level */ - diva_os_board_trace_t board_trace ; /* traces from the board */ - diva_os_spin_lock_t isr_spin_lock; - diva_os_spin_lock_t data_spin_lock; - diva_os_soft_isr_t req_soft_isr; - diva_os_soft_isr_t isr_soft_isr; - diva_os_atomic_t in_dpc; - PBUFFER RBuffer; /* Copy of receive lookahead buffer */ - word e_max; - word e_count; - E_INFO *e_tbl; - word assign; /* list of pending ASSIGNs */ - word head; /* head of request queue */ - word tail; /* tail of request queue */ - ADAPTER a ; /* not a separate structure */ - void (* out)(ADAPTER * a) ; - byte (* dpc)(ADAPTER * a) ; - byte (* tst_irq)(ADAPTER * a) ; - void (* clr_irq)(ADAPTER * a) ; - int (* load)(PISDN_ADAPTER) ; - int (* mapmem)(PISDN_ADAPTER) ; - int (* chkIrq)(PISDN_ADAPTER) ; - void (* disIrq)(PISDN_ADAPTER) ; - void (* start)(PISDN_ADAPTER) ; - void (* stop)(PISDN_ADAPTER) ; - void (* rstFnc)(PISDN_ADAPTER) ; - void (* trapFnc)(PISDN_ADAPTER) ; - dword (* DetectDsps)(PISDN_ADAPTER) ; - void (* os_trap_nfy_Fnc)(PISDN_ADAPTER, dword) ; - diva_os_isr_callback_t diva_isr_handler; - dword sdram_bar; /* must be 32 bit */ - dword fpga_features; - volatile int pcm_pending; - volatile void * pcm_data; - diva_xdi_capi_cfg_t capi_cfg; - dword tasks; - void *dma_map; - int (*DivaAdapterTestProc)(PISDN_ADAPTER); - void *AdapterTestMemoryStart; - dword AdapterTestMemoryLength; - const byte* cfg_lib_memory_init; - dword cfg_lib_memory_init_length; + void (*DIRequest)(PISDN_ADAPTER, ENTITY *); + int State; /* from NT4 1.srv, a good idea, but a poor achievement */ + int Initialized; + int RegisteredWithDidd; + int Unavailable; /* callback function possible? */ + int ResourcesClaimed; + int PnpBiosConfigUsed; + dword Logging; + dword features; + char ProtocolIdString[80]; + /* + remember mapped memory areas + */ + ADAPTER_MEMORY MappedMemory[MAX_MAPPED_ENTRIES]; + CARD_PROPERTIES Properties; + dword cardType; + dword protocol_id; /* configured protocol identifier */ + char protocol_name[8]; /* readable name of protocol */ + dword BusType; + dword BusNumber; + dword slotNumber; + dword slotId; + dword ControllerNumber; /* for QUADRO cards only */ + PISDN_ADAPTER MultiMaster; /* for 4-BRI card only - use MultiMaster or QuadroList */ + PADAPTER_LIST_ENTRY QuadroList; /* for QUADRO card only */ + PDEVICE_OBJECT DeviceObject; + dword DeviceId; + diva_os_adapter_irq_info_t irq_info; + dword volatile IrqCount; + int trapped; + dword DspCodeBaseAddr; + dword MaxDspCodeSize; + dword downloadAddr; + dword DspCodeBaseAddrTable[4]; /* add. for MultiMaster */ + dword MaxDspCodeSizeTable[4]; /* add. for MultiMaster */ + dword downloadAddrTable[4]; /* add. for MultiMaster */ + dword MemoryBase; + dword MemorySize; + byte __iomem *Address; + byte __iomem *Config; + byte __iomem *Control; + byte __iomem *reset; + byte __iomem *port; + byte __iomem *ram; + byte __iomem *cfg; + byte __iomem *prom; + byte __iomem *ctlReg; + struct pc_maint *pcm; + diva_os_dependent_devica_name_t os_name; + byte Name[32]; + dword serialNo; + dword ANum; + dword ArchiveType; /* ARCHIVE_TYPE_NONE ..._SINGLE ..._USGEN ..._MULTI */ + char *ProtocolSuffix; /* internal protocolfile table */ + char Archive[32]; + char Protocol[32]; + char AddDownload[32]; /* Dsp- or other additional download files */ + char Oad1[ISDN_MAX_NUM_LEN]; + char Osa1[ISDN_MAX_NUM_LEN]; + char Oad2[ISDN_MAX_NUM_LEN]; + char Osa2[ISDN_MAX_NUM_LEN]; + char Spid1[ISDN_MAX_NUM_LEN]; + char Spid2[ISDN_MAX_NUM_LEN]; + byte nosig; + byte BriLayer2LinkCount; /* amount of TEI's that adapter will support in P2MP mode */ + dword Channels; + dword tei; + dword nt2; + dword TerminalCount; + dword WatchDog; + dword Permanent; + dword BChMask; /* B channel mask for unchannelized modes */ + dword StableL2; + dword DidLen; + dword NoOrderCheck; + dword ForceLaw; /* VoiceCoding - default:0, a-law: 1, my-law: 2 */ + dword SigFlags; + dword LowChannel; + dword NoHscx30; + dword ProtVersion; + dword crc4; + dword L1TristateOrQsig; /* enable Layer 1 Tristate (bit 2)Or Qsig params (bit 0,1)*/ + dword InitialDspInfo; + dword ModemGuardTone; + dword ModemMinSpeed; + dword ModemMaxSpeed; + dword ModemOptions; + dword ModemOptions2; + dword ModemNegotiationMode; + dword ModemModulationsMask; + dword ModemTransmitLevel; + dword FaxOptions; + dword FaxMaxSpeed; + dword Part68LevelLimiter; + dword UsEktsNumCallApp; + byte UsEktsFeatAddConf; + byte UsEktsFeatRemoveConf; + byte UsEktsFeatCallTransfer; + byte UsEktsFeatMsgWaiting; + byte QsigDialect; + byte ForceVoiceMailAlert; + byte DisableAutoSpid; + byte ModemCarrierWaitTimeSec; + byte ModemCarrierLossWaitTimeTenthSec; + byte PiafsLinkTurnaroundInFrames; + byte DiscAfterProgress; + byte AniDniLimiter[3]; + byte TxAttenuation; /* PRI/E1 only: attenuate TX signal */ + word QsigFeatures; + dword GenerateRingtone; + dword SupplementaryServicesFeatures; + dword R2Dialect; + dword R2CasOptions; + dword FaxV34Options; + dword DisabledDspMask; + dword AdapterTestMask; + dword DspImageLength; + word AlertToIn20mSecTicks; + word ModemEyeSetup; + byte R2CtryLength; + byte CCBSRelTimer; + byte *PcCfgBufferFile;/* flexible parameter via file */ + byte *PcCfgBuffer; /* flexible parameter via multistring */ + diva_os_dump_file_t dump_file; /* dump memory to file at lowest irq level */ + diva_os_board_trace_t board_trace; /* traces from the board */ + diva_os_spin_lock_t isr_spin_lock; + diva_os_spin_lock_t data_spin_lock; + diva_os_soft_isr_t req_soft_isr; + diva_os_soft_isr_t isr_soft_isr; + diva_os_atomic_t in_dpc; + PBUFFER RBuffer; /* Copy of receive lookahead buffer */ + word e_max; + word e_count; + E_INFO *e_tbl; + word assign; /* list of pending ASSIGNs */ + word head; /* head of request queue */ + word tail; /* tail of request queue */ + ADAPTER a; /* not a separate structure */ + void (*out)(ADAPTER *a); + byte (*dpc)(ADAPTER *a); + byte (*tst_irq)(ADAPTER *a); + void (*clr_irq)(ADAPTER *a); + int (*load)(PISDN_ADAPTER); + int (*mapmem)(PISDN_ADAPTER); + int (*chkIrq)(PISDN_ADAPTER); + void (*disIrq)(PISDN_ADAPTER); + void (*start)(PISDN_ADAPTER); + void (*stop)(PISDN_ADAPTER); + void (*rstFnc)(PISDN_ADAPTER); + void (*trapFnc)(PISDN_ADAPTER); + dword (*DetectDsps)(PISDN_ADAPTER); + void (*os_trap_nfy_Fnc)(PISDN_ADAPTER, dword); + diva_os_isr_callback_t diva_isr_handler; + dword sdram_bar; /* must be 32 bit */ + dword fpga_features; + volatile int pcm_pending; + volatile void *pcm_data; + diva_xdi_capi_cfg_t capi_cfg; + dword tasks; + void *dma_map; + int (*DivaAdapterTestProc)(PISDN_ADAPTER); + void *AdapterTestMemoryStart; + dword AdapterTestMemoryLength; + const byte *cfg_lib_memory_init; + dword cfg_lib_memory_init_length; }; /* --------------------------------------------------------------------- - Entity table + Entity table --------------------------------------------------------------------- */ struct e_info_s { - ENTITY * e; - byte next; /* chaining index */ - word assign_ref; /* assign reference */ + ENTITY *e; + byte next; /* chaining index */ + word assign_ref; /* assign reference */ }; /* --------------------------------------------------------------------- - S-cards shared ram structure for loading + S-cards shared ram structure for loading --------------------------------------------------------------------- */ struct s_load { - byte ctrl; - byte card; - byte msize; - byte fill0; - word ebit; - word elocl; - word eloch; - byte reserved[20]; - word signature; - byte fill[224]; - byte b[256]; + byte ctrl; + byte card; + byte msize; + byte fill0; + word ebit; + word elocl; + word eloch; + byte reserved[20]; + word signature; + byte fill[224]; + byte b[256]; }; #define PR_RAM ((struct pr_ram *)0) #define RAM ((struct dual *)0) /* --------------------------------------------------------------------- - platform specific conversions + platform specific conversions --------------------------------------------------------------------- */ -extern void * PTR_P(ADAPTER * a, ENTITY * e, void * P); -extern void * PTR_X(ADAPTER * a, ENTITY * e); -extern void * PTR_R(ADAPTER * a, ENTITY * e); -extern void CALLBACK(ADAPTER * a, ENTITY * e); -extern void set_ram(void * * adr_ptr); +extern void *PTR_P(ADAPTER *a, ENTITY *e, void *P); +extern void *PTR_X(ADAPTER *a, ENTITY *e); +extern void *PTR_R(ADAPTER *a, ENTITY *e); +extern void CALLBACK(ADAPTER *a, ENTITY *e); +extern void set_ram(void **adr_ptr); /* --------------------------------------------------------------------- - ram access functions for io mapped cards + ram access functions for io mapped cards --------------------------------------------------------------------- */ -byte io_in(ADAPTER * a, void * adr); -word io_inw(ADAPTER * a, void * adr); -void io_in_buffer(ADAPTER * a, void * adr, void * P, word length); -void io_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e); -void io_out(ADAPTER * a, void * adr, byte data); -void io_outw(ADAPTER * a, void * adr, word data); -void io_out_buffer(ADAPTER * a, void * adr, void * P, word length); -void io_inc(ADAPTER * a, void * adr); -void bri_in_buffer (PISDN_ADAPTER IoAdapter, dword Pos, - void *Buf, dword Len); -int bri_out_buffer (PISDN_ADAPTER IoAdapter, dword Pos, - void *Buf, dword Len, int Verify); +byte io_in(ADAPTER *a, void *adr); +word io_inw(ADAPTER *a, void *adr); +void io_in_buffer(ADAPTER *a, void *adr, void *P, word length); +void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e); +void io_out(ADAPTER *a, void *adr, byte data); +void io_outw(ADAPTER *a, void *adr, word data); +void io_out_buffer(ADAPTER *a, void *adr, void *P, word length); +void io_inc(ADAPTER *a, void *adr); +void bri_in_buffer(PISDN_ADAPTER IoAdapter, dword Pos, + void *Buf, dword Len); +int bri_out_buffer(PISDN_ADAPTER IoAdapter, dword Pos, + void *Buf, dword Len, int Verify); /* --------------------------------------------------------------------- - ram access functions for memory mapped cards + ram access functions for memory mapped cards --------------------------------------------------------------------- */ -byte mem_in(ADAPTER * a, void * adr); -word mem_inw(ADAPTER * a, void * adr); -void mem_in_buffer(ADAPTER * a, void * adr, void * P, word length); -void mem_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e); -void mem_out(ADAPTER * a, void * adr, byte data); -void mem_outw(ADAPTER * a, void * adr, word data); -void mem_out_buffer(ADAPTER * a, void * adr, void * P, word length); -void mem_inc(ADAPTER * a, void * adr); -void mem_in_dw (ADAPTER *a, void *addr, dword* data, int dwords); -void mem_out_dw (ADAPTER *a, void *addr, const dword* data, int dwords); +byte mem_in(ADAPTER *a, void *adr); +word mem_inw(ADAPTER *a, void *adr); +void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length); +void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e); +void mem_out(ADAPTER *a, void *adr, byte data); +void mem_outw(ADAPTER *a, void *adr, word data); +void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length); +void mem_inc(ADAPTER *a, void *adr); +void mem_in_dw(ADAPTER *a, void *addr, dword *data, int dwords); +void mem_out_dw(ADAPTER *a, void *addr, const dword *data, int dwords); /* --------------------------------------------------------------------- - functions exported by io.c + functions exported by io.c --------------------------------------------------------------------- */ -extern IDI_CALL Requests[MAX_ADAPTER] ; -extern void DIDpcRoutine (struct _diva_os_soft_isr* psoft_isr, - void* context); -extern void request (PISDN_ADAPTER, ENTITY *) ; +extern IDI_CALL Requests[MAX_ADAPTER]; +extern void DIDpcRoutine(struct _diva_os_soft_isr *psoft_isr, + void *context); +extern void request(PISDN_ADAPTER, ENTITY *); /* --------------------------------------------------------------------- - trapFn helpers, used to recover debug trace from dead card + trapFn helpers, used to recover debug trace from dead card --------------------------------------------------------------------- */ typedef struct { - word *buf ; - word cnt ; - word out ; -} Xdesc ; -extern void dump_trap_frame (PISDN_ADAPTER IoAdapter, byte __iomem *exception) ; -extern void dump_xlog_buffer (PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc) ; + word *buf; + word cnt; + word out; +} Xdesc; +extern void dump_trap_frame(PISDN_ADAPTER IoAdapter, byte __iomem *exception); +extern void dump_xlog_buffer(PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc); /* --------------------------------------------------------------------- */ #endif /* } __DIVA_XDI_COMMON_IO_H_INC__ */ diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c index 23139668d9b..045bda5c839 100644 --- a/drivers/isdn/hardware/eicon/istream.c +++ b/drivers/isdn/hardware/eicon/istream.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -31,196 +31,196 @@ #include "divasync.h" #include "di.h" #if !defined USE_EXTENDED_DEBUGS - #include "dimaint.h" +#include "dimaint.h" #else - #define dprintf +#define dprintf #endif #include "dfifo.h" -int diva_istream_write (void* context, - int Id, - void* data, - int length, - int final, - byte usr1, - byte usr2); -int diva_istream_read (void* context, - int Id, - void* data, - int max_length, - int* final, - byte* usr1, - byte* usr2); +int diva_istream_write(void *context, + int Id, + void *data, + int length, + int final, + byte usr1, + byte usr2); +int diva_istream_read(void *context, + int Id, + void *data, + int max_length, + int *final, + byte *usr1, + byte *usr2); /* ------------------------------------------------------------------- - Does provide iStream interface to the client + Does provide iStream interface to the client ------------------------------------------------------------------- */ -void diva_xdi_provide_istream_info (ADAPTER* a, - diva_xdi_stream_interface_t* pi) { - pi->provided_service = 0; +void diva_xdi_provide_istream_info(ADAPTER *a, + diva_xdi_stream_interface_t *pi) { + pi->provided_service = 0; } /* ------------------------------------------------------------------ - Does write the data from caller's buffer to the card's - stream interface. - If synchronous service was requested, then function - does return amount of data written to stream. - 'final' does indicate that pice of data to be written is - final part of frame (necessary only by structured datatransfer) - return 0 if zero lengh packet was written - return -1 if stream is full - ------------------------------------------------------------------ */ -int diva_istream_write (void* context, - int Id, - void* data, - int length, - int final, - byte usr1, - byte usr2) { - ADAPTER* a = (ADAPTER*)context; - int written = 0, to_write = -1; - char tmp[4]; - byte* data_ptr = (byte*)data; - for (;;) { - a->ram_in_dw (a, + Does write the data from caller's buffer to the card's + stream interface. + If synchronous service was requested, then function + does return amount of data written to stream. + 'final' does indicate that piece of data to be written is + final part of frame (necessary only by structured datatransfer) + return 0 if zero lengh packet was written + return -1 if stream is full + ------------------------------------------------------------------ */ +int diva_istream_write(void *context, + int Id, + void *data, + int length, + int final, + byte usr1, + byte usr2) { + ADAPTER *a = (ADAPTER *)context; + int written = 0, to_write = -1; + char tmp[4]; + byte *data_ptr = (byte *)data; + for (;;) { + a->ram_in_dw(a, #ifdef PLATFORM_GT_32BIT - ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]), + ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]), #else - (void*)(a->tx_stream[Id] + a->tx_pos[Id]), + (void *)(a->tx_stream[Id] + a->tx_pos[Id]), #endif - (dword*)&tmp[0], - 1); - if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */ - if (to_write < 0) - return (-1); /* was not able to write */ - break; /* only part of message was written */ - } - to_write = MIN(length, DIVA_DFIFO_DATA_SZ); - if (to_write) { - a->ram_out_buffer (a, + (dword *)&tmp[0], + 1); + if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */ + if (to_write < 0) + return (-1); /* was not able to write */ + break; /* only part of message was written */ + } + to_write = min(length, DIVA_DFIFO_DATA_SZ); + if (to_write) { + a->ram_out_buffer(a, #ifdef PLATFORM_GT_32BIT - ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]+4), + ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id] + 4), #else - (void*)(a->tx_stream[Id] + a->tx_pos[Id] + 4), + (void *)(a->tx_stream[Id] + a->tx_pos[Id] + 4), #endif - data_ptr, - (word)to_write); - length -= to_write; - written += to_write; - data_ptr += to_write; - } - tmp[1] = (char)to_write; - tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) | - DIVA_DFIFO_READY | - ((!length && final) ? DIVA_DFIFO_LAST : 0); - if (tmp[0] & DIVA_DFIFO_LAST) { - tmp[2] = usr1; - tmp[3] = usr2; - } - a->ram_out_dw (a, + data_ptr, + (word)to_write); + length -= to_write; + written += to_write; + data_ptr += to_write; + } + tmp[1] = (char)to_write; + tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) | + DIVA_DFIFO_READY | + ((!length && final) ? DIVA_DFIFO_LAST : 0); + if (tmp[0] & DIVA_DFIFO_LAST) { + tmp[2] = usr1; + tmp[3] = usr2; + } + a->ram_out_dw(a, #ifdef PLATFORM_GT_32BIT - ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]), + ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]), #else - (void*)(a->tx_stream[Id] + a->tx_pos[Id]), + (void *)(a->tx_stream[Id] + a->tx_pos[Id]), #endif - (dword*)&tmp[0], - 1); - if (tmp[0] & DIVA_DFIFO_WRAP) { - a->tx_pos[Id] = 0; - } else { - a->tx_pos[Id] += DIVA_DFIFO_STEP; - } - if (!length) { - break; - } - } - return (written); + (dword *)&tmp[0], + 1); + if (tmp[0] & DIVA_DFIFO_WRAP) { + a->tx_pos[Id] = 0; + } else { + a->tx_pos[Id] += DIVA_DFIFO_STEP; + } + if (!length) { + break; + } + } + return (written); } /* ------------------------------------------------------------------- - In case of SYNCRONOUS service: - Does write data from stream in caller's buffer. - Does return amount of data written to buffer - Final flag is set on return if last part of structured frame - was received - return 0 if zero packet was received - return -1 if stream is empty - return -2 if read buffer does not profide sufficient space - to accommodate entire segment - max_length should be at least 68 bytes - ------------------------------------------------------------------- */ -int diva_istream_read (void* context, - int Id, - void* data, - int max_length, - int* final, - byte* usr1, - byte* usr2) { - ADAPTER* a = (ADAPTER*)context; - int read = 0, to_read = -1; - char tmp[4]; - byte* data_ptr = (byte*)data; - *final = 0; - for (;;) { - a->ram_in_dw (a, + In case of SYNCRONOUS service: + Does write data from stream in caller's buffer. + Does return amount of data written to buffer + Final flag is set on return if last part of structured frame + was received + return 0 if zero packet was received + return -1 if stream is empty + return -2 if read buffer does not profide sufficient space + to accommodate entire segment + max_length should be at least 68 bytes + ------------------------------------------------------------------- */ +int diva_istream_read(void *context, + int Id, + void *data, + int max_length, + int *final, + byte *usr1, + byte *usr2) { + ADAPTER *a = (ADAPTER *)context; + int read = 0, to_read = -1; + char tmp[4]; + byte *data_ptr = (byte *)data; + *final = 0; + for (;;) { + a->ram_in_dw(a, #ifdef PLATFORM_GT_32BIT - ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]), + ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]), #else - (void*)(a->rx_stream[Id] + a->rx_pos[Id]), + (void *)(a->rx_stream[Id] + a->rx_pos[Id]), #endif - (dword*)&tmp[0], - 1); - if (tmp[1] > max_length) { - if (to_read < 0) - return (-2); /* was not able to read */ - break; - } - if (!(tmp[0] & DIVA_DFIFO_READY)) { - if (to_read < 0) - return (-1); /* was not able to read */ - break; - } - to_read = MIN(max_length, tmp[1]); - if (to_read) { - a->ram_in_buffer(a, + (dword *)&tmp[0], + 1); + if (tmp[1] > max_length) { + if (to_read < 0) + return (-2); /* was not able to read */ + break; + } + if (!(tmp[0] & DIVA_DFIFO_READY)) { + if (to_read < 0) + return (-1); /* was not able to read */ + break; + } + to_read = min(max_length, (int)tmp[1]); + if (to_read) { + a->ram_in_buffer(a, #ifdef PLATFORM_GT_32BIT - ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4), + ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4), #else - (void*)(a->rx_stream[Id] + a->rx_pos[Id] + 4), + (void *)(a->rx_stream[Id] + a->rx_pos[Id] + 4), #endif - data_ptr, - (word)to_read); - max_length -= to_read; - read += to_read; - data_ptr += to_read; - } - if (tmp[0] & DIVA_DFIFO_LAST) { - *final = 1; - } - tmp[0] &= DIVA_DFIFO_WRAP; - a->ram_out_dw(a, + data_ptr, + (word)to_read); + max_length -= to_read; + read += to_read; + data_ptr += to_read; + } + if (tmp[0] & DIVA_DFIFO_LAST) { + *final = 1; + } + tmp[0] &= DIVA_DFIFO_WRAP; + a->ram_out_dw(a, #ifdef PLATFORM_GT_32BIT - ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]), + ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]), #else - (void*)(a->rx_stream[Id] + a->rx_pos[Id]), + (void *)(a->rx_stream[Id] + a->rx_pos[Id]), #endif - (dword*)&tmp[0], - 1); - if (tmp[0] & DIVA_DFIFO_WRAP) { - a->rx_pos[Id] = 0; - } else { - a->rx_pos[Id] += DIVA_DFIFO_STEP; - } - if (*final) { - if (usr1) - *usr1 = tmp[2]; - if (usr2) - *usr2 = tmp[3]; - break; - } - } - return (read); + (dword *)&tmp[0], + 1); + if (tmp[0] & DIVA_DFIFO_WRAP) { + a->rx_pos[Id] = 0; + } else { + a->rx_pos[Id] += DIVA_DFIFO_STEP; + } + if (*final) { + if (usr1) + *usr1 = tmp[2]; + if (usr2) + *usr2 = tmp[3]; + break; + } + } + return (read); } /* --------------------------------------------------------------------- - Does check if one of streams had caused interrupt and does - wake up corresponding application + Does check if one of streams had caused interrupt and does + wake up corresponding application --------------------------------------------------------------------- */ -void pr_stream (ADAPTER * a) { +void pr_stream(ADAPTER *a) { } #endif /* } */ diff --git a/drivers/isdn/hardware/eicon/kst_ifc.h b/drivers/isdn/hardware/eicon/kst_ifc.h index 203189a010c..894fdfda109 100644 --- a/drivers/isdn/hardware/eicon/kst_ifc.h +++ b/drivers/isdn/hardware/eicon/kst_ifc.h @@ -1,25 +1,25 @@ /* * - Copyright (c) Eicon Networks, 2000. + Copyright (c) Eicon Networks, 2000. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 1.9 + Eicon File Revision : 1.9 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_EICON_TRACE_API__ @@ -35,9 +35,9 @@ typedef struct _diva_trace_ie { } diva_trace_ie_t; /* - Structure used to represent "State\\BX\\Modem" directory - to user. - */ + Structure used to represent "State\\BX\\Modem" directory + to user. +*/ typedef struct _diva_trace_modem_state { dword ChannelNumber; @@ -70,8 +70,8 @@ typedef struct _diva_trace_modem_state { } diva_trace_modem_state_t; /* - Representation of "State\\BX\\FAX" directory - */ + Representation of "State\\BX\\FAX" directory +*/ typedef struct _diva_trace_fax_state { dword ChannelNumber; dword Event; @@ -90,9 +90,9 @@ typedef struct _diva_trace_fax_state { } diva_trace_fax_state_t; /* - Structure used to represent Interface State in the abstract - and interface/D-channel protocol independent form. - */ + Structure used to represent Interface State in the abstract + and interface/D-channel protocol independent form. +*/ typedef struct _diva_trace_interface_state { char Layer1[DIVA_TRACE_LINE_TYPE_LEN]; char Layer2[DIVA_TRACE_LINE_TYPE_LEN]; @@ -164,18 +164,18 @@ typedef struct _diva_prot_statistics { typedef struct _diva_ifc_statistics { diva_incoming_call_statistics_t inc; diva_outgoing_call_statistics_t outg; - diva_modem_call_statistics_t mdm; - diva_fax_call_statistics_t fax; - diva_prot_statistics_t b1; - diva_prot_statistics_t b2; - diva_prot_statistics_t d1; - diva_prot_statistics_t d2; + diva_modem_call_statistics_t mdm; + diva_fax_call_statistics_t fax; + diva_prot_statistics_t b1; + diva_prot_statistics_t b2; + diva_prot_statistics_t d1; + diva_prot_statistics_t d2; } diva_ifc_statistics_t; /* - Structure used to represent "State\\BX" directory - to user. - */ + Structure used to represent "State\\BX" directory + to user. +*/ typedef struct _diva_trace_line_state { dword ChannelNumber; @@ -192,9 +192,9 @@ typedef struct _diva_trace_line_state { char LocalAddress[DIVA_TRACE_LINE_TYPE_LEN]; char LocalSubAddress[DIVA_TRACE_LINE_TYPE_LEN]; - diva_trace_ie_t call_BC; - diva_trace_ie_t call_HLC; - diva_trace_ie_t call_LLC; + diva_trace_ie_t call_BC; + diva_trace_ie_t call_HLC; + diva_trace_ie_t call_LLC; dword Charges; @@ -205,11 +205,11 @@ typedef struct _diva_trace_line_state { char UserID[DIVA_TRACE_LINE_TYPE_LEN]; diva_trace_modem_state_t modem; - diva_trace_fax_state_t fax; + diva_trace_fax_state_t fax; - diva_trace_interface_state_t* pInterface; + diva_trace_interface_state_t *pInterface; - diva_ifc_statistics_t* pInterfaceStat; + diva_ifc_statistics_t *pInterfaceStat; } diva_trace_line_state_t; @@ -222,115 +222,114 @@ typedef struct _diva_trace_line_state { #define DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE ('F') struct _diva_strace_library_interface; -typedef void (*diva_trace_channel_state_change_proc_t)(void* user_context, - struct _diva_strace_library_interface* hLib, - int Adapter, - diva_trace_line_state_t* channel, int notify_subject); -typedef void (*diva_trace_channel_trace_proc_t)(void* user_context, - struct _diva_strace_library_interface* hLib, - int Adapter, void* xlog_buffer, int length); -typedef void (*diva_trace_error_proc_t)(void* user_context, - struct _diva_strace_library_interface* hLib, - int Adapter, - int error, const char* file, int line); +typedef void (*diva_trace_channel_state_change_proc_t)(void *user_context, + struct _diva_strace_library_interface *hLib, + int Adapter, + diva_trace_line_state_t *channel, int notify_subject); +typedef void (*diva_trace_channel_trace_proc_t)(void *user_context, + struct _diva_strace_library_interface *hLib, + int Adapter, void *xlog_buffer, int length); +typedef void (*diva_trace_error_proc_t)(void *user_context, + struct _diva_strace_library_interface *hLib, + int Adapter, + int error, const char *file, int line); /* - This structure creates interface from user to library - */ + This structure creates interface from user to library +*/ typedef struct _diva_trace_library_user_interface { - void* user_context; - diva_trace_channel_state_change_proc_t notify_proc; - diva_trace_channel_trace_proc_t trace_proc; - diva_trace_error_proc_t error_notify_proc; + void *user_context; + diva_trace_channel_state_change_proc_t notify_proc; + diva_trace_channel_trace_proc_t trace_proc; + diva_trace_error_proc_t error_notify_proc; } diva_trace_library_user_interface_t; /* - Interface from Library to User - */ -typedef int (*DivaSTraceLibraryStart_proc_t)(void* hLib); -typedef int (*DivaSTraceLibraryFinit_proc_t)(void* hLib); -typedef int (*DivaSTraceMessageInput_proc_t)(void* hLib); -typedef void* (*DivaSTraceGetHandle_proc_t)(void* hLib); + Interface from Library to User +*/ +typedef int (*DivaSTraceLibraryStart_proc_t)(void *hLib); +typedef int (*DivaSTraceLibraryFinit_proc_t)(void *hLib); +typedef int (*DivaSTraceMessageInput_proc_t)(void *hLib); +typedef void* (*DivaSTraceGetHandle_proc_t)(void *hLib); /* - Turn Audio Tap trace on/off - Channel should be in the range 1 ... Number of Channels - */ -typedef int (*DivaSTraceSetAudioTap_proc_t)(void* hLib, int Channel, int on); + Turn Audio Tap trace on/off + Channel should be in the range 1 ... Number of Channels +*/ +typedef int (*DivaSTraceSetAudioTap_proc_t)(void *hLib, int Channel, int on); /* - Turn B-channel trace on/off - Channel should be in the range 1 ... Number of Channels - */ -typedef int (*DivaSTraceSetBChannel_proc_t)(void* hLib, int Channel, int on); + Turn B-channel trace on/off + Channel should be in the range 1 ... Number of Channels +*/ +typedef int (*DivaSTraceSetBChannel_proc_t)(void *hLib, int Channel, int on); /* - Turn D-channel (Layer1/Layer2/Layer3) trace on/off - Layer1 - All D-channel frames received/sent over the interface - inclusive Layer 2 headers, Layer 2 frames and TEI management frames - Layer2 - Events from LAPD protocol instance with SAPI of signalling protocol - Layer3 - All D-channel frames addressed to assigned to the card TEI and - SAPI of signalling protocol, and signalling protocol events. - */ -typedef int (*DivaSTraceSetDChannel_proc_t)(void* hLib, int on); + Turn D-channel (Layer1/Layer2/Layer3) trace on/off + Layer1 - All D-channel frames received/sent over the interface + inclusive Layer 2 headers, Layer 2 frames and TEI management frames + Layer2 - Events from LAPD protocol instance with SAPI of signalling protocol + Layer3 - All D-channel frames addressed to assigned to the card TEI and + SAPI of signalling protocol, and signalling protocol events. +*/ +typedef int (*DivaSTraceSetDChannel_proc_t)(void *hLib, int on); /* - Get overall card statistics - */ -typedef int (*DivaSTraceGetOutgoingCallStatistics_proc_t)(void* hLib); -typedef int (*DivaSTraceGetIncomingCallStatistics_proc_t)(void* hLib); -typedef int (*DivaSTraceGetModemStatistics_proc_t)(void* hLib); -typedef int (*DivaSTraceGetFaxStatistics_proc_t)(void* hLib); -typedef int (*DivaSTraceGetBLayer1Statistics_proc_t)(void* hLib); -typedef int (*DivaSTraceGetBLayer2Statistics_proc_t)(void* hLib); -typedef int (*DivaSTraceGetDLayer1Statistics_proc_t)(void* hLib); -typedef int (*DivaSTraceGetDLayer2Statistics_proc_t)(void* hLib); + Get overall card statistics +*/ +typedef int (*DivaSTraceGetOutgoingCallStatistics_proc_t)(void *hLib); +typedef int (*DivaSTraceGetIncomingCallStatistics_proc_t)(void *hLib); +typedef int (*DivaSTraceGetModemStatistics_proc_t)(void *hLib); +typedef int (*DivaSTraceGetFaxStatistics_proc_t)(void *hLib); +typedef int (*DivaSTraceGetBLayer1Statistics_proc_t)(void *hLib); +typedef int (*DivaSTraceGetBLayer2Statistics_proc_t)(void *hLib); +typedef int (*DivaSTraceGetDLayer1Statistics_proc_t)(void *hLib); +typedef int (*DivaSTraceGetDLayer2Statistics_proc_t)(void *hLib); /* - Call control - */ -typedef int (*DivaSTraceClearCall_proc_t)(void* hLib, int Channel); + Call control +*/ +typedef int (*DivaSTraceClearCall_proc_t)(void *hLib, int Channel); typedef struct _diva_strace_library_interface { - void* hLib; - DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStart; - DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStop; + void *hLib; + DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStart; + DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStop; DivaSTraceLibraryFinit_proc_t DivaSTraceLibraryFinit; DivaSTraceMessageInput_proc_t DivaSTraceMessageInput; - DivaSTraceGetHandle_proc_t DivaSTraceGetHandle; - DivaSTraceSetAudioTap_proc_t DivaSTraceSetAudioTap; - DivaSTraceSetBChannel_proc_t DivaSTraceSetBChannel; - DivaSTraceSetDChannel_proc_t DivaSTraceSetDChannel; - DivaSTraceSetDChannel_proc_t DivaSTraceSetInfo; + DivaSTraceGetHandle_proc_t DivaSTraceGetHandle; + DivaSTraceSetAudioTap_proc_t DivaSTraceSetAudioTap; + DivaSTraceSetBChannel_proc_t DivaSTraceSetBChannel; + DivaSTraceSetDChannel_proc_t DivaSTraceSetDChannel; + DivaSTraceSetDChannel_proc_t DivaSTraceSetInfo; DivaSTraceGetOutgoingCallStatistics_proc_t \ - DivaSTraceGetOutgoingCallStatistics; + DivaSTraceGetOutgoingCallStatistics; DivaSTraceGetIncomingCallStatistics_proc_t \ - DivaSTraceGetIncomingCallStatistics; + DivaSTraceGetIncomingCallStatistics; DivaSTraceGetModemStatistics_proc_t \ - DivaSTraceGetModemStatistics; + DivaSTraceGetModemStatistics; DivaSTraceGetFaxStatistics_proc_t \ - DivaSTraceGetFaxStatistics; + DivaSTraceGetFaxStatistics; DivaSTraceGetBLayer1Statistics_proc_t \ - DivaSTraceGetBLayer1Statistics; + DivaSTraceGetBLayer1Statistics; DivaSTraceGetBLayer2Statistics_proc_t \ - DivaSTraceGetBLayer2Statistics; + DivaSTraceGetBLayer2Statistics; DivaSTraceGetDLayer1Statistics_proc_t \ - DivaSTraceGetDLayer1Statistics; + DivaSTraceGetDLayer1Statistics; DivaSTraceGetDLayer2Statistics_proc_t \ - DivaSTraceGetDLayer2Statistics; - DivaSTraceClearCall_proc_t DivaSTraceClearCall; + DivaSTraceGetDLayer2Statistics; + DivaSTraceClearCall_proc_t DivaSTraceClearCall; } diva_strace_library_interface_t; /* - Create and return Library interface - */ -diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter, - const diva_trace_library_user_interface_t* user_proc, - byte* pmem); -dword DivaSTraceGetMemotyRequirement (int channels); + Create and return Library interface +*/ +diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter, + const diva_trace_library_user_interface_t *user_proc, + byte *pmem); +dword DivaSTraceGetMemotyRequirement(int channels); #define DIVA_MAX_ADAPTERS 64 #define DIVA_MAX_LINES 32 #endif - diff --git a/drivers/isdn/hardware/eicon/main_if.h b/drivers/isdn/hardware/eicon/main_if.h deleted file mode 100644 index 0ea339afd42..00000000000 --- a/drivers/isdn/hardware/eicon/main_if.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - Copyright (c) Eicon Technology Corporation, 2000. - * - This source file is supplied for the use with Eicon - Technology Corporation's range of DIVA Server Adapters. - * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -/*------------------------------------------------------------------*/ -/* file: main_if.h */ -/*------------------------------------------------------------------*/ -# ifndef MAIN_IF___H -# define MAIN_IF___H - -# include "debug_if.h" - -void DI_lock (void) ; -void DI_unlock (void) ; - -#ifdef NOT_YET_NEEDED -void DI_nttime (LARGE_INTEGER *NTtime) ; -void DI_ntlcltime(LARGE_INTEGER *NTtime, LARGE_INTEGER *lclNTtime) ; -void DI_nttimefields(LARGE_INTEGER *NTtime, TIME_FIELDS *TimeFields); -unsigned long DI_wintime(LARGE_INTEGER *NTtime) ; - -unsigned short DiInsertProcessorNumber (int type) ; -void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap); - -void StartIoctlTimer (void (*Handler)(void), unsigned long msec) ; -void StopIoctlTimer (void) ; -void UnpendIoctl (DbgRequest *pDbgReq) ; -#endif - -void add_to_q(int, char* , unsigned int); -# endif /* MAIN_IF___H */ - diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c index 23960cb6eaa..2ee789f9586 100644 --- a/drivers/isdn/hardware/eicon/maintidi.c +++ b/drivers/isdn/hardware/eicon/maintidi.c @@ -1,25 +1,25 @@ /* * - Copyright (c) Eicon Networks, 2000. + Copyright (c) Eicon Networks, 2000. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 1.9 + Eicon File Revision : 1.9 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -30,7 +30,7 @@ #include "man_defs.h" -extern void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...); +extern void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...); #define MODEM_PARSE_ENTRIES 16 /* amount of variables of interest */ #define FAX_PARSE_ENTRIES 12 /* amount of variables of interest */ @@ -38,77 +38,77 @@ extern void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...); #define STAT_PARSE_ENTRIES 70 /* amount of variables of interest */ /* - LOCAL FUNCTIONS - */ -static int DivaSTraceLibraryStart (void* hLib); -static int DivaSTraceLibraryStop (void* hLib); -static int SuperTraceLibraryFinit (void* hLib); -static void* SuperTraceGetHandle (void* hLib); -static int SuperTraceMessageInput (void* hLib); -static int SuperTraceSetAudioTap (void* hLib, int Channel, int on); -static int SuperTraceSetBChannel (void* hLib, int Channel, int on); -static int SuperTraceSetDChannel (void* hLib, int on); -static int SuperTraceSetInfo (void* hLib, int on); -static int SuperTraceClearCall (void* hLib, int Channel); -static int SuperTraceGetOutgoingCallStatistics (void* hLib); -static int SuperTraceGetIncomingCallStatistics (void* hLib); -static int SuperTraceGetModemStatistics (void* hLib); -static int SuperTraceGetFaxStatistics (void* hLib); -static int SuperTraceGetBLayer1Statistics (void* hLib); -static int SuperTraceGetBLayer2Statistics (void* hLib); -static int SuperTraceGetDLayer1Statistics (void* hLib); -static int SuperTraceGetDLayer2Statistics (void* hLib); + LOCAL FUNCTIONS +*/ +static int DivaSTraceLibraryStart(void *hLib); +static int DivaSTraceLibraryStop(void *hLib); +static int SuperTraceLibraryFinit(void *hLib); +static void *SuperTraceGetHandle(void *hLib); +static int SuperTraceMessageInput(void *hLib); +static int SuperTraceSetAudioTap(void *hLib, int Channel, int on); +static int SuperTraceSetBChannel(void *hLib, int Channel, int on); +static int SuperTraceSetDChannel(void *hLib, int on); +static int SuperTraceSetInfo(void *hLib, int on); +static int SuperTraceClearCall(void *hLib, int Channel); +static int SuperTraceGetOutgoingCallStatistics(void *hLib); +static int SuperTraceGetIncomingCallStatistics(void *hLib); +static int SuperTraceGetModemStatistics(void *hLib); +static int SuperTraceGetFaxStatistics(void *hLib); +static int SuperTraceGetBLayer1Statistics(void *hLib); +static int SuperTraceGetBLayer2Statistics(void *hLib); +static int SuperTraceGetDLayer1Statistics(void *hLib); +static int SuperTraceGetDLayer2Statistics(void *hLib); /* - LOCAL FUNCTIONS - */ -static int ScheduleNextTraceRequest (diva_strace_context_t* pLib); -static int process_idi_event (diva_strace_context_t* pLib, - diva_man_var_header_t* pVar); -static int process_idi_info (diva_strace_context_t* pLib, - diva_man_var_header_t* pVar); -static int diva_modem_event (diva_strace_context_t* pLib, int Channel); -static int diva_fax_event (diva_strace_context_t* pLib, int Channel); -static int diva_line_event (diva_strace_context_t* pLib, int Channel); -static int diva_modem_info (diva_strace_context_t* pLib, - int Channel, - diva_man_var_header_t* pVar); -static int diva_fax_info (diva_strace_context_t* pLib, - int Channel, - diva_man_var_header_t* pVar); -static int diva_line_info (diva_strace_context_t* pLib, - int Channel, - diva_man_var_header_t* pVar); -static int diva_ifc_statistics (diva_strace_context_t* pLib, - diva_man_var_header_t* pVar); -static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar); -static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar, - const char* name); -static int diva_strace_read_int (diva_man_var_header_t* pVar, int* var); -static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var); -static int diva_strace_read_asz (diva_man_var_header_t* pVar, char* var); -static int diva_strace_read_asc (diva_man_var_header_t* pVar, char* var); -static int diva_strace_read_ie (diva_man_var_header_t* pVar, - diva_trace_ie_t* var); -static void diva_create_parse_table (diva_strace_context_t* pLib); -static void diva_trace_error (diva_strace_context_t* pLib, - int error, const char* file, int line); -static void diva_trace_notify_user (diva_strace_context_t* pLib, - int Channel, - int notify_subject); -static int diva_trace_read_variable (diva_man_var_header_t* pVar, - void* variable); + LOCAL FUNCTIONS +*/ +static int ScheduleNextTraceRequest(diva_strace_context_t *pLib); +static int process_idi_event(diva_strace_context_t *pLib, + diva_man_var_header_t *pVar); +static int process_idi_info(diva_strace_context_t *pLib, + diva_man_var_header_t *pVar); +static int diva_modem_event(diva_strace_context_t *pLib, int Channel); +static int diva_fax_event(diva_strace_context_t *pLib, int Channel); +static int diva_line_event(diva_strace_context_t *pLib, int Channel); +static int diva_modem_info(diva_strace_context_t *pLib, + int Channel, + diva_man_var_header_t *pVar); +static int diva_fax_info(diva_strace_context_t *pLib, + int Channel, + diva_man_var_header_t *pVar); +static int diva_line_info(diva_strace_context_t *pLib, + int Channel, + diva_man_var_header_t *pVar); +static int diva_ifc_statistics(diva_strace_context_t *pLib, + diva_man_var_header_t *pVar); +static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar); +static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar, + const char *name); +static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var); +static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var); +static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var); +static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var); +static int diva_strace_read_ie(diva_man_var_header_t *pVar, + diva_trace_ie_t *var); +static void diva_create_parse_table(diva_strace_context_t *pLib); +static void diva_trace_error(diva_strace_context_t *pLib, + int error, const char *file, int line); +static void diva_trace_notify_user(diva_strace_context_t *pLib, + int Channel, + int notify_subject); +static int diva_trace_read_variable(diva_man_var_header_t *pVar, + void *variable); /* - Initialize the library and return context - of the created trace object that will represent - the IDI adapter. - Return 0 on error. - */ -diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter, - const diva_trace_library_user_interface_t* user_proc, - byte* pmem) { - diva_strace_context_t* pLib = (diva_strace_context_t*)pmem; + Initialize the library and return context + of the created trace object that will represent + the IDI adapter. + Return 0 on error. +*/ +diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter, + const diva_trace_library_user_interface_t *user_proc, + byte *pmem) { + diva_strace_context_t *pLib = (diva_strace_context_t *)pmem; int i; if (!pLib) { @@ -121,11 +121,11 @@ diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter, pLib->Adapter = Adapter; /* - Set up Library Interface - */ + Set up Library Interface + */ pLib->instance.hLib = pLib; - pLib->instance.DivaSTraceLibraryStart = DivaSTraceLibraryStart; - pLib->instance.DivaSTraceLibraryStop = DivaSTraceLibraryStop; + pLib->instance.DivaSTraceLibraryStart = DivaSTraceLibraryStart; + pLib->instance.DivaSTraceLibraryStop = DivaSTraceLibraryStop; pLib->instance.DivaSTraceLibraryFinit = SuperTraceLibraryFinit; pLib->instance.DivaSTraceMessageInput = SuperTraceMessageInput; pLib->instance.DivaSTraceGetHandle = SuperTraceGetHandle; @@ -134,21 +134,21 @@ diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter, pLib->instance.DivaSTraceSetDChannel = SuperTraceSetDChannel; pLib->instance.DivaSTraceSetInfo = SuperTraceSetInfo; pLib->instance.DivaSTraceGetOutgoingCallStatistics = \ - SuperTraceGetOutgoingCallStatistics; + SuperTraceGetOutgoingCallStatistics; pLib->instance.DivaSTraceGetIncomingCallStatistics = \ - SuperTraceGetIncomingCallStatistics; + SuperTraceGetIncomingCallStatistics; pLib->instance.DivaSTraceGetModemStatistics = \ - SuperTraceGetModemStatistics; + SuperTraceGetModemStatistics; pLib->instance.DivaSTraceGetFaxStatistics = \ - SuperTraceGetFaxStatistics; + SuperTraceGetFaxStatistics; pLib->instance.DivaSTraceGetBLayer1Statistics = \ - SuperTraceGetBLayer1Statistics; + SuperTraceGetBLayer1Statistics; pLib->instance.DivaSTraceGetBLayer2Statistics = \ - SuperTraceGetBLayer2Statistics; + SuperTraceGetBLayer2Statistics; pLib->instance.DivaSTraceGetDLayer1Statistics = \ - SuperTraceGetDLayer1Statistics; + SuperTraceGetDLayer1Statistics; pLib->instance.DivaSTraceGetDLayer2Statistics = \ - SuperTraceGetDLayer2Statistics; + SuperTraceGetDLayer2Statistics; pLib->instance.DivaSTraceClearCall = SuperTraceClearCall; @@ -159,272 +159,272 @@ diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter, pLib->user_proc_table.error_notify_proc = user_proc->error_notify_proc; } - if (!(pLib->hAdapter = SuperTraceOpenAdapter (Adapter))) { - diva_mnt_internal_dprintf (0, DLI_ERR, "Can not open XDI adapter"); + if (!(pLib->hAdapter = SuperTraceOpenAdapter(Adapter))) { + diva_mnt_internal_dprintf(0, DLI_ERR, "Can not open XDI adapter"); return NULL; } - pLib->Channels = SuperTraceGetNumberOfChannels (pLib->hAdapter); + pLib->Channels = SuperTraceGetNumberOfChannels(pLib->hAdapter); /* - Calculate amount of parte table entites necessary to translate - information from all events of onterest - */ + Calculate amount of parte table entites necessary to translate + information from all events of onterest + */ pLib->parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \ - STAT_PARSE_ENTRIES + \ - LINE_PARSE_ENTRIES + 1) * pLib->Channels; - pLib->parse_table = (diva_strace_path2action_t*)pmem; + STAT_PARSE_ENTRIES + \ + LINE_PARSE_ENTRIES + 1) * pLib->Channels; + pLib->parse_table = (diva_strace_path2action_t *)pmem; for (i = 0; i < 30; i++) { pLib->lines[i].pInterface = &pLib->Interface; pLib->lines[i].pInterfaceStat = &pLib->InterfaceStat; } - pLib->e.R = &pLib->RData; + pLib->e.R = &pLib->RData; pLib->req_busy = 1; pLib->rc_ok = ASSIGN_OK; - diva_create_parse_table (pLib); + diva_create_parse_table(pLib); - return ((diva_strace_library_interface_t*)pLib); + return ((diva_strace_library_interface_t *)pLib); } -static int DivaSTraceLibraryStart (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int DivaSTraceLibraryStart(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; - return (SuperTraceASSIGN (pLib->hAdapter, pLib->buffer)); + return (SuperTraceASSIGN(pLib->hAdapter, pLib->buffer)); } /* Return (-1) on error Return (0) if was initiated or pending Return (1) if removal is complete - */ -static int DivaSTraceLibraryStop (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +*/ +static int DivaSTraceLibraryStop(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; - if (!pLib->e.Id) { /* Was never started/assigned */ - return (1); - } + if (!pLib->e.Id) { /* Was never started/assigned */ + return (1); + } - switch (pLib->removal_state) { - case 0: - pLib->removal_state = 1; - ScheduleNextTraceRequest(pLib); - break; + switch (pLib->removal_state) { + case 0: + pLib->removal_state = 1; + ScheduleNextTraceRequest(pLib); + break; - case 3: - return (1); - } + case 3: + return (1); + } - return (0); + return (0); } -static int SuperTraceLibraryFinit (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceLibraryFinit(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; if (pLib) { if (pLib->hAdapter) { - SuperTraceCloseAdapter (pLib->hAdapter); + SuperTraceCloseAdapter(pLib->hAdapter); } return (0); } return (-1); } -static void* SuperTraceGetHandle (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static void *SuperTraceGetHandle(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; - return (&pLib->e); + return (&pLib->e); } /* - After library handle object is gone in signaled state - this function should be called and will pick up incoming - IDI messages (return codes and indications). - */ -static int SuperTraceMessageInput (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; + After library handle object is gone in signaled state + this function should be called and will pick up incoming + IDI messages (return codes and indications). +*/ +static int SuperTraceMessageInput(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; int ret = 0; - byte Rc, Ind; + byte Rc, Ind; - if (pLib->e.complete == 255) { - /* - Process return code - */ - pLib->req_busy = 0; - Rc = pLib->e.Rc; - pLib->e.Rc = 0; + if (pLib->e.complete == 255) { + /* + Process return code + */ + pLib->req_busy = 0; + Rc = pLib->e.Rc; + pLib->e.Rc = 0; - if (pLib->removal_state == 2) { - pLib->removal_state = 3; - return (0); - } + if (pLib->removal_state == 2) { + pLib->removal_state = 3; + return (0); + } if (Rc != pLib->rc_ok) { - int ignore = 0; - /* - Auto-detect amount of events/channels and features - */ - if (pLib->general_b_ch_event == 1) { - pLib->general_b_ch_event = 2; - ignore = 1; - } else if (pLib->general_fax_event == 1) { - pLib->general_fax_event = 2; - ignore = 1; - } else if (pLib->general_mdm_event == 1) { - pLib->general_mdm_event = 2; - ignore = 1; - } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) { - pLib->ChannelsTraceActive = pLib->Channels; - ignore = 1; - } else if (pLib->ModemTraceActive < pLib->Channels) { - pLib->ModemTraceActive = pLib->Channels; - ignore = 1; - } else if (pLib->FaxTraceActive < pLib->Channels) { - pLib->FaxTraceActive = pLib->Channels; - ignore = 1; - } else if (pLib->audio_trace_init == 2) { - ignore = 1; - pLib->audio_trace_init = 1; - } else if (pLib->eye_pattern_pending) { + int ignore = 0; + /* + Auto-detect amount of events/channels and features + */ + if (pLib->general_b_ch_event == 1) { + pLib->general_b_ch_event = 2; + ignore = 1; + } else if (pLib->general_fax_event == 1) { + pLib->general_fax_event = 2; + ignore = 1; + } else if (pLib->general_mdm_event == 1) { + pLib->general_mdm_event = 2; + ignore = 1; + } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) { + pLib->ChannelsTraceActive = pLib->Channels; + ignore = 1; + } else if (pLib->ModemTraceActive < pLib->Channels) { + pLib->ModemTraceActive = pLib->Channels; + ignore = 1; + } else if (pLib->FaxTraceActive < pLib->Channels) { + pLib->FaxTraceActive = pLib->Channels; + ignore = 1; + } else if (pLib->audio_trace_init == 2) { + ignore = 1; + pLib->audio_trace_init = 1; + } else if (pLib->eye_pattern_pending) { pLib->eye_pattern_pending = 0; ignore = 1; } else if (pLib->audio_tap_pending) { pLib->audio_tap_pending = 0; ignore = 1; - } - - if (!ignore) { - return (-1); /* request failed */ - } - } else { - if (pLib->general_b_ch_event == 1) { - pLib->ChannelsTraceActive = pLib->Channels; - pLib->general_b_ch_event = 2; - } else if (pLib->general_fax_event == 1) { - pLib->general_fax_event = 2; - pLib->FaxTraceActive = pLib->Channels; - } else if (pLib->general_mdm_event == 1) { - pLib->general_mdm_event = 2; - pLib->ModemTraceActive = pLib->Channels; - } - } - if (pLib->audio_trace_init == 2) { - pLib->audio_trace_init = 1; - } - pLib->rc_ok = 0xff; /* default OK after assign was done */ - if ((ret = ScheduleNextTraceRequest(pLib))) { - return (-1); - } - } else { - /* - Process indication - Always 'RNR' indication if return code is pending - */ - Ind = pLib->e.Ind; - pLib->e.Ind = 0; - if (pLib->removal_state) { - pLib->e.RNum = 0; - pLib->e.RNR = 2; - } else if (pLib->req_busy) { - pLib->e.RNum = 0; - pLib->e.RNR = 1; - } else { - if (pLib->e.complete != 0x02) { - /* - Look-ahead call, set up buffers - */ - pLib->e.RNum = 1; - pLib->e.R->P = (byte*)&pLib->buffer[0]; - pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1); - - } else { - /* - Indication reception complete, process it now - */ - byte* p = (byte*)&pLib->buffer[0]; - pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */ - - switch (Ind) { - case MAN_COMBI_IND: { - int total_length = pLib->e.R->PLength; - word this_ind_length; - - while (total_length > 3 && *p) { - Ind = *p++; - this_ind_length = (word)p[0] | ((word)p[1] << 8); - p += 2; - - switch (Ind) { - case MAN_INFO_IND: - if (process_idi_info (pLib, (diva_man_var_header_t*)p)) { - return (-1); - } - break; - case MAN_EVENT_IND: - if (process_idi_event (pLib, (diva_man_var_header_t*)p)) { - return (-1); - } - break; - case MAN_TRACE_IND: - if (pLib->trace_on == 1) { - /* - Ignore first trace event that is result of - EVENT_ON operation - */ - pLib->trace_on++; - } else { - /* - Delivery XLOG buffer to application - */ - if (pLib->user_proc_table.trace_proc) { - (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context, - &pLib->instance, pLib->Adapter, - p, this_ind_length); - } - } - break; - default: - diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind (DMA mode): %02x", Ind); - } - p += (this_ind_length+1); - total_length -= (4 + this_ind_length); - } - } break; - case MAN_INFO_IND: - if (process_idi_info (pLib, (diva_man_var_header_t*)p)) { - return (-1); - } - break; - case MAN_EVENT_IND: - if (process_idi_event (pLib, (diva_man_var_header_t*)p)) { - return (-1); - } - break; - case MAN_TRACE_IND: - if (pLib->trace_on == 1) { - /* - Ignore first trace event that is result of - EVENT_ON operation - */ - pLib->trace_on++; - } else { - /* - Delivery XLOG buffer to application - */ - if (pLib->user_proc_table.trace_proc) { - (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context, - &pLib->instance, pLib->Adapter, - p, pLib->e.R->PLength); - } - } - break; - default: - diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind: %02x", Ind); - } - } - } - } + } + + if (!ignore) { + return (-1); /* request failed */ + } + } else { + if (pLib->general_b_ch_event == 1) { + pLib->ChannelsTraceActive = pLib->Channels; + pLib->general_b_ch_event = 2; + } else if (pLib->general_fax_event == 1) { + pLib->general_fax_event = 2; + pLib->FaxTraceActive = pLib->Channels; + } else if (pLib->general_mdm_event == 1) { + pLib->general_mdm_event = 2; + pLib->ModemTraceActive = pLib->Channels; + } + } + if (pLib->audio_trace_init == 2) { + pLib->audio_trace_init = 1; + } + pLib->rc_ok = 0xff; /* default OK after assign was done */ + if ((ret = ScheduleNextTraceRequest(pLib))) { + return (-1); + } + } else { + /* + Process indication + Always 'RNR' indication if return code is pending + */ + Ind = pLib->e.Ind; + pLib->e.Ind = 0; + if (pLib->removal_state) { + pLib->e.RNum = 0; + pLib->e.RNR = 2; + } else if (pLib->req_busy) { + pLib->e.RNum = 0; + pLib->e.RNR = 1; + } else { + if (pLib->e.complete != 0x02) { + /* + Look-ahead call, set up buffers + */ + pLib->e.RNum = 1; + pLib->e.R->P = (byte *)&pLib->buffer[0]; + pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1); + + } else { + /* + Indication reception complete, process it now + */ + byte *p = (byte *)&pLib->buffer[0]; + pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */ + + switch (Ind) { + case MAN_COMBI_IND: { + int total_length = pLib->e.R->PLength; + word this_ind_length; + + while (total_length > 3 && *p) { + Ind = *p++; + this_ind_length = (word)p[0] | ((word)p[1] << 8); + p += 2; + + switch (Ind) { + case MAN_INFO_IND: + if (process_idi_info(pLib, (diva_man_var_header_t *)p)) { + return (-1); + } + break; + case MAN_EVENT_IND: + if (process_idi_event(pLib, (diva_man_var_header_t *)p)) { + return (-1); + } + break; + case MAN_TRACE_IND: + if (pLib->trace_on == 1) { + /* + Ignore first trace event that is result of + EVENT_ON operation + */ + pLib->trace_on++; + } else { + /* + Delivery XLOG buffer to application + */ + if (pLib->user_proc_table.trace_proc) { + (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context, + &pLib->instance, pLib->Adapter, + p, this_ind_length); + } + } + break; + default: + diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind); + } + p += (this_ind_length + 1); + total_length -= (4 + this_ind_length); + } + } break; + case MAN_INFO_IND: + if (process_idi_info(pLib, (diva_man_var_header_t *)p)) { + return (-1); + } + break; + case MAN_EVENT_IND: + if (process_idi_event(pLib, (diva_man_var_header_t *)p)) { + return (-1); + } + break; + case MAN_TRACE_IND: + if (pLib->trace_on == 1) { + /* + Ignore first trace event that is result of + EVENT_ON operation + */ + pLib->trace_on++; + } else { + /* + Delivery XLOG buffer to application + */ + if (pLib->user_proc_table.trace_proc) { + (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context, + &pLib->instance, pLib->Adapter, + p, pLib->e.R->PLength); + } + } + break; + default: + diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind: %02x", Ind); + } + } + } + } if ((ret = ScheduleNextTraceRequest(pLib))) { return (-1); @@ -434,9 +434,9 @@ static int SuperTraceMessageInput (void* hLib) { } /* - Internal state machine responsible for scheduling of requests - */ -static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { + Internal state machine responsible for scheduling of requests +*/ +static int ScheduleNextTraceRequest(diva_strace_context_t *pLib) { char name[64]; int ret = 0; int i; @@ -445,50 +445,50 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { return (0); } - if (pLib->removal_state == 1) { - if (SuperTraceREMOVE (pLib->hAdapter)) { - pLib->removal_state = 3; - } else { - pLib->req_busy = 1; - pLib->removal_state = 2; - } - return (0); - } + if (pLib->removal_state == 1) { + if (SuperTraceREMOVE(pLib->hAdapter)) { + pLib->removal_state = 3; + } else { + pLib->req_busy = 1; + pLib->removal_state = 2; + } + return (0); + } - if (pLib->removal_state) { - return (0); - } + if (pLib->removal_state) { + return (0); + } - if (!pLib->general_b_ch_event) { + if (!pLib->general_b_ch_event) { if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\B Event", pLib->buffer))) { - return (-1); - } - pLib->general_b_ch_event = 1; + return (-1); + } + pLib->general_b_ch_event = 1; pLib->req_busy = 1; return (0); - } + } - if (!pLib->general_fax_event) { + if (!pLib->general_fax_event) { if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\FAX Event", pLib->buffer))) { - return (-1); - } - pLib->general_fax_event = 1; + return (-1); + } + pLib->general_fax_event = 1; pLib->req_busy = 1; return (0); - } + } - if (!pLib->general_mdm_event) { + if (!pLib->general_mdm_event) { if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\Modem Event", pLib->buffer))) { - return (-1); - } - pLib->general_mdm_event = 1; + return (-1); + } + pLib->general_mdm_event = 1; pLib->req_busy = 1; return (0); - } + } if (pLib->ChannelsTraceActive < pLib->Channels) { pLib->ChannelsTraceActive++; - sprintf (name, "State\\B%d\\Line", pLib->ChannelsTraceActive); + sprintf(name, "State\\B%d\\Line", pLib->ChannelsTraceActive); if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) { pLib->ChannelsTraceActive--; return (-1); @@ -499,7 +499,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { if (pLib->ModemTraceActive < pLib->Channels) { pLib->ModemTraceActive++; - sprintf (name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive); + sprintf(name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive); if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) { pLib->ModemTraceActive--; return (-1); @@ -510,7 +510,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { if (pLib->FaxTraceActive < pLib->Channels) { pLib->FaxTraceActive++; - sprintf (name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive); + sprintf(name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive); if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) { pLib->FaxTraceActive--; return (-1); @@ -521,12 +521,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { if (!pLib->trace_mask_init) { word tmp = 0x0000; - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\Event Enable", - &tmp, - 0x87, /* MI_BITFLD */ - sizeof(tmp))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\Event Enable", + &tmp, + 0x87, /* MI_BITFLD */ + sizeof(tmp))) { return (-1); } pLib->trace_mask_init = 1; @@ -536,12 +536,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { if (!pLib->audio_trace_init) { dword tmp = 0x00000000; - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\AudioCh# Enable", - &tmp, - 0x87, /* MI_BITFLD */ - sizeof(tmp))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\AudioCh# Enable", + &tmp, + 0x87, /* MI_BITFLD */ + sizeof(tmp))) { return (-1); } pLib->audio_trace_init = 2; @@ -551,12 +551,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { if (!pLib->bchannel_init) { dword tmp = 0x00000000; - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\B-Ch# Enable", - &tmp, - 0x87, /* MI_BITFLD */ - sizeof(tmp))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\B-Ch# Enable", + &tmp, + 0x87, /* MI_BITFLD */ + sizeof(tmp))) { return (-1); } pLib->bchannel_init = 1; @@ -566,12 +566,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { if (!pLib->trace_length_init) { word tmp = 30; - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\Max Log Length", - &tmp, - 0x82, /* MI_UINT */ - sizeof(tmp))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\Max Log Length", + &tmp, + 0x82, /* MI_UINT */ + sizeof(tmp))) { return (-1); } pLib->trace_length_init = 1; @@ -580,9 +580,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (!pLib->trace_on) { - if (SuperTraceTraceOnRequest (pLib->hAdapter, - "Trace\\Log Buffer", - pLib->buffer)) { + if (SuperTraceTraceOnRequest(pLib->hAdapter, + "Trace\\Log Buffer", + pLib->buffer)) { return (-1); } pLib->trace_on = 1; @@ -591,12 +591,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->trace_event_mask != pLib->current_trace_event_mask) { - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\Event Enable", - &pLib->trace_event_mask, - 0x87, /* MI_BITFLD */ - sizeof(pLib->trace_event_mask))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\Event Enable", + &pLib->trace_event_mask, + 0x87, /* MI_BITFLD */ + sizeof(pLib->trace_event_mask))) { return (-1); } pLib->current_trace_event_mask = pLib->trace_event_mask; @@ -605,12 +605,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if ((pLib->audio_tap_pending >= 0) && (pLib->audio_tap_mask != pLib->current_audio_tap_mask)) { - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\AudioCh# Enable", - &pLib->audio_tap_mask, - 0x87, /* MI_BITFLD */ - sizeof(pLib->audio_tap_mask))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\AudioCh# Enable", + &pLib->audio_tap_mask, + 0x87, /* MI_BITFLD */ + sizeof(pLib->audio_tap_mask))) { return (-1); } pLib->current_audio_tap_mask = pLib->audio_tap_mask; @@ -620,12 +620,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if ((pLib->eye_pattern_pending >= 0) && (pLib->audio_tap_mask != pLib->current_eye_pattern_mask)) { - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\EyeCh# Enable", - &pLib->audio_tap_mask, - 0x87, /* MI_BITFLD */ - sizeof(pLib->audio_tap_mask))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\EyeCh# Enable", + &pLib->audio_tap_mask, + 0x87, /* MI_BITFLD */ + sizeof(pLib->audio_tap_mask))) { return (-1); } pLib->current_eye_pattern_mask = pLib->audio_tap_mask; @@ -635,12 +635,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->bchannel_trace_mask != pLib->current_bchannel_trace_mask) { - if (SuperTraceWriteVar (pLib->hAdapter, - pLib->buffer, - "Trace\\B-Ch# Enable", - &pLib->bchannel_trace_mask, - 0x87, /* MI_BITFLD */ - sizeof(pLib->bchannel_trace_mask))) { + if (SuperTraceWriteVar(pLib->hAdapter, + pLib->buffer, + "Trace\\B-Ch# Enable", + &pLib->bchannel_trace_mask, + 0x87, /* MI_BITFLD */ + sizeof(pLib->bchannel_trace_mask))) { return (-1); } pLib->current_bchannel_trace_mask = pLib->bchannel_trace_mask; @@ -649,9 +649,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (!pLib->trace_events_down) { - if (SuperTraceTraceOnRequest (pLib->hAdapter, - "Events Down", - pLib->buffer)) { + if (SuperTraceTraceOnRequest(pLib->hAdapter, + "Events Down", + pLib->buffer)) { return (-1); } pLib->trace_events_down = 1; @@ -660,9 +660,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (!pLib->l1_trace) { - if (SuperTraceTraceOnRequest (pLib->hAdapter, - "State\\Layer1", - pLib->buffer)) { + if (SuperTraceTraceOnRequest(pLib->hAdapter, + "State\\Layer1", + pLib->buffer)) { return (-1); } pLib->l1_trace = 1; @@ -671,9 +671,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (!pLib->l2_trace) { - if (SuperTraceTraceOnRequest (pLib->hAdapter, - "State\\Layer2 No1", - pLib->buffer)) { + if (SuperTraceTraceOnRequest(pLib->hAdapter, + "State\\Layer2 No1", + pLib->buffer)) { return (-1); } pLib->l2_trace = 1; @@ -683,8 +683,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { for (i = 0; i < 30; i++) { if (pLib->pending_line_status & (1L << i)) { - sprintf (name, "State\\B%d", i+1); - if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) { + sprintf(name, "State\\B%d", i + 1); + if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) { return (-1); } pLib->pending_line_status &= ~(1L << i); @@ -692,8 +692,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { return (0); } if (pLib->pending_modem_status & (1L << i)) { - sprintf (name, "State\\B%d\\Modem", i+1); - if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) { + sprintf(name, "State\\B%d\\Modem", i + 1); + if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) { return (-1); } pLib->pending_modem_status &= ~(1L << i); @@ -701,8 +701,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { return (0); } if (pLib->pending_fax_status & (1L << i)) { - sprintf (name, "State\\B%d\\FAX", i+1); - if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) { + sprintf(name, "State\\B%d\\FAX", i + 1); + if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) { return (-1); } pLib->pending_fax_status &= ~(1L << i); @@ -710,8 +710,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { return (0); } if (pLib->clear_call_command & (1L << i)) { - sprintf (name, "State\\B%d\\Clear Call", i+1); - if (SuperTraceExecuteRequest (pLib->hAdapter, name, pLib->buffer)) { + sprintf(name, "State\\B%d\\Clear Call", i + 1); + if (SuperTraceExecuteRequest(pLib->hAdapter, name, pLib->buffer)) { return (-1); } pLib->clear_call_command &= ~(1L << i); @@ -721,9 +721,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->outgoing_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\Outgoing Calls", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\Outgoing Calls", + pLib->buffer)) { return (-1); } pLib->outgoing_ifc_stats = 0; @@ -732,9 +732,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->incoming_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\Incoming Calls", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\Incoming Calls", + pLib->buffer)) { return (-1); } pLib->incoming_ifc_stats = 0; @@ -743,9 +743,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->modem_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\Modem", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\Modem", + pLib->buffer)) { return (-1); } pLib->modem_ifc_stats = 0; @@ -754,9 +754,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->fax_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\FAX", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\FAX", + pLib->buffer)) { return (-1); } pLib->fax_ifc_stats = 0; @@ -765,9 +765,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->b1_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\B-Layer1", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\B-Layer1", + pLib->buffer)) { return (-1); } pLib->b1_ifc_stats = 0; @@ -776,9 +776,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->b2_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\B-Layer2", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\B-Layer2", + pLib->buffer)) { return (-1); } pLib->b2_ifc_stats = 0; @@ -787,9 +787,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->d1_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\D-Layer1", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\D-Layer1", + pLib->buffer)) { return (-1); } pLib->d1_ifc_stats = 0; @@ -798,9 +798,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (pLib->d2_ifc_stats) { - if (SuperTraceReadRequest (pLib->hAdapter, - "Statistics\\D-Layer2", - pLib->buffer)) { + if (SuperTraceReadRequest(pLib->hAdapter, + "Statistics\\D-Layer2", + pLib->buffer)) { return (-1); } pLib->d2_ifc_stats = 0; @@ -810,7 +810,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { if (!pLib->IncomingCallsCallsActive) { pLib->IncomingCallsCallsActive = 1; - sprintf (name, "%s", "Statistics\\Incoming Calls\\Calls"); + sprintf(name, "%s", "Statistics\\Incoming Calls\\Calls"); if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) { pLib->IncomingCallsCallsActive = 0; return (-1); @@ -820,7 +820,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (!pLib->IncomingCallsConnectedActive) { pLib->IncomingCallsConnectedActive = 1; - sprintf (name, "%s", "Statistics\\Incoming Calls\\Connected"); + sprintf(name, "%s", "Statistics\\Incoming Calls\\Connected"); if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) { pLib->IncomingCallsConnectedActive = 0; return (-1); @@ -830,7 +830,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (!pLib->OutgoingCallsCallsActive) { pLib->OutgoingCallsCallsActive = 1; - sprintf (name, "%s", "Statistics\\Outgoing Calls\\Calls"); + sprintf(name, "%s", "Statistics\\Outgoing Calls\\Calls"); if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) { pLib->OutgoingCallsCallsActive = 0; return (-1); @@ -840,7 +840,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { } if (!pLib->OutgoingCallsConnectedActive) { pLib->OutgoingCallsConnectedActive = 1; - sprintf (name, "%s", "Statistics\\Outgoing Calls\\Connected"); + sprintf(name, "%s", "Statistics\\Outgoing Calls\\Connected"); if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) { pLib->OutgoingCallsConnectedActive = 0; return (-1); @@ -852,240 +852,241 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) { return (0); } -static int process_idi_event (diva_strace_context_t* pLib, - diva_man_var_header_t* pVar) { - const char* path = (char*)&pVar->path_length+1; +static int process_idi_event(diva_strace_context_t *pLib, + diva_man_var_header_t *pVar) { + const char *path = (char *)&pVar->path_length + 1; char name[64]; int i; if (!strncmp("State\\B Event", path, pVar->path_length)) { - dword ch_id; - if (!diva_trace_read_variable (pVar, &ch_id)) { - if (!pLib->line_init_event && !pLib->pending_line_status) { - for (i = 1; i <= pLib->Channels; i++) { - diva_line_event(pLib, i); - } - return (0); - } else if (ch_id && ch_id <= pLib->Channels) { - return (diva_line_event(pLib, (int)ch_id)); - } - return (0); - } - return (-1); - } + dword ch_id; + if (!diva_trace_read_variable(pVar, &ch_id)) { + if (!pLib->line_init_event && !pLib->pending_line_status) { + for (i = 1; i <= pLib->Channels; i++) { + diva_line_event(pLib, i); + } + return (0); + } else if (ch_id && ch_id <= pLib->Channels) { + return (diva_line_event(pLib, (int)ch_id)); + } + return (0); + } + return (-1); + } if (!strncmp("State\\FAX Event", path, pVar->path_length)) { - dword ch_id; - if (!diva_trace_read_variable (pVar, &ch_id)) { - if (!pLib->pending_fax_status && !pLib->fax_init_event) { - for (i = 1; i <= pLib->Channels; i++) { - diva_fax_event(pLib, i); - } - return (0); - } else if (ch_id && ch_id <= pLib->Channels) { - return (diva_fax_event(pLib, (int)ch_id)); - } - return (0); - } - return (-1); - } + dword ch_id; + if (!diva_trace_read_variable(pVar, &ch_id)) { + if (!pLib->pending_fax_status && !pLib->fax_init_event) { + for (i = 1; i <= pLib->Channels; i++) { + diva_fax_event(pLib, i); + } + return (0); + } else if (ch_id && ch_id <= pLib->Channels) { + return (diva_fax_event(pLib, (int)ch_id)); + } + return (0); + } + return (-1); + } if (!strncmp("State\\Modem Event", path, pVar->path_length)) { - dword ch_id; - if (!diva_trace_read_variable (pVar, &ch_id)) { - if (!pLib->pending_modem_status && !pLib->modem_init_event) { - for (i = 1; i <= pLib->Channels; i++) { - diva_modem_event(pLib, i); - } - return (0); - } else if (ch_id && ch_id <= pLib->Channels) { - return (diva_modem_event(pLib, (int)ch_id)); - } - return (0); - } - return (-1); - } + dword ch_id; + if (!diva_trace_read_variable(pVar, &ch_id)) { + if (!pLib->pending_modem_status && !pLib->modem_init_event) { + for (i = 1; i <= pLib->Channels; i++) { + diva_modem_event(pLib, i); + } + return (0); + } else if (ch_id && ch_id <= pLib->Channels) { + return (diva_modem_event(pLib, (int)ch_id)); + } + return (0); + } + return (-1); + } /* - First look for Line Event - */ + First look for Line Event + */ for (i = 1; i <= pLib->Channels; i++) { - sprintf (name, "State\\B%d\\Line", i); - if (find_var (pVar, name)) { + sprintf(name, "State\\B%d\\Line", i); + if (find_var(pVar, name)) { return (diva_line_event(pLib, i)); } } /* - Look for Moden Progress Event - */ + Look for Moden Progress Event + */ for (i = 1; i <= pLib->Channels; i++) { - sprintf (name, "State\\B%d\\Modem\\Event", i); - if (find_var (pVar, name)) { - return (diva_modem_event (pLib, i)); + sprintf(name, "State\\B%d\\Modem\\Event", i); + if (find_var(pVar, name)) { + return (diva_modem_event(pLib, i)); } } /* - Look for Fax Event - */ + Look for Fax Event + */ for (i = 1; i <= pLib->Channels; i++) { - sprintf (name, "State\\B%d\\FAX\\Event", i); - if (find_var (pVar, name)) { - return (diva_fax_event (pLib, i)); + sprintf(name, "State\\B%d\\FAX\\Event", i); + if (find_var(pVar, name)) { + return (diva_fax_event(pLib, i)); } } /* - Notification about loss of events - */ + Notification about loss of events + */ if (!strncmp("Events Down", path, pVar->path_length)) { if (pLib->trace_events_down == 1) { pLib->trace_events_down = 2; } else { - diva_trace_error (pLib, 1, "Events Down", 0); + diva_trace_error(pLib, 1, "Events Down", 0); } return (0); } if (!strncmp("State\\Layer1", path, pVar->path_length)) { - diva_strace_read_asz (pVar, &pLib->lines[0].pInterface->Layer1[0]); + diva_strace_read_asz(pVar, &pLib->lines[0].pInterface->Layer1[0]); if (pLib->l1_trace == 1) { pLib->l1_trace = 2; } else { - diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE); + diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE); } return (0); } if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) { - char* tmp = &pLib->lines[0].pInterface->Layer2[0]; - dword l2_state; - diva_strace_read_uint (pVar, &l2_state); + char *tmp = &pLib->lines[0].pInterface->Layer2[0]; + dword l2_state; + if (diva_strace_read_uint(pVar, &l2_state)) + return -1; switch (l2_state) { - case 0: - strcpy (tmp, "Idle"); - break; - case 1: - strcpy (tmp, "Layer2 UP"); - break; - case 2: - strcpy (tmp, "Layer2 Disconnecting"); - break; - case 3: - strcpy (tmp, "Layer2 Connecting"); - break; - case 4: - strcpy (tmp, "SPID Initializing"); - break; - case 5: - strcpy (tmp, "SPID Initialised"); - break; - case 6: - strcpy (tmp, "Layer2 Connecting"); - break; - - case 7: - strcpy (tmp, "Auto SPID Stopped"); - break; - - case 8: - strcpy (tmp, "Auto SPID Idle"); - break; - - case 9: - strcpy (tmp, "Auto SPID Requested"); - break; - - case 10: - strcpy (tmp, "Auto SPID Delivery"); - break; - - case 11: - strcpy (tmp, "Auto SPID Complete"); - break; - - default: - sprintf (tmp, "U:%d", (int)l2_state); + case 0: + strcpy(tmp, "Idle"); + break; + case 1: + strcpy(tmp, "Layer2 UP"); + break; + case 2: + strcpy(tmp, "Layer2 Disconnecting"); + break; + case 3: + strcpy(tmp, "Layer2 Connecting"); + break; + case 4: + strcpy(tmp, "SPID Initializing"); + break; + case 5: + strcpy(tmp, "SPID Initialised"); + break; + case 6: + strcpy(tmp, "Layer2 Connecting"); + break; + + case 7: + strcpy(tmp, "Auto SPID Stopped"); + break; + + case 8: + strcpy(tmp, "Auto SPID Idle"); + break; + + case 9: + strcpy(tmp, "Auto SPID Requested"); + break; + + case 10: + strcpy(tmp, "Auto SPID Delivery"); + break; + + case 11: + strcpy(tmp, "Auto SPID Complete"); + break; + + default: + sprintf(tmp, "U:%d", (int)l2_state); } if (pLib->l2_trace == 1) { pLib->l2_trace = 2; } else { - diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE); + diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE); } return (0); } if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) || - !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) { - return (SuperTraceGetIncomingCallStatistics (pLib)); + !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) { + return (SuperTraceGetIncomingCallStatistics(pLib)); } if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) || - !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) { - return (SuperTraceGetOutgoingCallStatistics (pLib)); + !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) { + return (SuperTraceGetOutgoingCallStatistics(pLib)); } return (-1); } -static int diva_line_event (diva_strace_context_t* pLib, int Channel) { - pLib->pending_line_status |= (1L << (Channel-1)); +static int diva_line_event(diva_strace_context_t *pLib, int Channel) { + pLib->pending_line_status |= (1L << (Channel - 1)); return (0); } -static int diva_modem_event (diva_strace_context_t* pLib, int Channel) { - pLib->pending_modem_status |= (1L << (Channel-1)); +static int diva_modem_event(diva_strace_context_t *pLib, int Channel) { + pLib->pending_modem_status |= (1L << (Channel - 1)); return (0); } -static int diva_fax_event (diva_strace_context_t* pLib, int Channel) { - pLib->pending_fax_status |= (1L << (Channel-1)); +static int diva_fax_event(diva_strace_context_t *pLib, int Channel) { + pLib->pending_fax_status |= (1L << (Channel - 1)); return (0); } /* - Process INFO indications that arrive from the card - Uses path of first I.E. to detect the source of the - infication - */ -static int process_idi_info (diva_strace_context_t* pLib, - diva_man_var_header_t* pVar) { - const char* path = (char*)&pVar->path_length+1; + Process INFO indications that arrive from the card + Uses path of first I.E. to detect the source of the + infication +*/ +static int process_idi_info(diva_strace_context_t *pLib, + diva_man_var_header_t *pVar) { + const char *path = (char *)&pVar->path_length + 1; char name[64]; int i, len; /* - First look for Modem Status Info - */ + First look for Modem Status Info + */ for (i = pLib->Channels; i > 0; i--) { - len = sprintf (name, "State\\B%d\\Modem", i); + len = sprintf(name, "State\\B%d\\Modem", i); if (!strncmp(name, path, len)) { - return (diva_modem_info (pLib, i, pVar)); + return (diva_modem_info(pLib, i, pVar)); } } /* - Look for Fax Status Info - */ + Look for Fax Status Info + */ for (i = pLib->Channels; i > 0; i--) { - len = sprintf (name, "State\\B%d\\FAX", i); + len = sprintf(name, "State\\B%d\\FAX", i); if (!strncmp(name, path, len)) { - return (diva_fax_info (pLib, i, pVar)); + return (diva_fax_info(pLib, i, pVar)); } } /* - Look for Line Status Info - */ + Look for Line Status Info + */ for (i = pLib->Channels; i > 0; i--) { - len = sprintf (name, "State\\B%d", i); + len = sprintf(name, "State\\B%d", i); if (!strncmp(name, path, len)) { - return (diva_line_info (pLib, i, pVar)); + return (diva_line_info(pLib, i, pVar)); } } - if (!diva_ifc_statistics (pLib, pVar)) { + if (!diva_ifc_statistics(pLib, pVar)) { return (0); } @@ -1093,38 +1094,38 @@ static int process_idi_info (diva_strace_context_t* pLib, } /* - MODEM INSTANCE STATE UPDATE - - Update Modem Status Information and issue notification to user, - that will inform about change in the state of modem instance, that is - associuated with this channel - */ -static int diva_modem_info (diva_strace_context_t* pLib, - int Channel, - diva_man_var_header_t* pVar) { - diva_man_var_header_t* cur; + MODEM INSTANCE STATE UPDATE + + Update Modem Status Information and issue notification to user, + that will inform about change in the state of modem instance, that is + associuated with this channel +*/ +static int diva_modem_info(diva_strace_context_t *pLib, + int Channel, + diva_man_var_header_t *pVar) { + diva_man_var_header_t *cur; int i, nr = Channel - 1; for (i = pLib->modem_parse_entry_first[nr]; - i <= pLib->modem_parse_entry_last[nr]; i++) { - if ((cur = find_var (pVar, pLib->parse_table[i].path))) { - if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) { - diva_trace_error (pLib, -3 , __FILE__, __LINE__); + i <= pLib->modem_parse_entry_last[nr]; i++) { + if ((cur = find_var(pVar, pLib->parse_table[i].path))) { + if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) { + diva_trace_error(pLib, -3, __FILE__, __LINE__); return (-1); } } else { - diva_trace_error (pLib, -2 , __FILE__, __LINE__); + diva_trace_error(pLib, -2, __FILE__, __LINE__); return (-1); } } /* - We do not use first event to notify user - this is the event that is - generated as result of EVENT ON operation and is used only to initialize - internal variables of application - */ + We do not use first event to notify user - this is the event that is + generated as result of EVENT ON operation and is used only to initialize + internal variables of application + */ if (pLib->modem_init_event & (1L << nr)) { - diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE); + diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE); } else { pLib->modem_init_event |= (1L << nr); } @@ -1132,32 +1133,32 @@ static int diva_modem_info (diva_strace_context_t* pLib, return (0); } -static int diva_fax_info (diva_strace_context_t* pLib, - int Channel, - diva_man_var_header_t* pVar) { - diva_man_var_header_t* cur; +static int diva_fax_info(diva_strace_context_t *pLib, + int Channel, + diva_man_var_header_t *pVar) { + diva_man_var_header_t *cur; int i, nr = Channel - 1; for (i = pLib->fax_parse_entry_first[nr]; - i <= pLib->fax_parse_entry_last[nr]; i++) { - if ((cur = find_var (pVar, pLib->parse_table[i].path))) { - if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) { - diva_trace_error (pLib, -3 , __FILE__, __LINE__); + i <= pLib->fax_parse_entry_last[nr]; i++) { + if ((cur = find_var(pVar, pLib->parse_table[i].path))) { + if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) { + diva_trace_error(pLib, -3, __FILE__, __LINE__); return (-1); } } else { - diva_trace_error (pLib, -2 , __FILE__, __LINE__); + diva_trace_error(pLib, -2, __FILE__, __LINE__); return (-1); } } /* - We do not use first event to notify user - this is the event that is - generated as result of EVENT ON operation and is used only to initialize - internal variables of application - */ + We do not use first event to notify user - this is the event that is + generated as result of EVENT ON operation and is used only to initialize + internal variables of application + */ if (pLib->fax_init_event & (1L << nr)) { - diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE); + diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE); } else { pLib->fax_init_event |= (1L << nr); } @@ -1166,43 +1167,43 @@ static int diva_fax_info (diva_strace_context_t* pLib, } /* - LINE STATE UPDATE - Update Line Status Information and issue notification to user, - that will inform about change in the line state. - */ -static int diva_line_info (diva_strace_context_t* pLib, - int Channel, - diva_man_var_header_t* pVar) { - diva_man_var_header_t* cur; + LINE STATE UPDATE + Update Line Status Information and issue notification to user, + that will inform about change in the line state. +*/ +static int diva_line_info(diva_strace_context_t *pLib, + int Channel, + diva_man_var_header_t *pVar) { + diva_man_var_header_t *cur; int i, nr = Channel - 1; - for (i = pLib->line_parse_entry_first[nr]; - i <= pLib->line_parse_entry_last[nr]; i++) { - if ((cur = find_var (pVar, pLib->parse_table[i].path))) { - if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) { - diva_trace_error (pLib, -3 , __FILE__, __LINE__); + for (i = pLib->line_parse_entry_first[nr]; + i <= pLib->line_parse_entry_last[nr]; i++) { + if ((cur = find_var(pVar, pLib->parse_table[i].path))) { + if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) { + diva_trace_error(pLib, -3, __FILE__, __LINE__); return (-1); } } else { - diva_trace_error (pLib, -2 , __FILE__, __LINE__); + diva_trace_error(pLib, -2 , __FILE__, __LINE__); return (-1); } } /* - We do not use first event to notify user - this is the event that is - generated as result of EVENT ON operation and is used only to initialize - internal variables of application + We do not use first event to notify user - this is the event that is + generated as result of EVENT ON operation and is used only to initialize + internal variables of application - Exception is is if the line is "online". In this case we have to notify - user about this confition. - */ + Exception is is if the line is "online". In this case we have to notify + user about this confition. + */ if (pLib->line_init_event & (1L << nr)) { - diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE); + diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE); } else { pLib->line_init_event |= (1L << nr); - if (strcmp (&pLib->lines[nr].Line[0], "Idle")) { - diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE); + if (strcmp(&pLib->lines[nr].Line[0], "Idle")) { + diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE); } } @@ -1210,49 +1211,49 @@ static int diva_line_info (diva_strace_context_t* pLib, } /* - Move position to next vatianle in the chain - */ -static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar) { - byte* msg = (byte*)pVar; - byte* start; + Move position to next vatianle in the chain +*/ +static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar) { + byte *msg = (byte *)pVar; + byte *start; int msg_length; if (*msg != ESC) return NULL; start = msg + 2; - msg_length = *(msg+1); - msg = (start+msg_length); + msg_length = *(msg + 1); + msg = (start + msg_length); if (*msg != ESC) return NULL; - return ((diva_man_var_header_t*)msg); + return ((diva_man_var_header_t *)msg); } /* - Move position to variable with given name - */ -static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar, - const char* name) { - const char* path; + Move position to variable with given name +*/ +static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar, + const char *name) { + const char *path; do { - path = (char*)&pVar->path_length+1; + path = (char *)&pVar->path_length + 1; - if (!strncmp (name, path, pVar->path_length)) { + if (!strncmp(name, path, pVar->path_length)) { break; } - } while ((pVar = get_next_var (pVar))); + } while ((pVar = get_next_var(pVar))); return (pVar); } -static void diva_create_line_parse_table (diva_strace_context_t* pLib, - int Channel) { - diva_trace_line_state_t* pLine = &pLib->lines[Channel]; - int nr = Channel+1; +static void diva_create_line_parse_table(diva_strace_context_t *pLib, + int Channel) { + diva_trace_line_state_t *pLine = &pLib->lines[Channel]; + int nr = Channel + 1; if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) { - diva_trace_error (pLib, -1, __FILE__, __LINE__); + diva_trace_error(pLib, -1, __FILE__, __LINE__); return; } @@ -1260,674 +1261,674 @@ static void diva_create_line_parse_table (diva_strace_context_t* pLib, pLib->line_parse_entry_first[Channel] = pLib->cur_parse_entry; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Framing", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Framing", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Line", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Line", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Layer2", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Layer2", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Layer3", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Layer3", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Remote Address", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Remote Address", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLine->RemoteAddress[0]; + &pLine->RemoteAddress[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Remote SubAddr", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Remote SubAddr", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLine->RemoteSubAddress[0]; + &pLine->RemoteSubAddress[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Local Address", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Local Address", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLine->LocalAddress[0]; + &pLine->LocalAddress[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Local SubAddr", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Local SubAddr", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLine->LocalSubAddress[0]; + &pLine->LocalSubAddress[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\BC", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\BC", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\HLC", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\HLC", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\LLC", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\LLC", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Charges", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Charges", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Call Reference", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Call Reference", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Last Disc Cause", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Last Disc Cause", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLine->LastDisconnecCause; + &pLine->LastDisconnecCause; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\User ID", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\User ID", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0]; pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1; } -static void diva_create_fax_parse_table (diva_strace_context_t* pLib, - int Channel) { - diva_trace_fax_state_t* pFax = &pLib->lines[Channel].fax; - int nr = Channel+1; +static void diva_create_fax_parse_table(diva_strace_context_t *pLib, + int Channel) { + diva_trace_fax_state_t *pFax = &pLib->lines[Channel].fax; + int nr = Channel + 1; if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) { - diva_trace_error (pLib, -1, __FILE__, __LINE__); + diva_trace_error(pLib, -1, __FILE__, __LINE__); return; } pFax->ChannelNumber = nr; pLib->fax_parse_entry_first[Channel] = pLib->cur_parse_entry; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Event", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Event", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Page Counter", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Page Counter", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Features", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Features", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Station ID", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Station ID", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Subaddress", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Subaddress", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Password", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Password", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0]; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Speed", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Speed", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Resolution", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Resolution", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Paper Width", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Paper Width", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Paper Length", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Paper Length", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Scanline Time", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Scanline Time", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\FAX\\Disc Reason", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\FAX\\Disc Reason", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason; pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1; } -static void diva_create_modem_parse_table (diva_strace_context_t* pLib, - int Channel) { - diva_trace_modem_state_t* pModem = &pLib->lines[Channel].modem; - int nr = Channel+1; +static void diva_create_modem_parse_table(diva_strace_context_t *pLib, + int Channel) { + diva_trace_modem_state_t *pModem = &pLib->lines[Channel].modem; + int nr = Channel + 1; if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) { - diva_trace_error (pLib, -1, __FILE__, __LINE__); + diva_trace_error(pLib, -1, __FILE__, __LINE__); return; } pModem->ChannelNumber = nr; pLib->modem_parse_entry_first[Channel] = pLib->cur_parse_entry; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Event", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Event", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Norm", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Norm", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Options", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Options", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\TX Speed", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\TX Speed", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\RX Speed", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\RX Speed", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Roundtrip ms", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Roundtrip ms", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Symbol Rate", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Symbol Rate", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\RX Level dBm", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\RX Level dBm", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Echo Level dBm", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Echo Level dBm", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\SNR dB", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\SNR dB", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\MAE", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\MAE", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Local Retrains", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Local Retrains", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Remote Retrains", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Remote Retrains", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Local Resyncs", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Local Resyncs", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Remote Resyncs", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Remote Resyncs", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs; - sprintf (pLib->parse_table[pLib->cur_parse_entry].path, - "State\\B%d\\Modem\\Disc Reason", nr); + sprintf(pLib->parse_table[pLib->cur_parse_entry].path, + "State\\B%d\\Modem\\Disc Reason", nr); pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason; pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1; } -static void diva_create_parse_table (diva_strace_context_t* pLib) { +static void diva_create_parse_table(diva_strace_context_t *pLib) { int i; for (i = 0; i < pLib->Channels; i++) { - diva_create_line_parse_table (pLib, i); - diva_create_modem_parse_table (pLib, i); - diva_create_fax_parse_table (pLib, i); + diva_create_line_parse_table(pLib, i); + diva_create_modem_parse_table(pLib, i); + diva_create_fax_parse_table(pLib, i); } pLib->statistic_parse_first = pLib->cur_parse_entry; /* - Outgoing Calls - */ - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Outgoing Calls\\Calls"); + Outgoing Calls + */ + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Outgoing Calls\\Calls"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.outg.Calls; + &pLib->InterfaceStat.outg.Calls; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Outgoing Calls\\Connected"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Outgoing Calls\\Connected"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.outg.Connected; + &pLib->InterfaceStat.outg.Connected; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Outgoing Calls\\User Busy"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Outgoing Calls\\User Busy"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.outg.User_Busy; + &pLib->InterfaceStat.outg.User_Busy; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Outgoing Calls\\No Answer"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Outgoing Calls\\No Answer"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.outg.No_Answer; + &pLib->InterfaceStat.outg.No_Answer; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Outgoing Calls\\Wrong Number"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Outgoing Calls\\Wrong Number"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.outg.Wrong_Number; + &pLib->InterfaceStat.outg.Wrong_Number; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Outgoing Calls\\Call Rejected"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Outgoing Calls\\Call Rejected"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.outg.Call_Rejected; + &pLib->InterfaceStat.outg.Call_Rejected; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Outgoing Calls\\Other Failures"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Outgoing Calls\\Other Failures"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.outg.Other_Failures; + &pLib->InterfaceStat.outg.Other_Failures; /* - Incoming Calls - */ - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\Calls"); + Incoming Calls + */ + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\Calls"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.Calls; + &pLib->InterfaceStat.inc.Calls; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\Connected"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\Connected"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.Connected; + &pLib->InterfaceStat.inc.Connected; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\User Busy"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\User Busy"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.User_Busy; + &pLib->InterfaceStat.inc.User_Busy; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\Call Rejected"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\Call Rejected"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.Call_Rejected; + &pLib->InterfaceStat.inc.Call_Rejected; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\Wrong Number"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\Wrong Number"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.Wrong_Number; + &pLib->InterfaceStat.inc.Wrong_Number; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\Incompatible Dst"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\Incompatible Dst"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.Incompatible_Dst; + &pLib->InterfaceStat.inc.Incompatible_Dst; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\Out of Order"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\Out of Order"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.Out_of_Order; + &pLib->InterfaceStat.inc.Out_of_Order; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Incoming Calls\\Ignored"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Incoming Calls\\Ignored"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.inc.Ignored; + &pLib->InterfaceStat.inc.Ignored; /* - Modem Statistics - */ + Modem Statistics + */ pLib->mdm_statistic_parse_first = pLib->cur_parse_entry; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Normal"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Normal"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Normal; + &pLib->InterfaceStat.mdm.Disc_Normal; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Unspecified"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Unspecified"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Unspecified; + &pLib->InterfaceStat.mdm.Disc_Unspecified; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Busy Tone"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Busy Tone"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Busy_Tone; + &pLib->InterfaceStat.mdm.Disc_Busy_Tone; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Congestion"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Congestion"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Congestion; + &pLib->InterfaceStat.mdm.Disc_Congestion; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Carr. Wait"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Carr. Wait"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Carr_Wait; + &pLib->InterfaceStat.mdm.Disc_Carr_Wait; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Trn Timeout"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Trn Timeout"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Trn_Timeout; + &pLib->InterfaceStat.mdm.Disc_Trn_Timeout; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Incompat."); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Incompat."); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Incompat; + &pLib->InterfaceStat.mdm.Disc_Incompat; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc Frame Rej."); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc Frame Rej."); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_Frame_Rej; + &pLib->InterfaceStat.mdm.Disc_Frame_Rej; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\Modem\\Disc V42bis"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\Modem\\Disc V42bis"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.mdm.Disc_V42bis; + &pLib->InterfaceStat.mdm.Disc_V42bis; pLib->mdm_statistic_parse_last = pLib->cur_parse_entry - 1; /* - Fax Statistics - */ + Fax Statistics + */ pLib->fax_statistic_parse_first = pLib->cur_parse_entry; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Normal"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Normal"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Normal; + &pLib->InterfaceStat.fax.Disc_Normal; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Not Ident."); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Not Ident."); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Not_Ident; + &pLib->InterfaceStat.fax.Disc_Not_Ident; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc No Response"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc No Response"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_No_Response; + &pLib->InterfaceStat.fax.Disc_No_Response; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Retries"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Retries"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Retries; + &pLib->InterfaceStat.fax.Disc_Retries; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Unexp. Msg."); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Unexp. Msg."); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Unexp_Msg; + &pLib->InterfaceStat.fax.Disc_Unexp_Msg; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc No Polling."); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc No Polling."); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_No_Polling; + &pLib->InterfaceStat.fax.Disc_No_Polling; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Training"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Training"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Training; + &pLib->InterfaceStat.fax.Disc_Training; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Unexpected"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Unexpected"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Unexpected; + &pLib->InterfaceStat.fax.Disc_Unexpected; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Application"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Application"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Application; + &pLib->InterfaceStat.fax.Disc_Application; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Incompat."); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Incompat."); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Incompat; + &pLib->InterfaceStat.fax.Disc_Incompat; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc No Command"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc No Command"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_No_Command; + &pLib->InterfaceStat.fax.Disc_No_Command; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Long Msg"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Long Msg"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Long_Msg; + &pLib->InterfaceStat.fax.Disc_Long_Msg; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Supervisor"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Supervisor"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Supervisor; + &pLib->InterfaceStat.fax.Disc_Supervisor; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc SUB SEP PWD"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc SUB SEP PWD"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD; + &pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Invalid Msg"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Invalid Msg"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Invalid_Msg; + &pLib->InterfaceStat.fax.Disc_Invalid_Msg; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Page Coding"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Page Coding"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Page_Coding; + &pLib->InterfaceStat.fax.Disc_Page_Coding; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc App Timeout"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc App Timeout"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_App_Timeout; + &pLib->InterfaceStat.fax.Disc_App_Timeout; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\FAX\\Disc Unspecified"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\FAX\\Disc Unspecified"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.fax.Disc_Unspecified; + &pLib->InterfaceStat.fax.Disc_Unspecified; pLib->fax_statistic_parse_last = pLib->cur_parse_entry - 1; /* - B-Layer1" - */ - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer1\\X-Frames"); + B-Layer1" + */ + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer1\\X-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b1.X_Frames; + &pLib->InterfaceStat.b1.X_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer1\\X-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer1\\X-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b1.X_Bytes; + &pLib->InterfaceStat.b1.X_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer1\\X-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer1\\X-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b1.X_Errors; + &pLib->InterfaceStat.b1.X_Errors; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer1\\R-Frames"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer1\\R-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b1.R_Frames; + &pLib->InterfaceStat.b1.R_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer1\\R-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer1\\R-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b1.R_Bytes; + &pLib->InterfaceStat.b1.R_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer1\\R-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer1\\R-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b1.R_Errors; + &pLib->InterfaceStat.b1.R_Errors; /* - B-Layer2 - */ - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer2\\X-Frames"); + B-Layer2 + */ + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer2\\X-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b2.X_Frames; + &pLib->InterfaceStat.b2.X_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer2\\X-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer2\\X-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b2.X_Bytes; + &pLib->InterfaceStat.b2.X_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer2\\X-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer2\\X-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b2.X_Errors; + &pLib->InterfaceStat.b2.X_Errors; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer2\\R-Frames"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer2\\R-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b2.R_Frames; + &pLib->InterfaceStat.b2.R_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer2\\R-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer2\\R-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b2.R_Bytes; + &pLib->InterfaceStat.b2.R_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\B-Layer2\\R-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\B-Layer2\\R-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.b2.R_Errors; + &pLib->InterfaceStat.b2.R_Errors; /* - D-Layer1 - */ - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer1\\X-Frames"); + D-Layer1 + */ + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer1\\X-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d1.X_Frames; + &pLib->InterfaceStat.d1.X_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer1\\X-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer1\\X-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d1.X_Bytes; + &pLib->InterfaceStat.d1.X_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer1\\X-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer1\\X-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d1.X_Errors; + &pLib->InterfaceStat.d1.X_Errors; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer1\\R-Frames"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer1\\R-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d1.R_Frames; + &pLib->InterfaceStat.d1.R_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer1\\R-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer1\\R-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d1.R_Bytes; + &pLib->InterfaceStat.d1.R_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer1\\R-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer1\\R-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d1.R_Errors; + &pLib->InterfaceStat.d1.R_Errors; /* - D-Layer2 - */ - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer2\\X-Frames"); + D-Layer2 + */ + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer2\\X-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d2.X_Frames; + &pLib->InterfaceStat.d2.X_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer2\\X-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer2\\X-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d2.X_Bytes; + &pLib->InterfaceStat.d2.X_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer2\\X-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer2\\X-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d2.X_Errors; + &pLib->InterfaceStat.d2.X_Errors; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer2\\R-Frames"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer2\\R-Frames"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d2.R_Frames; + &pLib->InterfaceStat.d2.R_Frames; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer2\\R-Bytes"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer2\\R-Bytes"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d2.R_Bytes; + &pLib->InterfaceStat.d2.R_Bytes; - strcpy (pLib->parse_table[pLib->cur_parse_entry].path, - "Statistics\\D-Layer2\\R-Errors"); + strcpy(pLib->parse_table[pLib->cur_parse_entry].path, + "Statistics\\D-Layer2\\R-Errors"); pLib->parse_table[pLib->cur_parse_entry++].variable = \ - &pLib->InterfaceStat.d2.R_Errors; + &pLib->InterfaceStat.d2.R_Errors; pLib->statistic_parse_last = pLib->cur_parse_entry - 1; } -static void diva_trace_error (diva_strace_context_t* pLib, - int error, const char* file, int line) { +static void diva_trace_error(diva_strace_context_t *pLib, + int error, const char *file, int line) { if (pLib->user_proc_table.error_notify_proc) { (*(pLib->user_proc_table.error_notify_proc))(\ - pLib->user_proc_table.user_context, - &pLib->instance, pLib->Adapter, - error, file, line); + pLib->user_proc_table.user_context, + &pLib->instance, pLib->Adapter, + error, file, line); } } /* - Delivery notification to user - */ -static void diva_trace_notify_user (diva_strace_context_t* pLib, - int Channel, - int notify_subject) { + Delivery notification to user +*/ +static void diva_trace_notify_user(diva_strace_context_t *pLib, + int Channel, + int notify_subject) { if (pLib->user_proc_table.notify_proc) { (*(pLib->user_proc_table.notify_proc))(pLib->user_proc_table.user_context, - &pLib->instance, - pLib->Adapter, - &pLib->lines[Channel], - notify_subject); + &pLib->instance, + pLib->Adapter, + &pLib->lines[Channel], + notify_subject); } } /* - Read variable value to they destination based on the variable type - */ -static int diva_trace_read_variable (diva_man_var_header_t* pVar, - void* variable) { + Read variable value to they destination based on the variable type +*/ +static int diva_trace_read_variable(diva_man_var_header_t *pVar, + void *variable) { switch (pVar->type) { - case 0x03: /* MI_ASCIIZ - syting */ - return (diva_strace_read_asz (pVar, (char*)variable)); - case 0x04: /* MI_ASCII - string */ - return (diva_strace_read_asc (pVar, (char*)variable)); - case 0x05: /* MI_NUMBER - counted sequence of bytes */ - return (diva_strace_read_ie (pVar, (diva_trace_ie_t*)variable)); - case 0x81: /* MI_INT - signed integer */ - return (diva_strace_read_int (pVar, (int*)variable)); - case 0x82: /* MI_UINT - unsigned integer */ - return (diva_strace_read_uint (pVar, (dword*)variable)); - case 0x83: /* MI_HINT - unsigned integer, hex representetion */ - return (diva_strace_read_uint (pVar, (dword*)variable)); - case 0x87: /* MI_BITFLD - unsigned integer, bit representation */ - return (diva_strace_read_uint (pVar, (dword*)variable)); + case 0x03: /* MI_ASCIIZ - syting */ + return (diva_strace_read_asz(pVar, (char *)variable)); + case 0x04: /* MI_ASCII - string */ + return (diva_strace_read_asc(pVar, (char *)variable)); + case 0x05: /* MI_NUMBER - counted sequence of bytes */ + return (diva_strace_read_ie(pVar, (diva_trace_ie_t *)variable)); + case 0x81: /* MI_INT - signed integer */ + return (diva_strace_read_int(pVar, (int *)variable)); + case 0x82: /* MI_UINT - unsigned integer */ + return (diva_strace_read_uint(pVar, (dword *)variable)); + case 0x83: /* MI_HINT - unsigned integer, hex representetion */ + return (diva_strace_read_uint(pVar, (dword *)variable)); + case 0x87: /* MI_BITFLD - unsigned integer, bit representation */ + return (diva_strace_read_uint(pVar, (dword *)variable)); } /* - This type of variable is not handled, indicate error - Or one problem in management interface, or in application recodeing - table, or this application should handle it. - */ + This type of variable is not handled, indicate error + Or one problem in management interface, or in application recodeing + table, or this application should handle it. + */ return (-1); } /* - Read signed integer to destination - */ -static int diva_strace_read_int (diva_man_var_header_t* pVar, int* var) { - byte* ptr = (char*)&pVar->path_length; + Read signed integer to destination +*/ +static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var) { + byte *ptr = (char *)&pVar->path_length; int value; ptr += (pVar->path_length + 1); switch (pVar->value_length) { - case 1: - value = *(char*)ptr; - break; + case 1: + value = *(char *)ptr; + break; - case 2: - value = (short)GET_WORD(ptr); - break; + case 2: + value = (short)GET_WORD(ptr); + break; - case 4: - value = (int)GET_DWORD(ptr); - break; + case 4: + value = (int)GET_DWORD(ptr); + break; - default: - return (-1); + default: + return (-1); } *var = value; @@ -1935,32 +1936,32 @@ static int diva_strace_read_int (diva_man_var_header_t* pVar, int* var) { return (0); } -static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var) { - byte* ptr = (char*)&pVar->path_length; +static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var) { + byte *ptr = (char *)&pVar->path_length; dword value; ptr += (pVar->path_length + 1); switch (pVar->value_length) { - case 1: - value = (byte)(*ptr); - break; + case 1: + value = (byte)(*ptr); + break; - case 2: - value = (word)GET_WORD(ptr); - break; + case 2: + value = (word)GET_WORD(ptr); + break; - case 3: - value = (dword)GET_DWORD(ptr); - value &= 0x00ffffff; - break; + case 3: + value = (dword)GET_DWORD(ptr); + value &= 0x00ffffff; + break; - case 4: - value = (dword)GET_DWORD(ptr); - break; + case 4: + value = (dword)GET_DWORD(ptr); + break; - default: - return (-1); + default: + return (-1); } *var = value; @@ -1969,54 +1970,54 @@ static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var) { } /* - Read zero terminated ASCII string - */ -static int diva_strace_read_asz (diva_man_var_header_t* pVar, char* var) { - char* ptr = (char*)&pVar->path_length; + Read zero terminated ASCII string +*/ +static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var) { + char *ptr = (char *)&pVar->path_length; int length; ptr += (pVar->path_length + 1); if (!(length = pVar->value_length)) { - length = strlen (ptr); + length = strlen(ptr); } - memcpy (var, ptr, length); + memcpy(var, ptr, length); var[length] = 0; return (0); } /* - Read counted (with leading length byte) ASCII string - */ -static int diva_strace_read_asc (diva_man_var_header_t* pVar, char* var) { - char* ptr = (char*)&pVar->path_length; + Read counted (with leading length byte) ASCII string +*/ +static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var) { + char *ptr = (char *)&pVar->path_length; ptr += (pVar->path_length + 1); - memcpy (var, ptr+1, *ptr); + memcpy(var, ptr + 1, *ptr); var[(int)*ptr] = 0; return (0); } /* - Read one information element - i.e. one string of byte values with - one length byte in front - */ -static int diva_strace_read_ie (diva_man_var_header_t* pVar, - diva_trace_ie_t* var) { - char* ptr = (char*)&pVar->path_length; + Read one information element - i.e. one string of byte values with + one length byte in front +*/ +static int diva_strace_read_ie(diva_man_var_header_t *pVar, + diva_trace_ie_t *var) { + char *ptr = (char *)&pVar->path_length; ptr += (pVar->path_length + 1); var->length = *ptr; - memcpy (&var->data[0], ptr+1, *ptr); + memcpy(&var->data[0], ptr + 1, *ptr); return (0); } -static int SuperTraceSetAudioTap (void* hLib, int Channel, int on) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceSetAudioTap(void *hLib, int Channel, int on) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; if ((Channel < 1) || (Channel > pLib->Channels)) { return (-1); @@ -2029,21 +2030,21 @@ static int SuperTraceSetAudioTap (void* hLib, int Channel, int on) { pLib->audio_tap_mask &= ~(1L << Channel); } - /* - EYE patterns have TM_M_DATA set as additional - condition - */ - if (pLib->audio_tap_mask) { - pLib->trace_event_mask |= TM_M_DATA; - } else { - pLib->trace_event_mask &= ~TM_M_DATA; - } + /* + EYE patterns have TM_M_DATA set as additional + condition + */ + if (pLib->audio_tap_mask) { + pLib->trace_event_mask |= TM_M_DATA; + } else { + pLib->trace_event_mask &= ~TM_M_DATA; + } - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceSetBChannel (void* hLib, int Channel, int on) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceSetBChannel(void *hLib, int Channel, int on) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; if ((Channel < 1) || (Channel > pLib->Channels)) { return (-1); @@ -2056,11 +2057,11 @@ static int SuperTraceSetBChannel (void* hLib, int Channel, int on) { pLib->bchannel_trace_mask &= ~(1L << Channel); } - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceSetDChannel (void* hLib, int on) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceSetDChannel(void *hLib, int on) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; if (on) { pLib->trace_event_mask |= (TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1); @@ -2068,11 +2069,11 @@ static int SuperTraceSetDChannel (void* hLib, int on) { pLib->trace_event_mask &= ~(TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1); } - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceSetInfo (void* hLib, int on) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceSetInfo(void *hLib, int on) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; if (on) { pLib->trace_event_mask |= TM_STRING; @@ -2080,11 +2081,11 @@ static int SuperTraceSetInfo (void* hLib, int on) { pLib->trace_event_mask &= ~TM_STRING; } - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceClearCall (void* hLib, int Channel) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceClearCall(void *hLib, int Channel) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; if ((Channel < 1) || (Channel > pLib->Channels)) { return (-1); @@ -2093,102 +2094,101 @@ static int SuperTraceClearCall (void* hLib, int Channel) { pLib->clear_call_command |= (1L << Channel); - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } /* - Parse and update cumulative statistice - */ -static int diva_ifc_statistics (diva_strace_context_t* pLib, - diva_man_var_header_t* pVar) { - diva_man_var_header_t* cur; + Parse and update cumulative statistice +*/ +static int diva_ifc_statistics(diva_strace_context_t *pLib, + diva_man_var_header_t *pVar) { + diva_man_var_header_t *cur; int i, one_updated = 0, mdm_updated = 0, fax_updated = 0; for (i = pLib->statistic_parse_first; i <= pLib->statistic_parse_last; i++) { - if ((cur = find_var (pVar, pLib->parse_table[i].path))) { - if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) { - diva_trace_error (pLib, -3 , __FILE__, __LINE__); + if ((cur = find_var(pVar, pLib->parse_table[i].path))) { + if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) { + diva_trace_error(pLib, -3 , __FILE__, __LINE__); return (-1); } one_updated = 1; - if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) { - mdm_updated = 1; - } - if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) { - fax_updated = 1; - } + if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) { + mdm_updated = 1; + } + if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) { + fax_updated = 1; + } } } /* - We do not use first event to notify user - this is the event that is - generated as result of EVENT ON operation and is used only to initialize - internal variables of application - */ - if (mdm_updated) { - diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE); - } else if (fax_updated) { - diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE); - } else if (one_updated) { - diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE); + We do not use first event to notify user - this is the event that is + generated as result of EVENT ON operation and is used only to initialize + internal variables of application + */ + if (mdm_updated) { + diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE); + } else if (fax_updated) { + diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE); + } else if (one_updated) { + diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE); } return (one_updated ? 0 : -1); } -static int SuperTraceGetOutgoingCallStatistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetOutgoingCallStatistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->outgoing_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceGetIncomingCallStatistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetIncomingCallStatistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->incoming_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceGetModemStatistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetModemStatistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->modem_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceGetFaxStatistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetFaxStatistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->fax_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceGetBLayer1Statistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetBLayer1Statistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->b1_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceGetBLayer2Statistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetBLayer2Statistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->b2_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceGetDLayer1Statistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetDLayer1Statistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->d1_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -static int SuperTraceGetDLayer2Statistics (void* hLib) { - diva_strace_context_t* pLib = (diva_strace_context_t*)hLib; +static int SuperTraceGetDLayer2Statistics(void *hLib) { + diva_strace_context_t *pLib = (diva_strace_context_t *)hLib; pLib->d2_ifc_stats = 1; - return (ScheduleNextTraceRequest (pLib)); + return (ScheduleNextTraceRequest(pLib)); } -dword DivaSTraceGetMemotyRequirement (int channels) { - dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \ - STAT_PARSE_ENTRIES + \ - LINE_PARSE_ENTRIES + 1) * channels; - return (sizeof(diva_strace_context_t) + \ - (parse_entries * sizeof(diva_strace_path2action_t))); +dword DivaSTraceGetMemotyRequirement(int channels) { + dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \ + STAT_PARSE_ENTRIES + \ + LINE_PARSE_ENTRIES + 1) * channels; + return (sizeof(diva_strace_context_t) + \ + (parse_entries * sizeof(diva_strace_path2action_t))); } - diff --git a/drivers/isdn/hardware/eicon/maintidi.h b/drivers/isdn/hardware/eicon/maintidi.h index 4f06294966b..2b46147c553 100644 --- a/drivers/isdn/hardware/eicon/maintidi.h +++ b/drivers/isdn/hardware/eicon/maintidi.h @@ -1,52 +1,52 @@ /* * - Copyright (c) Eicon Networks, 2000. + Copyright (c) Eicon Networks, 2000. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 1.9 + Eicon File Revision : 1.9 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_EICON_TRACE_IDI_IFC_H__ #define __DIVA_EICON_TRACE_IDI_IFC_H__ -void* SuperTraceOpenAdapter (int AdapterNumber); -int SuperTraceCloseAdapter (void* AdapterHandle); -int SuperTraceWrite (void* AdapterHandle, - const void* data, int length); -int SuperTraceReadRequest (void* AdapterHandle,const char* name,byte* data); -int SuperTraceGetNumberOfChannels (void* AdapterHandle); -int SuperTraceASSIGN (void* AdapterHandle, byte* data); -int SuperTraceREMOVE (void* AdapterHandle); -int SuperTraceTraceOnRequest(void* hAdapter, const char* name, byte* data); -int SuperTraceWriteVar (void* AdapterHandle, - byte* data, - const char* name, - void* var, - byte type, - byte var_length); -int SuperTraceExecuteRequest (void* AdapterHandle, - const char* name, - byte* data); +void *SuperTraceOpenAdapter(int AdapterNumber); +int SuperTraceCloseAdapter(void *AdapterHandle); +int SuperTraceWrite(void *AdapterHandle, + const void *data, int length); +int SuperTraceReadRequest(void *AdapterHandle, const char *name, byte *data); +int SuperTraceGetNumberOfChannels(void *AdapterHandle); +int SuperTraceASSIGN(void *AdapterHandle, byte *data); +int SuperTraceREMOVE(void *AdapterHandle); +int SuperTraceTraceOnRequest(void *hAdapter, const char *name, byte *data); +int SuperTraceWriteVar(void *AdapterHandle, + byte *data, + const char *name, + void *var, + byte type, + byte var_length); +int SuperTraceExecuteRequest(void *AdapterHandle, + const char *name, + byte *data); typedef struct _diva_strace_path2action { - char path[64]; /* Full path to variable */ - void* variable; /* Variable that will receive value */ + char path[64]; /* Full path to variable */ + void *variable; /* Variable that will receive value */ } diva_strace_path2action_t; #define DIVA_MAX_MANAGEMENT_TRANSFER_SIZE 4096 @@ -54,27 +54,27 @@ typedef struct _diva_strace_path2action { typedef struct _diva_strace_context { diva_strace_library_interface_t instance; - int Adapter; - void* hAdapter; + int Adapter; + void *hAdapter; int Channels; - int req_busy; + int req_busy; - ENTITY e; - IDI_CALL request; - BUFFERS XData; - BUFFERS RData; + ENTITY e; + IDI_CALL request; + BUFFERS XData; + BUFFERS RData; byte buffer[DIVA_MAX_MANAGEMENT_TRANSFER_SIZE + 1]; - int removal_state; - int general_b_ch_event; - int general_fax_event; - int general_mdm_event; + int removal_state; + int general_b_ch_event; + int general_fax_event; + int general_mdm_event; - byte rc_ok; + byte rc_ok; /* - Initialization request state machine - */ + Initialization request state machine + */ int ChannelsTraceActive; int ModemTraceActive; int FaxTraceActive; @@ -93,8 +93,8 @@ typedef struct _diva_strace_context { int l2_trace; /* - Trace\Event Enable - */ + Trace\Event Enable + */ word trace_event_mask; word current_trace_event_mask; @@ -112,7 +112,7 @@ typedef struct _diva_strace_context { int parse_entries; int cur_parse_entry; - diva_strace_path2action_t* parse_table; + diva_strace_path2action_t *parse_table; diva_trace_library_user_interface_t user_proc_table; @@ -169,4 +169,3 @@ typedef struct _diva_man_var_header { } diva_man_var_header_t; #endif - diff --git a/drivers/isdn/hardware/eicon/man_defs.h b/drivers/isdn/hardware/eicon/man_defs.h index cb4ef4cae6c..249c471700e 100644 --- a/drivers/isdn/hardware/eicon/man_defs.h +++ b/drivers/isdn/hardware/eicon/man_defs.h @@ -1,25 +1,25 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 1.9 + Eicon File Revision : 1.9 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* Definitions for use with the Management Information Element */ @@ -104,9 +104,9 @@ typedef struct mi_xlog_hdr_s MI_XLOG_HDR; struct mi_xlog_hdr_s { - unsigned long time; /* Timestamp in msec units */ - unsigned short size; /* Size of data that follows */ - unsigned short code; /* code of trace event */ + unsigned long time; /* Timestamp in msec units */ + unsigned short size; /* Size of data that follows */ + unsigned short code; /* code of trace event */ }; /* unspecified data follows this header */ /*------------------------------------------------------------------*/ diff --git a/drivers/isdn/hardware/eicon/mdm_msg.h b/drivers/isdn/hardware/eicon/mdm_msg.h index 7a737e10bce..0e6b2e009a7 100644 --- a/drivers/isdn/hardware/eicon/mdm_msg.h +++ b/drivers/isdn/hardware/eicon/mdm_msg.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __EICON_MDM_MSG_H__ @@ -30,18 +30,18 @@ #define DSP_UDATA_INDICATION_CTS_OFF 0x03 #define DSP_UDATA_INDICATION_CTS_ON 0x04 /* ===================================================================== -DCD_OFF Message: - <word> time of DCD off (sampled from counter at 8kHz) -DCD_ON Message: - <word> time of DCD on (sampled from counter at 8kHz) - <byte> connected norm - <word> connected options - <dword> connected speed (bit/s, max of tx and rx speed) - <word> roundtrip delay (ms) - <dword> connected speed tx (bit/s) - <dword> connected speed rx (bit/s) - Size of this message == 19 bytes, but we will receive only 11 - ===================================================================== */ + DCD_OFF Message: + <word> time of DCD off (sampled from counter at 8kHz) + DCD_ON Message: + <word> time of DCD on (sampled from counter at 8kHz) + <byte> connected norm + <word> connected options + <dword> connected speed (bit/s, max of tx and rx speed) + <word> roundtrip delay (ms) + <dword> connected speed tx (bit/s) + <dword> connected speed rx (bit/s) + Size of this message == 19 bytes, but we will receive only 11 + ===================================================================== */ #define DSP_CONNECTED_NORM_UNSPECIFIED 0 #define DSP_CONNECTED_NORM_V21 1 #define DSP_CONNECTED_NORM_V23 2 @@ -129,14 +129,14 @@ DCD_ON Message: #define DSP_CONNECTED_OPTION_MASK_COMPRESSION 0x0320 #define DSP_UDATA_INDICATION_DISCONNECT 5 /* -returns: + returns: <byte> cause */ /* ========================================================== - DLC: B2 modem configuration + DLC: B2 modem configuration ========================================================== */ /* -Fields in assign DLC information element for modem protocol V.42/MNP: + Fields in assign DLC information element for modem protocol V.42/MNP: <byte> length of information element <word> information field length <byte> address A (not used, default 3) @@ -172,10 +172,10 @@ Fields in assign DLC information element for modem protocol V.42/MNP: #define DLC_MODEMPROT_APPL_EARLY_CONNECT 0x01 #define DLC_MODEMPROT_APPL_PASS_INDICATIONS 0x02 /* ========================================================== - CAI parameters used for the modem L1 configuration + CAI parameters used for the modem L1 configuration ========================================================== */ /* -Fields in assign CAI information element: + Fields in assign CAI information element: <byte> length of information element <byte> info field and B-channel hardware <byte> rate adaptation bit rate @@ -311,21 +311,21 @@ Fields in assign CAI information element: #define DSP_CAI_MODEM_SPEAKER_VOLUME_MAX 0x0c #define DSP_CAI_MODEM_SPEAKER_VOLUME_MASK 0x0c /* ========================================================== - DCD/CTS State + DCD/CTS State ========================================================== */ #define MDM_WANT_CONNECT_B3_ACTIVE_I 0x01 #define MDM_NCPI_VALID 0x02 #define MDM_NCPI_CTS_ON_RECEIVED 0x04 #define MDM_NCPI_DCD_ON_RECEIVED 0x08 /* ========================================================== - CAPI NCPI Constants + CAPI NCPI Constants ========================================================== */ #define MDM_NCPI_ECM_V42 0x0001 #define MDM_NCPI_ECM_MNP 0x0002 #define MDM_NCPI_TRANSPARENT 0x0004 #define MDM_NCPI_COMPRESSED 0x0010 /* ========================================================== - CAPI B2 Config Constants + CAPI B2 Config Constants ========================================================== */ #define MDM_B2_DISABLE_V42bis 0x0001 #define MDM_B2_DISABLE_MNP 0x0002 @@ -333,7 +333,7 @@ Fields in assign CAI information element: #define MDM_B2_DISABLE_V42 0x0008 #define MDM_B2_DISABLE_COMP 0x0010 /* ========================================================== - CAPI B1 Config Constants + CAPI B1 Config Constants ========================================================== */ #define MDM_CAPI_DISABLE_RETRAIN 0x0001 #define MDM_CAPI_DISABLE_RING_TONE 0x0002 diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index f9b00f19afd..a82e542ffc2 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -1,26 +1,25 @@ - /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -65,178 +64,178 @@ static dword diva_xdi_extended_features = 0; /* CAPI can request to process all return codes self only if: protocol code supports this && xdi supports this - */ -#define DIVA_CAPI_SUPPORTS_NO_CANCEL(__a__) (((__a__)->manufacturer_features&MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)&& ((__a__)->manufacturer_features & MANUFACTURER_FEATURE_OK_FC_LABEL) && (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_NO_CANCEL)) +*/ +#define DIVA_CAPI_SUPPORTS_NO_CANCEL(__a__) (((__a__)->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) && ((__a__)->manufacturer_features & MANUFACTURER_FEATURE_OK_FC_LABEL) && (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_NO_CANCEL)) /*------------------------------------------------------------------*/ /* local function prototypes */ /*------------------------------------------------------------------*/ -static void group_optimization(DIVA_CAPI_ADAPTER * a, PLCI * plci); -static void set_group_ind_mask (PLCI *plci); -static void clear_group_ind_mask_bit (PLCI *plci, word b); -static byte test_group_ind_mask_bit (PLCI *plci, word b); -void AutomaticLaw(DIVA_CAPI_ADAPTER *); +static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci); +static void set_group_ind_mask(PLCI *plci); +static void clear_group_ind_mask_bit(PLCI *plci, word b); +static byte test_group_ind_mask_bit(PLCI *plci, word b); +void AutomaticLaw(DIVA_CAPI_ADAPTER *); word CapiRelease(word); word CapiRegister(word); -word api_put(APPL *, CAPI_MSG *); -static word api_parse(byte *, word, byte *, API_PARSE *); -static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out); -static void api_load_msg(API_SAVE *in, API_PARSE *out); +word api_put(APPL *, CAPI_MSG *); +static word api_parse(byte *, word, byte *, API_PARSE *); +static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out); +static void api_load_msg(API_SAVE *in, API_PARSE *out); word api_remove_start(void); void api_remove_complete(void); -static void plci_remove(PLCI *); -static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER * a); -static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER *, IDI_SYNC_REQ *); - -void callback(ENTITY *); - -static void control_rc(PLCI *, byte, byte, byte, byte, byte); -static void data_rc(PLCI *, byte); -static void data_ack(PLCI *, byte); -static void sig_ind(PLCI *); -static void SendInfo(PLCI *, dword, byte * *, byte); -static void SendSetupInfo(APPL *, PLCI *, dword, byte * *, byte); -static void SendSSExtInd(APPL *, PLCI * plci, dword Id, byte * * parms); - -static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms); - -static void nl_ind(PLCI *); - -static byte connect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte connect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte connect_a_res(dword,word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte disconnect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte disconnect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte listen_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte info_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte info_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte alert_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte facility_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte facility_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte connect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte connect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte connect_b3_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte disconnect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte disconnect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte data_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte data_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte reset_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte reset_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte connect_b3_t90_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte select_b_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte manufacturer_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); -static byte manufacturer_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); - -static word get_plci(DIVA_CAPI_ADAPTER *); -static void add_p(PLCI *, byte, byte *); -static void add_s(PLCI * plci, byte code, API_PARSE * p); -static void add_ss(PLCI * plci, byte code, API_PARSE * p); -static void add_ie(PLCI * plci, byte code, byte * p, word p_length); -static void add_d(PLCI *, word, byte *); -static void add_ai(PLCI *, API_PARSE *); -static word add_b1(PLCI *, API_PARSE *, word, word); -static word add_b23(PLCI *, API_PARSE *); -static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms); -static void sig_req(PLCI *, byte, byte); -static void nl_req_ncci(PLCI *, byte, byte); -static void send_req(PLCI *); -static void send_data(PLCI *); -static word plci_remove_check(PLCI *); -static void listen_check(DIVA_CAPI_ADAPTER *); -static byte AddInfo(byte **, byte **, byte *, byte *); +static void plci_remove(PLCI *); +static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a); +static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *, IDI_SYNC_REQ *); + +void callback(ENTITY *); + +static void control_rc(PLCI *, byte, byte, byte, byte, byte); +static void data_rc(PLCI *, byte); +static void data_ack(PLCI *, byte); +static void sig_ind(PLCI *); +static void SendInfo(PLCI *, dword, byte **, byte); +static void SendSetupInfo(APPL *, PLCI *, dword, byte **, byte); +static void SendSSExtInd(APPL *, PLCI *plci, dword Id, byte **parms); + +static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms); + +static void nl_ind(PLCI *); + +static byte connect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte connect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte connect_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte disconnect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte disconnect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte listen_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte info_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte info_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte alert_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte facility_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte facility_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte connect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte connect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte connect_b3_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte disconnect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte disconnect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte data_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte data_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte reset_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte reset_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte connect_b3_t90_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte select_b_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte manufacturer_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); +static byte manufacturer_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); + +static word get_plci(DIVA_CAPI_ADAPTER *); +static void add_p(PLCI *, byte, byte *); +static void add_s(PLCI *plci, byte code, API_PARSE *p); +static void add_ss(PLCI *plci, byte code, API_PARSE *p); +static void add_ie(PLCI *plci, byte code, byte *p, word p_length); +static void add_d(PLCI *, word, byte *); +static void add_ai(PLCI *, API_PARSE *); +static word add_b1(PLCI *, API_PARSE *, word, word); +static word add_b23(PLCI *, API_PARSE *); +static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms); +static void sig_req(PLCI *, byte, byte); +static void nl_req_ncci(PLCI *, byte, byte); +static void send_req(PLCI *); +static void send_data(PLCI *); +static word plci_remove_check(PLCI *); +static void listen_check(DIVA_CAPI_ADAPTER *); +static byte AddInfo(byte **, byte **, byte *, byte *); static byte getChannel(API_PARSE *); -static void IndParse(PLCI *, word *, byte **, byte); -static byte ie_compare(byte *, byte *); -static word find_cip(DIVA_CAPI_ADAPTER *, byte *, byte *); -static word CPN_filter_ok(byte *cpn,DIVA_CAPI_ADAPTER *,word); +static void IndParse(PLCI *, word *, byte **, byte); +static byte ie_compare(byte *, byte *); +static word find_cip(DIVA_CAPI_ADAPTER *, byte *, byte *); +static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *, word); /* XON protocol helpers - */ -static void channel_flow_control_remove (PLCI * plci); -static void channel_x_off (PLCI * plci, byte ch, byte flag); -static void channel_x_on (PLCI * plci, byte ch); -static void channel_request_xon (PLCI * plci, byte ch); -static void channel_xmit_xon (PLCI * plci); -static int channel_can_xon (PLCI * plci, byte ch); -static void channel_xmit_extended_xon (PLCI * plci); - -static byte SendMultiIE(PLCI * plci, dword Id, byte * * parms, byte ie_type, dword info_mask, byte setupParse); -static word AdvCodecSupport(DIVA_CAPI_ADAPTER *, PLCI *, APPL *, byte); -static void CodecIdCheck(DIVA_CAPI_ADAPTER *, PLCI *); -static void SetVoiceChannel(PLCI *, byte *, DIVA_CAPI_ADAPTER * ); -static void VoiceChannelOff(PLCI *plci); -static void adv_voice_write_coefs (PLCI *plci, word write_command); -static void adv_voice_clear_config (PLCI *plci); - -static word get_b1_facilities (PLCI * plci, byte b1_resource); -static byte add_b1_facilities (PLCI * plci, byte b1_resource, word b1_facilities); -static void adjust_b1_facilities (PLCI *plci, byte new_b1_resource, word new_b1_facilities); -static word adjust_b_process (dword Id, PLCI *plci, byte Rc); -static void adjust_b1_resource (dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command); -static void adjust_b_restore (dword Id, PLCI *plci, byte Rc); -static void reset_b3_command (dword Id, PLCI *plci, byte Rc); -static void select_b_command (dword Id, PLCI *plci, byte Rc); -static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc); -static void fax_edata_ack_command (dword Id, PLCI *plci, byte Rc); -static void fax_connect_info_command (dword Id, PLCI *plci, byte Rc); -static void fax_adjust_b23_command (dword Id, PLCI *plci, byte Rc); -static void fax_disconnect_command (dword Id, PLCI *plci, byte Rc); -static void hold_save_command (dword Id, PLCI *plci, byte Rc); -static void retrieve_restore_command (dword Id, PLCI *plci, byte Rc); -static void init_b1_config (PLCI *plci); -static void clear_b1_config (PLCI *plci); - -static void dtmf_command (dword Id, PLCI *plci, byte Rc); -static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg); -static void dtmf_confirmation (dword Id, PLCI *plci); -static void dtmf_indication (dword Id, PLCI *plci, byte *msg, word length); -static void dtmf_parameter_write (PLCI *plci); - - -static void mixer_set_bchannel_id_esc (PLCI *plci, byte bchannel_id); -static void mixer_set_bchannel_id (PLCI *plci, byte *chi); -static void mixer_clear_config (PLCI *plci); -static void mixer_notify_update (PLCI *plci, byte others); -static void mixer_command (dword Id, PLCI *plci, byte Rc); -static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg); -static void mixer_indication_coefs_set (dword Id, PLCI *plci); -static void mixer_indication_xconnect_from (dword Id, PLCI *plci, byte *msg, word length); -static void mixer_indication_xconnect_to (dword Id, PLCI *plci, byte *msg, word length); -static void mixer_remove (PLCI *plci); - - -static void ec_command (dword Id, PLCI *plci, byte Rc); -static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg); -static void ec_indication (dword Id, PLCI *plci, byte *msg, word length); - - -static void rtp_connect_b3_req_command (dword Id, PLCI *plci, byte Rc); -static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc); - - -static int diva_get_dma_descriptor (PLCI *plci, dword *dma_magic); -static void diva_free_dma_descriptor (PLCI *plci, int nr); +*/ +static void channel_flow_control_remove(PLCI *plci); +static void channel_x_off(PLCI *plci, byte ch, byte flag); +static void channel_x_on(PLCI *plci, byte ch); +static void channel_request_xon(PLCI *plci, byte ch); +static void channel_xmit_xon(PLCI *plci); +static int channel_can_xon(PLCI *plci, byte ch); +static void channel_xmit_extended_xon(PLCI *plci); + +static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type, dword info_mask, byte setupParse); +static word AdvCodecSupport(DIVA_CAPI_ADAPTER *, PLCI *, APPL *, byte); +static void CodecIdCheck(DIVA_CAPI_ADAPTER *, PLCI *); +static void SetVoiceChannel(PLCI *, byte *, DIVA_CAPI_ADAPTER *); +static void VoiceChannelOff(PLCI *plci); +static void adv_voice_write_coefs(PLCI *plci, word write_command); +static void adv_voice_clear_config(PLCI *plci); + +static word get_b1_facilities(PLCI *plci, byte b1_resource); +static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities); +static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities); +static word adjust_b_process(dword Id, PLCI *plci, byte Rc); +static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command); +static void adjust_b_restore(dword Id, PLCI *plci, byte Rc); +static void reset_b3_command(dword Id, PLCI *plci, byte Rc); +static void select_b_command(dword Id, PLCI *plci, byte Rc); +static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc); +static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc); +static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc); +static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc); +static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc); +static void hold_save_command(dword Id, PLCI *plci, byte Rc); +static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc); +static void init_b1_config(PLCI *plci); +static void clear_b1_config(PLCI *plci); + +static void dtmf_command(dword Id, PLCI *plci, byte Rc); +static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg); +static void dtmf_confirmation(dword Id, PLCI *plci); +static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length); +static void dtmf_parameter_write(PLCI *plci); + + +static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id); +static void mixer_set_bchannel_id(PLCI *plci, byte *chi); +static void mixer_clear_config(PLCI *plci); +static void mixer_notify_update(PLCI *plci, byte others); +static void mixer_command(dword Id, PLCI *plci, byte Rc); +static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg); +static void mixer_indication_coefs_set(dword Id, PLCI *plci); +static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length); +static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length); +static void mixer_remove(PLCI *plci); + + +static void ec_command(dword Id, PLCI *plci, byte Rc); +static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg); +static void ec_indication(dword Id, PLCI *plci, byte *msg, word length); + + +static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc); +static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc); + + +static int diva_get_dma_descriptor(PLCI *plci, dword *dma_magic); +static void diva_free_dma_descriptor(PLCI *plci, int nr); /*------------------------------------------------------------------*/ /* external function prototypes */ /*------------------------------------------------------------------*/ -extern byte MapController (byte); -extern byte UnMapController (byte); -#define MapId(Id) (((Id) & 0xffffff00L) | MapController ((byte)(Id))) -#define UnMapId(Id) (((Id) & 0xffffff00L) | UnMapController ((byte)(Id))) +extern byte MapController(byte); +extern byte UnMapController(byte); +#define MapId(Id)(((Id) & 0xffffff00L) | MapController((byte)(Id))) +#define UnMapId(Id)(((Id) & 0xffffff00L) | UnMapController((byte)(Id))) -void sendf(APPL *, word, dword, word, byte *, ...); -void * TransmitBufferSet(APPL * appl, dword ref); -void * TransmitBufferGet(APPL * appl, void * p); -void TransmitBufferFree(APPL * appl, void * p); -void * ReceiveBufferGet(APPL * appl, int Num); +void sendf(APPL *, word, dword, word, byte *, ...); +void *TransmitBufferSet(APPL *appl, dword ref); +void *TransmitBufferGet(APPL *appl, void *p); +void TransmitBufferFree(APPL *appl, void *p); +void *ReceiveBufferGet(APPL *appl, int Num); -int fax_head_line_time (char *buffer); +int fax_head_line_time(char *buffer); /*------------------------------------------------------------------*/ @@ -244,8 +243,8 @@ int fax_head_line_time (char *buffer); /*------------------------------------------------------------------*/ extern byte max_adapter; extern byte max_appl; -extern DIVA_CAPI_ADAPTER * adapter; -extern APPL * application; +extern DIVA_CAPI_ADAPTER *adapter; +extern APPL *application; @@ -253,107 +252,107 @@ extern APPL * application; -static byte remove_started = FALSE; +static byte remove_started = false; static PLCI dummy_plci; static struct _ftable { - word command; - byte * format; - byte (* function)(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); + word command; + byte *format; + byte (*function)(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *); } ftable[] = { - {_DATA_B3_R, "dwww", data_b3_req}, - {_DATA_B3_I|RESPONSE, "w", data_b3_res}, - {_INFO_R, "ss", info_req}, - {_INFO_I|RESPONSE, "", info_res}, - {_CONNECT_R, "wsssssssss", connect_req}, - {_CONNECT_I|RESPONSE, "wsssss", connect_res}, - {_CONNECT_ACTIVE_I|RESPONSE, "", connect_a_res}, - {_DISCONNECT_R, "s", disconnect_req}, - {_DISCONNECT_I|RESPONSE, "", disconnect_res}, - {_LISTEN_R, "dddss", listen_req}, - {_ALERT_R, "s", alert_req}, - {_FACILITY_R, "ws", facility_req}, - {_FACILITY_I|RESPONSE, "ws", facility_res}, - {_CONNECT_B3_R, "s", connect_b3_req}, - {_CONNECT_B3_I|RESPONSE, "ws", connect_b3_res}, - {_CONNECT_B3_ACTIVE_I|RESPONSE, "", connect_b3_a_res}, - {_DISCONNECT_B3_R, "s", disconnect_b3_req}, - {_DISCONNECT_B3_I|RESPONSE, "", disconnect_b3_res}, - {_RESET_B3_R, "s", reset_b3_req}, - {_RESET_B3_I|RESPONSE, "", reset_b3_res}, - {_CONNECT_B3_T90_ACTIVE_I|RESPONSE, "ws", connect_b3_t90_a_res}, - {_CONNECT_B3_T90_ACTIVE_I|RESPONSE, "", connect_b3_t90_a_res}, - {_SELECT_B_REQ, "s", select_b_req}, - {_MANUFACTURER_R, "dws", manufacturer_req}, - {_MANUFACTURER_I|RESPONSE, "dws", manufacturer_res}, - {_MANUFACTURER_I|RESPONSE, "", manufacturer_res} + {_DATA_B3_R, "dwww", data_b3_req}, + {_DATA_B3_I | RESPONSE, "w", data_b3_res}, + {_INFO_R, "ss", info_req}, + {_INFO_I | RESPONSE, "", info_res}, + {_CONNECT_R, "wsssssssss", connect_req}, + {_CONNECT_I | RESPONSE, "wsssss", connect_res}, + {_CONNECT_ACTIVE_I | RESPONSE, "", connect_a_res}, + {_DISCONNECT_R, "s", disconnect_req}, + {_DISCONNECT_I | RESPONSE, "", disconnect_res}, + {_LISTEN_R, "dddss", listen_req}, + {_ALERT_R, "s", alert_req}, + {_FACILITY_R, "ws", facility_req}, + {_FACILITY_I | RESPONSE, "ws", facility_res}, + {_CONNECT_B3_R, "s", connect_b3_req}, + {_CONNECT_B3_I | RESPONSE, "ws", connect_b3_res}, + {_CONNECT_B3_ACTIVE_I | RESPONSE, "", connect_b3_a_res}, + {_DISCONNECT_B3_R, "s", disconnect_b3_req}, + {_DISCONNECT_B3_I | RESPONSE, "", disconnect_b3_res}, + {_RESET_B3_R, "s", reset_b3_req}, + {_RESET_B3_I | RESPONSE, "", reset_b3_res}, + {_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "ws", connect_b3_t90_a_res}, + {_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "", connect_b3_t90_a_res}, + {_SELECT_B_REQ, "s", select_b_req}, + {_MANUFACTURER_R, "dws", manufacturer_req}, + {_MANUFACTURER_I | RESPONSE, "dws", manufacturer_res}, + {_MANUFACTURER_I | RESPONSE, "", manufacturer_res} }; -static byte * cip_bc[29][2] = { - { "", "" }, /* 0 */ - { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 1 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 2 */ - { "\x02\x89\x90", "\x02\x89\x90" }, /* 3 */ - { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 4 */ - { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 5 */ - { "\x02\x98\x90", "\x02\x98\x90" }, /* 6 */ - { "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */ - { "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */ - { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 9 */ - { "", "" }, /* 10 */ - { "", "" }, /* 11 */ - { "", "" }, /* 12 */ - { "", "" }, /* 13 */ - { "", "" }, /* 14 */ - { "", "" }, /* 15 */ - - { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 16 */ - { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 17 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 18 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 19 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 20 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 21 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 22 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 23 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 24 */ - { "\x02\x88\x90", "\x02\x88\x90" }, /* 25 */ - { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 26 */ - { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 27 */ - { "\x02\x88\x90", "\x02\x88\x90" } /* 28 */ +static byte *cip_bc[29][2] = { + { "", "" }, /* 0 */ + { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 1 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 2 */ + { "\x02\x89\x90", "\x02\x89\x90" }, /* 3 */ + { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 4 */ + { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 5 */ + { "\x02\x98\x90", "\x02\x98\x90" }, /* 6 */ + { "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */ + { "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */ + { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 9 */ + { "", "" }, /* 10 */ + { "", "" }, /* 11 */ + { "", "" }, /* 12 */ + { "", "" }, /* 13 */ + { "", "" }, /* 14 */ + { "", "" }, /* 15 */ + + { "\x03\x80\x90\xa3", "\x03\x80\x90\xa2" }, /* 16 */ + { "\x03\x90\x90\xa3", "\x03\x90\x90\xa2" }, /* 17 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 18 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 19 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 20 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 21 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 22 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 23 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 24 */ + { "\x02\x88\x90", "\x02\x88\x90" }, /* 25 */ + { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 26 */ + { "\x03\x91\x90\xa5", "\x03\x91\x90\xa5" }, /* 27 */ + { "\x02\x88\x90", "\x02\x88\x90" } /* 28 */ }; -static byte * cip_hlc[29] = { - "", /* 0 */ - "", /* 1 */ - "", /* 2 */ - "", /* 3 */ - "", /* 4 */ - "", /* 5 */ - "", /* 6 */ - "", /* 7 */ - "", /* 8 */ - "", /* 9 */ - "", /* 10 */ - "", /* 11 */ - "", /* 12 */ - "", /* 13 */ - "", /* 14 */ - "", /* 15 */ - - "\x02\x91\x81", /* 16 */ - "\x02\x91\x84", /* 17 */ - "\x02\x91\xa1", /* 18 */ - "\x02\x91\xa4", /* 19 */ - "\x02\x91\xa8", /* 20 */ - "\x02\x91\xb1", /* 21 */ - "\x02\x91\xb2", /* 22 */ - "\x02\x91\xb5", /* 23 */ - "\x02\x91\xb8", /* 24 */ - "\x02\x91\xc1", /* 25 */ - "\x02\x91\x81", /* 26 */ - "\x03\x91\xe0\x01", /* 27 */ - "\x03\x91\xe0\x02" /* 28 */ +static byte *cip_hlc[29] = { + "", /* 0 */ + "", /* 1 */ + "", /* 2 */ + "", /* 3 */ + "", /* 4 */ + "", /* 5 */ + "", /* 6 */ + "", /* 7 */ + "", /* 8 */ + "", /* 9 */ + "", /* 10 */ + "", /* 11 */ + "", /* 12 */ + "", /* 13 */ + "", /* 14 */ + "", /* 15 */ + + "\x02\x91\x81", /* 16 */ + "\x02\x91\x84", /* 17 */ + "\x02\x91\xa1", /* 18 */ + "\x02\x91\xa4", /* 19 */ + "\x02\x91\xa8", /* 20 */ + "\x02\x91\xb1", /* 21 */ + "\x02\x91\xb2", /* 22 */ + "\x02\x91\xb5", /* 23 */ + "\x02\x91\xb8", /* 24 */ + "\x02\x91\xc1", /* 25 */ + "\x02\x91\x81", /* 26 */ + "\x03\x91\xe0\x01", /* 27 */ + "\x03\x91\xe0\x02" /* 28 */ }; /*------------------------------------------------------------------*/ @@ -368,14 +367,14 @@ static byte * cip_hlc[29] = { static byte v120_default_header[] = { - 0x83 /* Ext, BR , res, res, C2 , C1 , B , F */ + 0x83 /* Ext, BR , res, res, C2 , C1 , B , F */ }; static byte v120_break_header[] = { - 0xc3 | V120_HEADER_BREAK_BIT /* Ext, BR , res, res, C2 , C1 , B , F */ + 0xc3 | V120_HEADER_BREAK_BIT /* Ext, BR , res, res, C2 , C1 , B , F */ }; @@ -384,208 +383,206 @@ static byte v120_break_header[] = /* API_PUT function */ /*------------------------------------------------------------------*/ -word api_put(APPL * appl, CAPI_MSG * msg) -{ - word i, j, k, l, n; - word ret; - byte c; - byte controller; - DIVA_CAPI_ADAPTER * a; - PLCI * plci; - NCCI * ncci_ptr; - word ncci; - CAPI_MSG *m; - API_PARSE msg_parms[MAX_MSG_PARMS+1]; - - if (msg->header.length < sizeof (msg->header) || - msg->header.length > MAX_MSG_SIZE) { - dbug(1,dprintf("bad len")); - return _BAD_MSG; - } - - controller = (byte)((msg->header.controller &0x7f)-1); - - /* controller starts with 0 up to (max_adapter - 1) */ - if ( controller >= max_adapter ) - { - dbug(1,dprintf("invalid ctrl")); - return _BAD_MSG; - } - - a = &adapter[controller]; - plci = NULL; - if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled) - { - dbug(1,dprintf("plci=%x",msg->header.plci)); - plci = &a->plci[msg->header.plci-1]; - ncci = GET_WORD(&msg->header.ncci); - if (plci->Id - && (plci->appl - || (plci->State == INC_CON_PENDING) - || (plci->State == INC_CON_ALERT) - || (msg->header.command == (_DISCONNECT_I|RESPONSE))) - && ((ncci == 0) - || (msg->header.command == (_DISCONNECT_B3_I|RESPONSE)) - || ((ncci < MAX_NCCI+1) && (a->ncci_plci[ncci] == plci->Id)))) - { - i = plci->msg_in_read_pos; - j = plci->msg_in_write_pos; - if (j >= i) - { - if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE) - i += MSG_IN_QUEUE_SIZE - j; - else - j = 0; - } - else - { - - n = (((CAPI_MSG *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc; - - if (i > MSG_IN_QUEUE_SIZE - n) - i = MSG_IN_QUEUE_SIZE - n + 1; - i -= j; - } - - if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc)) - - { - dbug(0,dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d", - msg->header.length, plci->msg_in_write_pos, - plci->msg_in_read_pos, plci->msg_in_wrap_pos, i)); - - return _QUEUE_FULL; - } - c = FALSE; - if ((((byte *) msg) < ((byte *)(plci->msg_in_queue))) - || (((byte *) msg) >= ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) - { - if (plci->msg_in_write_pos != plci->msg_in_read_pos) - c = TRUE; - } - if (msg->header.command == _DATA_B3_R) - { - if (msg->header.length < 20) - { - dbug(1,dprintf("DATA_B3 REQ wrong length %d", msg->header.length)); - return _BAD_MSG; - } - ncci_ptr = &(a->ncci[ncci]); - n = ncci_ptr->data_pending; - l = ncci_ptr->data_ack_pending; - k = plci->msg_in_read_pos; - while (k != plci->msg_in_write_pos) - { - if (k == plci->msg_in_wrap_pos) - k = 0; - if ((((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.command == _DATA_B3_R) - && (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.ncci == ncci)) - { - n++; - if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004) - l++; - } - - k += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.length + - MSG_IN_OVERHEAD + 3) & 0xfffc; - - } - if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK)) - { - dbug(0,dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d", - ncci_ptr->data_pending, n, ncci_ptr->data_ack_pending, l)); - - return _QUEUE_FULL; - } - if (plci->req_in || plci->internal_command) - { - if ((((byte *) msg) >= ((byte *)(plci->msg_in_queue))) - && (((byte *) msg) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) - { - dbug(0,dprintf("Q-FULL3(requeue)")); - - return _QUEUE_FULL; - } - c = TRUE; - } - } - else - { - if (plci->req_in || plci->internal_command) - c = TRUE; - else - { - plci->command = msg->header.command; - plci->number = msg->header.number; - } - } - if (c) - { - dbug(1,dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d", - msg->header.command, plci->req_in, plci->internal_command, - msg->header.length, plci->msg_in_write_pos, - plci->msg_in_read_pos, plci->msg_in_wrap_pos, i)); - if (j == 0) - plci->msg_in_wrap_pos = plci->msg_in_write_pos; - m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]); - for (i = 0; i < msg->header.length; i++) - ((byte *)(plci->msg_in_queue))[j++] = ((byte *) msg)[i]; - if (m->header.command == _DATA_B3_R) - { - - m->info.data_b3_req.Data = (dword)(TransmitBufferSet (appl, m->info.data_b3_req.Data)); - - } - - j = (j + 3) & 0xfffc; - - *((APPL * *)(&((byte *)(plci->msg_in_queue))[j])) = appl; - plci->msg_in_write_pos = j + MSG_IN_OVERHEAD; - return 0; - } - } - else - { - plci = NULL; - } - } - dbug(1,dprintf("com=%x",msg->header.command)); - - for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0; - for(i=0, ret = _BAD_MSG; - i<(sizeof(ftable)/sizeof(struct _ftable)); - i++) { - - if(ftable[i].command==msg->header.command) { - /* break loop if the message is correct, otherwise continue scan */ - /* (for example: CONNECT_B3_T90_ACT_RES has two specifications) */ - if(!api_parse(msg->info.b,(word)(msg->header.length-12),ftable[i].format,msg_parms)) { - ret = 0; - break; - } - for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0; - } - } - if(ret) { - dbug(1,dprintf("BAD_MSG")); - if(plci) plci->command = 0; - return ret; - } - - - c = ftable[i].function(GET_DWORD(&msg->header.controller), - msg->header.number, - a, - plci, - appl, - msg_parms); - - channel_xmit_extended_xon (plci); - - if(c==1) send_req(plci); - if(c==2 && plci) plci->req_in = plci->req_in_start = plci->req_out = 0; - if(plci && !plci->req_in) plci->command = 0; - return 0; +word api_put(APPL *appl, CAPI_MSG *msg) +{ + word i, j, k, l, n; + word ret; + byte c; + byte controller; + DIVA_CAPI_ADAPTER *a; + PLCI *plci; + NCCI *ncci_ptr; + word ncci; + CAPI_MSG *m; + API_PARSE msg_parms[MAX_MSG_PARMS + 1]; + + if (msg->header.length < sizeof(msg->header) || + msg->header.length > MAX_MSG_SIZE) { + dbug(1, dprintf("bad len")); + return _BAD_MSG; + } + + controller = (byte)((msg->header.controller & 0x7f) - 1); + + /* controller starts with 0 up to (max_adapter - 1) */ + if (controller >= max_adapter) + { + dbug(1, dprintf("invalid ctrl")); + return _BAD_MSG; + } + + a = &adapter[controller]; + plci = NULL; + if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled) + { + dbug(1, dprintf("plci=%x", msg->header.plci)); + plci = &a->plci[msg->header.plci - 1]; + ncci = GET_WORD(&msg->header.ncci); + if (plci->Id + && (plci->appl + || (plci->State == INC_CON_PENDING) + || (plci->State == INC_CON_ALERT) + || (msg->header.command == (_DISCONNECT_I | RESPONSE))) + && ((ncci == 0) + || (msg->header.command == (_DISCONNECT_B3_I | RESPONSE)) + || ((ncci < MAX_NCCI + 1) && (a->ncci_plci[ncci] == plci->Id)))) + { + i = plci->msg_in_read_pos; + j = plci->msg_in_write_pos; + if (j >= i) + { + if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE) + i += MSG_IN_QUEUE_SIZE - j; + else + j = 0; + } + else + { + + n = (((CAPI_MSG *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc; + + if (i > MSG_IN_QUEUE_SIZE - n) + i = MSG_IN_QUEUE_SIZE - n + 1; + i -= j; + } + + if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc)) + + { + dbug(0, dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d", + msg->header.length, plci->msg_in_write_pos, + plci->msg_in_read_pos, plci->msg_in_wrap_pos, i)); + + return _QUEUE_FULL; + } + c = false; + if ((((byte *) msg) < ((byte *)(plci->msg_in_queue))) + || (((byte *) msg) >= ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) + { + if (plci->msg_in_write_pos != plci->msg_in_read_pos) + c = true; + } + if (msg->header.command == _DATA_B3_R) + { + if (msg->header.length < 20) + { + dbug(1, dprintf("DATA_B3 REQ wrong length %d", msg->header.length)); + return _BAD_MSG; + } + ncci_ptr = &(a->ncci[ncci]); + n = ncci_ptr->data_pending; + l = ncci_ptr->data_ack_pending; + k = plci->msg_in_read_pos; + while (k != plci->msg_in_write_pos) + { + if (k == plci->msg_in_wrap_pos) + k = 0; + if ((((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.command == _DATA_B3_R) + && (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.ncci == ncci)) + { + n++; + if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004) + l++; + } + + k += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.length + + MSG_IN_OVERHEAD + 3) & 0xfffc; + + } + if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK)) + { + dbug(0, dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d", + ncci_ptr->data_pending, n, ncci_ptr->data_ack_pending, l)); + + return _QUEUE_FULL; + } + if (plci->req_in || plci->internal_command) + { + if ((((byte *) msg) >= ((byte *)(plci->msg_in_queue))) + && (((byte *) msg) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) + { + dbug(0, dprintf("Q-FULL3(requeue)")); + + return _QUEUE_FULL; + } + c = true; + } + } + else + { + if (plci->req_in || plci->internal_command) + c = true; + else + { + plci->command = msg->header.command; + plci->number = msg->header.number; + } + } + if (c) + { + dbug(1, dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d", + msg->header.command, plci->req_in, plci->internal_command, + msg->header.length, plci->msg_in_write_pos, + plci->msg_in_read_pos, plci->msg_in_wrap_pos, i)); + if (j == 0) + plci->msg_in_wrap_pos = plci->msg_in_write_pos; + m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]); + for (i = 0; i < msg->header.length; i++) + ((byte *)(plci->msg_in_queue))[j++] = ((byte *) msg)[i]; + if (m->header.command == _DATA_B3_R) + { + + m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet(appl, m->info.data_b3_req.Data)); + + } + + j = (j + 3) & 0xfffc; + + *((APPL **)(&((byte *)(plci->msg_in_queue))[j])) = appl; + plci->msg_in_write_pos = j + MSG_IN_OVERHEAD; + return 0; + } + } + else + { + plci = NULL; + } + } + dbug(1, dprintf("com=%x", msg->header.command)); + + for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0; + for (i = 0, ret = _BAD_MSG; i < ARRAY_SIZE(ftable); i++) { + + if (ftable[i].command == msg->header.command) { + /* break loop if the message is correct, otherwise continue scan */ + /* (for example: CONNECT_B3_T90_ACT_RES has two specifications) */ + if (!api_parse(msg->info.b, (word)(msg->header.length - 12), ftable[i].format, msg_parms)) { + ret = 0; + break; + } + for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0; + } + } + if (ret) { + dbug(1, dprintf("BAD_MSG")); + if (plci) plci->command = 0; + return ret; + } + + + c = ftable[i].function(GET_DWORD(&msg->header.controller), + msg->header.number, + a, + plci, + appl, + msg_parms); + + channel_xmit_extended_xon(plci); + + if (c == 1) send_req(plci); + if (c == 2 && plci) plci->req_in = plci->req_in_start = plci->req_out = 0; + if (plci && !plci->req_in) plci->command = 0; + return 0; } @@ -593,87 +590,87 @@ word api_put(APPL * appl, CAPI_MSG * msg) /* api_parse function, check the format of api messages */ /*------------------------------------------------------------------*/ -word api_parse(byte * msg, word length, byte * format, API_PARSE * parms) -{ - word i; - word p; - - for(i=0,p=0; format[i]; i++) { - if(parms) - { - parms[i].info = &msg[p]; - } - switch(format[i]) { - case 'b': - p +=1; - break; - case 'w': - p +=2; - break; - case 'd': - p +=4; - break; - case 's': - if(msg[p]==0xff) { - parms[i].info +=2; - parms[i].length = msg[p+1] + (msg[p+2]<<8); - p +=(parms[i].length +3); - } - else { - parms[i].length = msg[p]; - p +=(parms[i].length +1); - } - break; - } - - if(p>length) return TRUE; - } - if(parms) parms[i].info = NULL; - return FALSE; -} - -void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out) -{ - word i, j, n = 0; - byte *p; - - p = out->info; - for (i = 0; format[i] != '\0'; i++) - { - out->parms[i].info = p; - out->parms[i].length = in[i].length; - switch (format[i]) - { - case 'b': - n = 1; - break; - case 'w': - n = 2; - break; - case 'd': - n = 4; - break; - case 's': - n = in[i].length + 1; - break; - } - for (j = 0; j < n; j++) - *(p++) = in[i].info[j]; - } - out->parms[i].info = NULL; - out->parms[i].length = 0; -} - -void api_load_msg(API_SAVE *in, API_PARSE *out) -{ - word i; - - i = 0; - do - { - out[i].info = in->parms[i].info; - out[i].length = in->parms[i].length; - } while (in->parms[i++].info); +static word api_parse(byte *msg, word length, byte *format, API_PARSE *parms) +{ + word i; + word p; + + for (i = 0, p = 0; format[i]; i++) { + if (parms) + { + parms[i].info = &msg[p]; + } + switch (format[i]) { + case 'b': + p += 1; + break; + case 'w': + p += 2; + break; + case 'd': + p += 4; + break; + case 's': + if (msg[p] == 0xff) { + parms[i].info += 2; + parms[i].length = msg[p + 1] + (msg[p + 2] << 8); + p += (parms[i].length + 3); + } + else { + parms[i].length = msg[p]; + p += (parms[i].length + 1); + } + break; + } + + if (p > length) return true; + } + if (parms) parms[i].info = NULL; + return false; +} + +static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out) +{ + word i, j, n = 0; + byte *p; + + p = out->info; + for (i = 0; format[i] != '\0'; i++) + { + out->parms[i].info = p; + out->parms[i].length = in[i].length; + switch (format[i]) + { + case 'b': + n = 1; + break; + case 'w': + n = 2; + break; + case 'd': + n = 4; + break; + case 's': + n = in[i].length + 1; + break; + } + for (j = 0; j < n; j++) + *(p++) = in[i].info[j]; + } + out->parms[i].info = NULL; + out->parms[i].length = 0; +} + +static void api_load_msg(API_SAVE *in, API_PARSE *out) +{ + word i; + + i = 0; + do + { + out[i].info = in->parms[i].info; + out[i].length = in->parms[i].length; + } while (in->parms[i++].info); } @@ -683,31 +680,31 @@ void api_load_msg(API_SAVE *in, API_PARSE *out) word api_remove_start(void) { - word i; - word j; - - if(!remove_started) { - remove_started = TRUE; - for(i=0;i<max_adapter;i++) { - if(adapter[i].request) { - for(j=0;j<adapter[i].max_plci;j++) { - if(adapter[i].plci[j].Sig.Id) plci_remove(&adapter[i].plci[j]); - } - } - } - return 1; - } - else { - for(i=0;i<max_adapter;i++) { - if(adapter[i].request) { - for(j=0;j<adapter[i].max_plci;j++) { - if(adapter[i].plci[j].Sig.Id) return 1; - } - } - } - } - api_remove_complete(); - return 0; + word i; + word j; + + if (!remove_started) { + remove_started = true; + for (i = 0; i < max_adapter; i++) { + if (adapter[i].request) { + for (j = 0; j < adapter[i].max_plci; j++) { + if (adapter[i].plci[j].Sig.Id) plci_remove(&adapter[i].plci[j]); + } + } + } + return 1; + } + else { + for (i = 0; i < max_adapter; i++) { + if (adapter[i].request) { + for (j = 0; j < adapter[i].max_plci; j++) { + if (adapter[i].plci[j].Sig.Id) return 1; + } + } + } + } + api_remove_complete(); + return 0; } @@ -715,60 +712,60 @@ word api_remove_start(void) /* internal command queue */ /*------------------------------------------------------------------*/ -static void init_internal_command_queue (PLCI *plci) +static void init_internal_command_queue(PLCI *plci) { - word i; + word i; - dbug (1, dprintf ("%s,%d: init_internal_command_queue", - (char *)(FILE_), __LINE__)); + dbug(1, dprintf("%s,%d: init_internal_command_queue", + (char *)(FILE_), __LINE__)); - plci->internal_command = 0; - for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++) - plci->internal_command_queue[i] = NULL; + plci->internal_command = 0; + for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++) + plci->internal_command_queue[i] = NULL; } -static void start_internal_command (dword Id, PLCI *plci, t_std_internal_command command_function) +static void start_internal_command(dword Id, PLCI *plci, t_std_internal_command command_function) { - word i; + word i; - dbug (1, dprintf ("[%06lx] %s,%d: start_internal_command", - UnMapId (Id), (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: start_internal_command", + UnMapId(Id), (char *)(FILE_), __LINE__)); - if (plci->internal_command == 0) - { - plci->internal_command_queue[0] = command_function; - (* command_function)(Id, plci, OK); - } - else - { - i = 1; - while (plci->internal_command_queue[i] != 0) - i++; - plci->internal_command_queue[i] = command_function; - } + if (plci->internal_command == 0) + { + plci->internal_command_queue[0] = command_function; + (*command_function)(Id, plci, OK); + } + else + { + i = 1; + while (plci->internal_command_queue[i] != NULL) + i++; + plci->internal_command_queue[i] = command_function; + } } -static void next_internal_command (dword Id, PLCI *plci) +static void next_internal_command(dword Id, PLCI *plci) { - word i; + word i; - dbug (1, dprintf ("[%06lx] %s,%d: next_internal_command", - UnMapId (Id), (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: next_internal_command", + UnMapId(Id), (char *)(FILE_), __LINE__)); - plci->internal_command = 0; - plci->internal_command_queue[0] = NULL; - while (plci->internal_command_queue[1] != 0) - { - for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS - 1; i++) - plci->internal_command_queue[i] = plci->internal_command_queue[i+1]; - plci->internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS - 1] = NULL; - (*(plci->internal_command_queue[0]))(Id, plci, OK); - if (plci->internal_command != 0) - return; - plci->internal_command_queue[0] = NULL; - } + plci->internal_command = 0; + plci->internal_command_queue[0] = NULL; + while (plci->internal_command_queue[1] != NULL) + { + for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS - 1; i++) + plci->internal_command_queue[i] = plci->internal_command_queue[i + 1]; + plci->internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS - 1] = NULL; + (*(plci->internal_command_queue[0]))(Id, plci, OK); + if (plci->internal_command != 0) + return; + plci->internal_command_queue[0] = NULL; + } } @@ -778,238 +775,238 @@ static void next_internal_command (dword Id, PLCI *plci) static dword ncci_mapping_bug = 0; -static word get_ncci (PLCI *plci, byte ch, word force_ncci) -{ - DIVA_CAPI_ADAPTER *a; - word ncci, i, j, k; - - a = plci->adapter; - if (!ch || a->ch_ncci[ch]) - { - ncci_mapping_bug++; - dbug(1,dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x", - ncci_mapping_bug, ch, force_ncci, a->ncci_ch[a->ch_ncci[ch]], a->ch_ncci[ch])); - ncci = ch; - } - else - { - if (force_ncci) - ncci = force_ncci; - else - { - if ((ch < MAX_NCCI+1) && !a->ncci_ch[ch]) - ncci = ch; - else - { - ncci = 1; - while ((ncci < MAX_NCCI+1) && a->ncci_ch[ncci]) - ncci++; - if (ncci == MAX_NCCI+1) - { - ncci_mapping_bug++; - i = 1; - do - { - j = 1; - while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i)) - j++; - k = j; - if (j < MAX_NCCI+1) - { - do - { - j++; - } while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i)); - } - } while ((i < MAX_NL_CHANNEL+1) && (j < MAX_NCCI+1)); - if (i < MAX_NL_CHANNEL+1) - { - dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x", - ncci_mapping_bug, ch, force_ncci, i, k, j)); - } - else - { - dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x", - ncci_mapping_bug, ch, force_ncci)); - } - ncci = ch; - } - } - a->ncci_plci[ncci] = plci->Id; - a->ncci_state[ncci] = IDLE; - if (!plci->ncci_ring_list) - plci->ncci_ring_list = ncci; - else - a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list]; - a->ncci_next[plci->ncci_ring_list] = (byte) ncci; - } - a->ncci_ch[ncci] = ch; - a->ch_ncci[ch] = (byte) ncci; - dbug(1,dprintf("NCCI mapping established %ld %02x %02x %02x-%02x", - ncci_mapping_bug, ch, force_ncci, ch, ncci)); - } - return (ncci); -} - - -static void ncci_free_receive_buffers (PLCI *plci, word ncci) -{ - DIVA_CAPI_ADAPTER *a; - APPL *appl; - word i, ncci_code; - dword Id; - - a = plci->adapter; - Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id; - if (ncci) - { - if (a->ncci_plci[ncci] == plci->Id) - { - if (!plci->appl) - { - ncci_mapping_bug++; - dbug(1,dprintf("NCCI mapping appl expected %ld %08lx", - ncci_mapping_bug, Id)); - } - else - { - appl = plci->appl; - ncci_code = ncci | (((word) a->Id) << 8); - for (i = 0; i < appl->MaxBuffer; i++) - { - if ((appl->DataNCCI[i] == ncci_code) - && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id)) - { - appl->DataNCCI[i] = 0; - } - } - } - } - } - else - { - for (ncci = 1; ncci < MAX_NCCI+1; ncci++) - { - if (a->ncci_plci[ncci] == plci->Id) - { - if (!plci->appl) - { - ncci_mapping_bug++; - dbug(1,dprintf("NCCI mapping no appl %ld %08lx", - ncci_mapping_bug, Id)); - } - else - { - appl = plci->appl; - ncci_code = ncci | (((word) a->Id) << 8); - for (i = 0; i < appl->MaxBuffer; i++) - { - if ((appl->DataNCCI[i] == ncci_code) - && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id)) - { - appl->DataNCCI[i] = 0; - } - } - } - } - } - } -} - - -static void cleanup_ncci_data (PLCI *plci, word ncci) -{ - NCCI *ncci_ptr; - - if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id)) - { - ncci_ptr = &(plci->adapter->ncci[ncci]); - if (plci->appl) - { - while (ncci_ptr->data_pending != 0) - { - if (!plci->data_sent || (ncci_ptr->DBuffer[ncci_ptr->data_out].P != plci->data_sent_ptr)) - TransmitBufferFree (plci->appl, ncci_ptr->DBuffer[ncci_ptr->data_out].P); - (ncci_ptr->data_out)++; - if (ncci_ptr->data_out == MAX_DATA_B3) - ncci_ptr->data_out = 0; - (ncci_ptr->data_pending)--; - } - } - ncci_ptr->data_out = 0; - ncci_ptr->data_pending = 0; - ncci_ptr->data_ack_out = 0; - ncci_ptr->data_ack_pending = 0; - } -} - - -static void ncci_remove (PLCI *plci, word ncci, byte preserve_ncci) -{ - DIVA_CAPI_ADAPTER *a; - dword Id; - word i; - - a = plci->adapter; - Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id; - if (!preserve_ncci) - ncci_free_receive_buffers (plci, ncci); - if (ncci) - { - if (a->ncci_plci[ncci] != plci->Id) - { - ncci_mapping_bug++; - dbug(1,dprintf("NCCI mapping doesn't exist %ld %08lx %02x", - ncci_mapping_bug, Id, preserve_ncci)); - } - else - { - cleanup_ncci_data (plci, ncci); - dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x", - ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci)); - a->ch_ncci[a->ncci_ch[ncci]] = 0; - if (!preserve_ncci) - { - a->ncci_ch[ncci] = 0; - a->ncci_plci[ncci] = 0; - a->ncci_state[ncci] = IDLE; - i = plci->ncci_ring_list; - while ((i != 0) && (a->ncci_next[i] != plci->ncci_ring_list) && (a->ncci_next[i] != ncci)) - i = a->ncci_next[i]; - if ((i != 0) && (a->ncci_next[i] == ncci)) - { - if (i == ncci) - plci->ncci_ring_list = 0; - else if (plci->ncci_ring_list == ncci) - plci->ncci_ring_list = i; - a->ncci_next[i] = a->ncci_next[ncci]; - } - a->ncci_next[ncci] = 0; - } - } - } - else - { - for (ncci = 1; ncci < MAX_NCCI+1; ncci++) - { - if (a->ncci_plci[ncci] == plci->Id) - { - cleanup_ncci_data (plci, ncci); - dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x", - ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci)); - a->ch_ncci[a->ncci_ch[ncci]] = 0; - if (!preserve_ncci) - { - a->ncci_ch[ncci] = 0; - a->ncci_plci[ncci] = 0; - a->ncci_state[ncci] = IDLE; - a->ncci_next[ncci] = 0; - } - } - } - if (!preserve_ncci) - plci->ncci_ring_list = 0; - } +static word get_ncci(PLCI *plci, byte ch, word force_ncci) +{ + DIVA_CAPI_ADAPTER *a; + word ncci, i, j, k; + + a = plci->adapter; + if (!ch || a->ch_ncci[ch]) + { + ncci_mapping_bug++; + dbug(1, dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x", + ncci_mapping_bug, ch, force_ncci, a->ncci_ch[a->ch_ncci[ch]], a->ch_ncci[ch])); + ncci = ch; + } + else + { + if (force_ncci) + ncci = force_ncci; + else + { + if ((ch < MAX_NCCI + 1) && !a->ncci_ch[ch]) + ncci = ch; + else + { + ncci = 1; + while ((ncci < MAX_NCCI + 1) && a->ncci_ch[ncci]) + ncci++; + if (ncci == MAX_NCCI + 1) + { + ncci_mapping_bug++; + i = 1; + do + { + j = 1; + while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i)) + j++; + k = j; + if (j < MAX_NCCI + 1) + { + do + { + j++; + } while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i)); + } + } while ((i < MAX_NL_CHANNEL + 1) && (j < MAX_NCCI + 1)); + if (i < MAX_NL_CHANNEL + 1) + { + dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x", + ncci_mapping_bug, ch, force_ncci, i, k, j)); + } + else + { + dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x", + ncci_mapping_bug, ch, force_ncci)); + } + ncci = ch; + } + } + a->ncci_plci[ncci] = plci->Id; + a->ncci_state[ncci] = IDLE; + if (!plci->ncci_ring_list) + plci->ncci_ring_list = ncci; + else + a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list]; + a->ncci_next[plci->ncci_ring_list] = (byte) ncci; + } + a->ncci_ch[ncci] = ch; + a->ch_ncci[ch] = (byte) ncci; + dbug(1, dprintf("NCCI mapping established %ld %02x %02x %02x-%02x", + ncci_mapping_bug, ch, force_ncci, ch, ncci)); + } + return (ncci); +} + + +static void ncci_free_receive_buffers(PLCI *plci, word ncci) +{ + DIVA_CAPI_ADAPTER *a; + APPL *appl; + word i, ncci_code; + dword Id; + + a = plci->adapter; + Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id; + if (ncci) + { + if (a->ncci_plci[ncci] == plci->Id) + { + if (!plci->appl) + { + ncci_mapping_bug++; + dbug(1, dprintf("NCCI mapping appl expected %ld %08lx", + ncci_mapping_bug, Id)); + } + else + { + appl = plci->appl; + ncci_code = ncci | (((word) a->Id) << 8); + for (i = 0; i < appl->MaxBuffer; i++) + { + if ((appl->DataNCCI[i] == ncci_code) + && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id)) + { + appl->DataNCCI[i] = 0; + } + } + } + } + } + else + { + for (ncci = 1; ncci < MAX_NCCI + 1; ncci++) + { + if (a->ncci_plci[ncci] == plci->Id) + { + if (!plci->appl) + { + ncci_mapping_bug++; + dbug(1, dprintf("NCCI mapping no appl %ld %08lx", + ncci_mapping_bug, Id)); + } + else + { + appl = plci->appl; + ncci_code = ncci | (((word) a->Id) << 8); + for (i = 0; i < appl->MaxBuffer; i++) + { + if ((appl->DataNCCI[i] == ncci_code) + && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id)) + { + appl->DataNCCI[i] = 0; + } + } + } + } + } + } +} + + +static void cleanup_ncci_data(PLCI *plci, word ncci) +{ + NCCI *ncci_ptr; + + if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id)) + { + ncci_ptr = &(plci->adapter->ncci[ncci]); + if (plci->appl) + { + while (ncci_ptr->data_pending != 0) + { + if (!plci->data_sent || (ncci_ptr->DBuffer[ncci_ptr->data_out].P != plci->data_sent_ptr)) + TransmitBufferFree(plci->appl, ncci_ptr->DBuffer[ncci_ptr->data_out].P); + (ncci_ptr->data_out)++; + if (ncci_ptr->data_out == MAX_DATA_B3) + ncci_ptr->data_out = 0; + (ncci_ptr->data_pending)--; + } + } + ncci_ptr->data_out = 0; + ncci_ptr->data_pending = 0; + ncci_ptr->data_ack_out = 0; + ncci_ptr->data_ack_pending = 0; + } +} + + +static void ncci_remove(PLCI *plci, word ncci, byte preserve_ncci) +{ + DIVA_CAPI_ADAPTER *a; + dword Id; + word i; + + a = plci->adapter; + Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id; + if (!preserve_ncci) + ncci_free_receive_buffers(plci, ncci); + if (ncci) + { + if (a->ncci_plci[ncci] != plci->Id) + { + ncci_mapping_bug++; + dbug(1, dprintf("NCCI mapping doesn't exist %ld %08lx %02x", + ncci_mapping_bug, Id, preserve_ncci)); + } + else + { + cleanup_ncci_data(plci, ncci); + dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x", + ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci)); + a->ch_ncci[a->ncci_ch[ncci]] = 0; + if (!preserve_ncci) + { + a->ncci_ch[ncci] = 0; + a->ncci_plci[ncci] = 0; + a->ncci_state[ncci] = IDLE; + i = plci->ncci_ring_list; + while ((i != 0) && (a->ncci_next[i] != plci->ncci_ring_list) && (a->ncci_next[i] != ncci)) + i = a->ncci_next[i]; + if ((i != 0) && (a->ncci_next[i] == ncci)) + { + if (i == ncci) + plci->ncci_ring_list = 0; + else if (plci->ncci_ring_list == ncci) + plci->ncci_ring_list = i; + a->ncci_next[i] = a->ncci_next[ncci]; + } + a->ncci_next[ncci] = 0; + } + } + } + else + { + for (ncci = 1; ncci < MAX_NCCI + 1; ncci++) + { + if (a->ncci_plci[ncci] == plci->Id) + { + cleanup_ncci_data(plci, ncci); + dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x", + ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci)); + a->ch_ncci[a->ncci_ch[ncci]] = 0; + if (!preserve_ncci) + { + a->ncci_ch[ncci] = 0; + a->ncci_plci[ncci] = 0; + a->ncci_state[ncci] = IDLE; + a->ncci_next[ncci] = 0; + } + } + } + if (!preserve_ncci) + plci->ncci_ring_list = 0; + } } @@ -1017,170 +1014,170 @@ static void ncci_remove (PLCI *plci, word ncci, byte preserve_ncci) /* PLCI remove function */ /*------------------------------------------------------------------*/ -static void plci_free_msg_in_queue (PLCI *plci) -{ - word i; - - if (plci->appl) - { - i = plci->msg_in_read_pos; - while (i != plci->msg_in_write_pos) - { - if (i == plci->msg_in_wrap_pos) - i = 0; - if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R) - { - - TransmitBufferFree (plci->appl, - (byte *)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data)); - - } - - i += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.length + - MSG_IN_OVERHEAD + 3) & 0xfffc; - - } - } - plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; - plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; - plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; -} - - -static void plci_remove(PLCI * plci) -{ - - if(!plci) { - dbug(1,dprintf("plci_remove(no plci)")); - return; - } - init_internal_command_queue (plci); - dbug(1,dprintf("plci_remove(%x,tel=%x)",plci->Id,plci->tel)); - if(plci_remove_check(plci)) - { - return; - } - if (plci->Sig.Id == 0xff) - { - dbug(1,dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id)); - if (plci->NL.Id && !plci->nl_remove_id) - { - nl_req_ncci(plci,REMOVE,0); - send_req(plci); - } - } - else - { - if (!plci->sig_remove_id - && (plci->Sig.Id - || (plci->req_in!=plci->req_out) - || (plci->nl_req || plci->sig_req))) - { - sig_req(plci,HANGUP,0); - send_req(plci); - } - } - ncci_remove (plci, 0, FALSE); - plci_free_msg_in_queue (plci); - - plci->channels = 0; - plci->appl = NULL; - if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT)) - plci->State = OUTG_DIS_PENDING; +static void plci_free_msg_in_queue(PLCI *plci) +{ + word i; + + if (plci->appl) + { + i = plci->msg_in_read_pos; + while (i != plci->msg_in_write_pos) + { + if (i == plci->msg_in_wrap_pos) + i = 0; + if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R) + { + + TransmitBufferFree(plci->appl, + (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data)); + + } + + i += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.length + + MSG_IN_OVERHEAD + 3) & 0xfffc; + + } + } + plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; + plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; + plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; +} + + +static void plci_remove(PLCI *plci) +{ + + if (!plci) { + dbug(1, dprintf("plci_remove(no plci)")); + return; + } + init_internal_command_queue(plci); + dbug(1, dprintf("plci_remove(%x,tel=%x)", plci->Id, plci->tel)); + if (plci_remove_check(plci)) + { + return; + } + if (plci->Sig.Id == 0xff) + { + dbug(1, dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id)); + if (plci->NL.Id && !plci->nl_remove_id) + { + nl_req_ncci(plci, REMOVE, 0); + send_req(plci); + } + } + else + { + if (!plci->sig_remove_id + && (plci->Sig.Id + || (plci->req_in != plci->req_out) + || (plci->nl_req || plci->sig_req))) + { + sig_req(plci, HANGUP, 0); + send_req(plci); + } + } + ncci_remove(plci, 0, false); + plci_free_msg_in_queue(plci); + + plci->channels = 0; + plci->appl = NULL; + if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT)) + plci->State = OUTG_DIS_PENDING; } /*------------------------------------------------------------------*/ /* Application Group function helpers */ /*------------------------------------------------------------------*/ -static void set_group_ind_mask (PLCI *plci) +static void set_group_ind_mask(PLCI *plci) { - word i; + word i; - for (i = 0; i < C_IND_MASK_DWORDS; i++) - plci->group_optimization_mask_table[i] = 0xffffffffL; + for (i = 0; i < C_IND_MASK_DWORDS; i++) + plci->group_optimization_mask_table[i] = 0xffffffffL; } -static void clear_group_ind_mask_bit (PLCI *plci, word b) +static void clear_group_ind_mask_bit(PLCI *plci, word b) { - plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f)); + plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f)); } -static byte test_group_ind_mask_bit (PLCI *plci, word b) +static byte test_group_ind_mask_bit(PLCI *plci, word b) { - return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0); + return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0); } /*------------------------------------------------------------------*/ /* c_ind_mask operations for arbitrary MAX_APPL */ /*------------------------------------------------------------------*/ -static void clear_c_ind_mask (PLCI *plci) +static void clear_c_ind_mask(PLCI *plci) { - word i; + word i; - for (i = 0; i < C_IND_MASK_DWORDS; i++) - plci->c_ind_mask_table[i] = 0; + for (i = 0; i < C_IND_MASK_DWORDS; i++) + plci->c_ind_mask_table[i] = 0; } -static byte c_ind_mask_empty (PLCI *plci) +static byte c_ind_mask_empty(PLCI *plci) { - word i; + word i; - i = 0; - while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0)) - i++; - return (i == C_IND_MASK_DWORDS); + i = 0; + while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0)) + i++; + return (i == C_IND_MASK_DWORDS); } -static void set_c_ind_mask_bit (PLCI *plci, word b) +static void set_c_ind_mask_bit(PLCI *plci, word b) { - plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f)); + plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f)); } -static void clear_c_ind_mask_bit (PLCI *plci, word b) +static void clear_c_ind_mask_bit(PLCI *plci, word b) { - plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f)); + plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f)); } -static byte test_c_ind_mask_bit (PLCI *plci, word b) +static byte test_c_ind_mask_bit(PLCI *plci, word b) { - return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0); + return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0); } -static void dump_c_ind_mask (PLCI *plci) +static void dump_c_ind_mask(PLCI *plci) { -static char hex_digit_table[0x10] = - {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; - word i, j, k; - dword d; - char *p; - char buf[40]; + static char hex_digit_table[0x10] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + word i, j, k; + dword d; + char *p; + char buf[40]; - for (i = 0; i < C_IND_MASK_DWORDS; i += 4) - { - p = buf + 36; - *p = '\0'; - for (j = 0; j < 4; j++) - { - if (i+j < C_IND_MASK_DWORDS) - { - d = plci->c_ind_mask_table[i+j]; - for (k = 0; k < 8; k++) - { - *(--p) = hex_digit_table[d & 0xf]; - d >>= 4; - } - } - else if (i != 0) - { - for (k = 0; k < 8; k++) - *(--p) = ' '; - } - *(--p) = ' '; - } - dbug(1,dprintf ("c_ind_mask =%s", (char *) p)); - } + for (i = 0; i < C_IND_MASK_DWORDS; i += 4) + { + p = buf + 36; + *p = '\0'; + for (j = 0; j < 4; j++) + { + if (i + j < C_IND_MASK_DWORDS) + { + d = plci->c_ind_mask_table[i + j]; + for (k = 0; k < 8; k++) + { + *(--p) = hex_digit_table[d & 0xf]; + d >>= 4; + } + } + else if (i != 0) + { + for (k = 0; k < 8; k++) + *(--p) = ' '; + } + *(--p) = ' '; + } + dbug(1, dprintf("c_ind_mask =%s", (char *) p)); + } } @@ -1195,6185 +1192,6207 @@ static char hex_digit_table[0x10] = /* translation function for each message */ /*------------------------------------------------------------------*/ -byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word ch; - word i; - word Info; - word CIP; - byte LinkLayer; - API_PARSE * ai; - API_PARSE * bp; - API_PARSE ai_parms[5]; - word channel = 0; - dword ch_mask; - byte m; - static byte esc_chi[35] = {0x02,0x18,0x01}; - static byte lli[2] = {0x01,0x00}; - byte noCh = 0; - word dir = 0; - byte *p_chi = ""; - - for(i=0;i<5;i++) ai_parms[i].length = 0; - - dbug(1,dprintf("connect_req(%d)",parms->length)); - Info = _WRONG_IDENTIFIER; - if(a) - { - if(a->adapter_disabled) - { - dbug(1,dprintf("adapter disabled")); - Id = ((word)1<<8)|a->Id; - sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0); - sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR); - return FALSE; - } - Info = _OUT_OF_PLCI; - if((i=get_plci(a))) - { - Info = 0; - plci = &a->plci[i-1]; - plci->appl = appl; - plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; - /* check 'external controller' bit for codec support */ - if(Id & EXT_CONTROLLER) - { - if(AdvCodecSupport(a, plci, appl, 0) ) - { - plci->Id = 0; - sendf(appl, _CONNECT_R|CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER); - return 2; - } - } - ai = &parms[9]; - bp = &parms[5]; - ch = 0; - if(bp->length)LinkLayer = bp->info[3]; - else LinkLayer = 0; - if(ai->length) - { - ch=0xffff; - if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms)) - { - ch = 0; - if(ai_parms[0].length) - { - ch = GET_WORD(ai_parms[0].info+1); - if(ch>4) ch=0; /* safety -> ignore ChannelID */ - if(ch==4) /* explizit CHI in message */ - { - /* check length of B-CH struct */ - if((ai_parms[0].info)[3]>=1) - { - if((ai_parms[0].info)[4]==CHI) - { - p_chi = &((ai_parms[0].info)[5]); - } - else - { - p_chi = &((ai_parms[0].info)[3]); - } - if(p_chi[0]>35) /* check length of channel ID */ - { - Info = _WRONG_MESSAGE_FORMAT; - } - } - else Info = _WRONG_MESSAGE_FORMAT; - } - - if(ch==3 && ai_parms[0].length>=7 && ai_parms[0].length<=36) - { - dir = GET_WORD(ai_parms[0].info+3); - ch_mask = 0; - m = 0x3f; - for(i=0; i+5<=ai_parms[0].length; i++) - { - if(ai_parms[0].info[i+5]!=0) - { - if((ai_parms[0].info[i+5] | m) != 0xff) - Info = _WRONG_MESSAGE_FORMAT; - else - { - if (ch_mask == 0) - channel = i; - ch_mask |= 1L << i; - } - } - m = 0; - } - if (ch_mask == 0) - Info = _WRONG_MESSAGE_FORMAT; - if (!Info) - { - if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel)))) - { - esc_chi[0] = (byte)(ai_parms[0].length - 2); - for(i=0; i+5<=ai_parms[0].length; i++) - esc_chi[i+3] = ai_parms[0].info[i+5]; - } - else - esc_chi[0] = 2; - esc_chi[2] = (byte)channel; - plci->b_channel = (byte)channel; /* not correct for ETSI ch 17..31 */ - add_p(plci,LLI,lli); - add_p(plci,ESC,esc_chi); - plci->State = LOCAL_CONNECT; - if(!dir) plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; /* dir 0=DTE, 1=DCE */ - } - } - } - } - else Info = _WRONG_MESSAGE_FORMAT; - } - - dbug(1,dprintf("ch=%x,dir=%x,p_ch=%d",ch,dir,channel)); - plci->command = _CONNECT_R; - plci->number = Number; - /* x.31 or D-ch free SAPI in LinkLayer? */ - if(ch==1 && LinkLayer!=3 && LinkLayer!=12) noCh = TRUE; - if((ch==0 || ch==2 || noCh || ch==3 || ch==4) && !Info) - { - /* B-channel used for B3 connections (ch==0), or no B channel */ - /* is used (ch==2) or perm. connection (3) is used do a CALL */ - if(noCh) Info = add_b1(plci,&parms[5],2,0); /* no resource */ - else Info = add_b1(plci,&parms[5],ch,0); - add_s(plci,OAD,&parms[2]); - add_s(plci,OSA,&parms[4]); - add_s(plci,BC,&parms[6]); - add_s(plci,LLC,&parms[7]); - add_s(plci,HLC,&parms[8]); - CIP = GET_WORD(parms[0].info); - if (a->Info_Mask[appl->Id-1] & 0x200) - { - /* early B3 connect (CIP mask bit 9) no release after a disc */ - add_p(plci,LLI,"\x01\x01"); - } - if(GET_WORD(parms[0].info)<29) { - add_p(plci,BC,cip_bc[GET_WORD(parms[0].info)][a->u_law]); - add_p(plci,HLC,cip_hlc[GET_WORD(parms[0].info)]); - } - add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(plci,ASSIGN,DSIG_ID); - } - else if(ch==1) { - - /* D-Channel used for B3 connections */ - plci->Sig.Id = 0xff; - Info = 0; - } - - if(!Info && ch!=2 && !noCh ) { - Info = add_b23(plci,&parms[5]); - if(!Info) { - if(!(plci->tel && !plci->adv_nl))nl_req_ncci(plci,ASSIGN,0); - } - } - - if(!Info) - { - if(ch==0 || ch==2 || ch==3 || noCh || ch==4) - { - if(plci->spoofed_msg==SPOOFING_REQUIRED) - { - api_save_msg(parms, "wsssssssss", &plci->saved_msg); - plci->spoofed_msg = CALL_REQ; - plci->internal_command = BLOCK_PLCI; - plci->command = 0; - dbug(1,dprintf("Spoof")); - send_req(plci); - return FALSE; - } - if(ch==4)add_p(plci,CHI,p_chi); - add_s(plci,CPN,&parms[1]); - add_s(plci,DSA,&parms[3]); - if(noCh) add_p(plci,ESC,"\x02\x18\xfd"); /* D-channel, no B-L3 */ - add_ai(plci,&parms[9]); - if(!dir)sig_req(plci,CALL_REQ,0); - else - { - plci->command = PERM_LIST_REQ; - plci->appl = appl; - sig_req(plci,LISTEN_REQ,0); - send_req(plci); - return FALSE; - } - } - send_req(plci); - return FALSE; - } - plci->Id = 0; - } - } - sendf(appl, - _CONNECT_R|CONFIRM, - Id, - Number, - "w",Info); - return 2; -} - -byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word i, Info; - word Reject; - static byte cau_t[] = {0,0,0x90,0x91,0xac,0x9d,0x86,0xd8,0x9b}; - static byte esc_t[] = {0x03,0x08,0x00,0x00}; - API_PARSE * ai; - API_PARSE ai_parms[5]; - word ch=0; - - if(!plci) { - dbug(1,dprintf("connect_res(no plci)")); - return 0; /* no plci, no send */ - } - - dbug(1,dprintf("connect_res(State=0x%x)",plci->State)); - for(i=0;i<5;i++) ai_parms[i].length = 0; - ai = &parms[5]; - dbug(1,dprintf("ai->length=%d",ai->length)); - - if(ai->length) - { - if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms)) - { - dbug(1,dprintf("ai_parms[0].length=%d/0x%x",ai_parms[0].length,GET_WORD(ai_parms[0].info+1))); - ch = 0; - if(ai_parms[0].length) - { - ch = GET_WORD(ai_parms[0].info+1); - dbug(1,dprintf("BCH-I=0x%x",ch)); - } - } - } - - if(plci->State==INC_CON_CONNECTED_ALERT) - { - dbug(1,dprintf("Connected Alert Call_Res")); - if (a->Info_Mask[appl->Id-1] & 0x200) - { - /* early B3 connect (CIP mask bit 9) no release after a disc */ - add_p(plci,LLI,"\x01\x01"); - } - add_s(plci, CONN_NR, &parms[2]); - add_s(plci, LLC, &parms[4]); - add_ai(plci, &parms[5]); - plci->State = INC_CON_ACCEPT; - sig_req(plci, CALL_RES,0); - return 1; - } - else if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT) { - clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); - dump_c_ind_mask (plci); - Reject = GET_WORD(parms[0].info); - dbug(1,dprintf("Reject=0x%x",Reject)); - if(Reject) - { - if(c_ind_mask_empty (plci)) - { - if((Reject&0xff00)==0x3400) - { - esc_t[2] = ((byte)(Reject&0x00ff)) | 0x80; - add_p(plci,ESC,esc_t); - add_ai(plci, &parms[5]); - sig_req(plci,REJECT,0); - } - else if(Reject==1 || Reject>9) - { - add_ai(plci, &parms[5]); - sig_req(plci,HANGUP,0); - } - else - { - esc_t[2] = cau_t[(Reject&0x000f)]; - add_p(plci,ESC,esc_t); - add_ai(plci, &parms[5]); - sig_req(plci,REJECT,0); - } - plci->appl = appl; - } - else - { - sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); - } - } - else { - plci->appl = appl; - if(Id & EXT_CONTROLLER){ - if(AdvCodecSupport(a, plci, appl, 0)){ - dbug(1,dprintf("connect_res(error from AdvCodecSupport)")); - sig_req(plci,HANGUP,0); - return 1; - } - if(plci->tel == ADV_VOICE && a->AdvCodecPLCI) - { - Info = add_b23(plci, &parms[1]); - if (Info) - { - dbug(1,dprintf("connect_res(error from add_b23)")); - sig_req(plci,HANGUP,0); - return 1; - } - if(plci->adv_nl) - { - nl_req_ncci(plci, ASSIGN, 0); - } - } - } - else - { - plci->tel = 0; - if(ch!=2) - { - Info = add_b23(plci, &parms[1]); - if (Info) - { - dbug(1,dprintf("connect_res(error from add_b23 2)")); - sig_req(plci,HANGUP,0); - return 1; - } - } - nl_req_ncci(plci, ASSIGN, 0); - } - - if(plci->spoofed_msg==SPOOFING_REQUIRED) - { - api_save_msg(parms, "wsssss", &plci->saved_msg); - plci->spoofed_msg = CALL_RES; - plci->internal_command = BLOCK_PLCI; - plci->command = 0; - dbug(1,dprintf("Spoof")); - } - else - { - add_b1 (plci, &parms[1], ch, plci->B1_facilities); - if (a->Info_Mask[appl->Id-1] & 0x200) - { - /* early B3 connect (CIP mask bit 9) no release after a disc */ - add_p(plci,LLI,"\x01\x01"); - } - add_s(plci, CONN_NR, &parms[2]); - add_s(plci, LLC, &parms[4]); - add_ai(plci, &parms[5]); - plci->State = INC_CON_ACCEPT; - sig_req(plci, CALL_RES,0); - } - - for(i=0; i<max_appl; i++) { - if(test_c_ind_mask_bit (plci, i)) { - sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); - } - } - } - } - return 1; -} - -byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - dbug(1,dprintf("connect_a_res")); - return FALSE; -} - -byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - word Info; - word i; - - dbug(1,dprintf("disconnect_req")); - - Info = _WRONG_IDENTIFIER; - - if(plci) - { - if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT) - { - clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); - plci->appl = appl; - for(i=0; i<max_appl; i++) - { - if(test_c_ind_mask_bit (plci, i)) - sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0); - } - plci->State = OUTG_DIS_PENDING; - } - if(plci->Sig.Id && plci->appl) - { - Info = 0; - if(plci->Sig.Id!=0xff) - { - if(plci->State!=INC_DIS_PENDING) - { - add_ai(plci, &msg[0]); - sig_req(plci,HANGUP,0); - plci->State = OUTG_DIS_PENDING; - return 1; - } - } - else - { - if (plci->NL.Id && !plci->nl_remove_id) - { - mixer_remove (plci); - nl_req_ncci(plci,REMOVE,0); - sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0); - sendf(appl, _DISCONNECT_I, Id, 0, "w", 0); - plci->State = INC_DIS_PENDING; - } - return 1; - } - } - } - - if(!appl) return FALSE; - sendf(appl, _DISCONNECT_R|CONFIRM, Id, Number, "w",Info); - return FALSE; -} - -byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - dbug(1,dprintf("disconnect_res")); - if(plci) - { - /* clear ind mask bit, just in case of collsion of */ - /* DISCONNECT_IND and CONNECT_RES */ - clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); - ncci_free_receive_buffers (plci, 0); - if(plci_remove_check(plci)) - { - return 0; - } - if(plci->State==INC_DIS_PENDING - || plci->State==SUSPENDING) { - if(c_ind_mask_empty (plci)) { - if(plci->State!=SUSPENDING)plci->State = IDLE; - dbug(1,dprintf("chs=%d",plci->channels)); - if(!plci->channels) { - plci_remove(plci); - } - } - } - } - return 0; -} - -byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word Info; - byte i; - - dbug(1,dprintf("listen_req(Appl=0x%x)",appl->Id)); - - Info = _WRONG_IDENTIFIER; - if(a) { - Info = 0; - a->Info_Mask[appl->Id-1] = GET_DWORD(parms[0].info); - a->CIP_Mask[appl->Id-1] = GET_DWORD(parms[1].info); - dbug(1,dprintf("CIP_MASK=0x%lx",GET_DWORD(parms[1].info))); - if (a->Info_Mask[appl->Id-1] & 0x200){ /* early B3 connect provides */ - a->Info_Mask[appl->Id-1] |= 0x10; /* call progression infos */ - } - - /* check if external controller listen and switch listen on or off*/ - if(Id&EXT_CONTROLLER && GET_DWORD(parms[1].info)){ - if(a->profile.Global_Options & ON_BOARD_CODEC) { - dummy_plci.State = IDLE; - a->codec_listen[appl->Id-1] = &dummy_plci; - a->TelOAD[0] = (byte)(parms[3].length); - for(i=1;parms[3].length>=i && i<22;i++) { - a->TelOAD[i] = parms[3].info[i]; - } - a->TelOAD[i] = 0; - a->TelOSA[0] = (byte)(parms[4].length); - for(i=1;parms[4].length>=i && i<22;i++) { - a->TelOSA[i] = parms[4].info[i]; - } - a->TelOSA[i] = 0; - } - else Info = 0x2002; /* wrong controller, codec not supported */ - } - else{ /* clear listen */ - a->codec_listen[appl->Id-1] = (PLCI *)0; - } - } - sendf(appl, - _LISTEN_R|CONFIRM, - Id, - Number, - "w",Info); - - if (a) listen_check(a); - return FALSE; -} - -byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - word i; - API_PARSE * ai; - PLCI * rc_plci = NULL; - API_PARSE ai_parms[5]; - word Info = 0; - - dbug(1,dprintf("info_req")); - for(i=0;i<5;i++) ai_parms[i].length = 0; - - ai = &msg[1]; - - if(ai->length) - { - if(api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms)) - { - dbug(1,dprintf("AddInfo wrong")); - Info = _WRONG_MESSAGE_FORMAT; - } - } - if(!a) Info = _WRONG_STATE; - - if(!Info && plci) - { /* no fac, with CPN, or KEY */ - rc_plci = plci; - if(!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length) ) - { - /* overlap sending option */ - dbug(1,dprintf("OvlSnd")); - add_s(plci,CPN,&msg[0]); - add_s(plci,KEY,&ai_parms[1]); - sig_req(plci,INFO_REQ,0); - send_req(plci); - return FALSE; - } - - if(plci->State && ai_parms[2].length) - { - /* User_Info option */ - dbug(1,dprintf("UUI")); - add_s(plci,UUI,&ai_parms[2]); - sig_req(plci,USER_DATA,0); - } - else if(plci->State && ai_parms[3].length) - { - /* Facility option */ - dbug(1,dprintf("FAC")); - add_s(plci,CPN,&msg[0]); - add_ai(plci, &msg[1]); - sig_req(plci,FACILITY_REQ,0); - } - else - { - Info = _WRONG_STATE; - } - } - else if((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info) - { - /* NCR_Facility option -> send UUI and Keypad too */ - dbug(1,dprintf("NCR_FAC")); - if((i=get_plci(a))) - { - rc_plci = &a->plci[i-1]; - appl->NullCREnable = TRUE; - rc_plci->internal_command = C_NCR_FAC_REQ; - rc_plci->appl = appl; - add_p(rc_plci,CAI,"\x01\x80"); - add_p(rc_plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rc_plci,ASSIGN,DSIG_ID); - send_req(rc_plci); - } - else - { - Info = _OUT_OF_PLCI; - } - - if(!Info) - { - add_s(rc_plci,CPN,&msg[0]); - add_ai(rc_plci, &msg[1]); - sig_req(rc_plci,NCR_FACILITY,0); - send_req(rc_plci); - return FALSE; - /* for application controlled supplementary services */ - } - } - - if (!rc_plci) - { - Info = _WRONG_MESSAGE_FORMAT; - } - - if(!Info) - { - send_req(rc_plci); - } - else - { /* appl is not assigned to a PLCI or error condition */ - dbug(1,dprintf("localInfoCon")); - sendf(appl, - _INFO_R|CONFIRM, - Id, - Number, - "w",Info); - } - return FALSE; -} - -byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - dbug(1,dprintf("info_res")); - return FALSE; -} - -byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - word Info; - byte ret; - - dbug(1,dprintf("alert_req")); - - Info = _WRONG_IDENTIFIER; - ret = FALSE; - if(plci) { - Info = _ALERT_IGNORED; - if(plci->State!=INC_CON_ALERT) { - Info = _WRONG_STATE; - if(plci->State==INC_CON_PENDING) { - Info = 0; - plci->State=INC_CON_ALERT; - add_ai(plci, &msg[0]); - sig_req(plci,CALL_ALERT,0); - ret = 1; - } - } - } - sendf(appl, - _ALERT_R|CONFIRM, - Id, - Number, - "w",Info); - return ret; -} - -byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - word Info = 0; - word i = 0; - - word selector; - word SSreq; - long relatedPLCIvalue; - DIVA_CAPI_ADAPTER * relatedadapter; - byte * SSparms = ""; - byte RCparms[] = "\x05\x00\x00\x02\x00\x00"; - byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00"; - API_PARSE * parms; - API_PARSE ss_parms[11]; - PLCI *rplci; - byte cai[15]; - dword d; - API_PARSE dummy; - - dbug(1,dprintf("facility_req")); - for(i=0;i<9;i++) ss_parms[i].length = 0; - - parms = &msg[1]; - - if(!a) - { - dbug(1,dprintf("wrong Ctrl")); - Info = _WRONG_IDENTIFIER; - } - - selector = GET_WORD(msg[0].info); - - if(!Info) - { - switch(selector) - { - case SELECTOR_HANDSET: - Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT); - break; - - case SELECTOR_SU_SERV: - if(!msg[1].length) - { - Info = _WRONG_MESSAGE_FORMAT; - break; - } - SSreq = GET_WORD(&(msg[1].info[1])); - PUT_WORD(&RCparms[1],SSreq); - SSparms = RCparms; - switch(SSreq) - { - case S_GET_SUPPORTED_SERVICES: - if((i=get_plci(a))) - { - rplci = &a->plci[i-1]; - rplci->appl = appl; - add_p(rplci,CAI,"\x01\x80"); - add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rplci,ASSIGN,DSIG_ID); - send_req(rplci); - } - else - { - PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY); - SSparms = (byte *)SSstruct; - break; - } - rplci->internal_command = GETSERV_REQ_PEND; - rplci->number = Number; - rplci->appl = appl; - sig_req(rplci,S_SUPPORTED,0); - send_req(rplci); - return FALSE; - break; - - case S_LISTEN: - if(parms->length==7) - { - if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - } - else - { - Info = _WRONG_MESSAGE_FORMAT; - break; - } - a->Notification_Mask[appl->Id-1] = GET_DWORD(ss_parms[2].info); - if(a->Notification_Mask[appl->Id-1] & SMASK_MWI) /* MWI active? */ - { - if((i=get_plci(a))) - { - rplci = &a->plci[i-1]; - rplci->appl = appl; - add_p(rplci,CAI,"\x01\x80"); - add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rplci,ASSIGN,DSIG_ID); - send_req(rplci); - } - else - { - break; - } - rplci->internal_command = GET_MWI_STATE; - rplci->number = Number; - sig_req(rplci,MWI_POLL,0); - send_req(rplci); - } - break; - - case S_HOLD: - api_parse(&parms->info[1],(word)parms->length,"ws",ss_parms); - if(plci && plci->State && plci->SuppState==IDLE) - { - plci->SuppState = HOLD_REQUEST; - plci->command = C_HOLD_REQ; - add_s(plci,CAI,&ss_parms[1]); - sig_req(plci,CALL_HOLD,0); - send_req(plci); - return FALSE; - } - else Info = 0x3010; /* wrong state */ - break; - case S_RETRIEVE: - if(plci && plci->State && plci->SuppState==CALL_HELD) - { - if(Id & EXT_CONTROLLER) - { - if(AdvCodecSupport(a, plci, appl, 0)) - { - Info = 0x3010; /* wrong state */ - break; - } - } - else plci->tel = 0; - - plci->SuppState = RETRIEVE_REQUEST; - plci->command = C_RETRIEVE_REQ; - if(plci->spoofed_msg==SPOOFING_REQUIRED) - { - plci->spoofed_msg = CALL_RETRIEVE; - plci->internal_command = BLOCK_PLCI; - plci->command = 0; - dbug(1,dprintf("Spoof")); - return FALSE; - } - else - { - sig_req(plci,CALL_RETRIEVE,0); - send_req(plci); - return FALSE; - } - } - else Info = 0x3010; /* wrong state */ - break; - case S_SUSPEND: - if(parms->length) - { - if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - } - if(plci && plci->State) - { - add_s(plci,CAI,&ss_parms[2]); - plci->command = SUSPEND_REQ; - sig_req(plci,SUSPEND,0); - plci->State = SUSPENDING; - send_req(plci); - } - else Info = 0x3010; /* wrong state */ - break; - - case S_RESUME: - if(!(i=get_plci(a)) ) - { - Info = _OUT_OF_PLCI; - break; - } - rplci = &a->plci[i-1]; - rplci->appl = appl; - rplci->number = Number; - rplci->tel = 0; - rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; - /* check 'external controller' bit for codec support */ - if(Id & EXT_CONTROLLER) - { - if(AdvCodecSupport(a, rplci, appl, 0) ) - { - rplci->Id = 0; - Info = 0x300A; - break; - } - } - if(parms->length) - { - if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms)) - { - dbug(1,dprintf("format wrong")); - rplci->Id = 0; - Info = _WRONG_MESSAGE_FORMAT; - break; - } - } - dummy.length = 0; - dummy.info = "\x00"; - add_b1(rplci, &dummy, 0, 0); - if (a->Info_Mask[appl->Id-1] & 0x200) - { - /* early B3 connect (CIP mask bit 9) no release after a disc */ - add_p(rplci,LLI,"\x01\x01"); - } - add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rplci,ASSIGN,DSIG_ID); - send_req(rplci); - add_s(rplci,CAI,&ss_parms[2]); - rplci->command = RESUME_REQ; - sig_req(rplci,RESUME,0); - rplci->State = RESUMING; - send_req(rplci); - break; - - case S_CONF_BEGIN: /* Request */ - case S_CONF_DROP: - case S_CONF_ISOLATE: - case S_CONF_REATTACH: - if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if(plci && plci->State && ((plci->SuppState==IDLE)||(plci->SuppState==CALL_HELD))) - { - d = GET_DWORD(ss_parms[2].info); - if(d>=0x80) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - plci->ptyState = (byte)SSreq; - plci->command = 0; - cai[0] = 2; - switch(SSreq) - { - case S_CONF_BEGIN: - cai[1] = CONF_BEGIN; - plci->internal_command = CONF_BEGIN_REQ_PEND; - break; - case S_CONF_DROP: - cai[1] = CONF_DROP; - plci->internal_command = CONF_DROP_REQ_PEND; - break; - case S_CONF_ISOLATE: - cai[1] = CONF_ISOLATE; - plci->internal_command = CONF_ISOLATE_REQ_PEND; - break; - case S_CONF_REATTACH: - cai[1] = CONF_REATTACH; - plci->internal_command = CONF_REATTACH_REQ_PEND; - break; - } - cai[2] = (byte)d; /* Conference Size resp. PartyId */ - add_p(plci,CAI,cai); - sig_req(plci,S_SERVICE,0); - send_req(plci); - return FALSE; - } - else Info = 0x3010; /* wrong state */ - break; - - case S_ECT: - case S_3PTY_BEGIN: - case S_3PTY_END: - case S_CONF_ADD: - if(parms->length==7) - { - if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - } - else if(parms->length==8) /* workaround for the T-View-S */ - { - if(api_parse(&parms->info[1],(word)parms->length,"wbdb",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - } - else - { - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if(!msg[1].length) - { - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if (!plci) - { - Info = _WRONG_IDENTIFIER; - break; - } - relatedPLCIvalue = GET_DWORD(ss_parms[2].info); - relatedPLCIvalue &= 0x0000FFFF; - dbug(1,dprintf("PTY/ECT/addCONF,relPLCI=%lx",relatedPLCIvalue)); - /* controller starts with 0 up to (max_adapter - 1) */ - if (((relatedPLCIvalue & 0x7f) == 0) - || (MapController ((byte)(relatedPLCIvalue & 0x7f)) == 0) - || (MapController ((byte)(relatedPLCIvalue & 0x7f)) > max_adapter)) - { - if(SSreq==S_3PTY_END) - { - dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI")); - rplci = plci; - } - else - { - Info = 0x3010; /* wrong state */ - break; - } - } - else - { - relatedadapter = &adapter[MapController ((byte)(relatedPLCIvalue & 0x7f))-1]; - relatedPLCIvalue >>=8; - /* find PLCI PTR*/ - for(i=0,rplci=NULL;i<relatedadapter->max_plci;i++) - { - if(relatedadapter->plci[i].Id == (byte)relatedPLCIvalue) - { - rplci = &relatedadapter->plci[i]; - } - } - if(!rplci || !relatedPLCIvalue) - { - if(SSreq==S_3PTY_END) - { - dbug(1, dprintf("use 2nd PLCI=PLCI")); - rplci = plci; - } - else - { - Info = 0x3010; /* wrong state */ - break; - } - } - } +static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word ch; + word i; + word Info; + byte LinkLayer; + API_PARSE *ai; + API_PARSE *bp; + API_PARSE ai_parms[5]; + word channel = 0; + dword ch_mask; + byte m; + static byte esc_chi[35] = {0x02, 0x18, 0x01}; + static byte lli[2] = {0x01, 0x00}; + byte noCh = 0; + word dir = 0; + byte *p_chi = ""; + + for (i = 0; i < 5; i++) ai_parms[i].length = 0; + + dbug(1, dprintf("connect_req(%d)", parms->length)); + Info = _WRONG_IDENTIFIER; + if (a) + { + if (a->adapter_disabled) + { + dbug(1, dprintf("adapter disabled")); + Id = ((word)1 << 8) | a->Id; + sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0); + sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR); + return false; + } + Info = _OUT_OF_PLCI; + if ((i = get_plci(a))) + { + Info = 0; + plci = &a->plci[i - 1]; + plci->appl = appl; + plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; + /* check 'external controller' bit for codec support */ + if (Id & EXT_CONTROLLER) + { + if (AdvCodecSupport(a, plci, appl, 0)) + { + plci->Id = 0; + sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER); + return 2; + } + } + ai = &parms[9]; + bp = &parms[5]; + ch = 0; + if (bp->length)LinkLayer = bp->info[3]; + else LinkLayer = 0; + if (ai->length) + { + ch = 0xffff; + if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms)) + { + ch = 0; + if (ai_parms[0].length) + { + ch = GET_WORD(ai_parms[0].info + 1); + if (ch > 4) ch = 0; /* safety -> ignore ChannelID */ + if (ch == 4) /* explizit CHI in message */ + { + /* check length of B-CH struct */ + if ((ai_parms[0].info)[3] >= 1) + { + if ((ai_parms[0].info)[4] == CHI) + { + p_chi = &((ai_parms[0].info)[5]); + } + else + { + p_chi = &((ai_parms[0].info)[3]); + } + if (p_chi[0] > 35) /* check length of channel ID */ + { + Info = _WRONG_MESSAGE_FORMAT; + } + } + else Info = _WRONG_MESSAGE_FORMAT; + } + + if (ch == 3 && ai_parms[0].length >= 7 && ai_parms[0].length <= 36) + { + dir = GET_WORD(ai_parms[0].info + 3); + ch_mask = 0; + m = 0x3f; + for (i = 0; i + 5 <= ai_parms[0].length; i++) + { + if (ai_parms[0].info[i + 5] != 0) + { + if ((ai_parms[0].info[i + 5] | m) != 0xff) + Info = _WRONG_MESSAGE_FORMAT; + else + { + if (ch_mask == 0) + channel = i; + ch_mask |= 1L << i; + } + } + m = 0; + } + if (ch_mask == 0) + Info = _WRONG_MESSAGE_FORMAT; + if (!Info) + { + if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel)))) + { + esc_chi[0] = (byte)(ai_parms[0].length - 2); + for (i = 0; i + 5 <= ai_parms[0].length; i++) + esc_chi[i + 3] = ai_parms[0].info[i + 5]; + } + else + esc_chi[0] = 2; + esc_chi[2] = (byte)channel; + plci->b_channel = (byte)channel; /* not correct for ETSI ch 17..31 */ + add_p(plci, LLI, lli); + add_p(plci, ESC, esc_chi); + plci->State = LOCAL_CONNECT; + if (!dir) plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; /* dir 0=DTE, 1=DCE */ + } + } + } + } + else Info = _WRONG_MESSAGE_FORMAT; + } + + dbug(1, dprintf("ch=%x,dir=%x,p_ch=%d", ch, dir, channel)); + plci->command = _CONNECT_R; + plci->number = Number; + /* x.31 or D-ch free SAPI in LinkLayer? */ + if (ch == 1 && LinkLayer != 3 && LinkLayer != 12) noCh = true; + if ((ch == 0 || ch == 2 || noCh || ch == 3 || ch == 4) && !Info) + { + /* B-channel used for B3 connections (ch==0), or no B channel */ + /* is used (ch==2) or perm. connection (3) is used do a CALL */ + if (noCh) Info = add_b1(plci, &parms[5], 2, 0); /* no resource */ + else Info = add_b1(plci, &parms[5], ch, 0); + add_s(plci, OAD, &parms[2]); + add_s(plci, OSA, &parms[4]); + add_s(plci, BC, &parms[6]); + add_s(plci, LLC, &parms[7]); + add_s(plci, HLC, &parms[8]); + if (a->Info_Mask[appl->Id - 1] & 0x200) + { + /* early B3 connect (CIP mask bit 9) no release after a disc */ + add_p(plci, LLI, "\x01\x01"); + } + if (GET_WORD(parms[0].info) < 29) { + add_p(plci, BC, cip_bc[GET_WORD(parms[0].info)][a->u_law]); + add_p(plci, HLC, cip_hlc[GET_WORD(parms[0].info)]); + } + add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(plci, ASSIGN, DSIG_ID); + } + else if (ch == 1) { + + /* D-Channel used for B3 connections */ + plci->Sig.Id = 0xff; + Info = 0; + } + + if (!Info && ch != 2 && !noCh) { + Info = add_b23(plci, &parms[5]); + if (!Info) { + if (!(plci->tel && !plci->adv_nl))nl_req_ncci(plci, ASSIGN, 0); + } + } + + if (!Info) + { + if (ch == 0 || ch == 2 || ch == 3 || noCh || ch == 4) + { + if (plci->spoofed_msg == SPOOFING_REQUIRED) + { + api_save_msg(parms, "wsssssssss", &plci->saved_msg); + plci->spoofed_msg = CALL_REQ; + plci->internal_command = BLOCK_PLCI; + plci->command = 0; + dbug(1, dprintf("Spoof")); + send_req(plci); + return false; + } + if (ch == 4)add_p(plci, CHI, p_chi); + add_s(plci, CPN, &parms[1]); + add_s(plci, DSA, &parms[3]); + if (noCh) add_p(plci, ESC, "\x02\x18\xfd"); /* D-channel, no B-L3 */ + add_ai(plci, &parms[9]); + if (!dir)sig_req(plci, CALL_REQ, 0); + else + { + plci->command = PERM_LIST_REQ; + plci->appl = appl; + sig_req(plci, LISTEN_REQ, 0); + send_req(plci); + return false; + } + } + send_req(plci); + return false; + } + plci->Id = 0; + } + } + sendf(appl, + _CONNECT_R | CONFIRM, + Id, + Number, + "w", Info); + return 2; +} + +static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word i, Info; + word Reject; + static byte cau_t[] = {0, 0, 0x90, 0x91, 0xac, 0x9d, 0x86, 0xd8, 0x9b}; + static byte esc_t[] = {0x03, 0x08, 0x00, 0x00}; + API_PARSE *ai; + API_PARSE ai_parms[5]; + word ch = 0; + + if (!plci) { + dbug(1, dprintf("connect_res(no plci)")); + return 0; /* no plci, no send */ + } + + dbug(1, dprintf("connect_res(State=0x%x)", plci->State)); + for (i = 0; i < 5; i++) ai_parms[i].length = 0; + ai = &parms[5]; + dbug(1, dprintf("ai->length=%d", ai->length)); + + if (ai->length) + { + if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms)) + { + dbug(1, dprintf("ai_parms[0].length=%d/0x%x", ai_parms[0].length, GET_WORD(ai_parms[0].info + 1))); + ch = 0; + if (ai_parms[0].length) + { + ch = GET_WORD(ai_parms[0].info + 1); + dbug(1, dprintf("BCH-I=0x%x", ch)); + } + } + } + + if (plci->State == INC_CON_CONNECTED_ALERT) + { + dbug(1, dprintf("Connected Alert Call_Res")); + if (a->Info_Mask[appl->Id - 1] & 0x200) + { + /* early B3 connect (CIP mask bit 9) no release after a disc */ + add_p(plci, LLI, "\x01\x01"); + } + add_s(plci, CONN_NR, &parms[2]); + add_s(plci, LLC, &parms[4]); + add_ai(plci, &parms[5]); + plci->State = INC_CON_ACCEPT; + sig_req(plci, CALL_RES, 0); + return 1; + } + else if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT) { + clear_c_ind_mask_bit(plci, (word)(appl->Id - 1)); + dump_c_ind_mask(plci); + Reject = GET_WORD(parms[0].info); + dbug(1, dprintf("Reject=0x%x", Reject)); + if (Reject) + { + if (c_ind_mask_empty(plci)) + { + if ((Reject & 0xff00) == 0x3400) + { + esc_t[2] = ((byte)(Reject & 0x00ff)) | 0x80; + add_p(plci, ESC, esc_t); + add_ai(plci, &parms[5]); + sig_req(plci, REJECT, 0); + } + else if (Reject == 1 || Reject > 9) + { + add_ai(plci, &parms[5]); + sig_req(plci, HANGUP, 0); + } + else + { + esc_t[2] = cau_t[(Reject&0x000f)]; + add_p(plci, ESC, esc_t); + add_ai(plci, &parms[5]); + sig_req(plci, REJECT, 0); + } + plci->appl = appl; + } + else + { + sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); + } + } + else { + plci->appl = appl; + if (Id & EXT_CONTROLLER) { + if (AdvCodecSupport(a, plci, appl, 0)) { + dbug(1, dprintf("connect_res(error from AdvCodecSupport)")); + sig_req(plci, HANGUP, 0); + return 1; + } + if (plci->tel == ADV_VOICE && a->AdvCodecPLCI) + { + Info = add_b23(plci, &parms[1]); + if (Info) + { + dbug(1, dprintf("connect_res(error from add_b23)")); + sig_req(plci, HANGUP, 0); + return 1; + } + if (plci->adv_nl) + { + nl_req_ncci(plci, ASSIGN, 0); + } + } + } + else + { + plci->tel = 0; + if (ch != 2) + { + Info = add_b23(plci, &parms[1]); + if (Info) + { + dbug(1, dprintf("connect_res(error from add_b23 2)")); + sig_req(plci, HANGUP, 0); + return 1; + } + } + nl_req_ncci(plci, ASSIGN, 0); + } + + if (plci->spoofed_msg == SPOOFING_REQUIRED) + { + api_save_msg(parms, "wsssss", &plci->saved_msg); + plci->spoofed_msg = CALL_RES; + plci->internal_command = BLOCK_PLCI; + plci->command = 0; + dbug(1, dprintf("Spoof")); + } + else + { + add_b1(plci, &parms[1], ch, plci->B1_facilities); + if (a->Info_Mask[appl->Id - 1] & 0x200) + { + /* early B3 connect (CIP mask bit 9) no release after a disc */ + add_p(plci, LLI, "\x01\x01"); + } + add_s(plci, CONN_NR, &parms[2]); + add_s(plci, LLC, &parms[4]); + add_ai(plci, &parms[5]); + plci->State = INC_CON_ACCEPT; + sig_req(plci, CALL_RES, 0); + } + + for (i = 0; i < max_appl; i++) { + if (test_c_ind_mask_bit(plci, i)) { + sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); + } + } + } + } + return 1; +} + +static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + dbug(1, dprintf("connect_a_res")); + return false; +} + +static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word Info; + word i; + + dbug(1, dprintf("disconnect_req")); + + Info = _WRONG_IDENTIFIER; + + if (plci) + { + if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT) + { + clear_c_ind_mask_bit(plci, (word)(appl->Id - 1)); + plci->appl = appl; + for (i = 0; i < max_appl; i++) + { + if (test_c_ind_mask_bit(plci, i)) + sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0); + } + plci->State = OUTG_DIS_PENDING; + } + if (plci->Sig.Id && plci->appl) + { + Info = 0; + if (plci->Sig.Id != 0xff) + { + if (plci->State != INC_DIS_PENDING) + { + add_ai(plci, &msg[0]); + sig_req(plci, HANGUP, 0); + plci->State = OUTG_DIS_PENDING; + return 1; + } + } + else + { + if (plci->NL.Id && !plci->nl_remove_id) + { + mixer_remove(plci); + nl_req_ncci(plci, REMOVE, 0); + sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0); + sendf(appl, _DISCONNECT_I, Id, 0, "w", 0); + plci->State = INC_DIS_PENDING; + } + return 1; + } + } + } + + if (!appl) return false; + sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", Info); + return false; +} + +static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + dbug(1, dprintf("disconnect_res")); + if (plci) + { + /* clear ind mask bit, just in case of collsion of */ + /* DISCONNECT_IND and CONNECT_RES */ + clear_c_ind_mask_bit(plci, (word)(appl->Id - 1)); + ncci_free_receive_buffers(plci, 0); + if (plci_remove_check(plci)) + { + return 0; + } + if (plci->State == INC_DIS_PENDING + || plci->State == SUSPENDING) { + if (c_ind_mask_empty(plci)) { + if (plci->State != SUSPENDING) plci->State = IDLE; + dbug(1, dprintf("chs=%d", plci->channels)); + if (!plci->channels) { + plci_remove(plci); + } + } + } + } + return 0; +} + +static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word Info; + byte i; + + dbug(1, dprintf("listen_req(Appl=0x%x)", appl->Id)); + + Info = _WRONG_IDENTIFIER; + if (a) { + Info = 0; + a->Info_Mask[appl->Id - 1] = GET_DWORD(parms[0].info); + a->CIP_Mask[appl->Id - 1] = GET_DWORD(parms[1].info); + dbug(1, dprintf("CIP_MASK=0x%lx", GET_DWORD(parms[1].info))); + if (a->Info_Mask[appl->Id - 1] & 0x200) { /* early B3 connect provides */ + a->Info_Mask[appl->Id - 1] |= 0x10; /* call progression infos */ + } + + /* check if external controller listen and switch listen on or off*/ + if (Id&EXT_CONTROLLER && GET_DWORD(parms[1].info)) { + if (a->profile.Global_Options & ON_BOARD_CODEC) { + dummy_plci.State = IDLE; + a->codec_listen[appl->Id - 1] = &dummy_plci; + a->TelOAD[0] = (byte)(parms[3].length); + for (i = 1; parms[3].length >= i && i < 22; i++) { + a->TelOAD[i] = parms[3].info[i]; + } + a->TelOAD[i] = 0; + a->TelOSA[0] = (byte)(parms[4].length); + for (i = 1; parms[4].length >= i && i < 22; i++) { + a->TelOSA[i] = parms[4].info[i]; + } + a->TelOSA[i] = 0; + } + else Info = 0x2002; /* wrong controller, codec not supported */ + } + else{ /* clear listen */ + a->codec_listen[appl->Id - 1] = (PLCI *)0; + } + } + sendf(appl, + _LISTEN_R | CONFIRM, + Id, + Number, + "w", Info); + + if (a) listen_check(a); + return false; +} + +static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word i; + API_PARSE *ai; + PLCI *rc_plci = NULL; + API_PARSE ai_parms[5]; + word Info = 0; + + dbug(1, dprintf("info_req")); + for (i = 0; i < 5; i++) ai_parms[i].length = 0; + + ai = &msg[1]; + + if (ai->length) + { + if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms)) + { + dbug(1, dprintf("AddInfo wrong")); + Info = _WRONG_MESSAGE_FORMAT; + } + } + if (!a) Info = _WRONG_STATE; + + if (!Info && plci) + { /* no fac, with CPN, or KEY */ + rc_plci = plci; + if (!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length)) + { + /* overlap sending option */ + dbug(1, dprintf("OvlSnd")); + add_s(plci, CPN, &msg[0]); + add_s(plci, KEY, &ai_parms[1]); + sig_req(plci, INFO_REQ, 0); + send_req(plci); + return false; + } + + if (plci->State && ai_parms[2].length) + { + /* User_Info option */ + dbug(1, dprintf("UUI")); + add_s(plci, UUI, &ai_parms[2]); + sig_req(plci, USER_DATA, 0); + } + else if (plci->State && ai_parms[3].length) + { + /* Facility option */ + dbug(1, dprintf("FAC")); + add_s(plci, CPN, &msg[0]); + add_ai(plci, &msg[1]); + sig_req(plci, FACILITY_REQ, 0); + } + else + { + Info = _WRONG_STATE; + } + } + else if ((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info) + { + /* NCR_Facility option -> send UUI and Keypad too */ + dbug(1, dprintf("NCR_FAC")); + if ((i = get_plci(a))) + { + rc_plci = &a->plci[i - 1]; + appl->NullCREnable = true; + rc_plci->internal_command = C_NCR_FAC_REQ; + rc_plci->appl = appl; + add_p(rc_plci, CAI, "\x01\x80"); + add_p(rc_plci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rc_plci, ASSIGN, DSIG_ID); + send_req(rc_plci); + } + else + { + Info = _OUT_OF_PLCI; + } + + if (!Info) + { + add_s(rc_plci, CPN, &msg[0]); + add_ai(rc_plci, &msg[1]); + sig_req(rc_plci, NCR_FACILITY, 0); + send_req(rc_plci); + return false; + /* for application controlled supplementary services */ + } + } + + if (!rc_plci) + { + Info = _WRONG_MESSAGE_FORMAT; + } + + if (!Info) + { + send_req(rc_plci); + } + else + { /* appl is not assigned to a PLCI or error condition */ + dbug(1, dprintf("localInfoCon")); + sendf(appl, + _INFO_R | CONFIRM, + Id, + Number, + "w", Info); + } + return false; +} + +static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + dbug(1, dprintf("info_res")); + return false; +} + +static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word Info; + byte ret; + + dbug(1, dprintf("alert_req")); + + Info = _WRONG_IDENTIFIER; + ret = false; + if (plci) { + Info = _ALERT_IGNORED; + if (plci->State != INC_CON_ALERT) { + Info = _WRONG_STATE; + if (plci->State == INC_CON_PENDING) { + Info = 0; + plci->State = INC_CON_ALERT; + add_ai(plci, &msg[0]); + sig_req(plci, CALL_ALERT, 0); + ret = 1; + } + } + } + sendf(appl, + _ALERT_R | CONFIRM, + Id, + Number, + "w", Info); + return ret; +} + +static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word Info = 0; + word i = 0; + + word selector; + word SSreq; + long relatedPLCIvalue; + DIVA_CAPI_ADAPTER *relatedadapter; + byte *SSparms = ""; + byte RCparms[] = "\x05\x00\x00\x02\x00\x00"; + byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00"; + API_PARSE *parms; + API_PARSE ss_parms[11]; + PLCI *rplci; + byte cai[15]; + dword d; + API_PARSE dummy; + + dbug(1, dprintf("facility_req")); + for (i = 0; i < 9; i++) ss_parms[i].length = 0; + + parms = &msg[1]; + + if (!a) + { + dbug(1, dprintf("wrong Ctrl")); + Info = _WRONG_IDENTIFIER; + } + + selector = GET_WORD(msg[0].info); + + if (!Info) + { + switch (selector) + { + case SELECTOR_HANDSET: + Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT); + break; + + case SELECTOR_SU_SERV: + if (!msg[1].length) + { + Info = _WRONG_MESSAGE_FORMAT; + break; + } + SSreq = GET_WORD(&(msg[1].info[1])); + PUT_WORD(&RCparms[1], SSreq); + SSparms = RCparms; + switch (SSreq) + { + case S_GET_SUPPORTED_SERVICES: + if ((i = get_plci(a))) + { + rplci = &a->plci[i - 1]; + rplci->appl = appl; + add_p(rplci, CAI, "\x01\x80"); + add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rplci, ASSIGN, DSIG_ID); + send_req(rplci); + } + else + { + PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY); + SSparms = (byte *)SSstruct; + break; + } + rplci->internal_command = GETSERV_REQ_PEND; + rplci->number = Number; + rplci->appl = appl; + sig_req(rplci, S_SUPPORTED, 0); + send_req(rplci); + return false; + break; + + case S_LISTEN: + if (parms->length == 7) + { + if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + } + else + { + Info = _WRONG_MESSAGE_FORMAT; + break; + } + a->Notification_Mask[appl->Id - 1] = GET_DWORD(ss_parms[2].info); + if (a->Notification_Mask[appl->Id - 1] & SMASK_MWI) /* MWI active? */ + { + if ((i = get_plci(a))) + { + rplci = &a->plci[i - 1]; + rplci->appl = appl; + add_p(rplci, CAI, "\x01\x80"); + add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rplci, ASSIGN, DSIG_ID); + send_req(rplci); + } + else + { + break; + } + rplci->internal_command = GET_MWI_STATE; + rplci->number = Number; + sig_req(rplci, MWI_POLL, 0); + send_req(rplci); + } + break; + + case S_HOLD: + api_parse(&parms->info[1], (word)parms->length, "ws", ss_parms); + if (plci && plci->State && plci->SuppState == IDLE) + { + plci->SuppState = HOLD_REQUEST; + plci->command = C_HOLD_REQ; + add_s(plci, CAI, &ss_parms[1]); + sig_req(plci, CALL_HOLD, 0); + send_req(plci); + return false; + } + else Info = 0x3010; /* wrong state */ + break; + case S_RETRIEVE: + if (plci && plci->State && plci->SuppState == CALL_HELD) + { + if (Id & EXT_CONTROLLER) + { + if (AdvCodecSupport(a, plci, appl, 0)) + { + Info = 0x3010; /* wrong state */ + break; + } + } + else plci->tel = 0; + + plci->SuppState = RETRIEVE_REQUEST; + plci->command = C_RETRIEVE_REQ; + if (plci->spoofed_msg == SPOOFING_REQUIRED) + { + plci->spoofed_msg = CALL_RETRIEVE; + plci->internal_command = BLOCK_PLCI; + plci->command = 0; + dbug(1, dprintf("Spoof")); + return false; + } + else + { + sig_req(plci, CALL_RETRIEVE, 0); + send_req(plci); + return false; + } + } + else Info = 0x3010; /* wrong state */ + break; + case S_SUSPEND: + if (parms->length) + { + if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + } + if (plci && plci->State) + { + add_s(plci, CAI, &ss_parms[2]); + plci->command = SUSPEND_REQ; + sig_req(plci, SUSPEND, 0); + plci->State = SUSPENDING; + send_req(plci); + } + else Info = 0x3010; /* wrong state */ + break; + + case S_RESUME: + if (!(i = get_plci(a))) + { + Info = _OUT_OF_PLCI; + break; + } + rplci = &a->plci[i - 1]; + rplci->appl = appl; + rplci->number = Number; + rplci->tel = 0; + rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; + /* check 'external controller' bit for codec support */ + if (Id & EXT_CONTROLLER) + { + if (AdvCodecSupport(a, rplci, appl, 0)) + { + rplci->Id = 0; + Info = 0x300A; + break; + } + } + if (parms->length) + { + if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms)) + { + dbug(1, dprintf("format wrong")); + rplci->Id = 0; + Info = _WRONG_MESSAGE_FORMAT; + break; + } + } + dummy.length = 0; + dummy.info = "\x00"; + add_b1(rplci, &dummy, 0, 0); + if (a->Info_Mask[appl->Id - 1] & 0x200) + { + /* early B3 connect (CIP mask bit 9) no release after a disc */ + add_p(rplci, LLI, "\x01\x01"); + } + add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rplci, ASSIGN, DSIG_ID); + send_req(rplci); + add_s(rplci, CAI, &ss_parms[2]); + rplci->command = RESUME_REQ; + sig_req(rplci, RESUME, 0); + rplci->State = RESUMING; + send_req(rplci); + break; + + case S_CONF_BEGIN: /* Request */ + case S_CONF_DROP: + case S_CONF_ISOLATE: + case S_CONF_REATTACH: + if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (plci && plci->State && ((plci->SuppState == IDLE) || (plci->SuppState == CALL_HELD))) + { + d = GET_DWORD(ss_parms[2].info); + if (d >= 0x80) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + plci->ptyState = (byte)SSreq; + plci->command = 0; + cai[0] = 2; + switch (SSreq) + { + case S_CONF_BEGIN: + cai[1] = CONF_BEGIN; + plci->internal_command = CONF_BEGIN_REQ_PEND; + break; + case S_CONF_DROP: + cai[1] = CONF_DROP; + plci->internal_command = CONF_DROP_REQ_PEND; + break; + case S_CONF_ISOLATE: + cai[1] = CONF_ISOLATE; + plci->internal_command = CONF_ISOLATE_REQ_PEND; + break; + case S_CONF_REATTACH: + cai[1] = CONF_REATTACH; + plci->internal_command = CONF_REATTACH_REQ_PEND; + break; + } + cai[2] = (byte)d; /* Conference Size resp. PartyId */ + add_p(plci, CAI, cai); + sig_req(plci, S_SERVICE, 0); + send_req(plci); + return false; + } + else Info = 0x3010; /* wrong state */ + break; + + case S_ECT: + case S_3PTY_BEGIN: + case S_3PTY_END: + case S_CONF_ADD: + if (parms->length == 7) + { + if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + } + else if (parms->length == 8) /* workaround for the T-View-S */ + { + if (api_parse(&parms->info[1], (word)parms->length, "wbdb", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + } + else + { + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (!msg[1].length) + { + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (!plci) + { + Info = _WRONG_IDENTIFIER; + break; + } + relatedPLCIvalue = GET_DWORD(ss_parms[2].info); + relatedPLCIvalue &= 0x0000FFFF; + dbug(1, dprintf("PTY/ECT/addCONF,relPLCI=%lx", relatedPLCIvalue)); + /* controller starts with 0 up to (max_adapter - 1) */ + if (((relatedPLCIvalue & 0x7f) == 0) + || (MapController((byte)(relatedPLCIvalue & 0x7f)) == 0) + || (MapController((byte)(relatedPLCIvalue & 0x7f)) > max_adapter)) + { + if (SSreq == S_3PTY_END) + { + dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI")); + rplci = plci; + } + else + { + Info = 0x3010; /* wrong state */ + break; + } + } + else + { + relatedadapter = &adapter[MapController((byte)(relatedPLCIvalue & 0x7f)) - 1]; + relatedPLCIvalue >>= 8; + /* find PLCI PTR*/ + for (i = 0, rplci = NULL; i < relatedadapter->max_plci; i++) + { + if (relatedadapter->plci[i].Id == (byte)relatedPLCIvalue) + { + rplci = &relatedadapter->plci[i]; + } + } + if (!rplci || !relatedPLCIvalue) + { + if (SSreq == S_3PTY_END) + { + dbug(1, dprintf("use 2nd PLCI=PLCI")); + rplci = plci; + } + else + { + Info = 0x3010; /* wrong state */ + break; + } + } + } /* - dbug(1,dprintf("rplci:%x",rplci)); - dbug(1,dprintf("plci:%x",plci)); - dbug(1,dprintf("rplci->ptyState:%x",rplci->ptyState)); - dbug(1,dprintf("plci->ptyState:%x",plci->ptyState)); - dbug(1,dprintf("SSreq:%x",SSreq)); - dbug(1,dprintf("rplci->internal_command:%x",rplci->internal_command)); - dbug(1,dprintf("rplci->appl:%x",rplci->appl)); - dbug(1,dprintf("rplci->Id:%x",rplci->Id)); + dbug(1, dprintf("rplci:%x", rplci)); + dbug(1, dprintf("plci:%x", plci)); + dbug(1, dprintf("rplci->ptyState:%x", rplci->ptyState)); + dbug(1, dprintf("plci->ptyState:%x", plci->ptyState)); + dbug(1, dprintf("SSreq:%x", SSreq)); + dbug(1, dprintf("rplci->internal_command:%x", rplci->internal_command)); + dbug(1, dprintf("rplci->appl:%x", rplci->appl)); + dbug(1, dprintf("rplci->Id:%x", rplci->Id)); */ - /* send PTY/ECT req, cannot check all states because of US stuff */ - if( !rplci->internal_command && rplci->appl ) - { - plci->command = 0; - rplci->relatedPTYPLCI = plci; - plci->relatedPTYPLCI = rplci; - rplci->ptyState = (byte)SSreq; - if(SSreq==S_ECT) - { - rplci->internal_command = ECT_REQ_PEND; - cai[1] = ECT_EXECUTE; - - rplci->vswitchstate=0; - rplci->vsprot=0; - rplci->vsprotdialect=0; - plci->vswitchstate=0; - plci->vsprot=0; - plci->vsprotdialect=0; - - } - else if(SSreq==S_CONF_ADD) - { - rplci->internal_command = CONF_ADD_REQ_PEND; - cai[1] = CONF_ADD; - } - else - { - rplci->internal_command = PTY_REQ_PEND; - cai[1] = (byte)(SSreq-3); - } - rplci->number = Number; - if(plci!=rplci) /* explicit invocation */ - { - cai[0] = 2; - cai[2] = plci->Sig.Id; - dbug(1,dprintf("explicit invocation")); - } - else - { - dbug(1,dprintf("implicit invocation")); - cai[0] = 1; - } - add_p(rplci,CAI,cai); - sig_req(rplci,S_SERVICE,0); - send_req(rplci); - return FALSE; - } - else - { - dbug(0,dprintf("Wrong line")); - Info = 0x3010; /* wrong state */ - break; - } - break; - - case S_CALL_DEFLECTION: - if(api_parse(&parms->info[1],(word)parms->length,"wbwss",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if (!plci) - { - Info = _WRONG_IDENTIFIER; - break; - } - /* reuse unused screening indicator */ - ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0])); - plci->command = 0; - plci->internal_command = CD_REQ_PEND; - appl->CDEnable = TRUE; - cai[0] = 1; - cai[1] = CALL_DEFLECTION; - add_p(plci,CAI,cai); - add_p(plci,CPN,ss_parms[3].info); - sig_req(plci,S_SERVICE,0); - send_req(plci); - return FALSE; - break; - - case S_CALL_FORWARDING_START: - if(api_parse(&parms->info[1],(word)parms->length,"wbdwwsss",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - - if((i=get_plci(a))) - { - rplci = &a->plci[i-1]; - rplci->appl = appl; - add_p(rplci,CAI,"\x01\x80"); - add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rplci,ASSIGN,DSIG_ID); - send_req(rplci); - } - else - { - Info = _OUT_OF_PLCI; - break; - } - - /* reuse unused screening indicator */ - rplci->internal_command = CF_START_PEND; - rplci->appl = appl; - rplci->number = Number; - appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0])); - cai[0] = 2; - cai[1] = 0x70|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ - cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */ - add_p(rplci,CAI,cai); - add_p(rplci,OAD,ss_parms[5].info); - add_p(rplci,CPN,ss_parms[6].info); - sig_req(rplci,S_SERVICE,0); - send_req(rplci); - return FALSE; - break; - - case S_INTERROGATE_DIVERSION: - case S_INTERROGATE_NUMBERS: - case S_CALL_FORWARDING_STOP: - case S_CCBS_REQUEST: - case S_CCBS_DEACTIVATE: - case S_CCBS_INTERROGATE: - switch(SSreq) - { - case S_INTERROGATE_NUMBERS: - if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms)) - { - dbug(0,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - } - break; - case S_CCBS_REQUEST: - case S_CCBS_DEACTIVATE: - if(api_parse(&parms->info[1],(word)parms->length,"wbdw",ss_parms)) - { - dbug(0,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - } - break; - case S_CCBS_INTERROGATE: - if(api_parse(&parms->info[1],(word)parms->length,"wbdws",ss_parms)) - { - dbug(0,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - } - break; - default: - if(api_parse(&parms->info[1],(word)parms->length,"wbdwws",ss_parms)) - { - dbug(0,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - break; - } - - if(Info) break; - if((i=get_plci(a))) - { - rplci = &a->plci[i-1]; - switch(SSreq) - { - case S_INTERROGATE_DIVERSION: /* use cai with S_SERVICE below */ - cai[1] = 0x60|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ - rplci->internal_command = INTERR_DIVERSION_REQ_PEND; /* move to rplci if assigned */ - break; - case S_INTERROGATE_NUMBERS: /* use cai with S_SERVICE below */ - cai[1] = DIVERSION_INTERROGATE_NUM; /* Function */ - rplci->internal_command = INTERR_NUMBERS_REQ_PEND; /* move to rplci if assigned */ - break; - case S_CALL_FORWARDING_STOP: - rplci->internal_command = CF_STOP_PEND; - cai[1] = 0x80|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ - break; - case S_CCBS_REQUEST: - cai[1] = CCBS_REQUEST; - rplci->internal_command = CCBS_REQUEST_REQ_PEND; - break; - case S_CCBS_DEACTIVATE: - cai[1] = CCBS_DEACTIVATE; - rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND; - break; - case S_CCBS_INTERROGATE: - cai[1] = CCBS_INTERROGATE; - rplci->internal_command = CCBS_INTERROGATE_REQ_PEND; - break; - default: - cai[1] = 0; - break; - } - rplci->appl = appl; - rplci->number = Number; - add_p(rplci,CAI,"\x01\x80"); - add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rplci,ASSIGN,DSIG_ID); - send_req(rplci); - } - else - { - Info = _OUT_OF_PLCI; - break; - } - - appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0])); - switch(SSreq) - { - case S_INTERROGATE_NUMBERS: - cai[0] = 1; - add_p(rplci,CAI,cai); - break; - case S_CCBS_REQUEST: - case S_CCBS_DEACTIVATE: - cai[0] = 3; - PUT_WORD(&cai[2],GET_WORD(&(ss_parms[3].info[0]))); - add_p(rplci,CAI,cai); - break; - case S_CCBS_INTERROGATE: - cai[0] = 3; - PUT_WORD(&cai[2],GET_WORD(&(ss_parms[3].info[0]))); - add_p(rplci,CAI,cai); - add_p(rplci,OAD,ss_parms[4].info); - break; - default: - cai[0] = 2; - cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */ - add_p(rplci,CAI,cai); - add_p(rplci,OAD,ss_parms[5].info); - break; - } - - sig_req(rplci,S_SERVICE,0); - send_req(rplci); - return FALSE; - break; - - case S_MWI_ACTIVATE: - if(api_parse(&parms->info[1],(word)parms->length,"wbwdwwwssss",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if(!plci) - { - if((i=get_plci(a))) - { - rplci = &a->plci[i-1]; - rplci->appl = appl; - rplci->cr_enquiry=TRUE; - add_p(rplci,CAI,"\x01\x80"); - add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rplci,ASSIGN,DSIG_ID); - send_req(rplci); - } - else - { - Info = _OUT_OF_PLCI; - break; - } - } - else - { - rplci = plci; - rplci->cr_enquiry=FALSE; - } - - rplci->command = 0; - rplci->internal_command = MWI_ACTIVATE_REQ_PEND; - rplci->appl = appl; - rplci->number = Number; - - cai[0] = 13; - cai[1] = ACTIVATION_MWI; /* Function */ - PUT_WORD(&cai[2],GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */ - PUT_DWORD(&cai[4],GET_DWORD(&(ss_parms[3].info[0]))); /* Number of Messages */ - PUT_WORD(&cai[8],GET_WORD(&(ss_parms[4].info[0]))); /* Message Status */ - PUT_WORD(&cai[10],GET_WORD(&(ss_parms[5].info[0]))); /* Message Reference */ - PUT_WORD(&cai[12],GET_WORD(&(ss_parms[6].info[0]))); /* Invocation Mode */ - add_p(rplci,CAI,cai); - add_p(rplci,CPN,ss_parms[7].info); /* Receiving User Number */ - add_p(rplci,OAD,ss_parms[8].info); /* Controlling User Number */ - add_p(rplci,OSA,ss_parms[9].info); /* Controlling User Provided Number */ - add_p(rplci,UID,ss_parms[10].info); /* Time */ - sig_req(rplci,S_SERVICE,0); - send_req(rplci); - return FALSE; - - case S_MWI_DEACTIVATE: - if(api_parse(&parms->info[1],(word)parms->length,"wbwwss",ss_parms)) - { - dbug(1,dprintf("format wrong")); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if(!plci) - { - if((i=get_plci(a))) - { - rplci = &a->plci[i-1]; - rplci->appl = appl; - rplci->cr_enquiry=TRUE; - add_p(rplci,CAI,"\x01\x80"); - add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(rplci,ASSIGN,DSIG_ID); - send_req(rplci); - } - else - { - Info = _OUT_OF_PLCI; - break; - } - } - else - { - rplci = plci; - rplci->cr_enquiry=FALSE; - } - - rplci->command = 0; - rplci->internal_command = MWI_DEACTIVATE_REQ_PEND; - rplci->appl = appl; - rplci->number = Number; - - cai[0] = 5; - cai[1] = DEACTIVATION_MWI; /* Function */ - PUT_WORD(&cai[2],GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */ - PUT_WORD(&cai[4],GET_WORD(&(ss_parms[3].info[0]))); /* Invocation Mode */ - add_p(rplci,CAI,cai); - add_p(rplci,CPN,ss_parms[4].info); /* Receiving User Number */ - add_p(rplci,OAD,ss_parms[5].info); /* Controlling User Number */ - sig_req(rplci,S_SERVICE,0); - send_req(rplci); - return FALSE; - - default: - Info = 0x300E; /* not supported */ - break; - } - break; /* case SELECTOR_SU_SERV: end */ - - - case SELECTOR_DTMF: - return (dtmf_request (Id, Number, a, plci, appl, msg)); - - - - case SELECTOR_LINE_INTERCONNECT: - return (mixer_request (Id, Number, a, plci, appl, msg)); - - - - case PRIV_SELECTOR_ECHO_CANCELLER: - appl->appl_flags |= APPL_FLAG_PRIV_EC_SPEC; - return (ec_request (Id, Number, a, plci, appl, msg)); - - case SELECTOR_ECHO_CANCELLER: - appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC; - return (ec_request (Id, Number, a, plci, appl, msg)); - - - case SELECTOR_V42BIS: - default: - Info = _FACILITY_NOT_SUPPORTED; - break; - } /* end of switch(selector) */ - } - - dbug(1,dprintf("SendFacRc")); - sendf(appl, - _FACILITY_R|CONFIRM, - Id, - Number, - "wws",Info,selector,SSparms); - return FALSE; -} - -byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - dbug(1,dprintf("facility_res")); - return FALSE; -} - -byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word Info = 0; - byte req; - byte len; - word w; - word fax_control_bits, fax_feature_bits, fax_info_change; - API_PARSE * ncpi; - byte pvc[2]; - - API_PARSE fax_parms[9]; - word i; - - - dbug(1,dprintf("connect_b3_req")); - if(plci) - { - if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) - || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE)) - { - Info = _WRONG_STATE; - } - else - { - /* local reply if assign unsuccessfull - or B3 protocol allows only one layer 3 connection - and already connected - or B2 protocol not any LAPD - and connect_b3_req contradicts originate/answer direction */ - if (!plci->NL.Id - || (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)) - && ((plci->channels != 0) - || (((plci->B2_prot != B2_SDLC) && (plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL)) - && ((plci->call_dir & CALL_DIR_ANSWER) && !(plci->call_dir & CALL_DIR_FORCE_OUTG_NL)))))) - { - dbug(1,dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x", - plci->channels,plci->NL.Id,plci->call_dir,plci->SuppState)); - Info = _WRONG_STATE; - sendf(appl, - _CONNECT_B3_R|CONFIRM, - Id, - Number, - "w",Info); - return FALSE; - } - plci->requested_options_conn = 0; - - req = N_CONNECT; - ncpi = &parms[0]; - if(plci->B3_prot==2 || plci->B3_prot==3) - { - if(ncpi->length>2) - { - /* check for PVC */ - if(ncpi->info[2] || ncpi->info[3]) - { - pvc[0] = ncpi->info[3]; - pvc[1] = ncpi->info[2]; - add_d(plci,2,pvc); - req = N_RESET; - } - else - { - if(ncpi->info[1] &1) req = N_CONNECT | N_D_BIT; - add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]); - } - } - } - else if(plci->B3_prot==5) - { - if (plci->NL.Id && !plci->nl_remove_id) - { - fax_control_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low); - fax_feature_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low); - if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS) - || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)) - { - len = (byte)(&(((T30_INFO *) 0)->universal_6)); - fax_info_change = FALSE; - if (ncpi->length >= 4) - { - w = GET_WORD(&ncpi->info[3]); - if ((w & 0x0001) != ((word)(((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & 0x0001))) - { - ((T30_INFO *)(plci->fax_connect_info_buffer))->resolution = - (byte)((((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) | - ((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0)); - fax_info_change = TRUE; - } - fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS); - if (w & 0x0002) /* Fax-polling request */ - fax_control_bits |= T30_CONTROL_BIT_REQUEST_POLLING; - if ((w & 0x0004) /* Request to send / poll another document */ - && (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS)) - { - fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS; - } - if (ncpi->length >= 6) - { - w = GET_WORD(&ncpi->info[5]); - if (((byte) w) != ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format) - { - ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format = (byte) w; - fax_info_change = TRUE; - } - - if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD)) - && (GET_WORD(&ncpi->info[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */ - { - plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD); - } - if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD)) - && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */ - { - plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD); - } - fax_control_bits &= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_SEL_POLLING | - T30_CONTROL_BIT_ACCEPT_PASSWORD); - if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1]) - & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) - { - if (api_parse (&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms)) - Info = _WRONG_MESSAGE_FORMAT; - else - { - if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1]) - & (1L << PRIVATE_FAX_SUB_SEP_PWD)) - { - fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD; - if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING) - fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; - } - w = fax_parms[4].length; - if (w > 20) - w = 20; - ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = (byte) w; - for (i = 0; i < w; i++) - ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i]; - ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; - len = (byte)(((T30_INFO *) 0)->station_id + 20); - w = fax_parms[5].length; - if (w > 20) - w = 20; - plci->fax_connect_info_buffer[len++] = (byte) w; - for (i = 0; i < w; i++) - plci->fax_connect_info_buffer[len++] = fax_parms[5].info[1+i]; - w = fax_parms[6].length; - if (w > 20) - w = 20; - plci->fax_connect_info_buffer[len++] = (byte) w; - for (i = 0; i < w; i++) - plci->fax_connect_info_buffer[len++] = fax_parms[6].info[1+i]; - if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1]) - & (1L << PRIVATE_FAX_NONSTANDARD)) - { - if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) - { - dbug(1,dprintf("non-standard facilities info missing or wrong format")); - plci->fax_connect_info_buffer[len++] = 0; - } - else - { - if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) - plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); - plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); - for (i = 0; i < fax_parms[7].length; i++) - plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i]; - } - } - } - } - else - { - len = (byte)(&(((T30_INFO *) 0)->universal_6)); - } - fax_info_change = TRUE; - - } - if (fax_control_bits != GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low)) - { - PUT_WORD (&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits); - fax_info_change = TRUE; - } - } - if (Info == GOOD) - { - plci->fax_connect_info_length = len; - if (fax_info_change) - { - if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS) - { - start_internal_command (Id, plci, fax_connect_info_command); - return FALSE; - } - else - { - start_internal_command (Id, plci, fax_adjust_b23_command); - return FALSE; - } - } - } - } - else Info = _WRONG_STATE; - } - else Info = _WRONG_STATE; - } - - else if (plci->B3_prot == B3_RTP) - { - plci->internal_req_buffer[0] = ncpi->length + 1; - plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE; - for (w = 0; w < ncpi->length; w++) - plci->internal_req_buffer[2+w] = ncpi->info[1+w]; - start_internal_command (Id, plci, rtp_connect_b3_req_command); - return FALSE; - } - - if(!Info) - { - nl_req_ncci(plci,req,0); - return 1; - } - } - } - else Info = _WRONG_IDENTIFIER; - - sendf(appl, - _CONNECT_B3_R|CONFIRM, - Id, - Number, - "w",Info); - return FALSE; -} - -byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word ncci; - API_PARSE * ncpi; - byte req; - - word w; - - - API_PARSE fax_parms[9]; - word i; - byte len; - - - dbug(1,dprintf("connect_b3_res")); - - ncci = (word)(Id>>16); - if(plci && ncci) { - if(a->ncci_state[ncci]==INC_CON_PENDING) { - if (GET_WORD (&parms[0].info[0]) != 0) - { - a->ncci_state[ncci] = OUTG_REJ_PENDING; - channel_request_xon (plci, a->ncci_ch[ncci]); - channel_xmit_xon (plci); - cleanup_ncci_data (plci, ncci); - nl_req_ncci(plci,N_DISC,(byte)ncci); - return 1; - } - a->ncci_state[ncci] = INC_ACT_PENDING; - - req = N_CONNECT_ACK; - ncpi = &parms[1]; - if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7)) - { - - if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) - & (1L << PRIVATE_FAX_NONSTANDARD)) - { - if (((plci->B3_prot == 4) || (plci->B3_prot == 5)) - && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) - && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) - { - len = ((byte)(((T30_INFO *) 0)->station_id + 20)); - if (plci->fax_connect_info_length < len) - { - ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; - ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; - } - if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) - { - dbug(1,dprintf("non-standard facilities info missing or wrong format")); - } - else - { - if (plci->fax_connect_info_length <= len) - plci->fax_connect_info_buffer[len] = 0; - len += 1 + plci->fax_connect_info_buffer[len]; - if (plci->fax_connect_info_length <= len) - plci->fax_connect_info_buffer[len] = 0; - len += 1 + plci->fax_connect_info_buffer[len]; - if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) - plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); - plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); - for (i = 0; i < fax_parms[7].length; i++) - plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i]; - } - plci->fax_connect_info_length = len; - ((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0; - start_internal_command (Id, plci, fax_connect_ack_command); - return FALSE; - } - } - - nl_req_ncci(plci,req,(byte)ncci); - if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) - { - if (plci->B3_prot == 4) - sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); - else - sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); - plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; - } - } - - else if (plci->B3_prot == B3_RTP) - { - plci->internal_req_buffer[0] = ncpi->length + 1; - plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE; - for (w = 0; w < ncpi->length; w++) - plci->internal_req_buffer[2+w] = ncpi->info[1+w]; - start_internal_command (Id, plci, rtp_connect_b3_res_command); - return FALSE; - } - - else - { - if(ncpi->length>2) { - if(ncpi->info[1] &1) req = N_CONNECT_ACK | N_D_BIT; - add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]); - } - nl_req_ncci(plci,req,(byte)ncci); - sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); - if (plci->adjust_b_restore) - { - plci->adjust_b_restore = FALSE; - start_internal_command (Id, plci, adjust_b_restore); - } - } - return 1; - } - } - return FALSE; -} - -byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word ncci; - - ncci = (word)(Id>>16); - dbug(1,dprintf("connect_b3_a_res(ncci=0x%x)",ncci)); - - if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING) - && (plci->State != OUTG_DIS_PENDING)) - { - if(a->ncci_state[ncci]==INC_ACT_PENDING) { - a->ncci_state[ncci] = CONNECTED; - if(plci->State!=INC_CON_CONNECTED_ALERT) plci->State = CONNECTED; - channel_request_xon (plci, a->ncci_ch[ncci]); - channel_xmit_xon (plci); - } - } - return FALSE; -} - -byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word Info; - word ncci; - API_PARSE * ncpi; - - dbug(1,dprintf("disconnect_b3_req")); - - Info = _WRONG_IDENTIFIER; - ncci = (word)(Id>>16); - if (plci && ncci) - { - Info = _WRONG_STATE; - if ((a->ncci_state[ncci] == CONNECTED) - || (a->ncci_state[ncci] == OUTG_CON_PENDING) - || (a->ncci_state[ncci] == INC_CON_PENDING) - || (a->ncci_state[ncci] == INC_ACT_PENDING)) - { - a->ncci_state[ncci] = OUTG_DIS_PENDING; - channel_request_xon (plci, a->ncci_ch[ncci]); - channel_xmit_xon (plci); - - if (a->ncci[ncci].data_pending - && ((plci->B3_prot == B3_TRANSPARENT) - || (plci->B3_prot == B3_T30) - || (plci->B3_prot == B3_T30_WITH_EXTENSIONS))) - { - plci->send_disc = (byte)ncci; - plci->command = 0; - return FALSE; - } - else - { - cleanup_ncci_data (plci, ncci); - - if(plci->B3_prot==2 || plci->B3_prot==3) - { - ncpi = &parms[0]; - if(ncpi->length>3) - { - add_d(plci, (word)(ncpi->length - 3) ,(byte *)&(ncpi->info[4])); - } - } - nl_req_ncci(plci,N_DISC,(byte)ncci); - } - return 1; - } - } - sendf(appl, - _DISCONNECT_B3_R|CONFIRM, - Id, - Number, - "w",Info); - return FALSE; -} - -byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word ncci; - word i; - - ncci = (word)(Id>>16); - dbug(1,dprintf("disconnect_b3_res(ncci=0x%x",ncci)); - if(plci && ncci) { - plci->requested_options_conn = 0; - plci->fax_connect_info_length = 0; - plci->ncpi_state = 0x00; - if (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)) - && ((plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL))) - { - plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; - } - for(i=0; i<MAX_CHANNELS_PER_PLCI && plci->inc_dis_ncci_table[i]!=(byte)ncci; i++); - if(i<MAX_CHANNELS_PER_PLCI) { - if(plci->channels)plci->channels--; - for(; i<MAX_CHANNELS_PER_PLCI-1; i++) plci->inc_dis_ncci_table[i] = plci->inc_dis_ncci_table[i+1]; - plci->inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI-1] = 0; - - ncci_free_receive_buffers (plci, ncci); - - if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){ - if(plci->State == SUSPENDING){ - sendf(plci->appl, - _FACILITY_I, - Id & 0xffffL, - 0, - "ws", (word)3, "\x03\x04\x00\x00"); - sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0); - } - plci_remove(plci); - plci->State=IDLE; - } - } - else - { - if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) - && ((plci->B3_prot == 4) || (plci->B3_prot == 5)) - && (a->ncci_state[ncci] == INC_DIS_PENDING)) - { - ncci_free_receive_buffers (plci, ncci); - - nl_req_ncci(plci,N_EDATA,(byte)ncci); - - plci->adapter->ncci_state[ncci] = IDLE; - start_internal_command (Id, plci, fax_disconnect_command); - return 1; - } - } - } - return FALSE; -} - -byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - NCCI *ncci_ptr; - DATA_B3_DESC *data; - word Info; - word ncci; - word i; - - dbug(1,dprintf("data_b3_req")); - - Info = _WRONG_IDENTIFIER; - ncci = (word)(Id>>16); - dbug(1,dprintf("ncci=0x%x, plci=0x%x",ncci,plci)); - - if (plci && ncci) - { - Info = _WRONG_STATE; - if ((a->ncci_state[ncci] == CONNECTED) - || (a->ncci_state[ncci] == INC_ACT_PENDING)) - { - /* queue data */ - ncci_ptr = &(a->ncci[ncci]); - i = ncci_ptr->data_out + ncci_ptr->data_pending; - if (i >= MAX_DATA_B3) - i -= MAX_DATA_B3; - data = &(ncci_ptr->DBuffer[i]); - data->Number = Number; - if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue))) - && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) - { - - data->P = (byte *)(*((dword *)(parms[0].info))); - - } - else - data->P = TransmitBufferSet(appl,*(dword *)parms[0].info); - data->Length = GET_WORD(parms[1].info); - data->Handle = GET_WORD(parms[2].info); - data->Flags = GET_WORD(parms[3].info); - (ncci_ptr->data_pending)++; - - /* check for delivery confirmation */ - if (data->Flags & 0x0004) - { - i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending; - if (i >= MAX_DATA_ACK) - i -= MAX_DATA_ACK; - ncci_ptr->DataAck[i].Number = data->Number; - ncci_ptr->DataAck[i].Handle = data->Handle; - (ncci_ptr->data_ack_pending)++; - } - - send_data(plci); - return FALSE; - } - } - if (appl) - { - if (plci) - { - if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue))) - && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) - { - - TransmitBufferFree (appl, (byte *)(*((dword *)(parms[0].info)))); - - } - } - sendf(appl, - _DATA_B3_R|CONFIRM, - Id, - Number, - "ww",GET_WORD(parms[2].info),Info); - } - return FALSE; -} - -byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word n; - word ncci; - word NCCIcode; - - dbug(1,dprintf("data_b3_res")); - - ncci = (word)(Id>>16); - if(plci && ncci) { - n = GET_WORD(parms[0].info); - dbug(1,dprintf("free(%d)",n)); - NCCIcode = ncci | (((word) a->Id) << 8); - if(n<appl->MaxBuffer && - appl->DataNCCI[n]==NCCIcode && - (byte)(appl->DataFlags[n]>>8)==plci->Id) { - dbug(1,dprintf("found")); - appl->DataNCCI[n] = 0; - - if (channel_can_xon (plci, a->ncci_ch[ncci])) { - channel_request_xon (plci, a->ncci_ch[ncci]); - } - channel_xmit_xon (plci); - - if(appl->DataFlags[n] &4) { - nl_req_ncci(plci,N_DATA_ACK,(byte)ncci); - return 1; - } - } - } - return FALSE; -} - -byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word Info; - word ncci; - - dbug(1,dprintf("reset_b3_req")); - - Info = _WRONG_IDENTIFIER; - ncci = (word)(Id>>16); - if(plci && ncci) - { - Info = _WRONG_STATE; - switch (plci->B3_prot) - { - case B3_ISO8208: - case B3_X25_DCE: - if(a->ncci_state[ncci]==CONNECTED) - { - nl_req_ncci(plci,N_RESET,(byte)ncci); - send_req(plci); - Info = GOOD; - } - break; - case B3_TRANSPARENT: - if(a->ncci_state[ncci]==CONNECTED) - { - start_internal_command (Id, plci, reset_b3_command); - Info = GOOD; - } - break; - } - } - /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */ - sendf(appl, - _RESET_B3_R|CONFIRM, - Id, - Number, - "w",Info); - return FALSE; -} - -byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word ncci; - - dbug(1,dprintf("reset_b3_res")); - - ncci = (word)(Id>>16); - if(plci && ncci) { - switch (plci->B3_prot) - { - case B3_ISO8208: - case B3_X25_DCE: - if(a->ncci_state[ncci]==INC_RES_PENDING) - { - a->ncci_state[ncci] = CONNECTED; - nl_req_ncci(plci,N_RESET_ACK,(byte)ncci); - return TRUE; - } - break; - } - } - return FALSE; -} - -byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word ncci; - API_PARSE * ncpi; - byte req; - - dbug(1,dprintf("connect_b3_t90_a_res")); - - ncci = (word)(Id>>16); - if(plci && ncci) { - if(a->ncci_state[ncci]==INC_ACT_PENDING) { - a->ncci_state[ncci] = CONNECTED; - } - else if(a->ncci_state[ncci]==INC_CON_PENDING) { - a->ncci_state[ncci] = CONNECTED; - - req = N_CONNECT_ACK; - - /* parms[0]==0 for CAPI original message definition! */ - if(parms[0].info) { - ncpi = &parms[1]; - if(ncpi->length>2) { - if(ncpi->info[1] &1) req = N_CONNECT_ACK | N_D_BIT; - add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]); - } - } - nl_req_ncci(plci,req,(byte)ncci); - return 1; - } - } - return FALSE; -} - - -byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - word Info=0; - word i; - byte tel; - API_PARSE bp_parms[7]; - - if(!plci || !msg) - { - Info = _WRONG_IDENTIFIER; - } - else - { - dbug(1,dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x", - msg->length,plci->Id,plci->tel,plci->NL.Id,plci->appl,plci->SuppState)); - dbug(1,dprintf("PlciState=0x%x",plci->State)); - for(i=0;i<7;i++) bp_parms[i].length = 0; - - /* check if no channel is open, no B3 connected only */ - if((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) || (plci->State == INC_DIS_PENDING) - || (plci->SuppState != IDLE) || plci->channels || plci->nl_remove_id) - { - Info = _WRONG_STATE; - } - /* check message format and fill bp_parms pointer */ - else if(msg->length && api_parse(&msg->info[1], (word)msg->length, "wwwsss", bp_parms)) - { - Info = _WRONG_MESSAGE_FORMAT; - } - else - { - if((plci->State==INC_CON_PENDING) || (plci->State==INC_CON_ALERT)) /* send alert tone inband to the network, */ - { /* e.g. Qsig or RBS or Cornet-N or xess PRI */ - if(Id & EXT_CONTROLLER) - { - sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */ - return 0; - } - plci->State=INC_CON_CONNECTED_ALERT; - plci->appl = appl; - clear_c_ind_mask_bit (plci, (word)(appl->Id-1)); - dump_c_ind_mask (plci); - for(i=0; i<max_appl; i++) /* disconnect the other appls */ - { /* its quasi a connect */ - if(test_c_ind_mask_bit (plci, i)) - sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); - } - } - - api_save_msg(msg, "s", &plci->saved_msg); - tel = plci->tel; - if(Id & EXT_CONTROLLER) - { - if(tel) /* external controller in use by this PLCI */ - { - if(a->AdvSignalAppl && a->AdvSignalAppl!=appl) - { - dbug(1,dprintf("Ext_Ctrl in use 1")); - Info = _WRONG_STATE; - } - } - else /* external controller NOT in use by this PLCI ? */ - { - if(a->AdvSignalPLCI) - { - dbug(1,dprintf("Ext_Ctrl in use 2")); - Info = _WRONG_STATE; - } - else /* activate the codec */ - { - dbug(1,dprintf("Ext_Ctrl start")); - if(AdvCodecSupport(a, plci, appl, 0) ) - { - dbug(1,dprintf("Error in codec procedures")); - Info = _WRONG_STATE; - } - else if(plci->spoofed_msg==SPOOFING_REQUIRED) /* wait until codec is active */ - { - plci->spoofed_msg = AWAITING_SELECT_B; - plci->internal_command = BLOCK_PLCI; /* lock other commands */ - plci->command = 0; - dbug(1,dprintf("continue if codec loaded")); - return FALSE; - } - } - } - } - else /* external controller bit is OFF */ - { - if(tel) /* external controller in use, need to switch off */ - { - if(a->AdvSignalAppl==appl) - { - CodecIdCheck(a, plci); - plci->tel = 0; - plci->adv_nl = 0; - dbug(1,dprintf("Ext_Ctrl disable")); - } - else - { - dbug(1,dprintf("Ext_Ctrl not requested")); - } - } - } - if (!Info) - { - if (plci->call_dir & CALL_DIR_OUT) - plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; - else if (plci->call_dir & CALL_DIR_IN) - plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER; - start_internal_command (Id, plci, select_b_command); - return FALSE; - } - } - } - sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", Info); - return FALSE; -} - -byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms) -{ - word command; - word i; - word ncci; - API_PARSE * m; - API_PARSE m_parms[5]; - word codec; - byte req; - byte ch; - byte dir; - static byte chi[2] = {0x01,0x00}; - static byte lli[2] = {0x01,0x00}; - static byte codec_cai[2] = {0x01,0x01}; - static byte null_msg = {0}; - static API_PARSE null_parms = { 0, &null_msg }; - PLCI * v_plci; - word Info=0; - - dbug(1,dprintf("manufacturer_req")); - for(i=0;i<5;i++) m_parms[i].length = 0; - - if(GET_DWORD(parms[0].info)!=_DI_MANU_ID) { - Info = _WRONG_MESSAGE_FORMAT; - } - command = GET_WORD(parms[1].info); - m = &parms[2]; - if (!Info) - { - switch(command) { - case _DI_ASSIGN_PLCI: - if(api_parse(&m->info[1],(word)m->length,"wbbs",m_parms)) { - Info = _WRONG_MESSAGE_FORMAT; - break; - } - codec = GET_WORD(m_parms[0].info); - ch = m_parms[1].info[0]; - dir = m_parms[2].info[0]; - if((i=get_plci(a))) { - plci = &a->plci[i-1]; - plci->appl = appl; - plci->command = _MANUFACTURER_R; - plci->m_command = command; - plci->number = Number; - plci->State = LOCAL_CONNECT; - Id = ( ((word)plci->Id<<8)|plci->adapter->Id|0x80); - dbug(1,dprintf("ManCMD,plci=0x%x",Id)); - - if((ch==1 || ch==2) && (dir<=2)) { - chi[1] = (byte)(0x80|ch); - lli[1] = 0; - plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; - switch(codec) - { - case 0: - Info = add_b1(plci,&m_parms[3],0,0); - break; - case 1: - add_p(plci,CAI,codec_cai); - break; - /* manual 'swich on' to the codec support without signalling */ - /* first 'assign plci' with this function, then use */ - case 2: - if(AdvCodecSupport(a, plci, appl, 0) ) { - Info = _RESOURCE_ERROR; - } - else { - Info = add_b1(plci,&null_parms,0,B1_FACILITY_LOCAL); - lli[1] = 0x10; /* local call codec stream */ - } - break; - } - - plci->State = LOCAL_CONNECT; - plci->manufacturer = TRUE; - plci->command = _MANUFACTURER_R; - plci->m_command = command; - plci->number = Number; - - if(!Info) - { - add_p(plci,LLI,lli); - add_p(plci,CHI,chi); - add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(plci,ASSIGN,DSIG_ID); - - if(!codec) - { - Info = add_b23(plci,&m_parms[3]); - if(!Info) - { - nl_req_ncci(plci,ASSIGN,0); - send_req(plci); - } - } - if(!Info) - { - dbug(1,dprintf("dir=0x%x,spoof=0x%x",dir,plci->spoofed_msg)); - if (plci->spoofed_msg==SPOOFING_REQUIRED) - { - api_save_msg (m_parms, "wbbs", &plci->saved_msg); - plci->spoofed_msg = AWAITING_MANUF_CON; - plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */ - plci->command = 0; - send_req(plci); - return FALSE; - } - if(dir==1) { - sig_req(plci,CALL_REQ,0); - } - else if(!dir){ - sig_req(plci,LISTEN_REQ,0); - } - send_req(plci); - } - else - { - sendf(appl, - _MANUFACTURER_R|CONFIRM, - Id, - Number, - "dww",_DI_MANU_ID,command,Info); - return 2; - } - } - } - } - else Info = _OUT_OF_PLCI; - break; - - case _DI_IDI_CTRL: - if(!plci) - { - Info = _WRONG_IDENTIFIER; - break; - } - if(api_parse(&m->info[1],(word)m->length,"bs",m_parms)) { - Info = _WRONG_MESSAGE_FORMAT; - break; - } - req = m_parms[0].info[0]; - plci->command = _MANUFACTURER_R; - plci->m_command = command; - plci->number = Number; - if(req==CALL_REQ) - { - plci->b_channel = getChannel(&m_parms[1]); - mixer_set_bchannel_id_esc (plci, plci->b_channel); - if(plci->spoofed_msg==SPOOFING_REQUIRED) - { - plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON; - plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */ - plci->command = 0; - break; - } - } - else if(req==LAW_REQ) - { - plci->cr_enquiry = TRUE; - } - add_ss(plci,FTY,&m_parms[1]); - sig_req(plci,req,0); - send_req(plci); - if(req==HANGUP) - { - if (plci->NL.Id && !plci->nl_remove_id) - { - if (plci->channels) - { - for (ncci = 1; ncci < MAX_NCCI+1; ncci++) - { - if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED)) - { - a->ncci_state[ncci] = OUTG_DIS_PENDING; - cleanup_ncci_data (plci, ncci); - nl_req_ncci(plci,N_DISC,(byte)ncci); - } - } - } - mixer_remove (plci); - nl_req_ncci(plci,REMOVE,0); - send_req(plci); - } - } - break; - - case _DI_SIG_CTRL: - /* signalling control for loop activation B-channel */ - if(!plci) - { - Info = _WRONG_IDENTIFIER; - break; - } - if(m->length){ - plci->command = _MANUFACTURER_R; - plci->number = Number; - add_ss(plci,FTY,m); - sig_req(plci,SIG_CTRL,0); - send_req(plci); - } - else Info = _WRONG_MESSAGE_FORMAT; - break; - - case _DI_RXT_CTRL: - /* activation control for receiver/transmitter B-channel */ - if(!plci) - { - Info = _WRONG_IDENTIFIER; - break; - } - if(m->length){ - plci->command = _MANUFACTURER_R; - plci->number = Number; - add_ss(plci,FTY,m); - sig_req(plci,DSP_CTRL,0); - send_req(plci); - } - else Info = _WRONG_MESSAGE_FORMAT; - break; - - case _DI_ADV_CODEC: - case _DI_DSP_CTRL: - /* TEL_CTRL commands to support non standard adjustments: */ - /* Ring on/off, Handset micro volume, external micro vol. */ - /* handset+external speaker volume, receiver+transm. gain,*/ - /* handsfree on (hookinfo off), set mixer command */ - - if(command == _DI_ADV_CODEC) - { - if(!a->AdvCodecPLCI) { - Info = _WRONG_STATE; - break; - } - v_plci = a->AdvCodecPLCI; - } - else - { - if (plci - && (m->length >= 3) - && (m->info[1] == 0x1c) - && (m->info[2] >= 1)) - { - if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS) - { - if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI)) - { - Info = _WRONG_STATE; - break; - } - a->adv_voice_coef_length = m->info[2] - 1; - if (a->adv_voice_coef_length > m->length - 3) - a->adv_voice_coef_length = (byte)(m->length - 3); - if (a->adv_voice_coef_length > ADV_VOICE_COEF_BUFFER_SIZE) - a->adv_voice_coef_length = ADV_VOICE_COEF_BUFFER_SIZE; - for (i = 0; i < a->adv_voice_coef_length; i++) - a->adv_voice_coef_buffer[i] = m->info[4 + i]; - if (plci->B1_facilities & B1_FACILITY_VOICE) - adv_voice_write_coefs (plci, ADV_VOICE_WRITE_UPDATE); - break; - } - else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS) - { - if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS)) - { - Info = _FACILITY_NOT_SUPPORTED; - break; - } - - plci->dtmf_parameter_length = m->info[2] - 1; - if (plci->dtmf_parameter_length > m->length - 3) - plci->dtmf_parameter_length = (byte)(m->length - 3); - if (plci->dtmf_parameter_length > DTMF_PARAMETER_BUFFER_SIZE) - plci->dtmf_parameter_length = DTMF_PARAMETER_BUFFER_SIZE; - for (i = 0; i < plci->dtmf_parameter_length; i++) - plci->dtmf_parameter_buffer[i] = m->info[4+i]; - if (plci->B1_facilities & B1_FACILITY_DTMFR) - dtmf_parameter_write (plci); - break; - - } - } - v_plci = plci; - } - - if(!v_plci) - { - Info = _WRONG_IDENTIFIER; - break; - } - if(m->length){ - add_ss(v_plci,FTY,m); - sig_req(v_plci,TEL_CTRL,0); - send_req(v_plci); - } - else Info = _WRONG_MESSAGE_FORMAT; - - break; - - case _DI_OPTIONS_REQUEST: - if(api_parse(&m->info[1],(word)m->length,"d",m_parms)) { - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if (GET_DWORD (m_parms[0].info) & ~a->man_profile.private_options) - { - Info = _FACILITY_NOT_SUPPORTED; - break; - } - a->requested_options_table[appl->Id-1] = GET_DWORD (m_parms[0].info); - break; - - - - default: - Info = _WRONG_MESSAGE_FORMAT; - break; - } - } - - sendf(appl, - _MANUFACTURER_R|CONFIRM, - Id, - Number, - "dww",_DI_MANU_ID,command,Info); - return FALSE; -} - - -byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg) -{ - word indication; - - API_PARSE m_parms[3]; - API_PARSE *ncpi; - API_PARSE fax_parms[9]; - word i; - byte len; - - - dbug(1,dprintf("manufacturer_res")); - - if ((msg[0].length == 0) - || (msg[1].length == 0) - || (GET_DWORD(msg[0].info)!=_DI_MANU_ID)) - { - return FALSE; - } - indication = GET_WORD(msg[1].info); - switch (indication) - { - - case _DI_NEGOTIATE_B3: - if(!plci) - break; - if (((plci->B3_prot != 4) && (plci->B3_prot != 5)) - || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT)) - { - dbug(1,dprintf("wrong state for NEGOTIATE_B3 parameters")); - break; - } - if (api_parse (&msg[2].info[1], msg[2].length, "ws", m_parms)) - { - dbug(1,dprintf("wrong format in NEGOTIATE_B3 parameters")); - break; - } - ncpi = &m_parms[1]; - len = ((byte)(((T30_INFO *) 0)->station_id + 20)); - if (plci->fax_connect_info_length < len) - { - ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; - ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; - } - if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) - { - dbug(1,dprintf("non-standard facilities info missing or wrong format")); - } - else - { - if (plci->fax_connect_info_length <= len) - plci->fax_connect_info_buffer[len] = 0; - len += 1 + plci->fax_connect_info_buffer[len]; - if (plci->fax_connect_info_length <= len) - plci->fax_connect_info_buffer[len] = 0; - len += 1 + plci->fax_connect_info_buffer[len]; - if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) - plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); - plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); - for (i = 0; i < fax_parms[7].length; i++) - plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i]; - } - plci->fax_connect_info_length = len; - plci->fax_edata_ack_length = plci->fax_connect_info_length; - start_internal_command (Id, plci, fax_edata_ack_command); - break; - - } - return FALSE; + /* send PTY/ECT req, cannot check all states because of US stuff */ + if (!rplci->internal_command && rplci->appl) + { + plci->command = 0; + rplci->relatedPTYPLCI = plci; + plci->relatedPTYPLCI = rplci; + rplci->ptyState = (byte)SSreq; + if (SSreq == S_ECT) + { + rplci->internal_command = ECT_REQ_PEND; + cai[1] = ECT_EXECUTE; + + rplci->vswitchstate = 0; + rplci->vsprot = 0; + rplci->vsprotdialect = 0; + plci->vswitchstate = 0; + plci->vsprot = 0; + plci->vsprotdialect = 0; + + } + else if (SSreq == S_CONF_ADD) + { + rplci->internal_command = CONF_ADD_REQ_PEND; + cai[1] = CONF_ADD; + } + else + { + rplci->internal_command = PTY_REQ_PEND; + cai[1] = (byte)(SSreq - 3); + } + rplci->number = Number; + if (plci != rplci) /* explicit invocation */ + { + cai[0] = 2; + cai[2] = plci->Sig.Id; + dbug(1, dprintf("explicit invocation")); + } + else + { + dbug(1, dprintf("implicit invocation")); + cai[0] = 1; + } + add_p(rplci, CAI, cai); + sig_req(rplci, S_SERVICE, 0); + send_req(rplci); + return false; + } + else + { + dbug(0, dprintf("Wrong line")); + Info = 0x3010; /* wrong state */ + break; + } + break; + + case S_CALL_DEFLECTION: + if (api_parse(&parms->info[1], (word)parms->length, "wbwss", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (!plci) + { + Info = _WRONG_IDENTIFIER; + break; + } + /* reuse unused screening indicator */ + ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0])); + plci->command = 0; + plci->internal_command = CD_REQ_PEND; + appl->CDEnable = true; + cai[0] = 1; + cai[1] = CALL_DEFLECTION; + add_p(plci, CAI, cai); + add_p(plci, CPN, ss_parms[3].info); + sig_req(plci, S_SERVICE, 0); + send_req(plci); + return false; + break; + + case S_CALL_FORWARDING_START: + if (api_parse(&parms->info[1], (word)parms->length, "wbdwwsss", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + + if ((i = get_plci(a))) + { + rplci = &a->plci[i - 1]; + rplci->appl = appl; + add_p(rplci, CAI, "\x01\x80"); + add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rplci, ASSIGN, DSIG_ID); + send_req(rplci); + } + else + { + Info = _OUT_OF_PLCI; + break; + } + + /* reuse unused screening indicator */ + rplci->internal_command = CF_START_PEND; + rplci->appl = appl; + rplci->number = Number; + appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0])); + cai[0] = 2; + cai[1] = 0x70 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ + cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */ + add_p(rplci, CAI, cai); + add_p(rplci, OAD, ss_parms[5].info); + add_p(rplci, CPN, ss_parms[6].info); + sig_req(rplci, S_SERVICE, 0); + send_req(rplci); + return false; + break; + + case S_INTERROGATE_DIVERSION: + case S_INTERROGATE_NUMBERS: + case S_CALL_FORWARDING_STOP: + case S_CCBS_REQUEST: + case S_CCBS_DEACTIVATE: + case S_CCBS_INTERROGATE: + switch (SSreq) + { + case S_INTERROGATE_NUMBERS: + if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms)) + { + dbug(0, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + } + break; + case S_CCBS_REQUEST: + case S_CCBS_DEACTIVATE: + if (api_parse(&parms->info[1], (word)parms->length, "wbdw", ss_parms)) + { + dbug(0, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + } + break; + case S_CCBS_INTERROGATE: + if (api_parse(&parms->info[1], (word)parms->length, "wbdws", ss_parms)) + { + dbug(0, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + } + break; + default: + if (api_parse(&parms->info[1], (word)parms->length, "wbdwws", ss_parms)) + { + dbug(0, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + break; + } + + if (Info) break; + if ((i = get_plci(a))) + { + rplci = &a->plci[i - 1]; + switch (SSreq) + { + case S_INTERROGATE_DIVERSION: /* use cai with S_SERVICE below */ + cai[1] = 0x60 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ + rplci->internal_command = INTERR_DIVERSION_REQ_PEND; /* move to rplci if assigned */ + break; + case S_INTERROGATE_NUMBERS: /* use cai with S_SERVICE below */ + cai[1] = DIVERSION_INTERROGATE_NUM; /* Function */ + rplci->internal_command = INTERR_NUMBERS_REQ_PEND; /* move to rplci if assigned */ + break; + case S_CALL_FORWARDING_STOP: + rplci->internal_command = CF_STOP_PEND; + cai[1] = 0x80 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */ + break; + case S_CCBS_REQUEST: + cai[1] = CCBS_REQUEST; + rplci->internal_command = CCBS_REQUEST_REQ_PEND; + break; + case S_CCBS_DEACTIVATE: + cai[1] = CCBS_DEACTIVATE; + rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND; + break; + case S_CCBS_INTERROGATE: + cai[1] = CCBS_INTERROGATE; + rplci->internal_command = CCBS_INTERROGATE_REQ_PEND; + break; + default: + cai[1] = 0; + break; + } + rplci->appl = appl; + rplci->number = Number; + add_p(rplci, CAI, "\x01\x80"); + add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rplci, ASSIGN, DSIG_ID); + send_req(rplci); + } + else + { + Info = _OUT_OF_PLCI; + break; + } + + appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0])); + switch (SSreq) + { + case S_INTERROGATE_NUMBERS: + cai[0] = 1; + add_p(rplci, CAI, cai); + break; + case S_CCBS_REQUEST: + case S_CCBS_DEACTIVATE: + cai[0] = 3; + PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0]))); + add_p(rplci, CAI, cai); + break; + case S_CCBS_INTERROGATE: + cai[0] = 3; + PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0]))); + add_p(rplci, CAI, cai); + add_p(rplci, OAD, ss_parms[4].info); + break; + default: + cai[0] = 2; + cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */ + add_p(rplci, CAI, cai); + add_p(rplci, OAD, ss_parms[5].info); + break; + } + + sig_req(rplci, S_SERVICE, 0); + send_req(rplci); + return false; + break; + + case S_MWI_ACTIVATE: + if (api_parse(&parms->info[1], (word)parms->length, "wbwdwwwssss", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (!plci) + { + if ((i = get_plci(a))) + { + rplci = &a->plci[i - 1]; + rplci->appl = appl; + rplci->cr_enquiry = true; + add_p(rplci, CAI, "\x01\x80"); + add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rplci, ASSIGN, DSIG_ID); + send_req(rplci); + } + else + { + Info = _OUT_OF_PLCI; + break; + } + } + else + { + rplci = plci; + rplci->cr_enquiry = false; + } + + rplci->command = 0; + rplci->internal_command = MWI_ACTIVATE_REQ_PEND; + rplci->appl = appl; + rplci->number = Number; + + cai[0] = 13; + cai[1] = ACTIVATION_MWI; /* Function */ + PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */ + PUT_DWORD(&cai[4], GET_DWORD(&(ss_parms[3].info[0]))); /* Number of Messages */ + PUT_WORD(&cai[8], GET_WORD(&(ss_parms[4].info[0]))); /* Message Status */ + PUT_WORD(&cai[10], GET_WORD(&(ss_parms[5].info[0]))); /* Message Reference */ + PUT_WORD(&cai[12], GET_WORD(&(ss_parms[6].info[0]))); /* Invocation Mode */ + add_p(rplci, CAI, cai); + add_p(rplci, CPN, ss_parms[7].info); /* Receiving User Number */ + add_p(rplci, OAD, ss_parms[8].info); /* Controlling User Number */ + add_p(rplci, OSA, ss_parms[9].info); /* Controlling User Provided Number */ + add_p(rplci, UID, ss_parms[10].info); /* Time */ + sig_req(rplci, S_SERVICE, 0); + send_req(rplci); + return false; + + case S_MWI_DEACTIVATE: + if (api_parse(&parms->info[1], (word)parms->length, "wbwwss", ss_parms)) + { + dbug(1, dprintf("format wrong")); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (!plci) + { + if ((i = get_plci(a))) + { + rplci = &a->plci[i - 1]; + rplci->appl = appl; + rplci->cr_enquiry = true; + add_p(rplci, CAI, "\x01\x80"); + add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(rplci, ASSIGN, DSIG_ID); + send_req(rplci); + } + else + { + Info = _OUT_OF_PLCI; + break; + } + } + else + { + rplci = plci; + rplci->cr_enquiry = false; + } + + rplci->command = 0; + rplci->internal_command = MWI_DEACTIVATE_REQ_PEND; + rplci->appl = appl; + rplci->number = Number; + + cai[0] = 5; + cai[1] = DEACTIVATION_MWI; /* Function */ + PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */ + PUT_WORD(&cai[4], GET_WORD(&(ss_parms[3].info[0]))); /* Invocation Mode */ + add_p(rplci, CAI, cai); + add_p(rplci, CPN, ss_parms[4].info); /* Receiving User Number */ + add_p(rplci, OAD, ss_parms[5].info); /* Controlling User Number */ + sig_req(rplci, S_SERVICE, 0); + send_req(rplci); + return false; + + default: + Info = 0x300E; /* not supported */ + break; + } + break; /* case SELECTOR_SU_SERV: end */ + + + case SELECTOR_DTMF: + return (dtmf_request(Id, Number, a, plci, appl, msg)); + + + + case SELECTOR_LINE_INTERCONNECT: + return (mixer_request(Id, Number, a, plci, appl, msg)); + + + + case PRIV_SELECTOR_ECHO_CANCELLER: + appl->appl_flags |= APPL_FLAG_PRIV_EC_SPEC; + return (ec_request(Id, Number, a, plci, appl, msg)); + + case SELECTOR_ECHO_CANCELLER: + appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC; + return (ec_request(Id, Number, a, plci, appl, msg)); + + + case SELECTOR_V42BIS: + default: + Info = _FACILITY_NOT_SUPPORTED; + break; + } /* end of switch (selector) */ + } + + dbug(1, dprintf("SendFacRc")); + sendf(appl, + _FACILITY_R | CONFIRM, + Id, + Number, + "wws", Info, selector, SSparms); + return false; +} + +static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + dbug(1, dprintf("facility_res")); + return false; +} + +static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word Info = 0; + byte req; + byte len; + word w; + word fax_control_bits, fax_feature_bits, fax_info_change; + API_PARSE *ncpi; + byte pvc[2]; + + API_PARSE fax_parms[9]; + word i; + + + dbug(1, dprintf("connect_b3_req")); + if (plci) + { + if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) + || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE)) + { + Info = _WRONG_STATE; + } + else + { + /* local reply if assign unsuccessful + or B3 protocol allows only one layer 3 connection + and already connected + or B2 protocol not any LAPD + and connect_b3_req contradicts originate/answer direction */ + if (!plci->NL.Id + || (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)) + && ((plci->channels != 0) + || (((plci->B2_prot != B2_SDLC) && (plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL)) + && ((plci->call_dir & CALL_DIR_ANSWER) && !(plci->call_dir & CALL_DIR_FORCE_OUTG_NL)))))) + { + dbug(1, dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x", + plci->channels, plci->NL.Id, plci->call_dir, plci->SuppState)); + Info = _WRONG_STATE; + sendf(appl, + _CONNECT_B3_R | CONFIRM, + Id, + Number, + "w", Info); + return false; + } + plci->requested_options_conn = 0; + + req = N_CONNECT; + ncpi = &parms[0]; + if (plci->B3_prot == 2 || plci->B3_prot == 3) + { + if (ncpi->length > 2) + { + /* check for PVC */ + if (ncpi->info[2] || ncpi->info[3]) + { + pvc[0] = ncpi->info[3]; + pvc[1] = ncpi->info[2]; + add_d(plci, 2, pvc); + req = N_RESET; + } + else + { + if (ncpi->info[1] & 1) req = N_CONNECT | N_D_BIT; + add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]); + } + } + } + else if (plci->B3_prot == 5) + { + if (plci->NL.Id && !plci->nl_remove_id) + { + fax_control_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low); + fax_feature_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low); + if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS) + || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)) + { + len = offsetof(T30_INFO, universal_6); + fax_info_change = false; + if (ncpi->length >= 4) + { + w = GET_WORD(&ncpi->info[3]); + if ((w & 0x0001) != ((word)(((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & 0x0001))) + { + ((T30_INFO *)(plci->fax_connect_info_buffer))->resolution = + (byte)((((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) | + ((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0)); + fax_info_change = true; + } + fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS); + if (w & 0x0002) /* Fax-polling request */ + fax_control_bits |= T30_CONTROL_BIT_REQUEST_POLLING; + if ((w & 0x0004) /* Request to send / poll another document */ + && (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS)) + { + fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS; + } + if (ncpi->length >= 6) + { + w = GET_WORD(&ncpi->info[5]); + if (((byte) w) != ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format) + { + ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format = (byte) w; + fax_info_change = true; + } + + if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD)) + && (GET_WORD(&ncpi->info[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */ + { + plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD); + } + if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD)) + && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */ + { + plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD); + } + fax_control_bits &= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_SEL_POLLING | + T30_CONTROL_BIT_ACCEPT_PASSWORD); + if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1]) + & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) + { + if (api_parse(&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms)) + Info = _WRONG_MESSAGE_FORMAT; + else + { + if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1]) + & (1L << PRIVATE_FAX_SUB_SEP_PWD)) + { + fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD; + if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING) + fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; + } + w = fax_parms[4].length; + if (w > 20) + w = 20; + ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = (byte) w; + for (i = 0; i < w; i++) + ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1 + i]; + ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + w = fax_parms[5].length; + if (w > 20) + w = 20; + plci->fax_connect_info_buffer[len++] = (byte) w; + for (i = 0; i < w; i++) + plci->fax_connect_info_buffer[len++] = fax_parms[5].info[1 + i]; + w = fax_parms[6].length; + if (w > 20) + w = 20; + plci->fax_connect_info_buffer[len++] = (byte) w; + for (i = 0; i < w; i++) + plci->fax_connect_info_buffer[len++] = fax_parms[6].info[1 + i]; + if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1]) + & (1L << PRIVATE_FAX_NONSTANDARD)) + { + if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) + { + dbug(1, dprintf("non-standard facilities info missing or wrong format")); + plci->fax_connect_info_buffer[len++] = 0; + } + else + { + if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) + plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); + plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); + for (i = 0; i < fax_parms[7].length; i++) + plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i]; + } + } + } + } + else + { + len = offsetof(T30_INFO, universal_6); + } + fax_info_change = true; + + } + if (fax_control_bits != GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low)) + { + PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits); + fax_info_change = true; + } + } + if (Info == GOOD) + { + plci->fax_connect_info_length = len; + if (fax_info_change) + { + if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS) + { + start_internal_command(Id, plci, fax_connect_info_command); + return false; + } + else + { + start_internal_command(Id, plci, fax_adjust_b23_command); + return false; + } + } + } + } + else Info = _WRONG_STATE; + } + else Info = _WRONG_STATE; + } + + else if (plci->B3_prot == B3_RTP) + { + plci->internal_req_buffer[0] = ncpi->length + 1; + plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE; + for (w = 0; w < ncpi->length; w++) + plci->internal_req_buffer[2 + w] = ncpi->info[1 + w]; + start_internal_command(Id, plci, rtp_connect_b3_req_command); + return false; + } + + if (!Info) + { + nl_req_ncci(plci, req, 0); + return 1; + } + } + } + else Info = _WRONG_IDENTIFIER; + + sendf(appl, + _CONNECT_B3_R | CONFIRM, + Id, + Number, + "w", Info); + return false; +} + +static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word ncci; + API_PARSE *ncpi; + byte req; + + word w; + + + API_PARSE fax_parms[9]; + word i; + byte len; + + + dbug(1, dprintf("connect_b3_res")); + + ncci = (word)(Id >> 16); + if (plci && ncci) { + if (a->ncci_state[ncci] == INC_CON_PENDING) { + if (GET_WORD(&parms[0].info[0]) != 0) + { + a->ncci_state[ncci] = OUTG_REJ_PENDING; + channel_request_xon(plci, a->ncci_ch[ncci]); + channel_xmit_xon(plci); + cleanup_ncci_data(plci, ncci); + nl_req_ncci(plci, N_DISC, (byte)ncci); + return 1; + } + a->ncci_state[ncci] = INC_ACT_PENDING; + + req = N_CONNECT_ACK; + ncpi = &parms[1]; + if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7)) + { + + if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1]) + & (1L << PRIVATE_FAX_NONSTANDARD)) + { + if (((plci->B3_prot == 4) || (plci->B3_prot == 5)) + && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) + && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) + { + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + if (plci->fax_connect_info_length < len) + { + ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; + ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; + } + if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) + { + dbug(1, dprintf("non-standard facilities info missing or wrong format")); + } + else + { + if (plci->fax_connect_info_length <= len) + plci->fax_connect_info_buffer[len] = 0; + len += 1 + plci->fax_connect_info_buffer[len]; + if (plci->fax_connect_info_length <= len) + plci->fax_connect_info_buffer[len] = 0; + len += 1 + plci->fax_connect_info_buffer[len]; + if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) + plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); + plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); + for (i = 0; i < fax_parms[7].length; i++) + plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i]; + } + plci->fax_connect_info_length = len; + ((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0; + start_internal_command(Id, plci, fax_connect_ack_command); + return false; + } + } + + nl_req_ncci(plci, req, (byte)ncci); + if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) + { + if (plci->B3_prot == 4) + sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + else + sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer); + plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; + } + } + + else if (plci->B3_prot == B3_RTP) + { + plci->internal_req_buffer[0] = ncpi->length + 1; + plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE; + for (w = 0; w < ncpi->length; w++) + plci->internal_req_buffer[2 + w] = ncpi->info[1+w]; + start_internal_command(Id, plci, rtp_connect_b3_res_command); + return false; + } + + else + { + if (ncpi->length > 2) { + if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT; + add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]); + } + nl_req_ncci(plci, req, (byte)ncci); + sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + if (plci->adjust_b_restore) + { + plci->adjust_b_restore = false; + start_internal_command(Id, plci, adjust_b_restore); + } + } + return 1; + } + } + return false; +} + +static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word ncci; + + ncci = (word)(Id >> 16); + dbug(1, dprintf("connect_b3_a_res(ncci=0x%x)", ncci)); + + if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING) + && (plci->State != OUTG_DIS_PENDING)) + { + if (a->ncci_state[ncci] == INC_ACT_PENDING) { + a->ncci_state[ncci] = CONNECTED; + if (plci->State != INC_CON_CONNECTED_ALERT) plci->State = CONNECTED; + channel_request_xon(plci, a->ncci_ch[ncci]); + channel_xmit_xon(plci); + } + } + return false; +} + +static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word Info; + word ncci; + API_PARSE *ncpi; + + dbug(1, dprintf("disconnect_b3_req")); + + Info = _WRONG_IDENTIFIER; + ncci = (word)(Id >> 16); + if (plci && ncci) + { + Info = _WRONG_STATE; + if ((a->ncci_state[ncci] == CONNECTED) + || (a->ncci_state[ncci] == OUTG_CON_PENDING) + || (a->ncci_state[ncci] == INC_CON_PENDING) + || (a->ncci_state[ncci] == INC_ACT_PENDING)) + { + a->ncci_state[ncci] = OUTG_DIS_PENDING; + channel_request_xon(plci, a->ncci_ch[ncci]); + channel_xmit_xon(plci); + + if (a->ncci[ncci].data_pending + && ((plci->B3_prot == B3_TRANSPARENT) + || (plci->B3_prot == B3_T30) + || (plci->B3_prot == B3_T30_WITH_EXTENSIONS))) + { + plci->send_disc = (byte)ncci; + plci->command = 0; + return false; + } + else + { + cleanup_ncci_data(plci, ncci); + + if (plci->B3_prot == 2 || plci->B3_prot == 3) + { + ncpi = &parms[0]; + if (ncpi->length > 3) + { + add_d(plci, (word)(ncpi->length - 3), (byte *)&(ncpi->info[4])); + } + } + nl_req_ncci(plci, N_DISC, (byte)ncci); + } + return 1; + } + } + sendf(appl, + _DISCONNECT_B3_R | CONFIRM, + Id, + Number, + "w", Info); + return false; +} + +static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word ncci; + word i; + + ncci = (word)(Id >> 16); + dbug(1, dprintf("disconnect_b3_res(ncci=0x%x", ncci)); + if (plci && ncci) { + plci->requested_options_conn = 0; + plci->fax_connect_info_length = 0; + plci->ncpi_state = 0x00; + if (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)) + && ((plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL))) + { + plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; + } + for (i = 0; i < MAX_CHANNELS_PER_PLCI && plci->inc_dis_ncci_table[i] != (byte)ncci; i++); + if (i < MAX_CHANNELS_PER_PLCI) { + if (plci->channels)plci->channels--; + for (; i < MAX_CHANNELS_PER_PLCI - 1; i++) plci->inc_dis_ncci_table[i] = plci->inc_dis_ncci_table[i + 1]; + plci->inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI - 1] = 0; + + ncci_free_receive_buffers(plci, ncci); + + if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) { + if (plci->State == SUSPENDING) { + sendf(plci->appl, + _FACILITY_I, + Id & 0xffffL, + 0, + "ws", (word)3, "\x03\x04\x00\x00"); + sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0); + } + plci_remove(plci); + plci->State = IDLE; + } + } + else + { + if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) + && ((plci->B3_prot == 4) || (plci->B3_prot == 5)) + && (a->ncci_state[ncci] == INC_DIS_PENDING)) + { + ncci_free_receive_buffers(plci, ncci); + + nl_req_ncci(plci, N_EDATA, (byte)ncci); + + plci->adapter->ncci_state[ncci] = IDLE; + start_internal_command(Id, plci, fax_disconnect_command); + return 1; + } + } + } + return false; +} + +static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + NCCI *ncci_ptr; + DATA_B3_DESC *data; + word Info; + word ncci; + word i; + + dbug(1, dprintf("data_b3_req")); + + Info = _WRONG_IDENTIFIER; + ncci = (word)(Id >> 16); + dbug(1, dprintf("ncci=0x%x, plci=0x%x", ncci, plci)); + + if (plci && ncci) + { + Info = _WRONG_STATE; + if ((a->ncci_state[ncci] == CONNECTED) + || (a->ncci_state[ncci] == INC_ACT_PENDING)) + { + /* queue data */ + ncci_ptr = &(a->ncci[ncci]); + i = ncci_ptr->data_out + ncci_ptr->data_pending; + if (i >= MAX_DATA_B3) + i -= MAX_DATA_B3; + data = &(ncci_ptr->DBuffer[i]); + data->Number = Number; + if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue))) + && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) + { + + data->P = (byte *)(long)(*((dword *)(parms[0].info))); + + } + else + data->P = TransmitBufferSet(appl, *(dword *)parms[0].info); + data->Length = GET_WORD(parms[1].info); + data->Handle = GET_WORD(parms[2].info); + data->Flags = GET_WORD(parms[3].info); + (ncci_ptr->data_pending)++; + + /* check for delivery confirmation */ + if (data->Flags & 0x0004) + { + i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending; + if (i >= MAX_DATA_ACK) + i -= MAX_DATA_ACK; + ncci_ptr->DataAck[i].Number = data->Number; + ncci_ptr->DataAck[i].Handle = data->Handle; + (ncci_ptr->data_ack_pending)++; + } + + send_data(plci); + return false; + } + } + if (appl) + { + if (plci) + { + if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue))) + && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue))) + { + + TransmitBufferFree(appl, (byte *)(long)(*((dword *)(parms[0].info)))); + + } + } + sendf(appl, + _DATA_B3_R | CONFIRM, + Id, + Number, + "ww", GET_WORD(parms[2].info), Info); + } + return false; +} + +static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word n; + word ncci; + word NCCIcode; + + dbug(1, dprintf("data_b3_res")); + + ncci = (word)(Id >> 16); + if (plci && ncci) { + n = GET_WORD(parms[0].info); + dbug(1, dprintf("free(%d)", n)); + NCCIcode = ncci | (((word) a->Id) << 8); + if (n < appl->MaxBuffer && + appl->DataNCCI[n] == NCCIcode && + (byte)(appl->DataFlags[n] >> 8) == plci->Id) { + dbug(1, dprintf("found")); + appl->DataNCCI[n] = 0; + + if (channel_can_xon(plci, a->ncci_ch[ncci])) { + channel_request_xon(plci, a->ncci_ch[ncci]); + } + channel_xmit_xon(plci); + + if (appl->DataFlags[n] & 4) { + nl_req_ncci(plci, N_DATA_ACK, (byte)ncci); + return 1; + } + } + } + return false; +} + +static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word Info; + word ncci; + + dbug(1, dprintf("reset_b3_req")); + + Info = _WRONG_IDENTIFIER; + ncci = (word)(Id >> 16); + if (plci && ncci) + { + Info = _WRONG_STATE; + switch (plci->B3_prot) + { + case B3_ISO8208: + case B3_X25_DCE: + if (a->ncci_state[ncci] == CONNECTED) + { + nl_req_ncci(plci, N_RESET, (byte)ncci); + send_req(plci); + Info = GOOD; + } + break; + case B3_TRANSPARENT: + if (a->ncci_state[ncci] == CONNECTED) + { + start_internal_command(Id, plci, reset_b3_command); + Info = GOOD; + } + break; + } + } + /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */ + sendf(appl, + _RESET_B3_R | CONFIRM, + Id, + Number, + "w", Info); + return false; +} + +static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word ncci; + + dbug(1, dprintf("reset_b3_res")); + + ncci = (word)(Id >> 16); + if (plci && ncci) { + switch (plci->B3_prot) + { + case B3_ISO8208: + case B3_X25_DCE: + if (a->ncci_state[ncci] == INC_RES_PENDING) + { + a->ncci_state[ncci] = CONNECTED; + nl_req_ncci(plci, N_RESET_ACK, (byte)ncci); + return true; + } + break; + } + } + return false; +} + +static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word ncci; + API_PARSE *ncpi; + byte req; + + dbug(1, dprintf("connect_b3_t90_a_res")); + + ncci = (word)(Id >> 16); + if (plci && ncci) { + if (a->ncci_state[ncci] == INC_ACT_PENDING) { + a->ncci_state[ncci] = CONNECTED; + } + else if (a->ncci_state[ncci] == INC_CON_PENDING) { + a->ncci_state[ncci] = CONNECTED; + + req = N_CONNECT_ACK; + + /* parms[0]==0 for CAPI original message definition! */ + if (parms[0].info) { + ncpi = &parms[1]; + if (ncpi->length > 2) { + if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT; + add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]); + } + } + nl_req_ncci(plci, req, (byte)ncci); + return 1; + } + } + return false; +} + + +static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word Info = 0; + word i; + byte tel; + API_PARSE bp_parms[7]; + + if (!plci || !msg) + { + Info = _WRONG_IDENTIFIER; + } + else + { + dbug(1, dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x", + msg->length, plci->Id, plci->tel, plci->NL.Id, plci->appl, plci->SuppState)); + dbug(1, dprintf("PlciState=0x%x", plci->State)); + for (i = 0; i < 7; i++) bp_parms[i].length = 0; + + /* check if no channel is open, no B3 connected only */ + if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) || (plci->State == INC_DIS_PENDING) + || (plci->SuppState != IDLE) || plci->channels || plci->nl_remove_id) + { + Info = _WRONG_STATE; + } + /* check message format and fill bp_parms pointer */ + else if (msg->length && api_parse(&msg->info[1], (word)msg->length, "wwwsss", bp_parms)) + { + Info = _WRONG_MESSAGE_FORMAT; + } + else + { + if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT)) /* send alert tone inband to the network, */ + { /* e.g. Qsig or RBS or Cornet-N or xess PRI */ + if (Id & EXT_CONTROLLER) + { + sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */ + return 0; + } + plci->State = INC_CON_CONNECTED_ALERT; + plci->appl = appl; + clear_c_ind_mask_bit(plci, (word)(appl->Id - 1)); + dump_c_ind_mask(plci); + for (i = 0; i < max_appl; i++) /* disconnect the other appls */ + { /* its quasi a connect */ + if (test_c_ind_mask_bit(plci, i)) + sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED); + } + } + + api_save_msg(msg, "s", &plci->saved_msg); + tel = plci->tel; + if (Id & EXT_CONTROLLER) + { + if (tel) /* external controller in use by this PLCI */ + { + if (a->AdvSignalAppl && a->AdvSignalAppl != appl) + { + dbug(1, dprintf("Ext_Ctrl in use 1")); + Info = _WRONG_STATE; + } + } + else /* external controller NOT in use by this PLCI ? */ + { + if (a->AdvSignalPLCI) + { + dbug(1, dprintf("Ext_Ctrl in use 2")); + Info = _WRONG_STATE; + } + else /* activate the codec */ + { + dbug(1, dprintf("Ext_Ctrl start")); + if (AdvCodecSupport(a, plci, appl, 0)) + { + dbug(1, dprintf("Error in codec procedures")); + Info = _WRONG_STATE; + } + else if (plci->spoofed_msg == SPOOFING_REQUIRED) /* wait until codec is active */ + { + plci->spoofed_msg = AWAITING_SELECT_B; + plci->internal_command = BLOCK_PLCI; /* lock other commands */ + plci->command = 0; + dbug(1, dprintf("continue if codec loaded")); + return false; + } + } + } + } + else /* external controller bit is OFF */ + { + if (tel) /* external controller in use, need to switch off */ + { + if (a->AdvSignalAppl == appl) + { + CodecIdCheck(a, plci); + plci->tel = 0; + plci->adv_nl = 0; + dbug(1, dprintf("Ext_Ctrl disable")); + } + else + { + dbug(1, dprintf("Ext_Ctrl not requested")); + } + } + } + if (!Info) + { + if (plci->call_dir & CALL_DIR_OUT) + plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; + else if (plci->call_dir & CALL_DIR_IN) + plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER; + start_internal_command(Id, plci, select_b_command); + return false; + } + } + } + sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", Info); + return false; +} + +static byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *parms) +{ + word command; + word i; + word ncci; + API_PARSE *m; + API_PARSE m_parms[5]; + word codec; + byte req; + byte ch; + byte dir; + static byte chi[2] = {0x01, 0x00}; + static byte lli[2] = {0x01, 0x00}; + static byte codec_cai[2] = {0x01, 0x01}; + static byte null_msg = {0}; + static API_PARSE null_parms = { 0, &null_msg }; + PLCI *v_plci; + word Info = 0; + + dbug(1, dprintf("manufacturer_req")); + for (i = 0; i < 5; i++) m_parms[i].length = 0; + + if (GET_DWORD(parms[0].info) != _DI_MANU_ID) { + Info = _WRONG_MESSAGE_FORMAT; + } + command = GET_WORD(parms[1].info); + m = &parms[2]; + if (!Info) + { + switch (command) { + case _DI_ASSIGN_PLCI: + if (api_parse(&m->info[1], (word)m->length, "wbbs", m_parms)) { + Info = _WRONG_MESSAGE_FORMAT; + break; + } + codec = GET_WORD(m_parms[0].info); + ch = m_parms[1].info[0]; + dir = m_parms[2].info[0]; + if ((i = get_plci(a))) { + plci = &a->plci[i - 1]; + plci->appl = appl; + plci->command = _MANUFACTURER_R; + plci->m_command = command; + plci->number = Number; + plci->State = LOCAL_CONNECT; + Id = (((word)plci->Id << 8) | plci->adapter->Id | 0x80); + dbug(1, dprintf("ManCMD,plci=0x%x", Id)); + + if ((ch == 1 || ch == 2) && (dir <= 2)) { + chi[1] = (byte)(0x80 | ch); + lli[1] = 0; + plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; + switch (codec) + { + case 0: + Info = add_b1(plci, &m_parms[3], 0, 0); + break; + case 1: + add_p(plci, CAI, codec_cai); + break; + /* manual 'swich on' to the codec support without signalling */ + /* first 'assign plci' with this function, then use */ + case 2: + if (AdvCodecSupport(a, plci, appl, 0)) { + Info = _RESOURCE_ERROR; + } + else { + Info = add_b1(plci, &null_parms, 0, B1_FACILITY_LOCAL); + lli[1] = 0x10; /* local call codec stream */ + } + break; + } + + plci->State = LOCAL_CONNECT; + plci->manufacturer = true; + plci->command = _MANUFACTURER_R; + plci->m_command = command; + plci->number = Number; + + if (!Info) + { + add_p(plci, LLI, lli); + add_p(plci, CHI, chi); + add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(plci, ASSIGN, DSIG_ID); + + if (!codec) + { + Info = add_b23(plci, &m_parms[3]); + if (!Info) + { + nl_req_ncci(plci, ASSIGN, 0); + send_req(plci); + } + } + if (!Info) + { + dbug(1, dprintf("dir=0x%x,spoof=0x%x", dir, plci->spoofed_msg)); + if (plci->spoofed_msg == SPOOFING_REQUIRED) + { + api_save_msg(m_parms, "wbbs", &plci->saved_msg); + plci->spoofed_msg = AWAITING_MANUF_CON; + plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */ + plci->command = 0; + send_req(plci); + return false; + } + if (dir == 1) { + sig_req(plci, CALL_REQ, 0); + } + else if (!dir) { + sig_req(plci, LISTEN_REQ, 0); + } + send_req(plci); + } + else + { + sendf(appl, + _MANUFACTURER_R | CONFIRM, + Id, + Number, + "dww", _DI_MANU_ID, command, Info); + return 2; + } + } + } + } + else Info = _OUT_OF_PLCI; + break; + + case _DI_IDI_CTRL: + if (!plci) + { + Info = _WRONG_IDENTIFIER; + break; + } + if (api_parse(&m->info[1], (word)m->length, "bs", m_parms)) { + Info = _WRONG_MESSAGE_FORMAT; + break; + } + req = m_parms[0].info[0]; + plci->command = _MANUFACTURER_R; + plci->m_command = command; + plci->number = Number; + if (req == CALL_REQ) + { + plci->b_channel = getChannel(&m_parms[1]); + mixer_set_bchannel_id_esc(plci, plci->b_channel); + if (plci->spoofed_msg == SPOOFING_REQUIRED) + { + plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON; + plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */ + plci->command = 0; + break; + } + } + else if (req == LAW_REQ) + { + plci->cr_enquiry = true; + } + add_ss(plci, FTY, &m_parms[1]); + sig_req(plci, req, 0); + send_req(plci); + if (req == HANGUP) + { + if (plci->NL.Id && !plci->nl_remove_id) + { + if (plci->channels) + { + for (ncci = 1; ncci < MAX_NCCI + 1; ncci++) + { + if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED)) + { + a->ncci_state[ncci] = OUTG_DIS_PENDING; + cleanup_ncci_data(plci, ncci); + nl_req_ncci(plci, N_DISC, (byte)ncci); + } + } + } + mixer_remove(plci); + nl_req_ncci(plci, REMOVE, 0); + send_req(plci); + } + } + break; + + case _DI_SIG_CTRL: + /* signalling control for loop activation B-channel */ + if (!plci) + { + Info = _WRONG_IDENTIFIER; + break; + } + if (m->length) { + plci->command = _MANUFACTURER_R; + plci->number = Number; + add_ss(plci, FTY, m); + sig_req(plci, SIG_CTRL, 0); + send_req(plci); + } + else Info = _WRONG_MESSAGE_FORMAT; + break; + + case _DI_RXT_CTRL: + /* activation control for receiver/transmitter B-channel */ + if (!plci) + { + Info = _WRONG_IDENTIFIER; + break; + } + if (m->length) { + plci->command = _MANUFACTURER_R; + plci->number = Number; + add_ss(plci, FTY, m); + sig_req(plci, DSP_CTRL, 0); + send_req(plci); + } + else Info = _WRONG_MESSAGE_FORMAT; + break; + + case _DI_ADV_CODEC: + case _DI_DSP_CTRL: + /* TEL_CTRL commands to support non standard adjustments: */ + /* Ring on/off, Handset micro volume, external micro vol. */ + /* handset+external speaker volume, receiver+transm. gain,*/ + /* handsfree on (hookinfo off), set mixer command */ + + if (command == _DI_ADV_CODEC) + { + if (!a->AdvCodecPLCI) { + Info = _WRONG_STATE; + break; + } + v_plci = a->AdvCodecPLCI; + } + else + { + if (plci + && (m->length >= 3) + && (m->info[1] == 0x1c) + && (m->info[2] >= 1)) + { + if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS) + { + if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI)) + { + Info = _WRONG_STATE; + break; + } + a->adv_voice_coef_length = m->info[2] - 1; + if (a->adv_voice_coef_length > m->length - 3) + a->adv_voice_coef_length = (byte)(m->length - 3); + if (a->adv_voice_coef_length > ADV_VOICE_COEF_BUFFER_SIZE) + a->adv_voice_coef_length = ADV_VOICE_COEF_BUFFER_SIZE; + for (i = 0; i < a->adv_voice_coef_length; i++) + a->adv_voice_coef_buffer[i] = m->info[4 + i]; + if (plci->B1_facilities & B1_FACILITY_VOICE) + adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE); + break; + } + else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS) + { + if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS)) + { + Info = _FACILITY_NOT_SUPPORTED; + break; + } + + plci->dtmf_parameter_length = m->info[2] - 1; + if (plci->dtmf_parameter_length > m->length - 3) + plci->dtmf_parameter_length = (byte)(m->length - 3); + if (plci->dtmf_parameter_length > DTMF_PARAMETER_BUFFER_SIZE) + plci->dtmf_parameter_length = DTMF_PARAMETER_BUFFER_SIZE; + for (i = 0; i < plci->dtmf_parameter_length; i++) + plci->dtmf_parameter_buffer[i] = m->info[4 + i]; + if (plci->B1_facilities & B1_FACILITY_DTMFR) + dtmf_parameter_write(plci); + break; + + } + } + v_plci = plci; + } + + if (!v_plci) + { + Info = _WRONG_IDENTIFIER; + break; + } + if (m->length) { + add_ss(v_plci, FTY, m); + sig_req(v_plci, TEL_CTRL, 0); + send_req(v_plci); + } + else Info = _WRONG_MESSAGE_FORMAT; + + break; + + case _DI_OPTIONS_REQUEST: + if (api_parse(&m->info[1], (word)m->length, "d", m_parms)) { + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (GET_DWORD(m_parms[0].info) & ~a->man_profile.private_options) + { + Info = _FACILITY_NOT_SUPPORTED; + break; + } + a->requested_options_table[appl->Id - 1] = GET_DWORD(m_parms[0].info); + break; + + + + default: + Info = _WRONG_MESSAGE_FORMAT; + break; + } + } + + sendf(appl, + _MANUFACTURER_R | CONFIRM, + Id, + Number, + "dww", _DI_MANU_ID, command, Info); + return false; +} + + +static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, + PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word indication; + + API_PARSE m_parms[3]; + API_PARSE *ncpi; + API_PARSE fax_parms[9]; + word i; + byte len; + + + dbug(1, dprintf("manufacturer_res")); + + if ((msg[0].length == 0) + || (msg[1].length == 0) + || (GET_DWORD(msg[0].info) != _DI_MANU_ID)) + { + return false; + } + indication = GET_WORD(msg[1].info); + switch (indication) + { + + case _DI_NEGOTIATE_B3: + if (!plci) + break; + if (((plci->B3_prot != 4) && (plci->B3_prot != 5)) + || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT)) + { + dbug(1, dprintf("wrong state for NEGOTIATE_B3 parameters")); + break; + } + if (api_parse(&msg[2].info[1], msg[2].length, "ws", m_parms)) + { + dbug(1, dprintf("wrong format in NEGOTIATE_B3 parameters")); + break; + } + ncpi = &m_parms[1]; + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + if (plci->fax_connect_info_length < len) + { + ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; + ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; + } + if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms)) + { + dbug(1, dprintf("non-standard facilities info missing or wrong format")); + } + else + { + if (plci->fax_connect_info_length <= len) + plci->fax_connect_info_buffer[len] = 0; + len += 1 + plci->fax_connect_info_buffer[len]; + if (plci->fax_connect_info_length <= len) + plci->fax_connect_info_buffer[len] = 0; + len += 1 + plci->fax_connect_info_buffer[len]; + if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2)) + plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]); + plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length); + for (i = 0; i < fax_parms[7].length; i++) + plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i]; + } + plci->fax_connect_info_length = len; + plci->fax_edata_ack_length = plci->fax_connect_info_length; + start_internal_command(Id, plci, fax_edata_ack_command); + break; + + } + return false; } /*------------------------------------------------------------------*/ /* IDI callback function */ /*------------------------------------------------------------------*/ -void callback(ENTITY * e) -{ - DIVA_CAPI_ADAPTER * a; - APPL * appl; - PLCI * plci; - CAPI_MSG *m; - word i, j; - byte rc; - byte ch; - byte req; - byte global_req; - int no_cancel_rc; - - dbug(1,dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)", - (e->user[0]+1)&0x7fff,e->Id,e->Req,e->Rc,e->Ind)); - - a = &(adapter[(byte)e->user[0]]); - plci = &(a->plci[e->user[1]]); - no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a); - - /* - If new protocol code and new XDI is used then CAPI should work - fully in accordance with IDI cpec an look on callback field instead - of Rc field for return codes. - */ - if (((e->complete == 0xff) && no_cancel_rc) || - (e->Rc && !no_cancel_rc)) { - rc = e->Rc; - ch = e->RcCh; - req = e->Req; - e->Rc = 0; - - if (e->user[0] & 0x8000) - { - /* - If REMOVE request was sent then we have to wait until - return code with Id set to zero arrives. - All other return codes should be ignored. - */ - if (req == REMOVE) - { - if (e->Id) - { - dbug(1,dprintf("cancel RC in REMOVE state")); - return; - } - channel_flow_control_remove (plci); - for (i = 0; i < 256; i++) - { - if (a->FlowControlIdTable[i] == plci->nl_remove_id) - a->FlowControlIdTable[i] = 0; - } - plci->nl_remove_id = 0; - if (plci->rx_dma_descriptor > 0) { - diva_free_dma_descriptor (plci, plci->rx_dma_descriptor - 1); - plci->rx_dma_descriptor = 0; - } - } - if (rc == OK_FC) - { - a->FlowControlIdTable[ch] = e->Id; - a->FlowControlSkipTable[ch] = 0; - - a->ch_flow_control[ch] |= N_OK_FC_PENDING; - a->ch_flow_plci[ch] = plci->Id; - plci->nl_req = 0; - } - else - { - /* - Cancel return codes self, if feature was requested - */ - if (no_cancel_rc && (a->FlowControlIdTable[ch] == e->Id) && e->Id) { - a->FlowControlIdTable[ch] = 0; - if ((rc == OK) && a->FlowControlSkipTable[ch]) { - dbug(3,dprintf ("XDI CAPI: RC cancelled Id:0x02, Ch:%02x", e->Id, ch)); - return; - } - } - - if (a->ch_flow_control[ch] & N_OK_FC_PENDING) - { - a->ch_flow_control[ch] &= ~N_OK_FC_PENDING; - if (ch == e->ReqCh) - plci->nl_req = 0; - } - else - plci->nl_req = 0; - } - if (plci->nl_req) - control_rc (plci, 0, rc, ch, 0, TRUE); - else - { - if (req == N_XON) - { - channel_x_on (plci, ch); - if (plci->internal_command) - control_rc (plci, req, rc, ch, 0, TRUE); - } - else - { - if (plci->nl_global_req) - { - global_req = plci->nl_global_req; - plci->nl_global_req = 0; - if (rc != ASSIGN_OK) { - e->Id = 0; - if (plci->rx_dma_descriptor > 0) { - diva_free_dma_descriptor (plci, plci->rx_dma_descriptor - 1); - plci->rx_dma_descriptor = 0; - } - } - channel_xmit_xon (plci); - control_rc (plci, 0, rc, ch, global_req, TRUE); - } - else if (plci->data_sent) - { - channel_xmit_xon (plci); - plci->data_sent = FALSE; - plci->NL.XNum = 1; - data_rc (plci, ch); - if (plci->internal_command) - control_rc (plci, req, rc, ch, 0, TRUE); - } - else - { - channel_xmit_xon (plci); - control_rc (plci, req, rc, ch, 0, TRUE); - } - } - } - } - else - { - /* - If REMOVE request was sent then we have to wait until - return code with Id set to zero arrives. - All other return codes should be ignored. - */ - if (req == REMOVE) - { - if (e->Id) - { - dbug(1,dprintf("cancel RC in REMOVE state")); - return; - } - plci->sig_remove_id = 0; - } - plci->sig_req = 0; - if (plci->sig_global_req) - { - global_req = plci->sig_global_req; - plci->sig_global_req = 0; - if (rc != ASSIGN_OK) - e->Id = 0; - channel_xmit_xon (plci); - control_rc (plci, 0, rc, ch, global_req, FALSE); - } - else - { - channel_xmit_xon (plci); - control_rc (plci, req, rc, ch, 0, FALSE); - } - } - /* - Again: in accordance with IDI spec Rc and Ind can't be delivered in the - same callback. Also if new XDI and protocol code used then jump - direct to finish. - */ - if (no_cancel_rc) { - channel_xmit_xon(plci); - goto capi_callback_suffix; - } - } - - channel_xmit_xon(plci); - - if (e->Ind) { - if (e->user[0] &0x8000) { - byte Ind = e->Ind & 0x0f; - byte Ch = e->IndCh; - if (((Ind==N_DISC) || (Ind==N_DISC_ACK)) && - (a->ch_flow_plci[Ch] == plci->Id)) { - if (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK) { - dbug(3,dprintf ("XDI CAPI: I: pending N-XON Ch:%02x", Ch)); - } - a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK; - } - nl_ind(plci); - if ((e->RNR != 1) && - (a->ch_flow_plci[Ch] == plci->Id) && - (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK)) { - a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK; - dbug(3,dprintf ("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch)); - } - } else { - sig_ind(plci); - } - e->Ind = 0; - } +void callback(ENTITY *e) +{ + DIVA_CAPI_ADAPTER *a; + APPL *appl; + PLCI *plci; + CAPI_MSG *m; + word i, j; + byte rc; + byte ch; + byte req; + byte global_req; + int no_cancel_rc; + + dbug(1, dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)", + (e->user[0] + 1) & 0x7fff, e->Id, e->Req, e->Rc, e->Ind)); + + a = &(adapter[(byte)e->user[0]]); + plci = &(a->plci[e->user[1]]); + no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a); + + /* + If new protocol code and new XDI is used then CAPI should work + fully in accordance with IDI cpec an look on callback field instead + of Rc field for return codes. + */ + if (((e->complete == 0xff) && no_cancel_rc) || + (e->Rc && !no_cancel_rc)) { + rc = e->Rc; + ch = e->RcCh; + req = e->Req; + e->Rc = 0; + + if (e->user[0] & 0x8000) + { + /* + If REMOVE request was sent then we have to wait until + return code with Id set to zero arrives. + All other return codes should be ignored. + */ + if (req == REMOVE) + { + if (e->Id) + { + dbug(1, dprintf("cancel RC in REMOVE state")); + return; + } + channel_flow_control_remove(plci); + for (i = 0; i < 256; i++) + { + if (a->FlowControlIdTable[i] == plci->nl_remove_id) + a->FlowControlIdTable[i] = 0; + } + plci->nl_remove_id = 0; + if (plci->rx_dma_descriptor > 0) { + diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1); + plci->rx_dma_descriptor = 0; + } + } + if (rc == OK_FC) + { + a->FlowControlIdTable[ch] = e->Id; + a->FlowControlSkipTable[ch] = 0; + + a->ch_flow_control[ch] |= N_OK_FC_PENDING; + a->ch_flow_plci[ch] = plci->Id; + plci->nl_req = 0; + } + else + { + /* + Cancel return codes self, if feature was requested + */ + if (no_cancel_rc && (a->FlowControlIdTable[ch] == e->Id) && e->Id) { + a->FlowControlIdTable[ch] = 0; + if ((rc == OK) && a->FlowControlSkipTable[ch]) { + dbug(3, dprintf("XDI CAPI: RC cancelled Id:0x02, Ch:%02x", e->Id, ch)); + return; + } + } + + if (a->ch_flow_control[ch] & N_OK_FC_PENDING) + { + a->ch_flow_control[ch] &= ~N_OK_FC_PENDING; + if (ch == e->ReqCh) + plci->nl_req = 0; + } + else + plci->nl_req = 0; + } + if (plci->nl_req) + control_rc(plci, 0, rc, ch, 0, true); + else + { + if (req == N_XON) + { + channel_x_on(plci, ch); + if (plci->internal_command) + control_rc(plci, req, rc, ch, 0, true); + } + else + { + if (plci->nl_global_req) + { + global_req = plci->nl_global_req; + plci->nl_global_req = 0; + if (rc != ASSIGN_OK) { + e->Id = 0; + if (plci->rx_dma_descriptor > 0) { + diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1); + plci->rx_dma_descriptor = 0; + } + } + channel_xmit_xon(plci); + control_rc(plci, 0, rc, ch, global_req, true); + } + else if (plci->data_sent) + { + channel_xmit_xon(plci); + plci->data_sent = false; + plci->NL.XNum = 1; + data_rc(plci, ch); + if (plci->internal_command) + control_rc(plci, req, rc, ch, 0, true); + } + else + { + channel_xmit_xon(plci); + control_rc(plci, req, rc, ch, 0, true); + } + } + } + } + else + { + /* + If REMOVE request was sent then we have to wait until + return code with Id set to zero arrives. + All other return codes should be ignored. + */ + if (req == REMOVE) + { + if (e->Id) + { + dbug(1, dprintf("cancel RC in REMOVE state")); + return; + } + plci->sig_remove_id = 0; + } + plci->sig_req = 0; + if (plci->sig_global_req) + { + global_req = plci->sig_global_req; + plci->sig_global_req = 0; + if (rc != ASSIGN_OK) + e->Id = 0; + channel_xmit_xon(plci); + control_rc(plci, 0, rc, ch, global_req, false); + } + else + { + channel_xmit_xon(plci); + control_rc(plci, req, rc, ch, 0, false); + } + } + /* + Again: in accordance with IDI spec Rc and Ind can't be delivered in the + same callback. Also if new XDI and protocol code used then jump + direct to finish. + */ + if (no_cancel_rc) { + channel_xmit_xon(plci); + goto capi_callback_suffix; + } + } + + channel_xmit_xon(plci); + + if (e->Ind) { + if (e->user[0] & 0x8000) { + byte Ind = e->Ind & 0x0f; + byte Ch = e->IndCh; + if (((Ind == N_DISC) || (Ind == N_DISC_ACK)) && + (a->ch_flow_plci[Ch] == plci->Id)) { + if (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK) { + dbug(3, dprintf("XDI CAPI: I: pending N-XON Ch:%02x", Ch)); + } + a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK; + } + nl_ind(plci); + if ((e->RNR != 1) && + (a->ch_flow_plci[Ch] == plci->Id) && + (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK)) { + a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK; + dbug(3, dprintf("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch)); + } + } else { + sig_ind(plci); + } + e->Ind = 0; + } capi_callback_suffix: - while (!plci->req_in - && !plci->internal_command - && (plci->msg_in_write_pos != plci->msg_in_read_pos)) - { - j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos; - - i = (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc; - - m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]); - appl = *((APPL * *)(&((byte *)(plci->msg_in_queue))[j+i])); - dbug(1,dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d", - m->header.command, plci->msg_in_write_pos, plci->msg_in_read_pos, plci->msg_in_wrap_pos)); - if (plci->msg_in_read_pos == plci->msg_in_wrap_pos) - { - plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; - plci->msg_in_read_pos = i + MSG_IN_OVERHEAD; - } - else - { - plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD; - } - if (plci->msg_in_read_pos == plci->msg_in_write_pos) - { - plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; - plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; - } - else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos) - { - plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; - plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; - } - i = api_put (appl, m); - if (i != 0) - { - if (m->header.command == _DATA_B3_R) - - TransmitBufferFree (appl, (byte *)(m->info.data_b3_req.Data)); - - dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command)); - break; - } - - if (plci->li_notify_update) - { - plci->li_notify_update = FALSE; - mixer_notify_update (plci, FALSE); - } - - } - send_data(plci); - send_req(plci); -} - - -void control_rc(PLCI * plci, byte req, byte rc, byte ch, byte global_req, byte nl_rc) -{ - dword Id; - dword rId; - word Number; - word Info=0; - word i; - word ncci; - DIVA_CAPI_ADAPTER * a; - APPL * appl; - PLCI * rplci; - byte SSparms[] = "\x05\x00\x00\x02\x00\x00"; - byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00"; - - if (!plci) { - dbug(0,dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc)); - return; - } - dbug(1,dprintf("req0_in/out=%d/%d",plci->req_in,plci->req_out)); - if(plci->req_in!=plci->req_out) - { - if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK)) - { - dbug(1,dprintf("req_1return")); - return; - } - /* cancel outstanding request on the PLCI after SIG ASSIGN failure */ - } - plci->req_in = plci->req_in_start = plci->req_out = 0; - dbug(1,dprintf("control_rc")); - - appl = plci->appl; - a = plci->adapter; - ncci = a->ch_ncci[ch]; - if(appl) - { - Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id; - if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER; - Number = plci->number; - dbug(1,dprintf("Contr_RC-Id=%08lx,plci=%x,tel=%x, entity=0x%x, command=0x%x, int_command=0x%x",Id,plci->Id,plci->tel,plci->Sig.Id,plci->command,plci->internal_command)); - dbug(1,dprintf("channels=0x%x",plci->channels)); - if (plci_remove_check(plci)) - return; - if(req==REMOVE && rc==ASSIGN_OK) - { - sig_req(plci,HANGUP,0); - sig_req(plci,REMOVE,0); - send_req(plci); - } - if(plci->command) - { - switch(plci->command) - { - case C_HOLD_REQ: - dbug(1,dprintf("HoldRC=0x%x",rc)); - SSparms[1] = (byte)S_HOLD; - if(rc!=OK) - { - plci->SuppState = IDLE; - Info = 0x2001; - } - sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms); - break; - - case C_RETRIEVE_REQ: - dbug(1,dprintf("RetrieveRC=0x%x",rc)); - SSparms[1] = (byte)S_RETRIEVE; - if(rc!=OK) - { - plci->SuppState = CALL_HELD; - Info = 0x2001; - } - sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms); - break; - - case _INFO_R: - dbug(1,dprintf("InfoRC=0x%x",rc)); - if(rc!=OK) Info=_WRONG_STATE; - sendf(appl,_INFO_R|CONFIRM,Id,Number,"w",Info); - break; - - case _CONNECT_R: - dbug(1,dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x",req,rc,global_req,nl_rc)); - if (plci->State == INC_DIS_PENDING) - break; - if(plci->Sig.Id!=0xff) - { - if (((global_req == ASSIGN) && (rc != ASSIGN_OK)) - || (!nl_rc && (req == CALL_REQ) && (rc != OK))) - { - dbug(1,dprintf("No more IDs/Call_Req failed")); - sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI); - plci_remove(plci); - plci->State = IDLE; - break; - } - if(plci->State!=LOCAL_CONNECT)plci->State = OUTG_CON_PENDING; - sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0); - } - else /* D-ch activation */ - { - if (rc != ASSIGN_OK) - { - dbug(1,dprintf("No more IDs/X.25 Call_Req failed")); - sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI); - plci_remove(plci); - plci->State = IDLE; - break; - } - sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0); - sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"sss","","",""); - plci->State = INC_ACT_PENDING; - } - break; - - case _CONNECT_I|RESPONSE: - if (plci->State != INC_DIS_PENDING) - plci->State = INC_CON_ACCEPT; - break; - - case _DISCONNECT_R: - if (plci->State == INC_DIS_PENDING) - break; - if(plci->Sig.Id!=0xff) - { - plci->State = OUTG_DIS_PENDING; - sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0); - } - break; - - case SUSPEND_REQ: - break; - - case RESUME_REQ: - break; - - case _CONNECT_B3_R: - if(rc!=OK) - { - sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",_WRONG_IDENTIFIER); - break; - } - ncci = get_ncci (plci, ch, 0); - Id = (Id & 0xffff) | (((dword) ncci) << 16); - plci->channels++; - if(req==N_RESET) - { - a->ncci_state[ncci] = INC_ACT_PENDING; - sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0); - sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); - } - else - { - a->ncci_state[ncci] = OUTG_CON_PENDING; - sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0); - } - break; - - case _CONNECT_B3_I|RESPONSE: - break; - - case _RESET_B3_R: -/* sendf(appl,_RESET_B3_R|CONFIRM,Id,Number,"w",0);*/ - break; - - case _DISCONNECT_B3_R: - sendf(appl,_DISCONNECT_B3_R|CONFIRM,Id,Number,"w",0); - break; - - case _MANUFACTURER_R: - break; - - case PERM_LIST_REQ: - if(rc!=OK) - { - Info = _WRONG_IDENTIFIER; - sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info); - plci_remove(plci); - } - else - sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info); - break; - - default: - break; - } - plci->command = 0; - } - else if (plci->internal_command) - { - switch(plci->internal_command) - { - case BLOCK_PLCI: - return; - - case GET_MWI_STATE: - if(rc==OK) /* command supported, wait for indication */ - { - return; - } - plci_remove(plci); - break; - - /* Get Supported Services */ - case GETSERV_REQ_PEND: - if(rc==OK) /* command supported, wait for indication */ - { - break; - } - PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY); - sendf(appl, _FACILITY_R|CONFIRM, Id, Number, "wws",0,3,SSstruct); - plci_remove(plci); - break; - - case INTERR_DIVERSION_REQ_PEND: /* Interrogate Parameters */ - case INTERR_NUMBERS_REQ_PEND: - case CF_START_PEND: /* Call Forwarding Start pending */ - case CF_STOP_PEND: /* Call Forwarding Stop pending */ - case CCBS_REQUEST_REQ_PEND: - case CCBS_DEACTIVATE_REQ_PEND: - case CCBS_INTERROGATE_REQ_PEND: - switch(plci->internal_command) - { - case INTERR_DIVERSION_REQ_PEND: - SSparms[1] = S_INTERROGATE_DIVERSION; - break; - case INTERR_NUMBERS_REQ_PEND: - SSparms[1] = S_INTERROGATE_NUMBERS; - break; - case CF_START_PEND: - SSparms[1] = S_CALL_FORWARDING_START; - break; - case CF_STOP_PEND: - SSparms[1] = S_CALL_FORWARDING_STOP; - break; - case CCBS_REQUEST_REQ_PEND: - SSparms[1] = S_CCBS_REQUEST; - break; - case CCBS_DEACTIVATE_REQ_PEND: - SSparms[1] = S_CCBS_DEACTIVATE; - break; - case CCBS_INTERROGATE_REQ_PEND: - SSparms[1] = S_CCBS_INTERROGATE; - break; - } - if(global_req==ASSIGN) - { - dbug(1,dprintf("AssignDiversion_RC=0x%x/0x%x",req,rc)); - return; - } - if(!plci->appl) break; - if(rc==ISDN_GUARD_REJ) - { - Info = _CAPI_GUARD_ERROR; - } - else if(rc!=OK) - { - Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED; - } - sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7, - plci->number,"wws",Info,(word)3,SSparms); - if(Info) plci_remove(plci); - break; - - /* 3pty conference pending */ - case PTY_REQ_PEND: - if(!plci->relatedPTYPLCI) break; - rplci = plci->relatedPTYPLCI; - SSparms[1] = plci->ptyState; - rId = ((word)rplci->Id<<8)|rplci->adapter->Id; - if(rplci->tel) rId|=EXT_CONTROLLER; - if(rc!=OK) - { - Info = 0x300E; /* not supported */ - plci->relatedPTYPLCI = NULL; - plci->ptyState = 0; - } - sendf(rplci->appl, - _FACILITY_R|CONFIRM, - rId, - plci->number, - "wws",Info,(word)3,SSparms); - break; - - /* Explicit Call Transfer pending */ - case ECT_REQ_PEND: - dbug(1,dprintf("ECT_RC=0x%x/0x%x",req,rc)); - if(!plci->relatedPTYPLCI) break; - rplci = plci->relatedPTYPLCI; - SSparms[1] = S_ECT; - rId = ((word)rplci->Id<<8)|rplci->adapter->Id; - if(rplci->tel) rId|=EXT_CONTROLLER; - if(rc!=OK) - { - Info = 0x300E; /* not supported */ - plci->relatedPTYPLCI = NULL; - plci->ptyState = 0; - } - sendf(rplci->appl, - _FACILITY_R|CONFIRM, - rId, - plci->number, - "wws",Info,(word)3,SSparms); - break; - - case _MANUFACTURER_R: - dbug(1,dprintf("_Manufacturer_R=0x%x/0x%x",req,rc)); - if ((global_req == ASSIGN) && (rc != ASSIGN_OK)) - { - dbug(1,dprintf("No more IDs")); - sendf(appl,_MANUFACTURER_R|CONFIRM,Id,Number,"dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI); - plci_remove(plci); /* after codec init, internal codec commands pending */ - } - break; - - case _CONNECT_R: - dbug(1,dprintf("_Connect_R=0x%x/0x%x",req,rc)); - if ((global_req == ASSIGN) && (rc != ASSIGN_OK)) - { - dbug(1,dprintf("No more IDs")); - sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI); - plci_remove(plci); /* after codec init, internal codec commands pending */ - } - break; - - case PERM_COD_HOOK: /* finished with Hook_Ind */ - return; - - case PERM_COD_CALL: - dbug(1,dprintf("***Codec Connect_Pending A, Rc = 0x%x",rc)); - plci->internal_command = PERM_COD_CONN_PEND; - return; - - case PERM_COD_ASSIGN: - dbug(1,dprintf("***Codec Assign A, Rc = 0x%x",rc)); - if(rc!=ASSIGN_OK) break; - sig_req(plci,CALL_REQ,0); - send_req(plci); - plci->internal_command = PERM_COD_CALL; - return; - - /* Null Call Reference Request pending */ - case C_NCR_FAC_REQ: - dbug(1,dprintf("NCR_FAC=0x%x/0x%x",req,rc)); - if(global_req==ASSIGN) - { - if(rc==ASSIGN_OK) - { - return; - } - else - { - sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE); - appl->NullCREnable = FALSE; - plci_remove(plci); - } - } - else if(req==NCR_FACILITY) - { - if(rc==OK) - { - sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",0); - } - else - { - sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE); - appl->NullCREnable = FALSE; - } - plci_remove(plci); - } - break; - - case HOOK_ON_REQ: - if(plci->channels) - { - if(a->ncci_state[ncci]==CONNECTED) - { - a->ncci_state[ncci] = OUTG_DIS_PENDING; - cleanup_ncci_data (plci, ncci); - nl_req_ncci(plci,N_DISC,(byte)ncci); - } - break; - } - break; - - case HOOK_OFF_REQ: - if (plci->State == INC_DIS_PENDING) - break; - sig_req(plci,CALL_REQ,0); - send_req(plci); - plci->State=OUTG_CON_PENDING; - break; - - - case MWI_ACTIVATE_REQ_PEND: - case MWI_DEACTIVATE_REQ_PEND: - if(global_req == ASSIGN && rc==ASSIGN_OK) - { - dbug(1,dprintf("MWI_REQ assigned")); - return; - } - else if(rc!=OK) - { - if(rc==WRONG_IE) - { - Info = 0x2007; /* Illegal message parameter coding */ - dbug(1,dprintf("MWI_REQ invalid parameter")); - } - else - { - Info = 0x300B; /* not supported */ - dbug(1,dprintf("MWI_REQ not supported")); - } - /* 0x3010: Request not allowed in this state */ - PUT_WORD(&SSparms[4],0x300E); /* SS not supported */ - - } - if(plci->internal_command==MWI_ACTIVATE_REQ_PEND) - { - PUT_WORD(&SSparms[1],S_MWI_ACTIVATE); - } - else PUT_WORD(&SSparms[1],S_MWI_DEACTIVATE); - - if(plci->cr_enquiry) - { - sendf(plci->appl, - _FACILITY_R|CONFIRM, - Id&0xf, - plci->number, - "wws",Info,(word)3,SSparms); - if(rc!=OK) plci_remove(plci); - } - else - { - sendf(plci->appl, - _FACILITY_R|CONFIRM, - Id, - plci->number, - "wws",Info,(word)3,SSparms); - } - break; - - case CONF_BEGIN_REQ_PEND: - case CONF_ADD_REQ_PEND: - case CONF_SPLIT_REQ_PEND: - case CONF_DROP_REQ_PEND: - case CONF_ISOLATE_REQ_PEND: - case CONF_REATTACH_REQ_PEND: - dbug(1,dprintf("CONF_RC=0x%x/0x%x",req,rc)); - if((plci->internal_command==CONF_ADD_REQ_PEND)&&(!plci->relatedPTYPLCI)) break; - rplci = plci; - rId = Id; - switch(plci->internal_command) - { - case CONF_BEGIN_REQ_PEND: - SSparms[1] = S_CONF_BEGIN; - break; - case CONF_ADD_REQ_PEND: - SSparms[1] = S_CONF_ADD; - rplci = plci->relatedPTYPLCI; - rId = ((word)rplci->Id<<8)|rplci->adapter->Id; - break; - case CONF_SPLIT_REQ_PEND: - SSparms[1] = S_CONF_SPLIT; - break; - case CONF_DROP_REQ_PEND: - SSparms[1] = S_CONF_DROP; - break; - case CONF_ISOLATE_REQ_PEND: - SSparms[1] = S_CONF_ISOLATE; - break; - case CONF_REATTACH_REQ_PEND: - SSparms[1] = S_CONF_REATTACH; - break; - } - - if(rc!=OK) - { - Info = 0x300E; /* not supported */ - plci->relatedPTYPLCI = NULL; - plci->ptyState = 0; - } - sendf(rplci->appl, - _FACILITY_R|CONFIRM, - rId, - plci->number, - "wws",Info,(word)3,SSparms); - break; - - case VSWITCH_REQ_PEND: - if(rc!=OK) - { - if(plci->relatedPTYPLCI) - { - plci->relatedPTYPLCI->vswitchstate=0; - plci->relatedPTYPLCI->vsprot=0; - plci->relatedPTYPLCI->vsprotdialect=0; - } - plci->vswitchstate=0; - plci->vsprot=0; - plci->vsprotdialect=0; - } - else - { - if(plci->relatedPTYPLCI && - plci->vswitchstate==1 && - plci->relatedPTYPLCI->vswitchstate==3) /* join complete */ - plci->vswitchstate=3; - } - break; - - /* Call Deflection Request pending (SSCT) */ - case CD_REQ_PEND: - SSparms[1] = S_CALL_DEFLECTION; - if(rc!=OK) - { - Info = 0x300E; /* not supported */ - plci->appl->CDEnable = 0; - } - sendf(plci->appl,_FACILITY_R|CONFIRM,Id, - plci->number,"wws",Info,(word)3,SSparms); - break; - - case RTP_CONNECT_B3_REQ_COMMAND_2: - if (rc == OK) - { - ncci = get_ncci (plci, ch, 0); - Id = (Id & 0xffff) | (((dword) ncci) << 16); - plci->channels++; - a->ncci_state[ncci] = OUTG_CON_PENDING; - } - - default: - if (plci->internal_command_queue[0]) - { - (*(plci->internal_command_queue[0]))(Id, plci, rc); - if (plci->internal_command) - return; - } - break; - } - next_internal_command (Id, plci); - } - } - else /* appl==0 */ - { - Id = ((word)plci->Id<<8)|plci->adapter->Id; - if(plci->tel) Id|=EXT_CONTROLLER; - - switch(plci->internal_command) - { - case BLOCK_PLCI: - return; - - case START_L1_SIG_ASSIGN_PEND: - case REM_L1_SIG_ASSIGN_PEND: - if(global_req == ASSIGN) - { - break; - } - else - { - dbug(1,dprintf("***L1 Req rem PLCI")); - plci->internal_command = 0; - sig_req(plci,REMOVE,0); - send_req(plci); - } - break; - - /* Call Deflection Request pending, just no appl ptr assigned */ - case CD_REQ_PEND: - SSparms[1] = S_CALL_DEFLECTION; - if(rc!=OK) - { - Info = 0x300E; /* not supported */ - } - for(i=0; i<max_appl; i++) - { - if(application[i].CDEnable) - { - if(!application[i].Id) application[i].CDEnable = 0; - else - { - sendf(&application[i],_FACILITY_R|CONFIRM,Id, - plci->number,"wws",Info,(word)3,SSparms); - if(Info) application[i].CDEnable = 0; - } - } - } - plci->internal_command = 0; - break; - - case PERM_COD_HOOK: /* finished with Hook_Ind */ - return; - - case PERM_COD_CALL: - plci->internal_command = PERM_COD_CONN_PEND; - dbug(1,dprintf("***Codec Connect_Pending, Rc = 0x%x",rc)); - return; - - case PERM_COD_ASSIGN: - dbug(1,dprintf("***Codec Assign, Rc = 0x%x",rc)); - plci->internal_command = 0; - if(rc!=ASSIGN_OK) break; - plci->internal_command = PERM_COD_CALL; - sig_req(plci,CALL_REQ,0); - send_req(plci); - return; - - case LISTEN_SIG_ASSIGN_PEND: - if(rc == ASSIGN_OK) - { - plci->internal_command = 0; - dbug(1,dprintf("ListenCheck, new SIG_ID = 0x%x",plci->Sig.Id)); - add_p(plci,ESC,"\x02\x18\x00"); /* support call waiting */ - sig_req(plci,INDICATE_REQ,0); - send_req(plci); - } - else - { - dbug(1,dprintf("ListenCheck failed (assignRc=0x%x)",rc)); - a->listen_active--; - plci_remove(plci); - plci->State = IDLE; - } - break; - - case USELAW_REQ: - if(global_req == ASSIGN) - { - if (rc==ASSIGN_OK) - { - sig_req(plci,LAW_REQ,0); - send_req(plci); - dbug(1,dprintf("Auto-Law assigned")); - } - else - { - dbug(1,dprintf("Auto-Law assign failed")); - a->automatic_law = 3; - plci->internal_command = 0; - a->automatic_lawPLCI = NULL; - } - break; - } - else if(req == LAW_REQ && rc==OK) - { - dbug(1,dprintf("Auto-Law initiated")); - a->automatic_law = 2; - plci->internal_command = 0; - } - else - { - dbug(1,dprintf("Auto-Law not supported")); - a->automatic_law = 3; - plci->internal_command = 0; - sig_req(plci,REMOVE,0); - send_req(plci); - a->automatic_lawPLCI = NULL; - } - break; - } - plci_remove_check(plci); - } -} - -void data_rc(PLCI * plci, byte ch) -{ - dword Id; - DIVA_CAPI_ADAPTER * a; - NCCI *ncci_ptr; - DATA_B3_DESC *data; - word ncci; - - if (plci->appl) - { - TransmitBufferFree (plci->appl, plci->data_sent_ptr); - a = plci->adapter; - ncci = a->ch_ncci[ch]; - if (ncci && (a->ncci_plci[ncci] == plci->Id)) - { - ncci_ptr = &(a->ncci[ncci]); - dbug(1,dprintf("data_out=%d, data_pending=%d",ncci_ptr->data_out,ncci_ptr->data_pending)); - if (ncci_ptr->data_pending) - { - data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]); - if (!(data->Flags &4) && a->ncci_state[ncci]) - { - Id = (((dword)ncci)<<16)|((word)plci->Id<<8)|a->Id; - if(plci->tel) Id|=EXT_CONTROLLER; - sendf(plci->appl,_DATA_B3_R|CONFIRM,Id,data->Number, - "ww",data->Handle,0); - } - (ncci_ptr->data_out)++; - if (ncci_ptr->data_out == MAX_DATA_B3) - ncci_ptr->data_out = 0; - (ncci_ptr->data_pending)--; - } - } - } -} - -void data_ack(PLCI * plci, byte ch) -{ - dword Id; - DIVA_CAPI_ADAPTER * a; - NCCI *ncci_ptr; - word ncci; - - a = plci->adapter; - ncci = a->ch_ncci[ch]; - ncci_ptr = &(a->ncci[ncci]); - if (ncci_ptr->data_ack_pending) - { - if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id)) - { - Id = (((dword)ncci)<<16)|((word)plci->Id<<8)|a->Id; - if(plci->tel) Id|=EXT_CONTROLLER; - sendf(plci->appl,_DATA_B3_R|CONFIRM,Id,ncci_ptr->DataAck[ncci_ptr->data_ack_out].Number, - "ww",ncci_ptr->DataAck[ncci_ptr->data_ack_out].Handle,0); - } - (ncci_ptr->data_ack_out)++; - if (ncci_ptr->data_ack_out == MAX_DATA_ACK) - ncci_ptr->data_ack_out = 0; - (ncci_ptr->data_ack_pending)--; - } -} - -void sig_ind(PLCI * plci) -{ - dword x_Id; - dword Id; - dword rId; - word Number = 0; - word i; - word cip; - dword cip_mask; - byte *ie; - DIVA_CAPI_ADAPTER * a; - API_PARSE saved_parms[MAX_MSG_PARMS+1]; + while (!plci->req_in + && !plci->internal_command + && (plci->msg_in_write_pos != plci->msg_in_read_pos)) + { + j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos; + + i = (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc; + + m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]); + appl = *((APPL **)(&((byte *)(plci->msg_in_queue))[j + i])); + dbug(1, dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d", + m->header.command, plci->msg_in_write_pos, plci->msg_in_read_pos, plci->msg_in_wrap_pos)); + if (plci->msg_in_read_pos == plci->msg_in_wrap_pos) + { + plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; + plci->msg_in_read_pos = i + MSG_IN_OVERHEAD; + } + else + { + plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD; + } + if (plci->msg_in_read_pos == plci->msg_in_write_pos) + { + plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; + plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; + } + else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos) + { + plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; + plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; + } + i = api_put(appl, m); + if (i != 0) + { + if (m->header.command == _DATA_B3_R) + + TransmitBufferFree(appl, (byte *)(long)(m->info.data_b3_req.Data)); + + dbug(1, dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command)); + break; + } + + if (plci->li_notify_update) + { + plci->li_notify_update = false; + mixer_notify_update(plci, false); + } + + } + send_data(plci); + send_req(plci); +} + + +static void control_rc(PLCI *plci, byte req, byte rc, byte ch, byte global_req, + byte nl_rc) +{ + dword Id; + dword rId; + word Number; + word Info = 0; + word i; + word ncci; + DIVA_CAPI_ADAPTER *a; + APPL *appl; + PLCI *rplci; + byte SSparms[] = "\x05\x00\x00\x02\x00\x00"; + byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00"; + + if (!plci) { + dbug(0, dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc)); + return; + } + dbug(1, dprintf("req0_in/out=%d/%d", plci->req_in, plci->req_out)); + if (plci->req_in != plci->req_out) + { + if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK)) + { + dbug(1, dprintf("req_1return")); + return; + } + /* cancel outstanding request on the PLCI after SIG ASSIGN failure */ + } + plci->req_in = plci->req_in_start = plci->req_out = 0; + dbug(1, dprintf("control_rc")); + + appl = plci->appl; + a = plci->adapter; + ncci = a->ch_ncci[ch]; + if (appl) + { + Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id; + if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER; + Number = plci->number; + dbug(1, dprintf("Contr_RC-Id=%08lx,plci=%x,tel=%x, entity=0x%x, command=0x%x, int_command=0x%x", Id, plci->Id, plci->tel, plci->Sig.Id, plci->command, plci->internal_command)); + dbug(1, dprintf("channels=0x%x", plci->channels)); + if (plci_remove_check(plci)) + return; + if (req == REMOVE && rc == ASSIGN_OK) + { + sig_req(plci, HANGUP, 0); + sig_req(plci, REMOVE, 0); + send_req(plci); + } + if (plci->command) + { + switch (plci->command) + { + case C_HOLD_REQ: + dbug(1, dprintf("HoldRC=0x%x", rc)); + SSparms[1] = (byte)S_HOLD; + if (rc != OK) + { + plci->SuppState = IDLE; + Info = 0x2001; + } + sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms); + break; + + case C_RETRIEVE_REQ: + dbug(1, dprintf("RetrieveRC=0x%x", rc)); + SSparms[1] = (byte)S_RETRIEVE; + if (rc != OK) + { + plci->SuppState = CALL_HELD; + Info = 0x2001; + } + sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms); + break; + + case _INFO_R: + dbug(1, dprintf("InfoRC=0x%x", rc)); + if (rc != OK) Info = _WRONG_STATE; + sendf(appl, _INFO_R | CONFIRM, Id, Number, "w", Info); + break; + + case _CONNECT_R: + dbug(1, dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x", req, rc, global_req, nl_rc)); + if (plci->State == INC_DIS_PENDING) + break; + if (plci->Sig.Id != 0xff) + { + if (((global_req == ASSIGN) && (rc != ASSIGN_OK)) + || (!nl_rc && (req == CALL_REQ) && (rc != OK))) + { + dbug(1, dprintf("No more IDs/Call_Req failed")); + sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI); + plci_remove(plci); + plci->State = IDLE; + break; + } + if (plci->State != LOCAL_CONNECT) plci->State = OUTG_CON_PENDING; + sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0); + } + else /* D-ch activation */ + { + if (rc != ASSIGN_OK) + { + dbug(1, dprintf("No more IDs/X.25 Call_Req failed")); + sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI); + plci_remove(plci); + plci->State = IDLE; + break; + } + sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0); + sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "sss", "", "", ""); + plci->State = INC_ACT_PENDING; + } + break; + + case _CONNECT_I | RESPONSE: + if (plci->State != INC_DIS_PENDING) + plci->State = INC_CON_ACCEPT; + break; + + case _DISCONNECT_R: + if (plci->State == INC_DIS_PENDING) + break; + if (plci->Sig.Id != 0xff) + { + plci->State = OUTG_DIS_PENDING; + sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0); + } + break; + + case SUSPEND_REQ: + break; + + case RESUME_REQ: + break; + + case _CONNECT_B3_R: + if (rc != OK) + { + sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER); + break; + } + ncci = get_ncci(plci, ch, 0); + Id = (Id & 0xffff) | (((dword) ncci) << 16); + plci->channels++; + if (req == N_RESET) + { + a->ncci_state[ncci] = INC_ACT_PENDING; + sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0); + sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + } + else + { + a->ncci_state[ncci] = OUTG_CON_PENDING; + sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0); + } + break; + + case _CONNECT_B3_I | RESPONSE: + break; + + case _RESET_B3_R: +/* sendf(appl, _RESET_B3_R | CONFIRM, Id, Number, "w", 0);*/ + break; + + case _DISCONNECT_B3_R: + sendf(appl, _DISCONNECT_B3_R | CONFIRM, Id, Number, "w", 0); + break; + + case _MANUFACTURER_R: + break; + + case PERM_LIST_REQ: + if (rc != OK) + { + Info = _WRONG_IDENTIFIER; + sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info); + plci_remove(plci); + } + else + sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info); + break; + + default: + break; + } + plci->command = 0; + } + else if (plci->internal_command) + { + switch (plci->internal_command) + { + case BLOCK_PLCI: + return; + + case GET_MWI_STATE: + if (rc == OK) /* command supported, wait for indication */ + { + return; + } + plci_remove(plci); + break; + + /* Get Supported Services */ + case GETSERV_REQ_PEND: + if (rc == OK) /* command supported, wait for indication */ + { + break; + } + PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY); + sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", 0, 3, SSstruct); + plci_remove(plci); + break; + + case INTERR_DIVERSION_REQ_PEND: /* Interrogate Parameters */ + case INTERR_NUMBERS_REQ_PEND: + case CF_START_PEND: /* Call Forwarding Start pending */ + case CF_STOP_PEND: /* Call Forwarding Stop pending */ + case CCBS_REQUEST_REQ_PEND: + case CCBS_DEACTIVATE_REQ_PEND: + case CCBS_INTERROGATE_REQ_PEND: + switch (plci->internal_command) + { + case INTERR_DIVERSION_REQ_PEND: + SSparms[1] = S_INTERROGATE_DIVERSION; + break; + case INTERR_NUMBERS_REQ_PEND: + SSparms[1] = S_INTERROGATE_NUMBERS; + break; + case CF_START_PEND: + SSparms[1] = S_CALL_FORWARDING_START; + break; + case CF_STOP_PEND: + SSparms[1] = S_CALL_FORWARDING_STOP; + break; + case CCBS_REQUEST_REQ_PEND: + SSparms[1] = S_CCBS_REQUEST; + break; + case CCBS_DEACTIVATE_REQ_PEND: + SSparms[1] = S_CCBS_DEACTIVATE; + break; + case CCBS_INTERROGATE_REQ_PEND: + SSparms[1] = S_CCBS_INTERROGATE; + break; + } + if (global_req == ASSIGN) + { + dbug(1, dprintf("AssignDiversion_RC=0x%x/0x%x", req, rc)); + return; + } + if (!plci->appl) break; + if (rc == ISDN_GUARD_REJ) + { + Info = _CAPI_GUARD_ERROR; + } + else if (rc != OK) + { + Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED; + } + sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7, + plci->number, "wws", Info, (word)3, SSparms); + if (Info) plci_remove(plci); + break; + + /* 3pty conference pending */ + case PTY_REQ_PEND: + if (!plci->relatedPTYPLCI) break; + rplci = plci->relatedPTYPLCI; + SSparms[1] = plci->ptyState; + rId = ((word)rplci->Id << 8) | rplci->adapter->Id; + if (rplci->tel) rId |= EXT_CONTROLLER; + if (rc != OK) + { + Info = 0x300E; /* not supported */ + plci->relatedPTYPLCI = NULL; + plci->ptyState = 0; + } + sendf(rplci->appl, + _FACILITY_R | CONFIRM, + rId, + plci->number, + "wws", Info, (word)3, SSparms); + break; + + /* Explicit Call Transfer pending */ + case ECT_REQ_PEND: + dbug(1, dprintf("ECT_RC=0x%x/0x%x", req, rc)); + if (!plci->relatedPTYPLCI) break; + rplci = plci->relatedPTYPLCI; + SSparms[1] = S_ECT; + rId = ((word)rplci->Id << 8) | rplci->adapter->Id; + if (rplci->tel) rId |= EXT_CONTROLLER; + if (rc != OK) + { + Info = 0x300E; /* not supported */ + plci->relatedPTYPLCI = NULL; + plci->ptyState = 0; + } + sendf(rplci->appl, + _FACILITY_R | CONFIRM, + rId, + plci->number, + "wws", Info, (word)3, SSparms); + break; + + case _MANUFACTURER_R: + dbug(1, dprintf("_Manufacturer_R=0x%x/0x%x", req, rc)); + if ((global_req == ASSIGN) && (rc != ASSIGN_OK)) + { + dbug(1, dprintf("No more IDs")); + sendf(appl, _MANUFACTURER_R | CONFIRM, Id, Number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI); + plci_remove(plci); /* after codec init, internal codec commands pending */ + } + break; + + case _CONNECT_R: + dbug(1, dprintf("_Connect_R=0x%x/0x%x", req, rc)); + if ((global_req == ASSIGN) && (rc != ASSIGN_OK)) + { + dbug(1, dprintf("No more IDs")); + sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI); + plci_remove(plci); /* after codec init, internal codec commands pending */ + } + break; + + case PERM_COD_HOOK: /* finished with Hook_Ind */ + return; + + case PERM_COD_CALL: + dbug(1, dprintf("***Codec Connect_Pending A, Rc = 0x%x", rc)); + plci->internal_command = PERM_COD_CONN_PEND; + return; + + case PERM_COD_ASSIGN: + dbug(1, dprintf("***Codec Assign A, Rc = 0x%x", rc)); + if (rc != ASSIGN_OK) break; + sig_req(plci, CALL_REQ, 0); + send_req(plci); + plci->internal_command = PERM_COD_CALL; + return; + + /* Null Call Reference Request pending */ + case C_NCR_FAC_REQ: + dbug(1, dprintf("NCR_FAC=0x%x/0x%x", req, rc)); + if (global_req == ASSIGN) + { + if (rc == ASSIGN_OK) + { + return; + } + else + { + sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE); + appl->NullCREnable = false; + plci_remove(plci); + } + } + else if (req == NCR_FACILITY) + { + if (rc == OK) + { + sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", 0); + } + else + { + sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE); + appl->NullCREnable = false; + } + plci_remove(plci); + } + break; + + case HOOK_ON_REQ: + if (plci->channels) + { + if (a->ncci_state[ncci] == CONNECTED) + { + a->ncci_state[ncci] = OUTG_DIS_PENDING; + cleanup_ncci_data(plci, ncci); + nl_req_ncci(plci, N_DISC, (byte)ncci); + } + break; + } + break; + + case HOOK_OFF_REQ: + if (plci->State == INC_DIS_PENDING) + break; + sig_req(plci, CALL_REQ, 0); + send_req(plci); + plci->State = OUTG_CON_PENDING; + break; + + + case MWI_ACTIVATE_REQ_PEND: + case MWI_DEACTIVATE_REQ_PEND: + if (global_req == ASSIGN && rc == ASSIGN_OK) + { + dbug(1, dprintf("MWI_REQ assigned")); + return; + } + else if (rc != OK) + { + if (rc == WRONG_IE) + { + Info = 0x2007; /* Illegal message parameter coding */ + dbug(1, dprintf("MWI_REQ invalid parameter")); + } + else + { + Info = 0x300B; /* not supported */ + dbug(1, dprintf("MWI_REQ not supported")); + } + /* 0x3010: Request not allowed in this state */ + PUT_WORD(&SSparms[4], 0x300E); /* SS not supported */ + + } + if (plci->internal_command == MWI_ACTIVATE_REQ_PEND) + { + PUT_WORD(&SSparms[1], S_MWI_ACTIVATE); + } + else PUT_WORD(&SSparms[1], S_MWI_DEACTIVATE); + + if (plci->cr_enquiry) + { + sendf(plci->appl, + _FACILITY_R | CONFIRM, + Id & 0xf, + plci->number, + "wws", Info, (word)3, SSparms); + if (rc != OK) plci_remove(plci); + } + else + { + sendf(plci->appl, + _FACILITY_R | CONFIRM, + Id, + plci->number, + "wws", Info, (word)3, SSparms); + } + break; + + case CONF_BEGIN_REQ_PEND: + case CONF_ADD_REQ_PEND: + case CONF_SPLIT_REQ_PEND: + case CONF_DROP_REQ_PEND: + case CONF_ISOLATE_REQ_PEND: + case CONF_REATTACH_REQ_PEND: + dbug(1, dprintf("CONF_RC=0x%x/0x%x", req, rc)); + if ((plci->internal_command == CONF_ADD_REQ_PEND) && (!plci->relatedPTYPLCI)) break; + rplci = plci; + rId = Id; + switch (plci->internal_command) + { + case CONF_BEGIN_REQ_PEND: + SSparms[1] = S_CONF_BEGIN; + break; + case CONF_ADD_REQ_PEND: + SSparms[1] = S_CONF_ADD; + rplci = plci->relatedPTYPLCI; + rId = ((word)rplci->Id << 8) | rplci->adapter->Id; + break; + case CONF_SPLIT_REQ_PEND: + SSparms[1] = S_CONF_SPLIT; + break; + case CONF_DROP_REQ_PEND: + SSparms[1] = S_CONF_DROP; + break; + case CONF_ISOLATE_REQ_PEND: + SSparms[1] = S_CONF_ISOLATE; + break; + case CONF_REATTACH_REQ_PEND: + SSparms[1] = S_CONF_REATTACH; + break; + } + + if (rc != OK) + { + Info = 0x300E; /* not supported */ + plci->relatedPTYPLCI = NULL; + plci->ptyState = 0; + } + sendf(rplci->appl, + _FACILITY_R | CONFIRM, + rId, + plci->number, + "wws", Info, (word)3, SSparms); + break; + + case VSWITCH_REQ_PEND: + if (rc != OK) + { + if (plci->relatedPTYPLCI) + { + plci->relatedPTYPLCI->vswitchstate = 0; + plci->relatedPTYPLCI->vsprot = 0; + plci->relatedPTYPLCI->vsprotdialect = 0; + } + plci->vswitchstate = 0; + plci->vsprot = 0; + plci->vsprotdialect = 0; + } + else + { + if (plci->relatedPTYPLCI && + plci->vswitchstate == 1 && + plci->relatedPTYPLCI->vswitchstate == 3) /* join complete */ + plci->vswitchstate = 3; + } + break; + + /* Call Deflection Request pending (SSCT) */ + case CD_REQ_PEND: + SSparms[1] = S_CALL_DEFLECTION; + if (rc != OK) + { + Info = 0x300E; /* not supported */ + plci->appl->CDEnable = 0; + } + sendf(plci->appl, _FACILITY_R | CONFIRM, Id, + plci->number, "wws", Info, (word)3, SSparms); + break; + + case RTP_CONNECT_B3_REQ_COMMAND_2: + if (rc == OK) + { + ncci = get_ncci(plci, ch, 0); + Id = (Id & 0xffff) | (((dword) ncci) << 16); + plci->channels++; + a->ncci_state[ncci] = OUTG_CON_PENDING; + } + + default: + if (plci->internal_command_queue[0]) + { + (*(plci->internal_command_queue[0]))(Id, plci, rc); + if (plci->internal_command) + return; + } + break; + } + next_internal_command(Id, plci); + } + } + else /* appl==0 */ + { + Id = ((word)plci->Id << 8) | plci->adapter->Id; + if (plci->tel) Id |= EXT_CONTROLLER; + + switch (plci->internal_command) + { + case BLOCK_PLCI: + return; + + case START_L1_SIG_ASSIGN_PEND: + case REM_L1_SIG_ASSIGN_PEND: + if (global_req == ASSIGN) + { + break; + } + else + { + dbug(1, dprintf("***L1 Req rem PLCI")); + plci->internal_command = 0; + sig_req(plci, REMOVE, 0); + send_req(plci); + } + break; + + /* Call Deflection Request pending, just no appl ptr assigned */ + case CD_REQ_PEND: + SSparms[1] = S_CALL_DEFLECTION; + if (rc != OK) + { + Info = 0x300E; /* not supported */ + } + for (i = 0; i < max_appl; i++) + { + if (application[i].CDEnable) + { + if (!application[i].Id) application[i].CDEnable = 0; + else + { + sendf(&application[i], _FACILITY_R | CONFIRM, Id, + plci->number, "wws", Info, (word)3, SSparms); + if (Info) application[i].CDEnable = 0; + } + } + } + plci->internal_command = 0; + break; + + case PERM_COD_HOOK: /* finished with Hook_Ind */ + return; + + case PERM_COD_CALL: + plci->internal_command = PERM_COD_CONN_PEND; + dbug(1, dprintf("***Codec Connect_Pending, Rc = 0x%x", rc)); + return; + + case PERM_COD_ASSIGN: + dbug(1, dprintf("***Codec Assign, Rc = 0x%x", rc)); + plci->internal_command = 0; + if (rc != ASSIGN_OK) break; + plci->internal_command = PERM_COD_CALL; + sig_req(plci, CALL_REQ, 0); + send_req(plci); + return; + + case LISTEN_SIG_ASSIGN_PEND: + if (rc == ASSIGN_OK) + { + plci->internal_command = 0; + dbug(1, dprintf("ListenCheck, new SIG_ID = 0x%x", plci->Sig.Id)); + add_p(plci, ESC, "\x02\x18\x00"); /* support call waiting */ + sig_req(plci, INDICATE_REQ, 0); + send_req(plci); + } + else + { + dbug(1, dprintf("ListenCheck failed (assignRc=0x%x)", rc)); + a->listen_active--; + plci_remove(plci); + plci->State = IDLE; + } + break; + + case USELAW_REQ: + if (global_req == ASSIGN) + { + if (rc == ASSIGN_OK) + { + sig_req(plci, LAW_REQ, 0); + send_req(plci); + dbug(1, dprintf("Auto-Law assigned")); + } + else + { + dbug(1, dprintf("Auto-Law assign failed")); + a->automatic_law = 3; + plci->internal_command = 0; + a->automatic_lawPLCI = NULL; + } + break; + } + else if (req == LAW_REQ && rc == OK) + { + dbug(1, dprintf("Auto-Law initiated")); + a->automatic_law = 2; + plci->internal_command = 0; + } + else + { + dbug(1, dprintf("Auto-Law not supported")); + a->automatic_law = 3; + plci->internal_command = 0; + sig_req(plci, REMOVE, 0); + send_req(plci); + a->automatic_lawPLCI = NULL; + } + break; + } + plci_remove_check(plci); + } +} + +static void data_rc(PLCI *plci, byte ch) +{ + dword Id; + DIVA_CAPI_ADAPTER *a; + NCCI *ncci_ptr; + DATA_B3_DESC *data; + word ncci; + + if (plci->appl) + { + TransmitBufferFree(plci->appl, plci->data_sent_ptr); + a = plci->adapter; + ncci = a->ch_ncci[ch]; + if (ncci && (a->ncci_plci[ncci] == plci->Id)) + { + ncci_ptr = &(a->ncci[ncci]); + dbug(1, dprintf("data_out=%d, data_pending=%d", ncci_ptr->data_out, ncci_ptr->data_pending)); + if (ncci_ptr->data_pending) + { + data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]); + if (!(data->Flags & 4) && a->ncci_state[ncci]) + { + Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id; + if (plci->tel) Id |= EXT_CONTROLLER; + sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, data->Number, + "ww", data->Handle, 0); + } + (ncci_ptr->data_out)++; + if (ncci_ptr->data_out == MAX_DATA_B3) + ncci_ptr->data_out = 0; + (ncci_ptr->data_pending)--; + } + } + } +} + +static void data_ack(PLCI *plci, byte ch) +{ + dword Id; + DIVA_CAPI_ADAPTER *a; + NCCI *ncci_ptr; + word ncci; + + a = plci->adapter; + ncci = a->ch_ncci[ch]; + ncci_ptr = &(a->ncci[ncci]); + if (ncci_ptr->data_ack_pending) + { + if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id)) + { + Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id; + if (plci->tel) Id |= EXT_CONTROLLER; + sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, ncci_ptr->DataAck[ncci_ptr->data_ack_out].Number, + "ww", ncci_ptr->DataAck[ncci_ptr->data_ack_out].Handle, 0); + } + (ncci_ptr->data_ack_out)++; + if (ncci_ptr->data_ack_out == MAX_DATA_ACK) + ncci_ptr->data_ack_out = 0; + (ncci_ptr->data_ack_pending)--; + } +} + +static void sig_ind(PLCI *plci) +{ + dword x_Id; + dword Id; + dword rId; + word i; + word cip; + dword cip_mask; + byte *ie; + DIVA_CAPI_ADAPTER *a; + API_PARSE saved_parms[MAX_MSG_PARMS + 1]; #define MAXPARMSIDS 31 - byte * parms[MAXPARMSIDS]; - byte * add_i[4]; - byte * multi_fac_parms[MAX_MULTI_IE]; - byte * multi_pi_parms [MAX_MULTI_IE]; - byte * multi_ssext_parms [MAX_MULTI_IE]; - byte * multi_CiPN_parms [MAX_MULTI_IE]; - - byte * multi_vswitch_parms [MAX_MULTI_IE]; - - byte ai_len; - byte *esc_chi = ""; - byte *esc_law = ""; - byte *pty_cai = ""; - byte *esc_cr = ""; - byte *esc_profile = ""; - - byte facility[256]; - PLCI * tplci = NULL; - byte chi[] = "\x02\x18\x01"; - byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08"; - byte resume_cau[] = "\x05\x05\x00\x02\x00\x00"; - /* ESC_MSGTYPE must be the last but one message, a new IE has to be */ - /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */ - /* SMSG is situated at the end because its 0 (for compatibility reasons */ - /* (see Info_Mask Bit 4, first IE. then the message type) */ - word parms_id[] = - {MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA, - UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW, - RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR, - CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG}; - /* 14 FTY repl by ESC_CHI */ - /* 18 PI repl by ESC_LAW */ - /* removed OAD changed to 0xff for future use, OAD is multiIE now */ - word multi_fac_id[] = {1, FTY}; - word multi_pi_id[] = {1, PI}; - word multi_CiPN_id[] = {1, OAD}; - word multi_ssext_id[] = {1, ESC_SSEXT}; - - word multi_vswitch_id[] = {1, ESC_VSWITCH}; - - byte * cau; - word ncci; - byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ - byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00"; - byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00"; - byte force_mt_info = FALSE; - byte dir; - dword d; - word w; - - a = plci->adapter; - Id = ((word)plci->Id<<8)|a->Id; - PUT_WORD(&SS_Ind[4],0x0000); - - if (plci->sig_remove_id) - { - plci->Sig.RNR = 2; /* discard */ - dbug(1,dprintf("SIG discard while remove pending")); - return; - } - if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER; - dbug(1,dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d", - Id,plci->Id,plci->tel,plci->State,plci->channels,plci->hangup_flow_ctrl_timer)); - if(plci->Sig.Ind==CALL_HOLD_ACK && plci->channels) - { - plci->Sig.RNR = 1; - return; - } - if(plci->Sig.Ind==HANGUP && plci->channels) - { - plci->Sig.RNR = 1; - plci->hangup_flow_ctrl_timer++; - /* recover the network layer after timeout */ - if(plci->hangup_flow_ctrl_timer==100) - { - dbug(1,dprintf("Exceptional disc")); - plci->Sig.RNR = 0; - plci->hangup_flow_ctrl_timer = 0; - for (ncci = 1; ncci < MAX_NCCI+1; ncci++) - { - if (a->ncci_plci[ncci] == plci->Id) - { - cleanup_ncci_data (plci, ncci); - if(plci->channels)plci->channels--; - if (plci->appl) - sendf(plci->appl,_DISCONNECT_B3_I, (((dword) ncci) << 16) | Id,0,"ws",0,""); - } - } - if (plci->appl) - sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0); - plci_remove(plci); - plci->State=IDLE; - } - return; - } - - /* do first parse the info with no OAD in, because OAD will be converted */ - /* first the multiple facility IE, then mult. progress ind. */ - /* then the parameters for the info_ind + conn_ind */ - IndParse(plci,multi_fac_id,multi_fac_parms,MAX_MULTI_IE); - IndParse(plci,multi_pi_id,multi_pi_parms,MAX_MULTI_IE); - IndParse(plci,multi_ssext_id,multi_ssext_parms,MAX_MULTI_IE); - - IndParse(plci,multi_vswitch_id,multi_vswitch_parms,MAX_MULTI_IE); - - IndParse(plci,parms_id,parms,0); - IndParse(plci,multi_CiPN_id,multi_CiPN_parms,MAX_MULTI_IE); - esc_chi = parms[14]; - esc_law = parms[18]; - pty_cai = parms[24]; - esc_cr = parms[25]; - esc_profile = parms[27]; - if(esc_cr[0] && plci) - { - if(plci->cr_enquiry && plci->appl) - { - plci->cr_enquiry = FALSE; - /* d = MANU_ID */ - /* w = m_command */ - /* b = total length */ - /* b = indication type */ - /* b = length of all IEs */ - /* b = IE1 */ - /* S = IE1 length + cont. */ - /* b = IE2 */ - /* S = IE2 lenght + cont. */ - sendf(plci->appl, - _MANUFACTURER_I, - Id, - 0, - "dwbbbbSbS",_DI_MANU_ID,plci->m_command, - 2+1+1+esc_cr[0]+1+1+esc_law[0],plci->Sig.Ind,1+1+esc_cr[0]+1+1+esc_law[0],ESC,esc_cr,ESC,esc_law); - } - } - /* create the additional info structure */ - add_i[1] = parms[15]; /* KEY of additional info */ - add_i[2] = parms[11]; /* UUI of additional info */ - ai_len = AddInfo(add_i,multi_fac_parms, esc_chi, facility); - - /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card */ - /* indication returns by the card if requested by the function */ - /* AutomaticLaw() after driver init */ - if (a->automatic_law<4) - { - if(esc_law[0]){ - if(esc_law[2]){ - dbug(0,dprintf("u-Law selected")); - a->u_law = 1; - } - else { - dbug(0,dprintf("a-Law selected")); - a->u_law = 0; - } - a->automatic_law = 4; - if(plci==a->automatic_lawPLCI) { - plci->internal_command = 0; - sig_req(plci,REMOVE,0); - send_req(plci); - a->automatic_lawPLCI = NULL; - } - } - if (esc_profile[0]) - { - dbug (1, dprintf ("[%06x] CardProfile: %lx %lx %lx %lx %lx", - UnMapController (a->Id), GET_DWORD (&esc_profile[6]), - GET_DWORD (&esc_profile[10]), GET_DWORD (&esc_profile[14]), - GET_DWORD (&esc_profile[18]), GET_DWORD (&esc_profile[46]))); - - a->profile.Global_Options &= 0x000000ffL; - a->profile.B1_Protocols &= 0x000003ffL; - a->profile.B2_Protocols &= 0x00001fdfL; - a->profile.B3_Protocols &= 0x000000b7L; - - a->profile.Global_Options &= GET_DWORD (&esc_profile[6]) | - GL_BCHANNEL_OPERATION_SUPPORTED; - a->profile.B1_Protocols &= GET_DWORD (&esc_profile[10]); - a->profile.B2_Protocols &= GET_DWORD (&esc_profile[14]); - a->profile.B3_Protocols &= GET_DWORD (&esc_profile[18]); - a->manufacturer_features = GET_DWORD (&esc_profile[46]); - a->man_profile.private_options = 0; - - if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER) - { - a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER; - a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED; - } - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP) - a->man_profile.private_options |= 1L << PRIVATE_RTP; - a->man_profile.rtp_primary_payloads = GET_DWORD (&esc_profile[50]); - a->man_profile.rtp_additional_payloads = GET_DWORD (&esc_profile[54]); - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_T38) - a->man_profile.private_options |= 1L << PRIVATE_T38; - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD) - a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD; - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_V18) - a->man_profile.private_options |= 1L << PRIVATE_V18; - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE) - a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE; - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS) - a->man_profile.private_options |= 1L << PRIVATE_PIAFS; - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) - a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS; - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN) - a->man_profile.private_options |= 1L << PRIVATE_VOWN; - - - if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD) - a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD; - - } - else - { - a->profile.Global_Options &= 0x0000007fL; - a->profile.B1_Protocols &= 0x000003dfL; - a->profile.B2_Protocols &= 0x00001adfL; - a->profile.B3_Protocols &= 0x000000b7L; - a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF; - } - if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF | - MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) - { - a->profile.Global_Options |= GL_DTMF_SUPPORTED; - } - a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL; - dbug (1, dprintf ("[%06x] Profile: %lx %lx %lx %lx %lx", - UnMapController (a->Id), a->profile.Global_Options, - a->profile.B1_Protocols, a->profile.B2_Protocols, - a->profile.B3_Protocols, a->manufacturer_features)); - } - /* codec plci for the handset/hook state support is just an internal id */ - if(plci!=a->AdvCodecPLCI) - { - force_mt_info = SendMultiIE(plci,Id,multi_fac_parms, FTY, 0x20, 0); - force_mt_info |= SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, 0); - SendSSExtInd(NULL,plci,Id,multi_ssext_parms); - SendInfo(plci,Id, parms, force_mt_info); - - VSwitchReqInd(plci,Id,multi_vswitch_parms); - - } - - /* switch the codec to the b-channel */ - if(esc_chi[0] && plci && !plci->SuppState){ - plci->b_channel = esc_chi[esc_chi[0]]&0x1f; - mixer_set_bchannel_id_esc (plci, plci->b_channel); - dbug(1,dprintf("storeChannel=0x%x",plci->b_channel)); - if(plci->tel==ADV_VOICE && plci->appl) { - SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a); - } - } - - if(plci->appl) Number = plci->appl->Number++; - - switch(plci->Sig.Ind) { - /* Response to Get_Supported_Services request */ - case S_SUPPORTED: - dbug(1,dprintf("S_Supported")); - if(!plci->appl) break; - if(pty_cai[0]==4) - { - PUT_DWORD(&CF_Ind[6],GET_DWORD(&pty_cai[1]) ); - } - else - { - PUT_DWORD(&CF_Ind[6],MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE); - } - PUT_WORD (&CF_Ind[1], 0); - PUT_WORD (&CF_Ind[4], 0); - sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7,plci->number, "wws",0,3,CF_Ind); - plci_remove(plci); - break; - - /* Supplementary Service rejected */ - case S_SERVICE_REJ: - dbug(1,dprintf("S_Reject=0x%x",pty_cai[5])); - if(!pty_cai[0]) break; - switch (pty_cai[5]) - { - case ECT_EXECUTE: - case THREE_PTY_END: - case THREE_PTY_BEGIN: - if(!plci->relatedPTYPLCI) break; - tplci = plci->relatedPTYPLCI; - rId = ( (word)tplci->Id<<8)|tplci->adapter->Id; - if(tplci->tel) rId|=EXT_CONTROLLER; - if(pty_cai[5]==ECT_EXECUTE) - { - PUT_WORD(&SS_Ind[1],S_ECT); - - plci->vswitchstate=0; - plci->relatedPTYPLCI->vswitchstate=0; - - } - else - { - PUT_WORD(&SS_Ind[1],pty_cai[5]+3); - } - if(pty_cai[2]!=0xff) - { - PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]); - } - else - { - PUT_WORD(&SS_Ind[4],0x300E); - } - plci->relatedPTYPLCI = NULL; - plci->ptyState = 0; - sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind); - break; - - case CALL_DEFLECTION: - if(pty_cai[2]!=0xff) - { - PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]); - } - else - { - PUT_WORD(&SS_Ind[4],0x300E); - } - PUT_WORD(&SS_Ind[1],pty_cai[5]); - for(i=0; i<max_appl; i++) - { - if(application[i].CDEnable) - { - if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind); - application[i].CDEnable = FALSE; - } - } - break; - - case DEACTIVATION_DIVERSION: - case ACTIVATION_DIVERSION: - case DIVERSION_INTERROGATE_CFU: - case DIVERSION_INTERROGATE_CFB: - case DIVERSION_INTERROGATE_CFNR: - case DIVERSION_INTERROGATE_NUM: - case CCBS_REQUEST: - case CCBS_DEACTIVATE: - case CCBS_INTERROGATE: - if(!plci->appl) break; - if(pty_cai[2]!=0xff) - { - PUT_WORD(&Interr_Err_Ind[4],0x3600|(word)pty_cai[2]); - } - else - { - PUT_WORD(&Interr_Err_Ind[4],0x300E); - } - switch (pty_cai[5]) - { - case DEACTIVATION_DIVERSION: - dbug(1,dprintf("Deact_Div")); - Interr_Err_Ind[0]=0x9; - Interr_Err_Ind[3]=0x6; - PUT_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_STOP); - break; - case ACTIVATION_DIVERSION: - dbug(1,dprintf("Act_Div")); - Interr_Err_Ind[0]=0x9; - Interr_Err_Ind[3]=0x6; - PUT_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_START); - break; - case DIVERSION_INTERROGATE_CFU: - case DIVERSION_INTERROGATE_CFB: - case DIVERSION_INTERROGATE_CFNR: - dbug(1,dprintf("Interr_Div")); - Interr_Err_Ind[0]=0xa; - Interr_Err_Ind[3]=0x7; - PUT_WORD(&Interr_Err_Ind[1],S_INTERROGATE_DIVERSION); - break; - case DIVERSION_INTERROGATE_NUM: - dbug(1,dprintf("Interr_Num")); - Interr_Err_Ind[0]=0xa; - Interr_Err_Ind[3]=0x7; - PUT_WORD(&Interr_Err_Ind[1],S_INTERROGATE_NUMBERS); - break; - case CCBS_REQUEST: - dbug(1,dprintf("CCBS Request")); - Interr_Err_Ind[0]=0xd; - Interr_Err_Ind[3]=0xa; - PUT_WORD(&Interr_Err_Ind[1],S_CCBS_REQUEST); - break; - case CCBS_DEACTIVATE: - dbug(1,dprintf("CCBS Deactivate")); - Interr_Err_Ind[0]=0x9; - Interr_Err_Ind[3]=0x6; - PUT_WORD(&Interr_Err_Ind[1],S_CCBS_DEACTIVATE); - break; - case CCBS_INTERROGATE: - dbug(1,dprintf("CCBS Interrogate")); - Interr_Err_Ind[0]=0xb; - Interr_Err_Ind[3]=0x8; - PUT_WORD(&Interr_Err_Ind[1],S_CCBS_INTERROGATE); - break; - } - PUT_DWORD(&Interr_Err_Ind[6],plci->appl->S_Handle); - sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, Interr_Err_Ind); - plci_remove(plci); - break; - case ACTIVATION_MWI: - case DEACTIVATION_MWI: - if(pty_cai[5]==ACTIVATION_MWI) - { - PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE); - } - else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE); - - if(pty_cai[2]!=0xff) - { - PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]); - } - else - { - PUT_WORD(&SS_Ind[4],0x300E); - } - - if(plci->cr_enquiry) - { - sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind); - plci_remove(plci); - } - else - { - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); - } - break; - case CONF_ADD: /* ERROR */ - case CONF_BEGIN: - case CONF_DROP: - case CONF_ISOLATE: - case CONF_REATTACH: - CONF_Ind[0]=9; - CONF_Ind[3]=6; - switch(pty_cai[5]) - { - case CONF_BEGIN: - PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN); - plci->ptyState = 0; - break; - case CONF_DROP: - CONF_Ind[0]=5; - CONF_Ind[3]=2; - PUT_WORD(&CONF_Ind[1],S_CONF_DROP); - plci->ptyState = CONNECTED; - break; - case CONF_ISOLATE: - CONF_Ind[0]=5; - CONF_Ind[3]=2; - PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE); - plci->ptyState = CONNECTED; - break; - case CONF_REATTACH: - CONF_Ind[0]=5; - CONF_Ind[3]=2; - PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH); - plci->ptyState = CONNECTED; - break; - case CONF_ADD: - PUT_WORD(&CONF_Ind[1],S_CONF_ADD); - plci->relatedPTYPLCI = NULL; - tplci=plci->relatedPTYPLCI; - if(tplci) tplci->ptyState = CONNECTED; - plci->ptyState = CONNECTED; - break; - } - - if(pty_cai[2]!=0xff) - { - PUT_WORD(&CONF_Ind[4],0x3600|(word)pty_cai[2]); - } - else - { - PUT_WORD(&CONF_Ind[4],0x3303); /* Time-out: network did not respond - within the required time */ - } - - PUT_DWORD(&CONF_Ind[6],0x0); - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind); - break; - } - break; - - /* Supplementary Service indicates success */ - case S_SERVICE: - dbug(1,dprintf("Service_Ind")); - PUT_WORD (&CF_Ind[4], 0); - switch (pty_cai[5]) - { - case THREE_PTY_END: - case THREE_PTY_BEGIN: - case ECT_EXECUTE: - if(!plci->relatedPTYPLCI) break; - tplci = plci->relatedPTYPLCI; - rId = ( (word)tplci->Id<<8)|tplci->adapter->Id; - if(tplci->tel) rId|=EXT_CONTROLLER; - if(pty_cai[5]==ECT_EXECUTE) - { - PUT_WORD(&SS_Ind[1],S_ECT); - - if(plci->vswitchstate!=3) - { - - plci->ptyState = IDLE; - plci->relatedPTYPLCI = NULL; - plci->ptyState = 0; - - } - - dbug(1,dprintf("ECT OK")); - sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind); - - - - } - else - { - switch (plci->ptyState) - { - case S_3PTY_BEGIN: - plci->ptyState = CONNECTED; - dbug(1,dprintf("3PTY ON")); - break; - - case S_3PTY_END: - plci->ptyState = IDLE; - plci->relatedPTYPLCI = NULL; - plci->ptyState = 0; - dbug(1,dprintf("3PTY OFF")); - break; - } - PUT_WORD(&SS_Ind[1],pty_cai[5]+3); - sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind); - } - break; - - case CALL_DEFLECTION: - PUT_WORD(&SS_Ind[1],pty_cai[5]); - for(i=0; i<max_appl; i++) - { - if(application[i].CDEnable) - { - if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind); - application[i].CDEnable = FALSE; - } - } - break; - - case DEACTIVATION_DIVERSION: - case ACTIVATION_DIVERSION: - if(!plci->appl) break; - PUT_WORD(&CF_Ind[1],pty_cai[5]+2); - PUT_DWORD(&CF_Ind[6],plci->appl->S_Handle); - sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, CF_Ind); - plci_remove(plci); - break; - - case DIVERSION_INTERROGATE_CFU: - case DIVERSION_INTERROGATE_CFB: - case DIVERSION_INTERROGATE_CFNR: - case DIVERSION_INTERROGATE_NUM: - case CCBS_REQUEST: - case CCBS_DEACTIVATE: - case CCBS_INTERROGATE: - if(!plci->appl) break; - switch (pty_cai[5]) - { - case DIVERSION_INTERROGATE_CFU: - case DIVERSION_INTERROGATE_CFB: - case DIVERSION_INTERROGATE_CFNR: - dbug(1,dprintf("Interr_Div")); - PUT_WORD(&pty_cai[1],S_INTERROGATE_DIVERSION); - pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ - break; - case DIVERSION_INTERROGATE_NUM: - dbug(1,dprintf("Interr_Num")); - PUT_WORD(&pty_cai[1],S_INTERROGATE_NUMBERS); - pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ - break; - case CCBS_REQUEST: - dbug(1,dprintf("CCBS Request")); - PUT_WORD(&pty_cai[1],S_CCBS_REQUEST); - pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ - break; - case CCBS_DEACTIVATE: - dbug(1,dprintf("CCBS Deactivate")); - PUT_WORD(&pty_cai[1],S_CCBS_DEACTIVATE); - pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ - break; - case CCBS_INTERROGATE: - dbug(1,dprintf("CCBS Interrogate")); - PUT_WORD(&pty_cai[1],S_CCBS_INTERROGATE); - pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */ - break; - } - PUT_WORD(&pty_cai[4],0); /* Supplementary Service Reason */ - PUT_DWORD(&pty_cai[6],plci->appl->S_Handle); - sendf(plci->appl,_FACILITY_I,Id&0x7,0,"wS",3, pty_cai); - plci_remove(plci); - break; - - case ACTIVATION_MWI: - case DEACTIVATION_MWI: - if(pty_cai[5]==ACTIVATION_MWI) - { - PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE); - } - else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE); - if(plci->cr_enquiry) - { - sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind); - plci_remove(plci); - } - else - { - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); - } - break; - case MWI_INDICATION: - if(pty_cai[0]>=0x12) - { - PUT_WORD(&pty_cai[3],S_MWI_INDICATE); - pty_cai[2]=pty_cai[0]-2; /* len Parameter */ - pty_cai[5]=pty_cai[0]-5; /* Supplementary Service-specific parameter len */ - if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_MWI)) - { - if(plci->internal_command==GET_MWI_STATE) /* result on Message Waiting Listen */ - { - sendf(plci->appl,_FACILITY_I,Id&0xf,0,"wS",3, &pty_cai[2]); - plci_remove(plci); - return; - } - else sendf(plci->appl,_FACILITY_I,Id,0,"wS",3, &pty_cai[2]); - pty_cai[0]=0; - } - else - { - for(i=0; i<max_appl; i++) - { - if(a->Notification_Mask[i]&SMASK_MWI) - { - sendf(&application[i],_FACILITY_I,Id&0x7,0,"wS",3, &pty_cai[2]); - pty_cai[0]=0; - } - } - } - - if(!pty_cai[0]) - { /* acknowledge */ - facility[2]= 0; /* returncode */ - } - else facility[2]= 0xff; - } - else - { - /* reject */ - facility[2]= 0xff; /* returncode */ - } - facility[0]= 2; - facility[1]= MWI_RESPONSE; /* Function */ - add_p(plci,CAI,facility); - add_p(plci,ESC,multi_ssext_parms[0]); /* remembered parameter -> only one possible */ - sig_req(plci,S_SERVICE,0); - send_req(plci); - plci->command = 0; - next_internal_command (Id, plci); - break; - case CONF_ADD: /* OK */ - case CONF_BEGIN: - case CONF_DROP: - case CONF_ISOLATE: - case CONF_REATTACH: - case CONF_PARTYDISC: - CONF_Ind[0]=9; - CONF_Ind[3]=6; - switch(pty_cai[5]) - { - case CONF_BEGIN: - PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN); - if(pty_cai[0]==6) - { - d=pty_cai[6]; - PUT_DWORD(&CONF_Ind[6],d); /* PartyID */ - } - else - { - PUT_DWORD(&CONF_Ind[6],0x0); - } - break; - case CONF_ISOLATE: - PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE); - CONF_Ind[0]=5; - CONF_Ind[3]=2; - break; - case CONF_REATTACH: - PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH); - CONF_Ind[0]=5; - CONF_Ind[3]=2; - break; - case CONF_DROP: - PUT_WORD(&CONF_Ind[1],S_CONF_DROP); - CONF_Ind[0]=5; - CONF_Ind[3]=2; - break; - case CONF_ADD: - PUT_WORD(&CONF_Ind[1],S_CONF_ADD); - d=pty_cai[6]; - PUT_DWORD(&CONF_Ind[6],d); /* PartyID */ - tplci=plci->relatedPTYPLCI; - if(tplci) tplci->ptyState = CONNECTED; - break; - case CONF_PARTYDISC: - CONF_Ind[0]=7; - CONF_Ind[3]=4; - PUT_WORD(&CONF_Ind[1],S_CONF_PARTYDISC); - d=pty_cai[6]; - PUT_DWORD(&CONF_Ind[4],d); /* PartyID */ - break; - } - plci->ptyState = CONNECTED; - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind); - break; - case CCBS_INFO_RETAIN: - case CCBS_ERASECALLLINKAGEID: - case CCBS_STOP_ALERTING: - CONF_Ind[0]=5; - CONF_Ind[3]=2; - switch(pty_cai[5]) - { - case CCBS_INFO_RETAIN: - PUT_WORD(&CONF_Ind[1],S_CCBS_INFO_RETAIN); - break; - case CCBS_STOP_ALERTING: - PUT_WORD(&CONF_Ind[1],S_CCBS_STOP_ALERTING); - break; - case CCBS_ERASECALLLINKAGEID: - PUT_WORD(&CONF_Ind[1],S_CCBS_ERASECALLLINKAGEID); - CONF_Ind[0]=7; - CONF_Ind[3]=4; - CONF_Ind[6]=0; - CONF_Ind[7]=0; - break; - } - w=pty_cai[6]; - PUT_WORD(&CONF_Ind[4],w); /* PartyID */ - - if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_CCBS)) - { - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind); - } - else - { - for(i=0; i<max_appl; i++) - if(a->Notification_Mask[i]&SMASK_CCBS) - sendf(&application[i],_FACILITY_I,Id&0x7,0,"ws",3, CONF_Ind); - } - break; - } - break; - case CALL_HOLD_REJ: - cau = parms[7]; - if(cau) - { - i = _L3_CAUSE | cau[2]; - if(cau[2]==0) i = 0x3603; - } - else - { - i = 0x3603; - } - PUT_WORD(&SS_Ind[1],S_HOLD); - PUT_WORD(&SS_Ind[4],i); - if(plci->SuppState == HOLD_REQUEST) - { - plci->SuppState = IDLE; - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); - } - break; - - case CALL_HOLD_ACK: - if(plci->SuppState == HOLD_REQUEST) - { - plci->SuppState = CALL_HELD; - CodecIdCheck(a, plci); - start_internal_command (Id, plci, hold_save_command); - } - break; - - case CALL_RETRIEVE_REJ: - cau = parms[7]; - if(cau) - { - i = _L3_CAUSE | cau[2]; - if(cau[2]==0) i = 0x3603; - } - else - { - i = 0x3603; - } - PUT_WORD(&SS_Ind[1],S_RETRIEVE); - PUT_WORD(&SS_Ind[4],i); - if(plci->SuppState == RETRIEVE_REQUEST) - { - plci->SuppState = CALL_HELD; - CodecIdCheck(a, plci); - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); - } - break; - - case CALL_RETRIEVE_ACK: - PUT_WORD(&SS_Ind[1],S_RETRIEVE); - if(plci->SuppState == RETRIEVE_REQUEST) - { - plci->SuppState = IDLE; - plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; - plci->b_channel = esc_chi[esc_chi[0]]&0x1f; - if(plci->tel) - { - mixer_set_bchannel_id_esc (plci, plci->b_channel); - dbug(1,dprintf("RetrChannel=0x%x",plci->b_channel)); - SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a); - if(plci->B2_prot==B2_TRANSPARENT && plci->B3_prot==B3_TRANSPARENT) - { - dbug(1,dprintf("Get B-ch")); - start_internal_command (Id, plci, retrieve_restore_command); - } - else - sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind); - } - else - start_internal_command (Id, plci, retrieve_restore_command); - } - break; - - case INDICATE_IND: - if(plci->State != LISTENING) { - sig_req(plci,HANGUP,0); - send_req(plci); - break; - } - cip = find_cip(a,parms[4],parms[6]); - cip_mask = 1L<<cip; - dbug(1,dprintf("cip=%d,cip_mask=%lx",cip,cip_mask)); - clear_c_ind_mask (plci); - if (!remove_started && !a->adapter_disabled) - { - set_c_ind_mask_bit (plci, MAX_APPL); - group_optimization(a, plci); - for(i=0; i<max_appl; i++) { - if(application[i].Id - && (a->CIP_Mask[i]&1 || a->CIP_Mask[i]&cip_mask) - && CPN_filter_ok(parms[0],a,i) - && test_group_ind_mask_bit (plci, i) ) { - dbug(1,dprintf("storedcip_mask[%d]=0x%lx",i,a->CIP_Mask[i] )); - set_c_ind_mask_bit (plci, i); - dump_c_ind_mask (plci); - plci->State = INC_CON_PENDING; - plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) | - CALL_DIR_IN | CALL_DIR_ANSWER; - if(esc_chi[0]) { - plci->b_channel = esc_chi[esc_chi[0]]&0x1f; - mixer_set_bchannel_id_esc (plci, plci->b_channel); - } - /* if a listen on the ext controller is done, check if hook states */ - /* are supported or if just a on board codec must be activated */ - if(a->codec_listen[i] && !a->AdvSignalPLCI) { - if(a->profile.Global_Options & HANDSET) - plci->tel = ADV_VOICE; - else if(a->profile.Global_Options & ON_BOARD_CODEC) - plci->tel = CODEC; - if(plci->tel) Id|=EXT_CONTROLLER; - a->codec_listen[i] = plci; - } - - sendf(&application[i],_CONNECT_I,Id,0, - "wSSSSSSSbSSSSS", cip, /* CIP */ - parms[0], /* CalledPartyNumber */ - multi_CiPN_parms[0], /* CallingPartyNumber */ - parms[2], /* CalledPartySubad */ - parms[3], /* CallingPartySubad */ - parms[4], /* BearerCapability */ - parms[5], /* LowLC */ - parms[6], /* HighLC */ - ai_len, /* nested struct add_i */ - add_i[0], /* B channel info */ - add_i[1], /* keypad facility */ - add_i[2], /* user user data */ - add_i[3], /* nested facility */ - multi_CiPN_parms[1] /* second CiPN(SCR) */ - ); - SendSSExtInd(&application[i], - plci, - Id, - multi_ssext_parms); - SendSetupInfo(&application[i], - plci, - Id, - parms, - SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, TRUE)); - } - } - clear_c_ind_mask_bit (plci, MAX_APPL); - dump_c_ind_mask (plci); - } - if(c_ind_mask_empty (plci)) { - sig_req(plci,HANGUP,0); - send_req(plci); - plci->State = IDLE; - } - plci->notifiedcall = 0; - a->listen_active--; - listen_check(a); - break; - - case CALL_PEND_NOTIFY: - plci->notifiedcall = 1; - listen_check(a); - break; - - case CALL_IND: - case CALL_CON: - if(plci->State==ADVANCED_VOICE_SIG || plci->State==ADVANCED_VOICE_NOSIG) - { - if(plci->internal_command==PERM_COD_CONN_PEND) - { - if(plci->State==ADVANCED_VOICE_NOSIG) - { - dbug(1,dprintf("***Codec OK")); - if(a->AdvSignalPLCI) - { - tplci = a->AdvSignalPLCI; - if(tplci->spoofed_msg) - { - dbug(1,dprintf("***Spoofed Msg(0x%x)",tplci->spoofed_msg)); - tplci->command = 0; - tplci->internal_command = 0; - x_Id = ((word)tplci->Id<<8)|tplci->adapter->Id | 0x80; - switch (tplci->spoofed_msg) - { - case CALL_RES: - tplci->command = _CONNECT_I|RESPONSE; - api_load_msg (&tplci->saved_msg, saved_parms); - add_b1(tplci,&saved_parms[1],0,tplci->B1_facilities); - if (tplci->adapter->Info_Mask[tplci->appl->Id-1] & 0x200) - { - /* early B3 connect (CIP mask bit 9) no release after a disc */ - add_p(tplci,LLI,"\x01\x01"); - } - add_s(tplci, CONN_NR, &saved_parms[2]); - add_s(tplci, LLC, &saved_parms[4]); - add_ai(tplci, &saved_parms[5]); - tplci->State = INC_CON_ACCEPT; - sig_req(tplci, CALL_RES,0); - send_req(tplci); - break; - - case AWAITING_SELECT_B: - dbug(1,dprintf("Select_B continue")); - start_internal_command (x_Id, tplci, select_b_command); - break; - - case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */ - if(!tplci->Sig.Id) - { - dbug(1,dprintf("No SigID!")); - sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI); - plci_remove(tplci); - break; - } - tplci->command = _MANUFACTURER_R; - api_load_msg (&tplci->saved_msg, saved_parms); - dir = saved_parms[2].info[0]; - if(dir==1) { - sig_req(tplci,CALL_REQ,0); - } - else if(!dir){ - sig_req(tplci,LISTEN_REQ,0); - } - send_req(tplci); - sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,0); - break; - - case (CALL_REQ|AWAITING_MANUF_CON): - sig_req(tplci,CALL_REQ,0); - send_req(tplci); - break; - - case CALL_REQ: - if(!tplci->Sig.Id) - { - dbug(1,dprintf("No SigID!")); - sendf(tplci->appl,_CONNECT_R|CONFIRM,tplci->adapter->Id,0,"w",_OUT_OF_PLCI); - plci_remove(tplci); - break; - } - tplci->command = _CONNECT_R; - api_load_msg (&tplci->saved_msg, saved_parms); - add_s(tplci,CPN,&saved_parms[1]); - add_s(tplci,DSA,&saved_parms[3]); - add_ai(tplci,&saved_parms[9]); - sig_req(tplci,CALL_REQ,0); - send_req(tplci); - break; - - case CALL_RETRIEVE: - tplci->command = C_RETRIEVE_REQ; - sig_req(tplci,CALL_RETRIEVE,0); - send_req(tplci); - break; - } - tplci->spoofed_msg = 0; - if (tplci->internal_command == 0) - next_internal_command (x_Id, tplci); - } - } - next_internal_command (Id, plci); - break; - } - dbug(1,dprintf("***Codec Hook Init Req")); - plci->internal_command = PERM_COD_HOOK; - add_p(plci,FTY,"\x01\x09"); /* Get Hook State*/ - sig_req(plci,TEL_CTRL,0); - send_req(plci); - } - } - else if(plci->command != _MANUFACTURER_R /* old style permanent connect */ - && plci->State!=INC_ACT_PENDING) - { - mixer_set_bchannel_id_esc (plci, plci->b_channel); - if(plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */ - { - chi[2] = plci->b_channel; - SetVoiceChannel(a->AdvCodecPLCI, chi, a); - } - sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"Sss",parms[21],"",""); - plci->State = INC_ACT_PENDING; - } - break; - - case TEL_CTRL: - Number = 0; - ie = multi_fac_parms[0]; /* inspect the facility hook indications */ - if(plci->State==ADVANCED_VOICE_SIG && ie[0]){ - switch (ie[1]&0x91) { - case 0x80: /* hook off */ - case 0x81: - if(plci->internal_command==PERM_COD_HOOK) - { - dbug(1,dprintf("init:hook_off")); - plci->hook_state = ie[1]; - next_internal_command (Id, plci); - break; - } - else /* ignore doubled hook indications */ - { - if( ((plci->hook_state)&0xf0)==0x80) - { - dbug(1,dprintf("ignore hook")); - break; - } - plci->hook_state = ie[1]&0x91; - } - /* check for incoming call pending */ - /* and signal '+'.Appl must decide */ - /* with connect_res if call must */ - /* accepted or not */ - for(i=0, tplci=NULL;i<max_appl;i++){ - if(a->codec_listen[i] - && (a->codec_listen[i]->State==INC_CON_PENDING - ||a->codec_listen[i]->State==INC_CON_ALERT) ){ - tplci = a->codec_listen[i]; - tplci->appl = &application[i]; - } - } - /* no incoming call, do outgoing call */ - /* and signal '+' if outg. setup */ - if(!a->AdvSignalPLCI && !tplci){ - if((i=get_plci(a))) { - a->AdvSignalPLCI = &a->plci[i-1]; - tplci = a->AdvSignalPLCI; - tplci->tel = ADV_VOICE; - PUT_WORD(&voice_cai[5],a->AdvSignalAppl->MaxDataLength); - if (a->Info_Mask[a->AdvSignalAppl->Id-1] & 0x200){ - /* early B3 connect (CIP mask bit 9) no release after a disc */ - add_p(tplci,LLI,"\x01\x01"); - } - add_p(tplci, CAI, voice_cai); - add_p(tplci, OAD, a->TelOAD); - add_p(tplci, OSA, a->TelOSA); - add_p(tplci,SHIFT|6,NULL); - add_p(tplci,SIN,"\x02\x01\x00"); - add_p(tplci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(tplci,ASSIGN,DSIG_ID); - a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ; - a->AdvSignalPLCI->command = 0; - tplci->appl = a->AdvSignalAppl; - tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; - send_req(tplci); - } - - } - - if(!tplci) break; - Id = ((word)tplci->Id<<8)|a->Id; - Id|=EXT_CONTROLLER; - sendf(tplci->appl, - _FACILITY_I, - Id, - 0, - "ws", (word)0, "\x01+"); - break; - - case 0x90: /* hook on */ - case 0x91: - if(plci->internal_command==PERM_COD_HOOK) - { - dbug(1,dprintf("init:hook_on")); - plci->hook_state = ie[1]&0x91; - next_internal_command (Id, plci); - break; - } - else /* ignore doubled hook indications */ - { - if( ((plci->hook_state)&0xf0)==0x90) break; - plci->hook_state = ie[1]&0x91; - } - /* hangup the adv. voice call and signal '-' to the appl */ - if(a->AdvSignalPLCI) { - Id = ((word)a->AdvSignalPLCI->Id<<8)|a->Id; - if(plci->tel) Id|=EXT_CONTROLLER; - sendf(a->AdvSignalAppl, - _FACILITY_I, - Id, - 0, - "ws", (word)0, "\x01-"); - a->AdvSignalPLCI->internal_command = HOOK_ON_REQ; - a->AdvSignalPLCI->command = 0; - sig_req(a->AdvSignalPLCI,HANGUP,0); - send_req(a->AdvSignalPLCI); - } - break; - } - } - break; - - case RESUME: - clear_c_ind_mask_bit (plci, (word)(plci->appl->Id-1)); - PUT_WORD(&resume_cau[4],GOOD); - sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau); - break; - - case SUSPEND: - clear_c_ind_mask (plci); - - if (plci->NL.Id && !plci->nl_remove_id) { - mixer_remove (plci); - nl_req_ncci(plci,REMOVE,0); - } - if (!plci->sig_remove_id) { - plci->internal_command = 0; - sig_req(plci,REMOVE,0); - } - send_req(plci); - if(!plci->channels) { - sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, "\x05\x04\x00\x02\x00\x00"); - sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0); - } - break; - - case SUSPEND_REJ: - break; - - case HANGUP: - plci->hangup_flow_ctrl_timer=0; - if(plci->manufacturer && plci->State==LOCAL_CONNECT) break; - cau = parms[7]; - if(cau) { - i = _L3_CAUSE | cau[2]; - if(cau[2]==0) i = 0; - else if(cau[2]==8) i = _L1_ERROR; - else if(cau[2]==9 || cau[2]==10) i = _L2_ERROR; - else if(cau[2]==5) i = _CAPI_GUARD_ERROR; - } - else { - i = _L3_ERROR; - } - - if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT) - { - for(i=0; i<max_appl; i++) - { - if(test_c_ind_mask_bit (plci, i)) - sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0); - } - } - else - { - clear_c_ind_mask (plci); - } - if(!plci->appl) - { - if (plci->State == LISTENING) - { - plci->notifiedcall=0; - a->listen_active--; - } - plci->State = INC_DIS_PENDING; - if(c_ind_mask_empty (plci)) - { - plci->State = IDLE; - if (plci->NL.Id && !plci->nl_remove_id) - { - mixer_remove (plci); - nl_req_ncci(plci,REMOVE,0); - } - if (!plci->sig_remove_id) - { - plci->internal_command = 0; - sig_req(plci,REMOVE,0); - } - send_req(plci); - } - } - else - { - /* collision of DISCONNECT or CONNECT_RES with HANGUP can */ - /* result in a second HANGUP! Don't generate another */ - /* DISCONNECT */ - if(plci->State!=IDLE && plci->State!=INC_DIS_PENDING) - { - if(plci->State==RESUMING) - { - PUT_WORD(&resume_cau[4],i); - sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau); - } - plci->State = INC_DIS_PENDING; - sendf(plci->appl,_DISCONNECT_I,Id,0,"w",i); - } - } - break; - - case SSEXT_IND: - SendSSExtInd(NULL,plci,Id,multi_ssext_parms); - break; - - case VSWITCH_REQ: - VSwitchReqInd(plci,Id,multi_vswitch_parms); - break; - case VSWITCH_IND: - if(plci->relatedPTYPLCI && - plci->vswitchstate==3 && - plci->relatedPTYPLCI->vswitchstate==3 && - parms[MAXPARMSIDS-1][0]) - { - add_p(plci->relatedPTYPLCI,SMSG,parms[MAXPARMSIDS-1]); - sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0); - send_req(plci->relatedPTYPLCI); - } - else VSwitchReqInd(plci,Id,multi_vswitch_parms); - break; - - } -} - - -static void SendSetupInfo(APPL * appl, PLCI * plci, dword Id, byte * * parms, byte Info_Sent_Flag) -{ - word i; - byte * ie; - word Info_Number; - byte * Info_Element; - word Info_Mask = 0; - - dbug(1,dprintf("SetupInfo")); - - for(i=0; i<MAXPARMSIDS; i++) { - ie = parms[i]; - Info_Number = 0; - Info_Element = ie; - if(ie[0]) { - switch(i) { - case 0: - dbug(1,dprintf("CPN ")); - Info_Number = 0x0070; - Info_Mask = 0x80; - Info_Sent_Flag = TRUE; - break; - case 8: /* display */ - dbug(1,dprintf("display(%d)",i)); - Info_Number = 0x0028; - Info_Mask = 0x04; - Info_Sent_Flag = TRUE; - break; - case 16: /* Channel Id */ - dbug(1,dprintf("CHI")); - Info_Number = 0x0018; - Info_Mask = 0x100; - Info_Sent_Flag = TRUE; - mixer_set_bchannel_id (plci, Info_Element); - break; - case 19: /* Redirected Number */ - dbug(1,dprintf("RDN")); - Info_Number = 0x0074; - Info_Mask = 0x400; - Info_Sent_Flag = TRUE; - break; - case 20: /* Redirected Number extended */ - dbug(1,dprintf("RDX")); - Info_Number = 0x0073; - Info_Mask = 0x400; - Info_Sent_Flag = TRUE; - break; - case 22: /* Redirecing Number */ - dbug(1,dprintf("RIN")); - Info_Number = 0x0076; - Info_Mask = 0x400; - Info_Sent_Flag = TRUE; - break; - default: - Info_Number = 0; - break; - } - } - - if(i==MAXPARMSIDS-2){ /* to indicate the message type "Setup" */ - Info_Number = 0x8000 |5; - Info_Mask = 0x10; - Info_Element = ""; - } - - if(Info_Sent_Flag && Info_Number){ - if(plci->adapter->Info_Mask[appl->Id-1] & Info_Mask) { - sendf(appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element); - } - } - } -} - - -void SendInfo(PLCI * plci, dword Id, byte * * parms, byte iesent) -{ - word i; - word j; - word k; - byte * ie; - word Info_Number; - byte * Info_Element; - word Info_Mask = 0; - static byte charges[5] = {4,0,0,0,0}; - static byte cause[] = {0x02,0x80,0x00}; - APPL *appl; - - dbug(1,dprintf("InfoParse ")); - - if( - !plci->appl - && !plci->State - && plci->Sig.Ind!=NCR_FACILITY - ) - { - dbug(1,dprintf("NoParse ")); - return; - } - cause[2] = 0; - for(i=0; i<MAXPARMSIDS; i++) { - ie = parms[i]; - Info_Number = 0; - Info_Element = ie; - if(ie[0]) { - switch(i) { - case 0: - dbug(1,dprintf("CPN ")); - Info_Number = 0x0070; - Info_Mask = 0x80; - break; - case 7: /* ESC_CAU */ - dbug(1,dprintf("cau(0x%x)",ie[2])); - Info_Number = 0x0008; - Info_Mask = 0x00; - cause[2] = ie[2]; - Info_Element = NULL; - break; - case 8: /* display */ - dbug(1,dprintf("display(%d)",i)); - Info_Number = 0x0028; - Info_Mask = 0x04; - break; - case 9: /* Date display */ - dbug(1,dprintf("date(%d)",i)); - Info_Number = 0x0029; - Info_Mask = 0x02; - break; - case 10: /* charges */ - for(j=0;j<4;j++) charges[1+j] = 0; - for(j=0; j<ie[0] && !(ie[1+j]&0x80); j++); - for(k=1,j++; j<ie[0] && k<=4; j++,k++) charges[k] = ie[1+j]; - Info_Number = 0x4000; - Info_Mask = 0x40; - Info_Element = charges; - break; - case 11: /* user user info */ - dbug(1,dprintf("uui")); - Info_Number = 0x007E; - Info_Mask = 0x08; - break; - case 12: /* congestion receiver ready */ - dbug(1,dprintf("clRDY")); - Info_Number = 0x00B0; - Info_Mask = 0x08; - Info_Element = ""; - break; - case 13: /* congestion receiver not ready */ - dbug(1,dprintf("clNRDY")); - Info_Number = 0x00BF; - Info_Mask = 0x08; - Info_Element = ""; - break; - case 15: /* Keypad Facility */ - dbug(1,dprintf("KEY")); - Info_Number = 0x002C; - Info_Mask = 0x20; - break; - case 16: /* Channel Id */ - dbug(1,dprintf("CHI")); - Info_Number = 0x0018; - Info_Mask = 0x100; - mixer_set_bchannel_id (plci, Info_Element); - break; - case 17: /* if no 1tr6 cause, send full cause, else esc_cause */ - dbug(1,dprintf("q9cau(0x%x)",ie[2])); - if(!cause[2] || cause[2]<0x80) break; /* eg. layer 1 error */ - Info_Number = 0x0008; - Info_Mask = 0x01; - if(cause[2] != ie[2]) Info_Element = cause; - break; - case 19: /* Redirected Number */ - dbug(1,dprintf("RDN")); - Info_Number = 0x0074; - Info_Mask = 0x400; - break; - case 22: /* Redirecing Number */ - dbug(1,dprintf("RIN")); - Info_Number = 0x0076; - Info_Mask = 0x400; - break; - case 23: /* Notification Indicator */ - dbug(1,dprintf("NI")); - Info_Number = (word)NI; - Info_Mask = 0x210; - break; - case 26: /* Call State */ - dbug(1,dprintf("CST")); - Info_Number = (word)CST; - Info_Mask = 0x01; /* do with cause i.e. for now */ - break; - case MAXPARMSIDS-2: /* Escape Message Type, must be the last indication */ - dbug(1,dprintf("ESC/MT[0x%x]",ie[3])); - Info_Number = 0x8000 |ie[3]; - if(iesent) Info_Mask = 0xffff; - else Info_Mask = 0x10; - Info_Element = ""; - break; - default: - Info_Number = 0; - Info_Mask = 0; - Info_Element = ""; - break; - } - } - - if(plci->Sig.Ind==NCR_FACILITY) /* check controller broadcast */ - { - for(j=0; j<max_appl; j++) - { - appl = &application[j]; - if(Info_Number - && appl->Id - && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask) - { - dbug(1,dprintf("NCR_Ind")); - iesent=TRUE; - sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element); - } - } - } - else if(!plci->appl) - { /* overlap receiving broadcast */ - if(Info_Number==CPN - || Info_Number==KEY - || Info_Number==NI - || Info_Number==DSP - || Info_Number==UUI ) - { - for(j=0; j<max_appl; j++) - { - if(test_c_ind_mask_bit (plci, j)) - { - dbug(1,dprintf("Ovl_Ind")); - iesent=TRUE; - sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element); - } - } - } - } /* all other signalling states */ - else if(Info_Number - && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask) - { - dbug(1,dprintf("Std_Ind")); - iesent=TRUE; - sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element); - } - } -} - - -byte SendMultiIE(PLCI * plci, dword Id, byte * * parms, byte ie_type, dword info_mask, byte setupParse) -{ - word i; - word j; - byte * ie; - word Info_Number; - byte * Info_Element; - APPL *appl; - word Info_Mask = 0; - byte iesent=0; - - if( - !plci->appl - && !plci->State - && plci->Sig.Ind!=NCR_FACILITY - && !setupParse - ) - { - dbug(1,dprintf("NoM-IEParse ")); - return 0; - } - dbug(1,dprintf("M-IEParse ")); - - for(i=0; i<MAX_MULTI_IE; i++) - { - ie = parms[i]; - Info_Number = 0; - Info_Element = ie; - if(ie[0]) - { - dbug(1,dprintf("[Ind0x%x]:IE=0x%x",plci->Sig.Ind,ie_type)); - Info_Number = (word)ie_type; - Info_Mask = (word)info_mask; - } - - if(plci->Sig.Ind==NCR_FACILITY) /* check controller broadcast */ - { - for(j=0; j<max_appl; j++) - { - appl = &application[j]; - if(Info_Number - && appl->Id - && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask) - { - iesent = TRUE; - dbug(1,dprintf("Mlt_NCR_Ind")); - sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element); - } - } - } - else if(!plci->appl && Info_Number) - { /* overlap receiving broadcast */ - for(j=0; j<max_appl; j++) - { - if(test_c_ind_mask_bit (plci, j)) - { - iesent = TRUE; - dbug(1,dprintf("Mlt_Ovl_Ind")); - sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element); - } - } - } /* all other signalling states */ - else if(Info_Number - && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask) - { - iesent = TRUE; - dbug(1,dprintf("Mlt_Std_Ind")); - sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element); - } - } - return iesent; -} - -static void SendSSExtInd(APPL * appl, PLCI * plci, dword Id, byte * * parms) -{ - word i; - /* Format of multi_ssext_parms[i][]: - 0 byte length - 1 byte SSEXTIE - 2 byte SSEXT_REQ/SSEXT_IND - 3 byte length - 4 word SSExtCommand - 6... Params - */ - if( - plci - && plci->State - && plci->Sig.Ind!=NCR_FACILITY - ) - for(i=0;i<MAX_MULTI_IE;i++) - { - if(parms[i][0]<6) continue; - if(parms[i][2]==SSEXT_REQ) continue; - - if(appl) - { - parms[i][0]=0; /* kill it */ - sendf(appl,_MANUFACTURER_I, - Id, - 0, - "dwS", - _DI_MANU_ID, - _DI_SSEXT_CTRL, - &parms[i][3]); - } - else if(plci->appl) - { - parms[i][0]=0; /* kill it */ - sendf(plci->appl,_MANUFACTURER_I, - Id, - 0, - "dwS", - _DI_MANU_ID, - _DI_SSEXT_CTRL, - &parms[i][3]); - } - } + byte *parms[MAXPARMSIDS]; + byte *add_i[4]; + byte *multi_fac_parms[MAX_MULTI_IE]; + byte *multi_pi_parms[MAX_MULTI_IE]; + byte *multi_ssext_parms[MAX_MULTI_IE]; + byte *multi_CiPN_parms[MAX_MULTI_IE]; + + byte *multi_vswitch_parms[MAX_MULTI_IE]; + + byte ai_len; + byte *esc_chi = ""; + byte *esc_law = ""; + byte *pty_cai = ""; + byte *esc_cr = ""; + byte *esc_profile = ""; + + byte facility[256]; + PLCI *tplci = NULL; + byte chi[] = "\x02\x18\x01"; + byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08"; + byte resume_cau[] = "\x05\x05\x00\x02\x00\x00"; + /* ESC_MSGTYPE must be the last but one message, a new IE has to be */ + /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */ + /* SMSG is situated at the end because its 0 (for compatibility reasons */ + /* (see Info_Mask Bit 4, first IE. then the message type) */ + word parms_id[] = + {MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA, + UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW, + RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR, + CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG}; + /* 14 FTY repl by ESC_CHI */ + /* 18 PI repl by ESC_LAW */ + /* removed OAD changed to 0xff for future use, OAD is multiIE now */ + word multi_fac_id[] = {1, FTY}; + word multi_pi_id[] = {1, PI}; + word multi_CiPN_id[] = {1, OAD}; + word multi_ssext_id[] = {1, ESC_SSEXT}; + + word multi_vswitch_id[] = {1, ESC_VSWITCH}; + + byte *cau; + word ncci; + byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ + byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00"; + byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00"; + byte force_mt_info = false; + byte dir; + dword d; + word w; + + a = plci->adapter; + Id = ((word)plci->Id << 8) | a->Id; + PUT_WORD(&SS_Ind[4], 0x0000); + + if (plci->sig_remove_id) + { + plci->Sig.RNR = 2; /* discard */ + dbug(1, dprintf("SIG discard while remove pending")); + return; + } + if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER; + dbug(1, dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d", + Id, plci->Id, plci->tel, plci->State, plci->channels, plci->hangup_flow_ctrl_timer)); + if (plci->Sig.Ind == CALL_HOLD_ACK && plci->channels) + { + plci->Sig.RNR = 1; + return; + } + if (plci->Sig.Ind == HANGUP && plci->channels) + { + plci->Sig.RNR = 1; + plci->hangup_flow_ctrl_timer++; + /* recover the network layer after timeout */ + if (plci->hangup_flow_ctrl_timer == 100) + { + dbug(1, dprintf("Exceptional disc")); + plci->Sig.RNR = 0; + plci->hangup_flow_ctrl_timer = 0; + for (ncci = 1; ncci < MAX_NCCI + 1; ncci++) + { + if (a->ncci_plci[ncci] == plci->Id) + { + cleanup_ncci_data(plci, ncci); + if (plci->channels)plci->channels--; + if (plci->appl) + sendf(plci->appl, _DISCONNECT_B3_I, (((dword) ncci) << 16) | Id, 0, "ws", 0, ""); + } + } + if (plci->appl) + sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0); + plci_remove(plci); + plci->State = IDLE; + } + return; + } + + /* do first parse the info with no OAD in, because OAD will be converted */ + /* first the multiple facility IE, then mult. progress ind. */ + /* then the parameters for the info_ind + conn_ind */ + IndParse(plci, multi_fac_id, multi_fac_parms, MAX_MULTI_IE); + IndParse(plci, multi_pi_id, multi_pi_parms, MAX_MULTI_IE); + IndParse(plci, multi_ssext_id, multi_ssext_parms, MAX_MULTI_IE); + + IndParse(plci, multi_vswitch_id, multi_vswitch_parms, MAX_MULTI_IE); + + IndParse(plci, parms_id, parms, 0); + IndParse(plci, multi_CiPN_id, multi_CiPN_parms, MAX_MULTI_IE); + esc_chi = parms[14]; + esc_law = parms[18]; + pty_cai = parms[24]; + esc_cr = parms[25]; + esc_profile = parms[27]; + if (esc_cr[0] && plci) + { + if (plci->cr_enquiry && plci->appl) + { + plci->cr_enquiry = false; + /* d = MANU_ID */ + /* w = m_command */ + /* b = total length */ + /* b = indication type */ + /* b = length of all IEs */ + /* b = IE1 */ + /* S = IE1 length + cont. */ + /* b = IE2 */ + /* S = IE2 length + cont. */ + sendf(plci->appl, + _MANUFACTURER_I, + Id, + 0, + "dwbbbbSbS", _DI_MANU_ID, plci->m_command, + 2 + 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], plci->Sig.Ind, 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], ESC, esc_cr, ESC, esc_law); + } + } + /* create the additional info structure */ + add_i[1] = parms[15]; /* KEY of additional info */ + add_i[2] = parms[11]; /* UUI of additional info */ + ai_len = AddInfo(add_i, multi_fac_parms, esc_chi, facility); + + /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card */ + /* indication returns by the card if requested by the function */ + /* AutomaticLaw() after driver init */ + if (a->automatic_law < 4) + { + if (esc_law[0]) { + if (esc_law[2]) { + dbug(0, dprintf("u-Law selected")); + a->u_law = 1; + } + else { + dbug(0, dprintf("a-Law selected")); + a->u_law = 0; + } + a->automatic_law = 4; + if (plci == a->automatic_lawPLCI) { + plci->internal_command = 0; + sig_req(plci, REMOVE, 0); + send_req(plci); + a->automatic_lawPLCI = NULL; + } + } + if (esc_profile[0]) + { + dbug(1, dprintf("[%06x] CardProfile: %lx %lx %lx %lx %lx", + UnMapController(a->Id), GET_DWORD(&esc_profile[6]), + GET_DWORD(&esc_profile[10]), GET_DWORD(&esc_profile[14]), + GET_DWORD(&esc_profile[18]), GET_DWORD(&esc_profile[46]))); + + a->profile.Global_Options &= 0x000000ffL; + a->profile.B1_Protocols &= 0x000003ffL; + a->profile.B2_Protocols &= 0x00001fdfL; + a->profile.B3_Protocols &= 0x000000b7L; + + a->profile.Global_Options &= GET_DWORD(&esc_profile[6]) | + GL_BCHANNEL_OPERATION_SUPPORTED; + a->profile.B1_Protocols &= GET_DWORD(&esc_profile[10]); + a->profile.B2_Protocols &= GET_DWORD(&esc_profile[14]); + a->profile.B3_Protocols &= GET_DWORD(&esc_profile[18]); + a->manufacturer_features = GET_DWORD(&esc_profile[46]); + a->man_profile.private_options = 0; + + if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER) + { + a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER; + a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED; + } + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP) + a->man_profile.private_options |= 1L << PRIVATE_RTP; + a->man_profile.rtp_primary_payloads = GET_DWORD(&esc_profile[50]); + a->man_profile.rtp_additional_payloads = GET_DWORD(&esc_profile[54]); + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_T38) + a->man_profile.private_options |= 1L << PRIVATE_T38; + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD) + a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD; + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_V18) + a->man_profile.private_options |= 1L << PRIVATE_V18; + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE) + a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE; + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS) + a->man_profile.private_options |= 1L << PRIVATE_PIAFS; + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) + a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS; + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN) + a->man_profile.private_options |= 1L << PRIVATE_VOWN; + + + if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD) + a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD; + + } + else + { + a->profile.Global_Options &= 0x0000007fL; + a->profile.B1_Protocols &= 0x000003dfL; + a->profile.B2_Protocols &= 0x00001adfL; + a->profile.B3_Protocols &= 0x000000b7L; + a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF; + } + if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF | + MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) + { + a->profile.Global_Options |= GL_DTMF_SUPPORTED; + } + a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL; + dbug(1, dprintf("[%06x] Profile: %lx %lx %lx %lx %lx", + UnMapController(a->Id), a->profile.Global_Options, + a->profile.B1_Protocols, a->profile.B2_Protocols, + a->profile.B3_Protocols, a->manufacturer_features)); + } + /* codec plci for the handset/hook state support is just an internal id */ + if (plci != a->AdvCodecPLCI) + { + force_mt_info = SendMultiIE(plci, Id, multi_fac_parms, FTY, 0x20, 0); + force_mt_info |= SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, 0); + SendSSExtInd(NULL, plci, Id, multi_ssext_parms); + SendInfo(plci, Id, parms, force_mt_info); + + VSwitchReqInd(plci, Id, multi_vswitch_parms); + + } + + /* switch the codec to the b-channel */ + if (esc_chi[0] && plci && !plci->SuppState) { + plci->b_channel = esc_chi[esc_chi[0]]&0x1f; + mixer_set_bchannel_id_esc(plci, plci->b_channel); + dbug(1, dprintf("storeChannel=0x%x", plci->b_channel)); + if (plci->tel == ADV_VOICE && plci->appl) { + SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a); + } + } + + if (plci->appl) plci->appl->Number++; + + switch (plci->Sig.Ind) { + /* Response to Get_Supported_Services request */ + case S_SUPPORTED: + dbug(1, dprintf("S_Supported")); + if (!plci->appl) break; + if (pty_cai[0] == 4) + { + PUT_DWORD(&CF_Ind[6], GET_DWORD(&pty_cai[1])); + } + else + { + PUT_DWORD(&CF_Ind[6], MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE); + } + PUT_WORD(&CF_Ind[1], 0); + PUT_WORD(&CF_Ind[4], 0); + sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7, plci->number, "wws", 0, 3, CF_Ind); + plci_remove(plci); + break; + + /* Supplementary Service rejected */ + case S_SERVICE_REJ: + dbug(1, dprintf("S_Reject=0x%x", pty_cai[5])); + if (!pty_cai[0]) break; + switch (pty_cai[5]) + { + case ECT_EXECUTE: + case THREE_PTY_END: + case THREE_PTY_BEGIN: + if (!plci->relatedPTYPLCI) break; + tplci = plci->relatedPTYPLCI; + rId = ((word)tplci->Id << 8) | tplci->adapter->Id; + if (tplci->tel) rId |= EXT_CONTROLLER; + if (pty_cai[5] == ECT_EXECUTE) + { + PUT_WORD(&SS_Ind[1], S_ECT); + + plci->vswitchstate = 0; + plci->relatedPTYPLCI->vswitchstate = 0; + + } + else + { + PUT_WORD(&SS_Ind[1], pty_cai[5] + 3); + } + if (pty_cai[2] != 0xff) + { + PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]); + } + else + { + PUT_WORD(&SS_Ind[4], 0x300E); + } + plci->relatedPTYPLCI = NULL; + plci->ptyState = 0; + sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind); + break; + + case CALL_DEFLECTION: + if (pty_cai[2] != 0xff) + { + PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]); + } + else + { + PUT_WORD(&SS_Ind[4], 0x300E); + } + PUT_WORD(&SS_Ind[1], pty_cai[5]); + for (i = 0; i < max_appl; i++) + { + if (application[i].CDEnable) + { + if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind); + application[i].CDEnable = false; + } + } + break; + + case DEACTIVATION_DIVERSION: + case ACTIVATION_DIVERSION: + case DIVERSION_INTERROGATE_CFU: + case DIVERSION_INTERROGATE_CFB: + case DIVERSION_INTERROGATE_CFNR: + case DIVERSION_INTERROGATE_NUM: + case CCBS_REQUEST: + case CCBS_DEACTIVATE: + case CCBS_INTERROGATE: + if (!plci->appl) break; + if (pty_cai[2] != 0xff) + { + PUT_WORD(&Interr_Err_Ind[4], 0x3600 | (word)pty_cai[2]); + } + else + { + PUT_WORD(&Interr_Err_Ind[4], 0x300E); + } + switch (pty_cai[5]) + { + case DEACTIVATION_DIVERSION: + dbug(1, dprintf("Deact_Div")); + Interr_Err_Ind[0] = 0x9; + Interr_Err_Ind[3] = 0x6; + PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_STOP); + break; + case ACTIVATION_DIVERSION: + dbug(1, dprintf("Act_Div")); + Interr_Err_Ind[0] = 0x9; + Interr_Err_Ind[3] = 0x6; + PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_START); + break; + case DIVERSION_INTERROGATE_CFU: + case DIVERSION_INTERROGATE_CFB: + case DIVERSION_INTERROGATE_CFNR: + dbug(1, dprintf("Interr_Div")); + Interr_Err_Ind[0] = 0xa; + Interr_Err_Ind[3] = 0x7; + PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_DIVERSION); + break; + case DIVERSION_INTERROGATE_NUM: + dbug(1, dprintf("Interr_Num")); + Interr_Err_Ind[0] = 0xa; + Interr_Err_Ind[3] = 0x7; + PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_NUMBERS); + break; + case CCBS_REQUEST: + dbug(1, dprintf("CCBS Request")); + Interr_Err_Ind[0] = 0xd; + Interr_Err_Ind[3] = 0xa; + PUT_WORD(&Interr_Err_Ind[1], S_CCBS_REQUEST); + break; + case CCBS_DEACTIVATE: + dbug(1, dprintf("CCBS Deactivate")); + Interr_Err_Ind[0] = 0x9; + Interr_Err_Ind[3] = 0x6; + PUT_WORD(&Interr_Err_Ind[1], S_CCBS_DEACTIVATE); + break; + case CCBS_INTERROGATE: + dbug(1, dprintf("CCBS Interrogate")); + Interr_Err_Ind[0] = 0xb; + Interr_Err_Ind[3] = 0x8; + PUT_WORD(&Interr_Err_Ind[1], S_CCBS_INTERROGATE); + break; + } + PUT_DWORD(&Interr_Err_Ind[6], plci->appl->S_Handle); + sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, Interr_Err_Ind); + plci_remove(plci); + break; + case ACTIVATION_MWI: + case DEACTIVATION_MWI: + if (pty_cai[5] == ACTIVATION_MWI) + { + PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE); + } + else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE); + + if (pty_cai[2] != 0xff) + { + PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]); + } + else + { + PUT_WORD(&SS_Ind[4], 0x300E); + } + + if (plci->cr_enquiry) + { + sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind); + plci_remove(plci); + } + else + { + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind); + } + break; + case CONF_ADD: /* ERROR */ + case CONF_BEGIN: + case CONF_DROP: + case CONF_ISOLATE: + case CONF_REATTACH: + CONF_Ind[0] = 9; + CONF_Ind[3] = 6; + switch (pty_cai[5]) + { + case CONF_BEGIN: + PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN); + plci->ptyState = 0; + break; + case CONF_DROP: + CONF_Ind[0] = 5; + CONF_Ind[3] = 2; + PUT_WORD(&CONF_Ind[1], S_CONF_DROP); + plci->ptyState = CONNECTED; + break; + case CONF_ISOLATE: + CONF_Ind[0] = 5; + CONF_Ind[3] = 2; + PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE); + plci->ptyState = CONNECTED; + break; + case CONF_REATTACH: + CONF_Ind[0] = 5; + CONF_Ind[3] = 2; + PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH); + plci->ptyState = CONNECTED; + break; + case CONF_ADD: + PUT_WORD(&CONF_Ind[1], S_CONF_ADD); + plci->relatedPTYPLCI = NULL; + tplci = plci->relatedPTYPLCI; + if (tplci) tplci->ptyState = CONNECTED; + plci->ptyState = CONNECTED; + break; + } + + if (pty_cai[2] != 0xff) + { + PUT_WORD(&CONF_Ind[4], 0x3600 | (word)pty_cai[2]); + } + else + { + PUT_WORD(&CONF_Ind[4], 0x3303); /* Time-out: network did not respond + within the required time */ + } + + PUT_DWORD(&CONF_Ind[6], 0x0); + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind); + break; + } + break; + + /* Supplementary Service indicates success */ + case S_SERVICE: + dbug(1, dprintf("Service_Ind")); + PUT_WORD(&CF_Ind[4], 0); + switch (pty_cai[5]) + { + case THREE_PTY_END: + case THREE_PTY_BEGIN: + case ECT_EXECUTE: + if (!plci->relatedPTYPLCI) break; + tplci = plci->relatedPTYPLCI; + rId = ((word)tplci->Id << 8) | tplci->adapter->Id; + if (tplci->tel) rId |= EXT_CONTROLLER; + if (pty_cai[5] == ECT_EXECUTE) + { + PUT_WORD(&SS_Ind[1], S_ECT); + + if (plci->vswitchstate != 3) + { + + plci->ptyState = IDLE; + plci->relatedPTYPLCI = NULL; + plci->ptyState = 0; + + } + + dbug(1, dprintf("ECT OK")); + sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind); + + + + } + else + { + switch (plci->ptyState) + { + case S_3PTY_BEGIN: + plci->ptyState = CONNECTED; + dbug(1, dprintf("3PTY ON")); + break; + + case S_3PTY_END: + plci->ptyState = IDLE; + plci->relatedPTYPLCI = NULL; + plci->ptyState = 0; + dbug(1, dprintf("3PTY OFF")); + break; + } + PUT_WORD(&SS_Ind[1], pty_cai[5] + 3); + sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind); + } + break; + + case CALL_DEFLECTION: + PUT_WORD(&SS_Ind[1], pty_cai[5]); + for (i = 0; i < max_appl; i++) + { + if (application[i].CDEnable) + { + if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind); + application[i].CDEnable = false; + } + } + break; + + case DEACTIVATION_DIVERSION: + case ACTIVATION_DIVERSION: + if (!plci->appl) break; + PUT_WORD(&CF_Ind[1], pty_cai[5] + 2); + PUT_DWORD(&CF_Ind[6], plci->appl->S_Handle); + sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, CF_Ind); + plci_remove(plci); + break; + + case DIVERSION_INTERROGATE_CFU: + case DIVERSION_INTERROGATE_CFB: + case DIVERSION_INTERROGATE_CFNR: + case DIVERSION_INTERROGATE_NUM: + case CCBS_REQUEST: + case CCBS_DEACTIVATE: + case CCBS_INTERROGATE: + if (!plci->appl) break; + switch (pty_cai[5]) + { + case DIVERSION_INTERROGATE_CFU: + case DIVERSION_INTERROGATE_CFB: + case DIVERSION_INTERROGATE_CFNR: + dbug(1, dprintf("Interr_Div")); + PUT_WORD(&pty_cai[1], S_INTERROGATE_DIVERSION); + pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */ + break; + case DIVERSION_INTERROGATE_NUM: + dbug(1, dprintf("Interr_Num")); + PUT_WORD(&pty_cai[1], S_INTERROGATE_NUMBERS); + pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */ + break; + case CCBS_REQUEST: + dbug(1, dprintf("CCBS Request")); + PUT_WORD(&pty_cai[1], S_CCBS_REQUEST); + pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */ + break; + case CCBS_DEACTIVATE: + dbug(1, dprintf("CCBS Deactivate")); + PUT_WORD(&pty_cai[1], S_CCBS_DEACTIVATE); + pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */ + break; + case CCBS_INTERROGATE: + dbug(1, dprintf("CCBS Interrogate")); + PUT_WORD(&pty_cai[1], S_CCBS_INTERROGATE); + pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */ + break; + } + PUT_WORD(&pty_cai[4], 0); /* Supplementary Service Reason */ + PUT_DWORD(&pty_cai[6], plci->appl->S_Handle); + sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "wS", 3, pty_cai); + plci_remove(plci); + break; + + case ACTIVATION_MWI: + case DEACTIVATION_MWI: + if (pty_cai[5] == ACTIVATION_MWI) + { + PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE); + } + else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE); + if (plci->cr_enquiry) + { + sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind); + plci_remove(plci); + } + else + { + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind); + } + break; + case MWI_INDICATION: + if (pty_cai[0] >= 0x12) + { + PUT_WORD(&pty_cai[3], S_MWI_INDICATE); + pty_cai[2] = pty_cai[0] - 2; /* len Parameter */ + pty_cai[5] = pty_cai[0] - 5; /* Supplementary Service-specific parameter len */ + if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_MWI)) + { + if (plci->internal_command == GET_MWI_STATE) /* result on Message Waiting Listen */ + { + sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "wS", 3, &pty_cai[2]); + plci_remove(plci); + return; + } + else sendf(plci->appl, _FACILITY_I, Id, 0, "wS", 3, &pty_cai[2]); + pty_cai[0] = 0; + } + else + { + for (i = 0; i < max_appl; i++) + { + if (a->Notification_Mask[i]&SMASK_MWI) + { + sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "wS", 3, &pty_cai[2]); + pty_cai[0] = 0; + } + } + } + + if (!pty_cai[0]) + { /* acknowledge */ + facility[2] = 0; /* returncode */ + } + else facility[2] = 0xff; + } + else + { + /* reject */ + facility[2] = 0xff; /* returncode */ + } + facility[0] = 2; + facility[1] = MWI_RESPONSE; /* Function */ + add_p(plci, CAI, facility); + add_p(plci, ESC, multi_ssext_parms[0]); /* remembered parameter -> only one possible */ + sig_req(plci, S_SERVICE, 0); + send_req(plci); + plci->command = 0; + next_internal_command(Id, plci); + break; + case CONF_ADD: /* OK */ + case CONF_BEGIN: + case CONF_DROP: + case CONF_ISOLATE: + case CONF_REATTACH: + case CONF_PARTYDISC: + CONF_Ind[0] = 9; + CONF_Ind[3] = 6; + switch (pty_cai[5]) + { + case CONF_BEGIN: + PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN); + if (pty_cai[0] == 6) + { + d = pty_cai[6]; + PUT_DWORD(&CONF_Ind[6], d); /* PartyID */ + } + else + { + PUT_DWORD(&CONF_Ind[6], 0x0); + } + break; + case CONF_ISOLATE: + PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE); + CONF_Ind[0] = 5; + CONF_Ind[3] = 2; + break; + case CONF_REATTACH: + PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH); + CONF_Ind[0] = 5; + CONF_Ind[3] = 2; + break; + case CONF_DROP: + PUT_WORD(&CONF_Ind[1], S_CONF_DROP); + CONF_Ind[0] = 5; + CONF_Ind[3] = 2; + break; + case CONF_ADD: + PUT_WORD(&CONF_Ind[1], S_CONF_ADD); + d = pty_cai[6]; + PUT_DWORD(&CONF_Ind[6], d); /* PartyID */ + tplci = plci->relatedPTYPLCI; + if (tplci) tplci->ptyState = CONNECTED; + break; + case CONF_PARTYDISC: + CONF_Ind[0] = 7; + CONF_Ind[3] = 4; + PUT_WORD(&CONF_Ind[1], S_CONF_PARTYDISC); + d = pty_cai[6]; + PUT_DWORD(&CONF_Ind[4], d); /* PartyID */ + break; + } + plci->ptyState = CONNECTED; + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind); + break; + case CCBS_INFO_RETAIN: + case CCBS_ERASECALLLINKAGEID: + case CCBS_STOP_ALERTING: + CONF_Ind[0] = 5; + CONF_Ind[3] = 2; + switch (pty_cai[5]) + { + case CCBS_INFO_RETAIN: + PUT_WORD(&CONF_Ind[1], S_CCBS_INFO_RETAIN); + break; + case CCBS_STOP_ALERTING: + PUT_WORD(&CONF_Ind[1], S_CCBS_STOP_ALERTING); + break; + case CCBS_ERASECALLLINKAGEID: + PUT_WORD(&CONF_Ind[1], S_CCBS_ERASECALLLINKAGEID); + CONF_Ind[0] = 7; + CONF_Ind[3] = 4; + CONF_Ind[6] = 0; + CONF_Ind[7] = 0; + break; + } + w = pty_cai[6]; + PUT_WORD(&CONF_Ind[4], w); /* PartyID */ + + if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_CCBS)) + { + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind); + } + else + { + for (i = 0; i < max_appl; i++) + if (a->Notification_Mask[i] & SMASK_CCBS) + sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "ws", 3, CONF_Ind); + } + break; + } + break; + case CALL_HOLD_REJ: + cau = parms[7]; + if (cau) + { + i = _L3_CAUSE | cau[2]; + if (cau[2] == 0) i = 0x3603; + } + else + { + i = 0x3603; + } + PUT_WORD(&SS_Ind[1], S_HOLD); + PUT_WORD(&SS_Ind[4], i); + if (plci->SuppState == HOLD_REQUEST) + { + plci->SuppState = IDLE; + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind); + } + break; + + case CALL_HOLD_ACK: + if (plci->SuppState == HOLD_REQUEST) + { + plci->SuppState = CALL_HELD; + CodecIdCheck(a, plci); + start_internal_command(Id, plci, hold_save_command); + } + break; + + case CALL_RETRIEVE_REJ: + cau = parms[7]; + if (cau) + { + i = _L3_CAUSE | cau[2]; + if (cau[2] == 0) i = 0x3603; + } + else + { + i = 0x3603; + } + PUT_WORD(&SS_Ind[1], S_RETRIEVE); + PUT_WORD(&SS_Ind[4], i); + if (plci->SuppState == RETRIEVE_REQUEST) + { + plci->SuppState = CALL_HELD; + CodecIdCheck(a, plci); + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind); + } + break; + + case CALL_RETRIEVE_ACK: + PUT_WORD(&SS_Ind[1], S_RETRIEVE); + if (plci->SuppState == RETRIEVE_REQUEST) + { + plci->SuppState = IDLE; + plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; + plci->b_channel = esc_chi[esc_chi[0]]&0x1f; + if (plci->tel) + { + mixer_set_bchannel_id_esc(plci, plci->b_channel); + dbug(1, dprintf("RetrChannel=0x%x", plci->b_channel)); + SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a); + if (plci->B2_prot == B2_TRANSPARENT && plci->B3_prot == B3_TRANSPARENT) + { + dbug(1, dprintf("Get B-ch")); + start_internal_command(Id, plci, retrieve_restore_command); + } + else + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind); + } + else + start_internal_command(Id, plci, retrieve_restore_command); + } + break; + + case INDICATE_IND: + if (plci->State != LISTENING) { + sig_req(plci, HANGUP, 0); + send_req(plci); + break; + } + cip = find_cip(a, parms[4], parms[6]); + cip_mask = 1L << cip; + dbug(1, dprintf("cip=%d,cip_mask=%lx", cip, cip_mask)); + clear_c_ind_mask(plci); + if (!remove_started && !a->adapter_disabled) + { + set_c_ind_mask_bit(plci, MAX_APPL); + group_optimization(a, plci); + for (i = 0; i < max_appl; i++) { + if (application[i].Id + && (a->CIP_Mask[i] & 1 || a->CIP_Mask[i] & cip_mask) + && CPN_filter_ok(parms[0], a, i) + && test_group_ind_mask_bit(plci, i)) { + dbug(1, dprintf("storedcip_mask[%d]=0x%lx", i, a->CIP_Mask[i])); + set_c_ind_mask_bit(plci, i); + dump_c_ind_mask(plci); + plci->State = INC_CON_PENDING; + plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) | + CALL_DIR_IN | CALL_DIR_ANSWER; + if (esc_chi[0]) { + plci->b_channel = esc_chi[esc_chi[0]] & 0x1f; + mixer_set_bchannel_id_esc(plci, plci->b_channel); + } + /* if a listen on the ext controller is done, check if hook states */ + /* are supported or if just a on board codec must be activated */ + if (a->codec_listen[i] && !a->AdvSignalPLCI) { + if (a->profile.Global_Options & HANDSET) + plci->tel = ADV_VOICE; + else if (a->profile.Global_Options & ON_BOARD_CODEC) + plci->tel = CODEC; + if (plci->tel) Id |= EXT_CONTROLLER; + a->codec_listen[i] = plci; + } + + sendf(&application[i], _CONNECT_I, Id, 0, + "wSSSSSSSbSSSSS", cip, /* CIP */ + parms[0], /* CalledPartyNumber */ + multi_CiPN_parms[0], /* CallingPartyNumber */ + parms[2], /* CalledPartySubad */ + parms[3], /* CallingPartySubad */ + parms[4], /* BearerCapability */ + parms[5], /* LowLC */ + parms[6], /* HighLC */ + ai_len, /* nested struct add_i */ + add_i[0], /* B channel info */ + add_i[1], /* keypad facility */ + add_i[2], /* user user data */ + add_i[3], /* nested facility */ + multi_CiPN_parms[1] /* second CiPN(SCR) */ + ); + SendSSExtInd(&application[i], + plci, + Id, + multi_ssext_parms); + SendSetupInfo(&application[i], + plci, + Id, + parms, + SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, true)); + } + } + clear_c_ind_mask_bit(plci, MAX_APPL); + dump_c_ind_mask(plci); + } + if (c_ind_mask_empty(plci)) { + sig_req(plci, HANGUP, 0); + send_req(plci); + plci->State = IDLE; + } + plci->notifiedcall = 0; + a->listen_active--; + listen_check(a); + break; + + case CALL_PEND_NOTIFY: + plci->notifiedcall = 1; + listen_check(a); + break; + + case CALL_IND: + case CALL_CON: + if (plci->State == ADVANCED_VOICE_SIG || plci->State == ADVANCED_VOICE_NOSIG) + { + if (plci->internal_command == PERM_COD_CONN_PEND) + { + if (plci->State == ADVANCED_VOICE_NOSIG) + { + dbug(1, dprintf("***Codec OK")); + if (a->AdvSignalPLCI) + { + tplci = a->AdvSignalPLCI; + if (tplci->spoofed_msg) + { + dbug(1, dprintf("***Spoofed Msg(0x%x)", tplci->spoofed_msg)); + tplci->command = 0; + tplci->internal_command = 0; + x_Id = ((word)tplci->Id << 8) | tplci->adapter->Id | 0x80; + switch (tplci->spoofed_msg) + { + case CALL_RES: + tplci->command = _CONNECT_I | RESPONSE; + api_load_msg(&tplci->saved_msg, saved_parms); + add_b1(tplci, &saved_parms[1], 0, tplci->B1_facilities); + if (tplci->adapter->Info_Mask[tplci->appl->Id - 1] & 0x200) + { + /* early B3 connect (CIP mask bit 9) no release after a disc */ + add_p(tplci, LLI, "\x01\x01"); + } + add_s(tplci, CONN_NR, &saved_parms[2]); + add_s(tplci, LLC, &saved_parms[4]); + add_ai(tplci, &saved_parms[5]); + tplci->State = INC_CON_ACCEPT; + sig_req(tplci, CALL_RES, 0); + send_req(tplci); + break; + + case AWAITING_SELECT_B: + dbug(1, dprintf("Select_B continue")); + start_internal_command(x_Id, tplci, select_b_command); + break; + + case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */ + if (!tplci->Sig.Id) + { + dbug(1, dprintf("No SigID!")); + sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI); + plci_remove(tplci); + break; + } + tplci->command = _MANUFACTURER_R; + api_load_msg(&tplci->saved_msg, saved_parms); + dir = saved_parms[2].info[0]; + if (dir == 1) { + sig_req(tplci, CALL_REQ, 0); + } + else if (!dir) { + sig_req(tplci, LISTEN_REQ, 0); + } + send_req(tplci); + sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, 0); + break; + + case (CALL_REQ | AWAITING_MANUF_CON): + sig_req(tplci, CALL_REQ, 0); + send_req(tplci); + break; + + case CALL_REQ: + if (!tplci->Sig.Id) + { + dbug(1, dprintf("No SigID!")); + sendf(tplci->appl, _CONNECT_R | CONFIRM, tplci->adapter->Id, 0, "w", _OUT_OF_PLCI); + plci_remove(tplci); + break; + } + tplci->command = _CONNECT_R; + api_load_msg(&tplci->saved_msg, saved_parms); + add_s(tplci, CPN, &saved_parms[1]); + add_s(tplci, DSA, &saved_parms[3]); + add_ai(tplci, &saved_parms[9]); + sig_req(tplci, CALL_REQ, 0); + send_req(tplci); + break; + + case CALL_RETRIEVE: + tplci->command = C_RETRIEVE_REQ; + sig_req(tplci, CALL_RETRIEVE, 0); + send_req(tplci); + break; + } + tplci->spoofed_msg = 0; + if (tplci->internal_command == 0) + next_internal_command(x_Id, tplci); + } + } + next_internal_command(Id, plci); + break; + } + dbug(1, dprintf("***Codec Hook Init Req")); + plci->internal_command = PERM_COD_HOOK; + add_p(plci, FTY, "\x01\x09"); /* Get Hook State*/ + sig_req(plci, TEL_CTRL, 0); + send_req(plci); + } + } + else if (plci->command != _MANUFACTURER_R /* old style permanent connect */ + && plci->State != INC_ACT_PENDING) + { + mixer_set_bchannel_id_esc(plci, plci->b_channel); + if (plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */ + { + chi[2] = plci->b_channel; + SetVoiceChannel(a->AdvCodecPLCI, chi, a); + } + sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "Sss", parms[21], "", ""); + plci->State = INC_ACT_PENDING; + } + break; + + case TEL_CTRL: + ie = multi_fac_parms[0]; /* inspect the facility hook indications */ + if (plci->State == ADVANCED_VOICE_SIG && ie[0]) { + switch (ie[1] & 0x91) { + case 0x80: /* hook off */ + case 0x81: + if (plci->internal_command == PERM_COD_HOOK) + { + dbug(1, dprintf("init:hook_off")); + plci->hook_state = ie[1]; + next_internal_command(Id, plci); + break; + } + else /* ignore doubled hook indications */ + { + if (((plci->hook_state) & 0xf0) == 0x80) + { + dbug(1, dprintf("ignore hook")); + break; + } + plci->hook_state = ie[1]&0x91; + } + /* check for incoming call pending */ + /* and signal '+'.Appl must decide */ + /* with connect_res if call must */ + /* accepted or not */ + for (i = 0, tplci = NULL; i < max_appl; i++) { + if (a->codec_listen[i] + && (a->codec_listen[i]->State == INC_CON_PENDING + || a->codec_listen[i]->State == INC_CON_ALERT)) { + tplci = a->codec_listen[i]; + tplci->appl = &application[i]; + } + } + /* no incoming call, do outgoing call */ + /* and signal '+' if outg. setup */ + if (!a->AdvSignalPLCI && !tplci) { + if ((i = get_plci(a))) { + a->AdvSignalPLCI = &a->plci[i - 1]; + tplci = a->AdvSignalPLCI; + tplci->tel = ADV_VOICE; + PUT_WORD(&voice_cai[5], a->AdvSignalAppl->MaxDataLength); + if (a->Info_Mask[a->AdvSignalAppl->Id - 1] & 0x200) { + /* early B3 connect (CIP mask bit 9) no release after a disc */ + add_p(tplci, LLI, "\x01\x01"); + } + add_p(tplci, CAI, voice_cai); + add_p(tplci, OAD, a->TelOAD); + add_p(tplci, OSA, a->TelOSA); + add_p(tplci, SHIFT | 6, NULL); + add_p(tplci, SIN, "\x02\x01\x00"); + add_p(tplci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(tplci, ASSIGN, DSIG_ID); + a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ; + a->AdvSignalPLCI->command = 0; + tplci->appl = a->AdvSignalAppl; + tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; + send_req(tplci); + } + + } + + if (!tplci) break; + Id = ((word)tplci->Id << 8) | a->Id; + Id |= EXT_CONTROLLER; + sendf(tplci->appl, + _FACILITY_I, + Id, + 0, + "ws", (word)0, "\x01+"); + break; + + case 0x90: /* hook on */ + case 0x91: + if (plci->internal_command == PERM_COD_HOOK) + { + dbug(1, dprintf("init:hook_on")); + plci->hook_state = ie[1] & 0x91; + next_internal_command(Id, plci); + break; + } + else /* ignore doubled hook indications */ + { + if (((plci->hook_state) & 0xf0) == 0x90) break; + plci->hook_state = ie[1] & 0x91; + } + /* hangup the adv. voice call and signal '-' to the appl */ + if (a->AdvSignalPLCI) { + Id = ((word)a->AdvSignalPLCI->Id << 8) | a->Id; + if (plci->tel) Id |= EXT_CONTROLLER; + sendf(a->AdvSignalAppl, + _FACILITY_I, + Id, + 0, + "ws", (word)0, "\x01-"); + a->AdvSignalPLCI->internal_command = HOOK_ON_REQ; + a->AdvSignalPLCI->command = 0; + sig_req(a->AdvSignalPLCI, HANGUP, 0); + send_req(a->AdvSignalPLCI); + } + break; + } + } + break; + + case RESUME: + clear_c_ind_mask_bit(plci, (word)(plci->appl->Id - 1)); + PUT_WORD(&resume_cau[4], GOOD); + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau); + break; + + case SUSPEND: + clear_c_ind_mask(plci); + + if (plci->NL.Id && !plci->nl_remove_id) { + mixer_remove(plci); + nl_req_ncci(plci, REMOVE, 0); + } + if (!plci->sig_remove_id) { + plci->internal_command = 0; + sig_req(plci, REMOVE, 0); + } + send_req(plci); + if (!plci->channels) { + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, "\x05\x04\x00\x02\x00\x00"); + sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0); + } + break; + + case SUSPEND_REJ: + break; + + case HANGUP: + plci->hangup_flow_ctrl_timer = 0; + if (plci->manufacturer && plci->State == LOCAL_CONNECT) break; + cau = parms[7]; + if (cau) { + i = _L3_CAUSE | cau[2]; + if (cau[2] == 0) i = 0; + else if (cau[2] == 8) i = _L1_ERROR; + else if (cau[2] == 9 || cau[2] == 10) i = _L2_ERROR; + else if (cau[2] == 5) i = _CAPI_GUARD_ERROR; + } + else { + i = _L3_ERROR; + } + + if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT) + { + for (i = 0; i < max_appl; i++) + { + if (test_c_ind_mask_bit(plci, i)) + sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0); + } + } + else + { + clear_c_ind_mask(plci); + } + if (!plci->appl) + { + if (plci->State == LISTENING) + { + plci->notifiedcall = 0; + a->listen_active--; + } + plci->State = INC_DIS_PENDING; + if (c_ind_mask_empty(plci)) + { + plci->State = IDLE; + if (plci->NL.Id && !plci->nl_remove_id) + { + mixer_remove(plci); + nl_req_ncci(plci, REMOVE, 0); + } + if (!plci->sig_remove_id) + { + plci->internal_command = 0; + sig_req(plci, REMOVE, 0); + } + send_req(plci); + } + } + else + { + /* collision of DISCONNECT or CONNECT_RES with HANGUP can */ + /* result in a second HANGUP! Don't generate another */ + /* DISCONNECT */ + if (plci->State != IDLE && plci->State != INC_DIS_PENDING) + { + if (plci->State == RESUMING) + { + PUT_WORD(&resume_cau[4], i); + sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau); + } + plci->State = INC_DIS_PENDING; + sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", i); + } + } + break; + + case SSEXT_IND: + SendSSExtInd(NULL, plci, Id, multi_ssext_parms); + break; + + case VSWITCH_REQ: + VSwitchReqInd(plci, Id, multi_vswitch_parms); + break; + case VSWITCH_IND: + if (plci->relatedPTYPLCI && + plci->vswitchstate == 3 && + plci->relatedPTYPLCI->vswitchstate == 3 && + parms[MAXPARMSIDS - 1][0]) + { + add_p(plci->relatedPTYPLCI, SMSG, parms[MAXPARMSIDS - 1]); + sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0); + send_req(plci->relatedPTYPLCI); + } + else VSwitchReqInd(plci, Id, multi_vswitch_parms); + break; + + } +} + + +static void SendSetupInfo(APPL *appl, PLCI *plci, dword Id, byte **parms, byte Info_Sent_Flag) +{ + word i; + byte *ie; + word Info_Number; + byte *Info_Element; + word Info_Mask = 0; + + dbug(1, dprintf("SetupInfo")); + + for (i = 0; i < MAXPARMSIDS; i++) { + ie = parms[i]; + Info_Number = 0; + Info_Element = ie; + if (ie[0]) { + switch (i) { + case 0: + dbug(1, dprintf("CPN ")); + Info_Number = 0x0070; + Info_Mask = 0x80; + Info_Sent_Flag = true; + break; + case 8: /* display */ + dbug(1, dprintf("display(%d)", i)); + Info_Number = 0x0028; + Info_Mask = 0x04; + Info_Sent_Flag = true; + break; + case 16: /* Channel Id */ + dbug(1, dprintf("CHI")); + Info_Number = 0x0018; + Info_Mask = 0x100; + Info_Sent_Flag = true; + mixer_set_bchannel_id(plci, Info_Element); + break; + case 19: /* Redirected Number */ + dbug(1, dprintf("RDN")); + Info_Number = 0x0074; + Info_Mask = 0x400; + Info_Sent_Flag = true; + break; + case 20: /* Redirected Number extended */ + dbug(1, dprintf("RDX")); + Info_Number = 0x0073; + Info_Mask = 0x400; + Info_Sent_Flag = true; + break; + case 22: /* Redirecing Number */ + dbug(1, dprintf("RIN")); + Info_Number = 0x0076; + Info_Mask = 0x400; + Info_Sent_Flag = true; + break; + default: + Info_Number = 0; + break; + } + } + + if (i == MAXPARMSIDS - 2) { /* to indicate the message type "Setup" */ + Info_Number = 0x8000 | 5; + Info_Mask = 0x10; + Info_Element = ""; + } + + if (Info_Sent_Flag && Info_Number) { + if (plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask) { + sendf(appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element); + } + } + } +} + + +static void SendInfo(PLCI *plci, dword Id, byte **parms, byte iesent) +{ + word i; + word j; + word k; + byte *ie; + word Info_Number; + byte *Info_Element; + word Info_Mask = 0; + static byte charges[5] = {4, 0, 0, 0, 0}; + static byte cause[] = {0x02, 0x80, 0x00}; + APPL *appl; + + dbug(1, dprintf("InfoParse ")); + + if ( + !plci->appl + && !plci->State + && plci->Sig.Ind != NCR_FACILITY + ) + { + dbug(1, dprintf("NoParse ")); + return; + } + cause[2] = 0; + for (i = 0; i < MAXPARMSIDS; i++) { + ie = parms[i]; + Info_Number = 0; + Info_Element = ie; + if (ie[0]) { + switch (i) { + case 0: + dbug(1, dprintf("CPN ")); + Info_Number = 0x0070; + Info_Mask = 0x80; + break; + case 7: /* ESC_CAU */ + dbug(1, dprintf("cau(0x%x)", ie[2])); + Info_Number = 0x0008; + Info_Mask = 0x00; + cause[2] = ie[2]; + Info_Element = NULL; + break; + case 8: /* display */ + dbug(1, dprintf("display(%d)", i)); + Info_Number = 0x0028; + Info_Mask = 0x04; + break; + case 9: /* Date display */ + dbug(1, dprintf("date(%d)", i)); + Info_Number = 0x0029; + Info_Mask = 0x02; + break; + case 10: /* charges */ + for (j = 0; j < 4; j++) charges[1 + j] = 0; + for (j = 0; j < ie[0] && !(ie[1 + j] & 0x80); j++); + for (k = 1, j++; j < ie[0] && k <= 4; j++, k++) charges[k] = ie[1 + j]; + Info_Number = 0x4000; + Info_Mask = 0x40; + Info_Element = charges; + break; + case 11: /* user user info */ + dbug(1, dprintf("uui")); + Info_Number = 0x007E; + Info_Mask = 0x08; + break; + case 12: /* congestion receiver ready */ + dbug(1, dprintf("clRDY")); + Info_Number = 0x00B0; + Info_Mask = 0x08; + Info_Element = ""; + break; + case 13: /* congestion receiver not ready */ + dbug(1, dprintf("clNRDY")); + Info_Number = 0x00BF; + Info_Mask = 0x08; + Info_Element = ""; + break; + case 15: /* Keypad Facility */ + dbug(1, dprintf("KEY")); + Info_Number = 0x002C; + Info_Mask = 0x20; + break; + case 16: /* Channel Id */ + dbug(1, dprintf("CHI")); + Info_Number = 0x0018; + Info_Mask = 0x100; + mixer_set_bchannel_id(plci, Info_Element); + break; + case 17: /* if no 1tr6 cause, send full cause, else esc_cause */ + dbug(1, dprintf("q9cau(0x%x)", ie[2])); + if (!cause[2] || cause[2] < 0x80) break; /* eg. layer 1 error */ + Info_Number = 0x0008; + Info_Mask = 0x01; + if (cause[2] != ie[2]) Info_Element = cause; + break; + case 19: /* Redirected Number */ + dbug(1, dprintf("RDN")); + Info_Number = 0x0074; + Info_Mask = 0x400; + break; + case 22: /* Redirecing Number */ + dbug(1, dprintf("RIN")); + Info_Number = 0x0076; + Info_Mask = 0x400; + break; + case 23: /* Notification Indicator */ + dbug(1, dprintf("NI")); + Info_Number = (word)NI; + Info_Mask = 0x210; + break; + case 26: /* Call State */ + dbug(1, dprintf("CST")); + Info_Number = (word)CST; + Info_Mask = 0x01; /* do with cause i.e. for now */ + break; + case MAXPARMSIDS - 2: /* Escape Message Type, must be the last indication */ + dbug(1, dprintf("ESC/MT[0x%x]", ie[3])); + Info_Number = 0x8000 | ie[3]; + if (iesent) Info_Mask = 0xffff; + else Info_Mask = 0x10; + Info_Element = ""; + break; + default: + Info_Number = 0; + Info_Mask = 0; + Info_Element = ""; + break; + } + } + + if (plci->Sig.Ind == NCR_FACILITY) /* check controller broadcast */ + { + for (j = 0; j < max_appl; j++) + { + appl = &application[j]; + if (Info_Number + && appl->Id + && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask) + { + dbug(1, dprintf("NCR_Ind")); + iesent = true; + sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element); + } + } + } + else if (!plci->appl) + { /* overlap receiving broadcast */ + if (Info_Number == CPN + || Info_Number == KEY + || Info_Number == NI + || Info_Number == DSP + || Info_Number == UUI) + { + for (j = 0; j < max_appl; j++) + { + if (test_c_ind_mask_bit(plci, j)) + { + dbug(1, dprintf("Ovl_Ind")); + iesent = true; + sendf(&application[j], _INFO_I, Id, 0, "wS", Info_Number, Info_Element); + } + } + } + } /* all other signalling states */ + else if (Info_Number + && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask) + { + dbug(1, dprintf("Std_Ind")); + iesent = true; + sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element); + } + } +} + + +static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type, + dword info_mask, byte setupParse) +{ + word i; + word j; + byte *ie; + word Info_Number; + byte *Info_Element; + APPL *appl; + word Info_Mask = 0; + byte iesent = 0; + + if ( + !plci->appl + && !plci->State + && plci->Sig.Ind != NCR_FACILITY + && !setupParse + ) + { + dbug(1, dprintf("NoM-IEParse ")); + return 0; + } + dbug(1, dprintf("M-IEParse ")); + + for (i = 0; i < MAX_MULTI_IE; i++) + { + ie = parms[i]; + Info_Number = 0; + Info_Element = ie; + if (ie[0]) + { + dbug(1, dprintf("[Ind0x%x]:IE=0x%x", plci->Sig.Ind, ie_type)); + Info_Number = (word)ie_type; + Info_Mask = (word)info_mask; + } + + if (plci->Sig.Ind == NCR_FACILITY) /* check controller broadcast */ + { + for (j = 0; j < max_appl; j++) + { + appl = &application[j]; + if (Info_Number + && appl->Id + && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask) + { + iesent = true; + dbug(1, dprintf("Mlt_NCR_Ind")); + sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element); + } + } + } + else if (!plci->appl && Info_Number) + { /* overlap receiving broadcast */ + for (j = 0; j < max_appl; j++) + { + if (test_c_ind_mask_bit(plci, j)) + { + iesent = true; + dbug(1, dprintf("Mlt_Ovl_Ind")); + sendf(&application[j] , _INFO_I, Id, 0, "wS", Info_Number, Info_Element); + } + } + } /* all other signalling states */ + else if (Info_Number + && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask) + { + iesent = true; + dbug(1, dprintf("Mlt_Std_Ind")); + sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element); + } + } + return iesent; +} + +static void SendSSExtInd(APPL *appl, PLCI *plci, dword Id, byte **parms) +{ + word i; + /* Format of multi_ssext_parms[i][]: + 0 byte length + 1 byte SSEXTIE + 2 byte SSEXT_REQ/SSEXT_IND + 3 byte length + 4 word SSExtCommand + 6... Params + */ + if ( + plci + && plci->State + && plci->Sig.Ind != NCR_FACILITY + ) + for (i = 0; i < MAX_MULTI_IE; i++) + { + if (parms[i][0] < 6) continue; + if (parms[i][2] == SSEXT_REQ) continue; + + if (appl) + { + parms[i][0] = 0; /* kill it */ + sendf(appl, _MANUFACTURER_I, + Id, + 0, + "dwS", + _DI_MANU_ID, + _DI_SSEXT_CTRL, + &parms[i][3]); + } + else if (plci->appl) + { + parms[i][0] = 0; /* kill it */ + sendf(plci->appl, _MANUFACTURER_I, + Id, + 0, + "dwS", + _DI_MANU_ID, + _DI_SSEXT_CTRL, + &parms[i][3]); + } + } }; -void nl_ind(PLCI * plci) -{ - byte ch; - word ncci; - dword Id; - DIVA_CAPI_ADAPTER * a; - word NCCIcode; - APPL * APPLptr; - word count; - word Num; - word i, ncpi_state; - byte len, ncci_state; - word msg; - word info = 0; - word fax_feature_bits; - byte fax_send_edata_ack; - static byte v120_header_buffer[2 + 3]; - static word fax_info[] = { - 0, /* T30_SUCCESS */ - _FAX_NO_CONNECTION, /* T30_ERR_NO_DIS_RECEIVED */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_NO_RESPONSE */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_RESPONSE */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_TOO_MANY_REPEATS */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_UNEXPECTED_MESSAGE */ - _FAX_REMOTE_ABORT, /* T30_ERR_UNEXPECTED_DCN */ - _FAX_LOCAL_ABORT, /* T30_ERR_DTC_UNSUPPORTED */ - _FAX_TRAINING_ERROR, /* T30_ERR_ALL_RATES_FAILED */ - _FAX_TRAINING_ERROR, /* T30_ERR_TOO_MANY_TRAINS */ - _FAX_PARAMETER_ERROR, /* T30_ERR_RECEIVE_CORRUPTED */ - _FAX_REMOTE_ABORT, /* T30_ERR_UNEXPECTED_DISC */ - _FAX_LOCAL_ABORT, /* T30_ERR_APPLICATION_DISC */ - _FAX_REMOTE_REJECT, /* T30_ERR_INCOMPATIBLE_DIS */ - _FAX_LOCAL_ABORT, /* T30_ERR_INCOMPATIBLE_DCS */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_NO_COMMAND */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_COMMAND */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG */ - _FAX_NO_CONNECTION, /* T30_ERR_NOT_IDENTIFIED */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_SUPERVISORY_TIMEOUT */ - _FAX_PARAMETER_ERROR, /* T30_ERR_TOO_LONG_SCAN_LINE */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_FTT */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_EOM */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_MPS */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCN_AFTER_MCF */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCN_AFTER_RTN */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_CFR */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_EOP */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_EOM */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_MPS */ - 0x331d, /* T30_ERR_SUB_SEP_UNSUPPORTED */ - 0x331e, /* T30_ERR_PWD_UNSUPPORTED */ - 0x331f, /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_INVALID_COMMAND_FRAME */ - _FAX_PARAMETER_ERROR, /* T30_ERR_UNSUPPORTED_PAGE_CODING */ - _FAX_PARAMETER_ERROR, /* T30_ERR_INVALID_PAGE_CODING */ - _FAX_REMOTE_REJECT, /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG */ - _FAX_LOCAL_ABORT, /* T30_ERR_TIMEOUT_FROM_APPLICATION */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_TRAINING_TIMEOUT */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_UNEXPECTED_V21 */ - _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_PRIMARY_CTS_ON */ - _FAX_LOCAL_ABORT, /* T30_ERR_V34FAX_TURNAROUND_POLLING */ - _FAX_LOCAL_ABORT /* T30_ERR_V34FAX_V8_INCOMPATIBILITY */ - }; - - byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1]; - - - static word rtp_info[] = { - GOOD, /* RTP_SUCCESS */ - 0x3600 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE */ - }; - - static dword udata_forwarding_table[0x100 / sizeof(dword)] = - { - 0x0020301e, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 - }; - - ch = plci->NL.IndCh; - a = plci->adapter; - ncci = a->ch_ncci[ch]; - Id = (((dword)(ncci ? ncci : ch)) << 16) | (((word) plci->Id) << 8) | a->Id; - if(plci->tel) Id|=EXT_CONTROLLER; - APPLptr = plci->appl; - dbug(1,dprintf("NL_IND-Id(NL:0x%x)=0x%08lx,plci=%x,tel=%x,state=0x%x,ch=0x%x,chs=%d,Ind=%x", - plci->NL.Id,Id,plci->Id,plci->tel,plci->State,ch,plci->channels,plci->NL.Ind &0x0f)); - - /* in the case if no connect_active_Ind was sent to the appl we wait for */ - - if (plci->nl_remove_id) - { - plci->NL.RNR = 2; /* discard */ - dbug(1,dprintf("NL discard while remove pending")); - return; - } - if((plci->NL.Ind &0x0f)==N_CONNECT) - { - if(plci->State==INC_DIS_PENDING - || plci->State==OUTG_DIS_PENDING - || plci->State==IDLE) - { - plci->NL.RNR = 2; /* discard */ - dbug(1,dprintf("discard n_connect")); - return; - } - if(plci->State < INC_ACT_PENDING) - { - plci->NL.RNR = 1; /* flow control */ - channel_x_off (plci, ch, N_XON_CONNECT_IND); - return; - } - } - - if(!APPLptr) /* no application or invalid data */ - { /* while reloading the DSP */ - dbug(1,dprintf("discard1")); - plci->NL.RNR = 2; - return; - } - - if (((plci->NL.Ind &0x0f) == N_UDATA) - && (((plci->B2_prot != B2_SDLC) && ((plci->B1_resource == 17) || (plci->B1_resource == 18))) - || (plci->B2_prot == 7) - || (plci->B3_prot == 7)) ) - { - plci->ncpi_buffer[0] = 0; - - ncpi_state = plci->ncpi_state; - if (plci->NL.complete == 1) - { - byte * data = &plci->NL.RBuffer->P[0]; - - if ((plci->NL.RBuffer->length >= 12) - &&( (*data == DSP_UDATA_INDICATION_DCD_ON) - ||(*data == DSP_UDATA_INDICATION_CTS_ON)) ) - { - word conn_opt, ncpi_opt = 0x00; +static void nl_ind(PLCI *plci) +{ + byte ch; + word ncci; + dword Id; + DIVA_CAPI_ADAPTER *a; + word NCCIcode; + APPL *APPLptr; + word count; + word Num; + word i, ncpi_state; + byte len, ncci_state; + word msg; + word info = 0; + word fax_feature_bits; + byte fax_send_edata_ack; + static byte v120_header_buffer[2 + 3]; + static word fax_info[] = { + 0, /* T30_SUCCESS */ + _FAX_NO_CONNECTION, /* T30_ERR_NO_DIS_RECEIVED */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_NO_RESPONSE */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_RESPONSE */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_TOO_MANY_REPEATS */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_UNEXPECTED_MESSAGE */ + _FAX_REMOTE_ABORT, /* T30_ERR_UNEXPECTED_DCN */ + _FAX_LOCAL_ABORT, /* T30_ERR_DTC_UNSUPPORTED */ + _FAX_TRAINING_ERROR, /* T30_ERR_ALL_RATES_FAILED */ + _FAX_TRAINING_ERROR, /* T30_ERR_TOO_MANY_TRAINS */ + _FAX_PARAMETER_ERROR, /* T30_ERR_RECEIVE_CORRUPTED */ + _FAX_REMOTE_ABORT, /* T30_ERR_UNEXPECTED_DISC */ + _FAX_LOCAL_ABORT, /* T30_ERR_APPLICATION_DISC */ + _FAX_REMOTE_REJECT, /* T30_ERR_INCOMPATIBLE_DIS */ + _FAX_LOCAL_ABORT, /* T30_ERR_INCOMPATIBLE_DCS */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_NO_COMMAND */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_COMMAND */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG */ + _FAX_NO_CONNECTION, /* T30_ERR_NOT_IDENTIFIED */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_SUPERVISORY_TIMEOUT */ + _FAX_PARAMETER_ERROR, /* T30_ERR_TOO_LONG_SCAN_LINE */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_FTT */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_EOM */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCS_AFTER_MPS */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCN_AFTER_MCF */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_DCN_AFTER_RTN */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_CFR */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_EOP */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_EOM */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_RETRY_NO_MCF_AFTER_MPS */ + 0x331d, /* T30_ERR_SUB_SEP_UNSUPPORTED */ + 0x331e, /* T30_ERR_PWD_UNSUPPORTED */ + 0x331f, /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_INVALID_COMMAND_FRAME */ + _FAX_PARAMETER_ERROR, /* T30_ERR_UNSUPPORTED_PAGE_CODING */ + _FAX_PARAMETER_ERROR, /* T30_ERR_INVALID_PAGE_CODING */ + _FAX_REMOTE_REJECT, /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG */ + _FAX_LOCAL_ABORT, /* T30_ERR_TIMEOUT_FROM_APPLICATION */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_TRAINING_TIMEOUT */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_UNEXPECTED_V21 */ + _FAX_PROTOCOL_ERROR, /* T30_ERR_V34FAX_PRIMARY_CTS_ON */ + _FAX_LOCAL_ABORT, /* T30_ERR_V34FAX_TURNAROUND_POLLING */ + _FAX_LOCAL_ABORT /* T30_ERR_V34FAX_V8_INCOMPATIBILITY */ + }; + + byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1]; + + + static word rtp_info[] = { + GOOD, /* RTP_SUCCESS */ + 0x3600 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE */ + }; + + static dword udata_forwarding_table[0x100 / sizeof(dword)] = + { + 0x0020301e, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 + }; + + ch = plci->NL.IndCh; + a = plci->adapter; + ncci = a->ch_ncci[ch]; + Id = (((dword)(ncci ? ncci : ch)) << 16) | (((word) plci->Id) << 8) | a->Id; + if (plci->tel) Id |= EXT_CONTROLLER; + APPLptr = plci->appl; + dbug(1, dprintf("NL_IND-Id(NL:0x%x)=0x%08lx,plci=%x,tel=%x,state=0x%x,ch=0x%x,chs=%d,Ind=%x", + plci->NL.Id, Id, plci->Id, plci->tel, plci->State, ch, plci->channels, plci->NL.Ind & 0x0f)); + + /* in the case if no connect_active_Ind was sent to the appl we wait for */ + + if (plci->nl_remove_id) + { + plci->NL.RNR = 2; /* discard */ + dbug(1, dprintf("NL discard while remove pending")); + return; + } + if ((plci->NL.Ind & 0x0f) == N_CONNECT) + { + if (plci->State == INC_DIS_PENDING + || plci->State == OUTG_DIS_PENDING + || plci->State == IDLE) + { + plci->NL.RNR = 2; /* discard */ + dbug(1, dprintf("discard n_connect")); + return; + } + if (plci->State < INC_ACT_PENDING) + { + plci->NL.RNR = 1; /* flow control */ + channel_x_off(plci, ch, N_XON_CONNECT_IND); + return; + } + } + + if (!APPLptr) /* no application or invalid data */ + { /* while reloading the DSP */ + dbug(1, dprintf("discard1")); + plci->NL.RNR = 2; + return; + } + + if (((plci->NL.Ind & 0x0f) == N_UDATA) + && (((plci->B2_prot != B2_SDLC) && ((plci->B1_resource == 17) || (plci->B1_resource == 18))) + || (plci->B2_prot == 7) + || (plci->B3_prot == 7))) + { + plci->ncpi_buffer[0] = 0; + + ncpi_state = plci->ncpi_state; + if (plci->NL.complete == 1) + { + byte *data = &plci->NL.RBuffer->P[0]; + + if ((plci->NL.RBuffer->length >= 12) + && ((*data == DSP_UDATA_INDICATION_DCD_ON) + || (*data == DSP_UDATA_INDICATION_CTS_ON))) + { + word conn_opt, ncpi_opt = 0x00; /* HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */ - if (*data == DSP_UDATA_INDICATION_DCD_ON) - plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED; - if (*data == DSP_UDATA_INDICATION_CTS_ON) - plci->ncpi_state |= NCPI_MDM_CTS_ON_RECEIVED; - - data++; /* indication code */ - data += 2; /* timestamp */ - if ((*data == DSP_CONNECTED_NORM_V18) || (*data == DSP_CONNECTED_NORM_VOWN)) - ncpi_state &= ~(NCPI_MDM_DCD_ON_RECEIVED | NCPI_MDM_CTS_ON_RECEIVED); - data++; /* connected norm */ - conn_opt = GET_WORD(data); - data += 2; /* connected options */ - - PUT_WORD (&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF)); - - if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42) - { - ncpi_opt |= MDM_NCPI_ECM_V42; - } - else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP) - { - ncpi_opt |= MDM_NCPI_ECM_MNP; - } - else - { - ncpi_opt |= MDM_NCPI_TRANSPARENT; - } - if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION) - { - ncpi_opt |= MDM_NCPI_COMPRESSED; - } - PUT_WORD (&(plci->ncpi_buffer[3]), ncpi_opt); - plci->ncpi_buffer[0] = 4; - - plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND; - } - } - if (plci->B3_prot == 7) - { - if (((a->ncci_state[ncci] == INC_ACT_PENDING) || (a->ncci_state[ncci] == OUTG_CON_PENDING)) - && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) - { - a->ncci_state[ncci] = INC_ACT_PENDING; - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); - plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; - } - } - - if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) - & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN))) - || !(ncpi_state & NCPI_MDM_DCD_ON_RECEIVED) - || !(ncpi_state & NCPI_MDM_CTS_ON_RECEIVED)) - - { - plci->NL.RNR = 2; - return; - } - } - - if(plci->NL.complete == 2) - { - if (((plci->NL.Ind &0x0f) == N_UDATA) - && !(udata_forwarding_table[plci->RData[0].P[0] >> 5] & (1L << (plci->RData[0].P[0] & 0x1f)))) - { - switch(plci->RData[0].P[0]) - { - - case DTMF_UDATA_INDICATION_FAX_CALLING_TONE: - if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG) - sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,"ws", SELECTOR_DTMF, "\x01X"); - break; - case DTMF_UDATA_INDICATION_ANSWER_TONE: - if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG) - sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,"ws", SELECTOR_DTMF, "\x01Y"); - break; - case DTMF_UDATA_INDICATION_DIGITS_RECEIVED: - dtmf_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength); - break; - case DTMF_UDATA_INDICATION_DIGITS_SENT: - dtmf_confirmation (Id, plci); - break; - - - case UDATA_INDICATION_MIXER_TAP_DATA: - capidtmf_recv_process_block (&(plci->capidtmf_state), plci->RData[0].P + 1, (word)(plci->RData[0].PLength - 1)); - i = capidtmf_indication (&(plci->capidtmf_state), dtmf_code_buffer + 1); - if (i != 0) - { - dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED; - dtmf_indication (Id, plci, dtmf_code_buffer, (word)(i + 1)); - } - break; - - - case UDATA_INDICATION_MIXER_COEFS_SET: - mixer_indication_coefs_set (Id, plci); - break; - case UDATA_INDICATION_XCONNECT_FROM: - mixer_indication_xconnect_from (Id, plci, plci->RData[0].P, plci->RData[0].PLength); - break; - case UDATA_INDICATION_XCONNECT_TO: - mixer_indication_xconnect_to (Id, plci, plci->RData[0].P, plci->RData[0].PLength); - break; - - - case LEC_UDATA_INDICATION_DISABLE_DETECT: - ec_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength); - break; - - - - default: - break; - } - } - else - { - if ((plci->RData[0].PLength != 0) - && ((plci->B2_prot == B2_V120_ASYNC) - || (plci->B2_prot == B2_V120_ASYNC_V42BIS) - || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))) - { - - sendf(plci->appl,_DATA_B3_I,Id,0, - "dwww", - plci->RData[1].P, - (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength, - plci->RNum, - plci->RFlags); - - } - else - { - - sendf(plci->appl,_DATA_B3_I,Id,0, - "dwww", - plci->RData[0].P, - plci->RData[0].PLength, - plci->RNum, - plci->RFlags); - - } - } - return; - } - - fax_feature_bits = 0; - if((plci->NL.Ind &0x0f)==N_CONNECT || - (plci->NL.Ind &0x0f)==N_CONNECT_ACK || - (plci->NL.Ind &0x0f)==N_DISC || - (plci->NL.Ind &0x0f)==N_EDATA || - (plci->NL.Ind &0x0f)==N_DISC_ACK) - { - info = 0; - plci->ncpi_buffer[0] = 0; - switch (plci->B3_prot) { - case 0: /*XPARENT*/ - case 1: /*T.90 NL*/ - break; /* no network control protocol info - jfr */ - case 2: /*ISO8202*/ - case 3: /*X25 DCE*/ - for(i=0; i<plci->NL.RLength; i++) plci->ncpi_buffer[4+i] = plci->NL.RBuffer->P[i]; - plci->ncpi_buffer[0] = (byte)(i+3); - plci->ncpi_buffer[1] = (byte)(plci->NL.Ind &N_D_BIT? 1:0); - plci->ncpi_buffer[2] = 0; - plci->ncpi_buffer[3] = 0; - break; - case 4: /*T.30 - FAX*/ - case 5: /*T.30 - FAX*/ - if(plci->NL.RLength>=sizeof(T30_INFO)) - { - dbug(1,dprintf("FaxStatus %04x", ((T30_INFO *)plci->NL.RBuffer->P)->code)); - len = 9; - PUT_WORD(&(plci->ncpi_buffer[1]),((T30_INFO *)plci->NL.RBuffer->P)->rate_div_2400 * 2400); - fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low); - i = (((T30_INFO *)plci->NL.RBuffer->P)->resolution & T30_RESOLUTION_R8_0770_OR_200) ? 0x0001 : 0x0000; - if (plci->B3_prot == 5) - { - if (!(fax_feature_bits & T30_FEATURE_BIT_ECM)) - i |= 0x8000; /* This is not an ECM connection */ - if (fax_feature_bits & T30_FEATURE_BIT_T6_CODING) - i |= 0x4000; /* This is a connection with MMR compression */ - if (fax_feature_bits & T30_FEATURE_BIT_2D_CODING) - i |= 0x2000; /* This is a connection with MR compression */ - if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS) - i |= 0x0004; /* More documents */ - if (fax_feature_bits & T30_FEATURE_BIT_POLLING) - i |= 0x0002; /* Fax-polling indication */ - } - dbug(1,dprintf("FAX Options %04x %04x",fax_feature_bits,i)); - PUT_WORD(&(plci->ncpi_buffer[3]),i); - PUT_WORD(&(plci->ncpi_buffer[5]),((T30_INFO *)plci->NL.RBuffer->P)->data_format); - plci->ncpi_buffer[7] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_low; - plci->ncpi_buffer[8] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_high; - plci->ncpi_buffer[len] = 0; - if(((T30_INFO *)plci->NL.RBuffer->P)->station_id_len) - { - plci->ncpi_buffer[len] = 20; - for (i = 0; i < 20; i++) - plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i]; - } - if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) - { - if (((T30_INFO *)plci->NL.RBuffer->P)->code < sizeof(fax_info) / sizeof(fax_info[0])) - info = fax_info[((T30_INFO *)plci->NL.RBuffer->P)->code]; - else - info = _FAX_PROTOCOL_ERROR; - } - - if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) - & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) - { - i = ((word)(((T30_INFO *) 0)->station_id + 20)) + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; - while (i < plci->NL.RBuffer->length) - plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++]; - } - - plci->ncpi_buffer[0] = len; - fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low); - PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low, fax_feature_bits); - - plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND; - if (((plci->NL.Ind &0x0f) == N_CONNECT_ACK) - || (((plci->NL.Ind &0x0f) == N_CONNECT) - && (fax_feature_bits & T30_FEATURE_BIT_POLLING)) - || (((plci->NL.Ind &0x0f) == N_EDATA) - && ((((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_TRAIN_OK) - || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS) - || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DTC)))) - { - plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT; - } - if (((plci->NL.Ind &0x0f) == N_DISC) - || ((plci->NL.Ind &0x0f) == N_DISC_ACK) - || (((plci->NL.Ind &0x0f) == N_EDATA) - && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_EOP_CAPI))) - { - plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND; - } - } - break; - - case B3_RTP: - if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) - { - if (plci->NL.RLength != 0) - { - info = rtp_info[plci->NL.RBuffer->P[0]]; - plci->ncpi_buffer[0] = plci->NL.RLength - 1; - for (i = 1; i < plci->NL.RLength; i++) - plci->ncpi_buffer[i] = plci->NL.RBuffer->P[i]; - } - } - break; - - } - plci->NL.RNR = 2; - } - switch(plci->NL.Ind &0x0f) { - case N_EDATA: - if ((plci->B3_prot == 4) || (plci->B3_prot == 5)) - { - dbug(1,dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci, a->ncci_state[ncci], - ((T30_INFO *)plci->NL.RBuffer->P)->code)); - fax_send_edata_ack = (((T30_INFO *)(plci->fax_connect_info_buffer))->operating_mode == T30_OPERATING_MODE_CAPI_NEG); - - if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) - && (plci->nsf_control_bits & (T30_NSF_CONTROL_BIT_NEGOTIATE_IND | T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) - && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS) - && (a->ncci_state[ncci] == OUTG_CON_PENDING) - && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT)) - { - ((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code; - sendf(plci->appl,_MANUFACTURER_I,Id,0,"dwbS",_DI_MANU_ID,_DI_NEGOTIATE_B3, - (byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer); - plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT; - if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP) - fax_send_edata_ack = FALSE; - } - - if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) - { - switch (((T30_INFO *)plci->NL.RBuffer->P)->code) - { - case EDATA_T30_DIS: - if ((a->ncci_state[ncci] == OUTG_CON_PENDING) - && !(GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) & T30_CONTROL_BIT_REQUEST_POLLING) - && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) - { - a->ncci_state[ncci] = INC_ACT_PENDING; - if (plci->B3_prot == 4) - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); - else - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); - plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; - } - break; - - case EDATA_T30_TRAIN_OK: - if ((a->ncci_state[ncci] == INC_ACT_PENDING) - && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) - { - if (plci->B3_prot == 4) - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); - else - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); - plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; - } - break; - - case EDATA_T30_EOP_CAPI: - if (a->ncci_state[ncci] == CONNECTED) - { - sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",GOOD,plci->ncpi_buffer); - a->ncci_state[ncci] = INC_DIS_PENDING; - plci->ncpi_state = 0; - fax_send_edata_ack = FALSE; - } - break; - } - } - else - { - switch (((T30_INFO *)plci->NL.RBuffer->P)->code) - { - case EDATA_T30_TRAIN_OK: - if ((a->ncci_state[ncci] == INC_ACT_PENDING) - && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) - { - if (plci->B3_prot == 4) - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); - else - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); - plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; - } - break; - } - } - if (fax_send_edata_ack) - { - ((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code; - plci->fax_edata_ack_length = 1; - start_internal_command (Id, plci, fax_edata_ack_command); - } - } - else - { - dbug(1,dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci])); - } - break; - case N_CONNECT: - if (!a->ch_ncci[ch]) - { - ncci = get_ncci (plci, ch, 0); - Id = (Id & 0xffff) | (((dword) ncci) << 16); - } - dbug(1,dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d", - ch, a->ncci_state[ncci], a->ncci_plci[ncci], plci->Id, plci->State)); - - msg = _CONNECT_B3_I; - if (a->ncci_state[ncci] == IDLE) - plci->channels++; - else if (plci->B3_prot == 1) - msg = _CONNECT_B3_T90_ACTIVE_I; - - a->ncci_state[ncci] = INC_CON_PENDING; - if(plci->B3_prot == 4) - sendf(plci->appl,msg,Id,0,"s",""); - else - sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); - break; - case N_CONNECT_ACK: - dbug(1,dprintf("N_connect_Ack")); - if (plci->internal_command_queue[0] - && ((plci->adjust_b_state == ADJUST_B_CONNECT_2) - || (plci->adjust_b_state == ADJUST_B_CONNECT_3) - || (plci->adjust_b_state == ADJUST_B_CONNECT_4))) - { - (*(plci->internal_command_queue[0]))(Id, plci, 0); - if (!plci->internal_command) - next_internal_command (Id, plci); - break; - } - msg = _CONNECT_B3_ACTIVE_I; - if (plci->B3_prot == 1) - { - if (a->ncci_state[ncci] != OUTG_CON_PENDING) - msg = _CONNECT_B3_T90_ACTIVE_I; - a->ncci_state[ncci] = INC_ACT_PENDING; - sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); - } - else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7)) - { - if ((a->ncci_state[ncci] == OUTG_CON_PENDING) - && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) - { - a->ncci_state[ncci] = INC_ACT_PENDING; - if (plci->B3_prot == 4) - sendf(plci->appl,msg,Id,0,"s",""); - else - sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); - plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; - } - } - else - { - a->ncci_state[ncci] = INC_ACT_PENDING; - sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer); - } - if (plci->adjust_b_restore) - { - plci->adjust_b_restore = FALSE; - start_internal_command (Id, plci, adjust_b_restore); - } - break; - case N_DISC: - case N_DISC_ACK: - if (plci->internal_command_queue[0] - && ((plci->internal_command == FAX_DISCONNECT_COMMAND_1) - || (plci->internal_command == FAX_DISCONNECT_COMMAND_2) - || (plci->internal_command == FAX_DISCONNECT_COMMAND_3))) - { - (*(plci->internal_command_queue[0]))(Id, plci, 0); - if (!plci->internal_command) - next_internal_command (Id, plci); - } - ncci_state = a->ncci_state[ncci]; - ncci_remove (plci, ncci, FALSE); - - /* with N_DISC or N_DISC_ACK the IDI frees the respective */ - /* channel, so we cannot store the state in ncci_state! The */ - /* information which channel we received a N_DISC is thus */ - /* stored in the inc_dis_ncci_table buffer. */ - for(i=0; plci->inc_dis_ncci_table[i]; i++); - plci->inc_dis_ncci_table[i] = (byte) ncci; - - /* need a connect_b3_ind before a disconnect_b3_ind with FAX */ - if (!plci->channels - && (plci->B1_resource == 16) - && (plci->State <= CONNECTED)) - { - len = 9; - i = ((T30_INFO *)plci->fax_connect_info_buffer)->rate_div_2400 * 2400; - PUT_WORD (&plci->ncpi_buffer[1], i); - PUT_WORD (&plci->ncpi_buffer[3], 0); - i = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format; - PUT_WORD (&plci->ncpi_buffer[5], i); - PUT_WORD (&plci->ncpi_buffer[7], 0); - plci->ncpi_buffer[len] = 0; - plci->ncpi_buffer[0] = len; - if(plci->B3_prot == 4) - sendf(plci->appl,_CONNECT_B3_I,Id,0,"s",""); - else - { - - if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) - & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) - { - plci->ncpi_buffer[++len] = 0; - plci->ncpi_buffer[++len] = 0; - plci->ncpi_buffer[++len] = 0; - plci->ncpi_buffer[0] = len; - } - - sendf(plci->appl,_CONNECT_B3_I,Id,0,"S",plci->ncpi_buffer); - } - sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",info,plci->ncpi_buffer); - plci->ncpi_state = 0; - sig_req(plci,HANGUP,0); - send_req(plci); - plci->State = OUTG_DIS_PENDING; - /* disc here */ - } - else if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) - && ((plci->B3_prot == 4) || (plci->B3_prot == 5)) - && ((ncci_state == INC_DIS_PENDING) || (ncci_state == IDLE))) - { - if (ncci_state == IDLE) - { - if (plci->channels) - plci->channels--; - if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){ - if(plci->State == SUSPENDING){ - sendf(plci->appl, - _FACILITY_I, - Id & 0xffffL, - 0, - "ws", (word)3, "\x03\x04\x00\x00"); - sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0); - } - plci_remove(plci); - plci->State=IDLE; - } - } - } - else if (plci->channels) - { - sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",info,plci->ncpi_buffer); - plci->ncpi_state = 0; - if ((ncci_state == OUTG_REJ_PENDING) - && ((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))) - { - sig_req(plci,HANGUP,0); - send_req(plci); - plci->State = OUTG_DIS_PENDING; - } - } - break; - case N_RESET: - a->ncci_state[ncci] = INC_RES_PENDING; - sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer); - break; - case N_RESET_ACK: - a->ncci_state[ncci] = CONNECTED; - sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer); - break; - - case N_UDATA: - if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f)))) - { - plci->RData[0].P = plci->internal_ind_buffer + (-((int)(plci->internal_ind_buffer)) & 3); - plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE; - plci->NL.R = plci->RData; - plci->NL.RNum = 1; - return; - } - case N_BDATA: - case N_DATA: - if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */ - || (a->ncci_state[ncci] == IDLE) - || (a->ncci_state[ncci] == INC_DIS_PENDING)) - { - plci->NL.RNR = 2; - break; - } - if ((a->ncci_state[ncci] != CONNECTED) - && (a->ncci_state[ncci] != OUTG_DIS_PENDING) - && (a->ncci_state[ncci] != OUTG_REJ_PENDING)) - { - dbug(1,dprintf("flow control")); - plci->NL.RNR = 1; /* flow control */ - channel_x_off (plci, ch, 0); - break; - } - - NCCIcode = ncci | (((word)a->Id) << 8); - - /* count all buffers within the Application pool */ - /* belonging to the same NCCI. If this is below the */ - /* number of buffers available per NCCI we accept */ - /* this packet, otherwise we reject it */ - count = 0; - Num = 0xffff; - for(i=0; i<APPLptr->MaxBuffer; i++) { - if(NCCIcode==APPLptr->DataNCCI[i]) count++; - if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i; - } - - if(count>=APPLptr->MaxNCCIData || Num==0xffff) - { - dbug(3,dprintf("Flow-Control")); - plci->NL.RNR = 1; - if( ++(APPLptr->NCCIDataFlowCtrlTimer)>= - (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000)) - { - plci->NL.RNR = 2; - dbug(3,dprintf("DiscardData")); - } else { - channel_x_off (plci, ch, 0); - } - break; - } - else - { - APPLptr->NCCIDataFlowCtrlTimer = 0; - } - - plci->RData[0].P = ReceiveBufferGet(APPLptr,Num); - if(!plci->RData[0].P) { - plci->NL.RNR = 1; - channel_x_off (plci, ch, 0); - break; - } - - APPLptr->DataNCCI[Num] = NCCIcode; - APPLptr->DataFlags[Num] = (plci->Id<<8) | (plci->NL.Ind>>4); - dbug(3,dprintf("Buffer(%d), Max = %d",Num,APPLptr->MaxBuffer)); - - plci->RNum = Num; - plci->RFlags = plci->NL.Ind>>4; - plci->RData[0].PLength = APPLptr->MaxDataLength; - plci->NL.R = plci->RData; - if ((plci->NL.RLength != 0) - && ((plci->B2_prot == B2_V120_ASYNC) - || (plci->B2_prot == B2_V120_ASYNC_V42BIS) - || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))) - { - plci->RData[1].P = plci->RData[0].P; - plci->RData[1].PLength = plci->RData[0].PLength; - plci->RData[0].P = v120_header_buffer + (-((int) v120_header_buffer) & 3); - if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1)) - plci->RData[0].PLength = 1; - else - plci->RData[0].PLength = 2; - if (plci->NL.RBuffer->P[0] & V120_HEADER_BREAK_BIT) - plci->RFlags |= 0x0010; - if (plci->NL.RBuffer->P[0] & (V120_HEADER_C1_BIT | V120_HEADER_C2_BIT)) - plci->RFlags |= 0x8000; - plci->NL.RNum = 2; - } - else - { - if((plci->NL.Ind &0x0f)==N_UDATA) - plci->RFlags |= 0x0010; - - else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA)) - plci->RFlags |= 0x0001; - - plci->NL.RNum = 1; - } - break; - case N_DATA_ACK: - data_ack (plci, ch); - break; - default: - plci->NL.RNR = 2; - break; - } + if (*data == DSP_UDATA_INDICATION_DCD_ON) + plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED; + if (*data == DSP_UDATA_INDICATION_CTS_ON) + plci->ncpi_state |= NCPI_MDM_CTS_ON_RECEIVED; + + data++; /* indication code */ + data += 2; /* timestamp */ + if ((*data == DSP_CONNECTED_NORM_V18) || (*data == DSP_CONNECTED_NORM_VOWN)) + ncpi_state &= ~(NCPI_MDM_DCD_ON_RECEIVED | NCPI_MDM_CTS_ON_RECEIVED); + data++; /* connected norm */ + conn_opt = GET_WORD(data); + data += 2; /* connected options */ + + PUT_WORD(&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF)); + + if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42) + { + ncpi_opt |= MDM_NCPI_ECM_V42; + } + else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP) + { + ncpi_opt |= MDM_NCPI_ECM_MNP; + } + else + { + ncpi_opt |= MDM_NCPI_TRANSPARENT; + } + if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION) + { + ncpi_opt |= MDM_NCPI_COMPRESSED; + } + PUT_WORD(&(plci->ncpi_buffer[3]), ncpi_opt); + plci->ncpi_buffer[0] = 4; + + plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND; + } + } + if (plci->B3_prot == 7) + { + if (((a->ncci_state[ncci] == INC_ACT_PENDING) || (a->ncci_state[ncci] == OUTG_CON_PENDING)) + && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) + { + a->ncci_state[ncci] = INC_ACT_PENDING; + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer); + plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; + } + } + + if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1]) + & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN))) + || !(ncpi_state & NCPI_MDM_DCD_ON_RECEIVED) + || !(ncpi_state & NCPI_MDM_CTS_ON_RECEIVED)) + + { + plci->NL.RNR = 2; + return; + } + } + + if (plci->NL.complete == 2) + { + if (((plci->NL.Ind & 0x0f) == N_UDATA) + && !(udata_forwarding_table[plci->RData[0].P[0] >> 5] & (1L << (plci->RData[0].P[0] & 0x1f)))) + { + switch (plci->RData[0].P[0]) + { + + case DTMF_UDATA_INDICATION_FAX_CALLING_TONE: + if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG) + sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01X"); + break; + case DTMF_UDATA_INDICATION_ANSWER_TONE: + if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG) + sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01Y"); + break; + case DTMF_UDATA_INDICATION_DIGITS_RECEIVED: + dtmf_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength); + break; + case DTMF_UDATA_INDICATION_DIGITS_SENT: + dtmf_confirmation(Id, plci); + break; + + + case UDATA_INDICATION_MIXER_TAP_DATA: + capidtmf_recv_process_block(&(plci->capidtmf_state), plci->RData[0].P + 1, (word)(plci->RData[0].PLength - 1)); + i = capidtmf_indication(&(plci->capidtmf_state), dtmf_code_buffer + 1); + if (i != 0) + { + dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED; + dtmf_indication(Id, plci, dtmf_code_buffer, (word)(i + 1)); + } + break; + + + case UDATA_INDICATION_MIXER_COEFS_SET: + mixer_indication_coefs_set(Id, plci); + break; + case UDATA_INDICATION_XCONNECT_FROM: + mixer_indication_xconnect_from(Id, plci, plci->RData[0].P, plci->RData[0].PLength); + break; + case UDATA_INDICATION_XCONNECT_TO: + mixer_indication_xconnect_to(Id, plci, plci->RData[0].P, plci->RData[0].PLength); + break; + + + case LEC_UDATA_INDICATION_DISABLE_DETECT: + ec_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength); + break; + + + + default: + break; + } + } + else + { + if ((plci->RData[0].PLength != 0) + && ((plci->B2_prot == B2_V120_ASYNC) + || (plci->B2_prot == B2_V120_ASYNC_V42BIS) + || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))) + { + + sendf(plci->appl, _DATA_B3_I, Id, 0, + "dwww", + plci->RData[1].P, + (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength, + plci->RNum, + plci->RFlags); + + } + else + { + + sendf(plci->appl, _DATA_B3_I, Id, 0, + "dwww", + plci->RData[0].P, + plci->RData[0].PLength, + plci->RNum, + plci->RFlags); + + } + } + return; + } + + fax_feature_bits = 0; + if ((plci->NL.Ind & 0x0f) == N_CONNECT || + (plci->NL.Ind & 0x0f) == N_CONNECT_ACK || + (plci->NL.Ind & 0x0f) == N_DISC || + (plci->NL.Ind & 0x0f) == N_EDATA || + (plci->NL.Ind & 0x0f) == N_DISC_ACK) + { + info = 0; + plci->ncpi_buffer[0] = 0; + switch (plci->B3_prot) { + case 0: /*XPARENT*/ + case 1: /*T.90 NL*/ + break; /* no network control protocol info - jfr */ + case 2: /*ISO8202*/ + case 3: /*X25 DCE*/ + for (i = 0; i < plci->NL.RLength; i++) plci->ncpi_buffer[4 + i] = plci->NL.RBuffer->P[i]; + plci->ncpi_buffer[0] = (byte)(i + 3); + plci->ncpi_buffer[1] = (byte)(plci->NL.Ind & N_D_BIT ? 1 : 0); + plci->ncpi_buffer[2] = 0; + plci->ncpi_buffer[3] = 0; + break; + case 4: /*T.30 - FAX*/ + case 5: /*T.30 - FAX*/ + if (plci->NL.RLength >= sizeof(T30_INFO)) + { + dbug(1, dprintf("FaxStatus %04x", ((T30_INFO *)plci->NL.RBuffer->P)->code)); + len = 9; + PUT_WORD(&(plci->ncpi_buffer[1]), ((T30_INFO *)plci->NL.RBuffer->P)->rate_div_2400 * 2400); + fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low); + i = (((T30_INFO *)plci->NL.RBuffer->P)->resolution & T30_RESOLUTION_R8_0770_OR_200) ? 0x0001 : 0x0000; + if (plci->B3_prot == 5) + { + if (!(fax_feature_bits & T30_FEATURE_BIT_ECM)) + i |= 0x8000; /* This is not an ECM connection */ + if (fax_feature_bits & T30_FEATURE_BIT_T6_CODING) + i |= 0x4000; /* This is a connection with MMR compression */ + if (fax_feature_bits & T30_FEATURE_BIT_2D_CODING) + i |= 0x2000; /* This is a connection with MR compression */ + if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS) + i |= 0x0004; /* More documents */ + if (fax_feature_bits & T30_FEATURE_BIT_POLLING) + i |= 0x0002; /* Fax-polling indication */ + } + dbug(1, dprintf("FAX Options %04x %04x", fax_feature_bits, i)); + PUT_WORD(&(plci->ncpi_buffer[3]), i); + PUT_WORD(&(plci->ncpi_buffer[5]), ((T30_INFO *)plci->NL.RBuffer->P)->data_format); + plci->ncpi_buffer[7] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_low; + plci->ncpi_buffer[8] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_high; + plci->ncpi_buffer[len] = 0; + if (((T30_INFO *)plci->NL.RBuffer->P)->station_id_len) + { + plci->ncpi_buffer[len] = 20; + for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++) + plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i]; + } + if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) + { + if (((T30_INFO *)plci->NL.RBuffer->P)->code < ARRAY_SIZE(fax_info)) + info = fax_info[((T30_INFO *)plci->NL.RBuffer->P)->code]; + else + info = _FAX_PROTOCOL_ERROR; + } + + if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1]) + & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) + { + i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; + while (i < plci->NL.RBuffer->length) + plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++]; + } + + plci->ncpi_buffer[0] = len; + fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low); + PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low, fax_feature_bits); + + plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND; + if (((plci->NL.Ind & 0x0f) == N_CONNECT_ACK) + || (((plci->NL.Ind & 0x0f) == N_CONNECT) + && (fax_feature_bits & T30_FEATURE_BIT_POLLING)) + || (((plci->NL.Ind & 0x0f) == N_EDATA) + && ((((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_TRAIN_OK) + || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS) + || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DTC)))) + { + plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT; + } + if (((plci->NL.Ind & 0x0f) == N_DISC) + || ((plci->NL.Ind & 0x0f) == N_DISC_ACK) + || (((plci->NL.Ind & 0x0f) == N_EDATA) + && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_EOP_CAPI))) + { + plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND; + } + } + break; + + case B3_RTP: + if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) + { + if (plci->NL.RLength != 0) + { + info = rtp_info[plci->NL.RBuffer->P[0]]; + plci->ncpi_buffer[0] = plci->NL.RLength - 1; + for (i = 1; i < plci->NL.RLength; i++) + plci->ncpi_buffer[i] = plci->NL.RBuffer->P[i]; + } + } + break; + + } + plci->NL.RNR = 2; + } + switch (plci->NL.Ind & 0x0f) { + case N_EDATA: + if ((plci->B3_prot == 4) || (plci->B3_prot == 5)) + { + dbug(1, dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci, a->ncci_state[ncci], + ((T30_INFO *)plci->NL.RBuffer->P)->code)); + fax_send_edata_ack = (((T30_INFO *)(plci->fax_connect_info_buffer))->operating_mode == T30_OPERATING_MODE_CAPI_NEG); + + if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) + && (plci->nsf_control_bits & (T30_NSF_CONTROL_BIT_NEGOTIATE_IND | T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) + && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS) + && (a->ncci_state[ncci] == OUTG_CON_PENDING) + && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT)) + { + ((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code; + sendf(plci->appl, _MANUFACTURER_I, Id, 0, "dwbS", _DI_MANU_ID, _DI_NEGOTIATE_B3, + (byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer); + plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT; + if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP) + fax_send_edata_ack = false; + } + + if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) + { + switch (((T30_INFO *)plci->NL.RBuffer->P)->code) + { + case EDATA_T30_DIS: + if ((a->ncci_state[ncci] == OUTG_CON_PENDING) + && !(GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) & T30_CONTROL_BIT_REQUEST_POLLING) + && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) + { + a->ncci_state[ncci] = INC_ACT_PENDING; + if (plci->B3_prot == 4) + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + else + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer); + plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; + } + break; + + case EDATA_T30_TRAIN_OK: + if ((a->ncci_state[ncci] == INC_ACT_PENDING) + && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) + { + if (plci->B3_prot == 4) + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + else + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer); + plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; + } + break; + + case EDATA_T30_EOP_CAPI: + if (a->ncci_state[ncci] == CONNECTED) + { + sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", GOOD, plci->ncpi_buffer); + a->ncci_state[ncci] = INC_DIS_PENDING; + plci->ncpi_state = 0; + fax_send_edata_ack = false; + } + break; + } + } + else + { + switch (((T30_INFO *)plci->NL.RBuffer->P)->code) + { + case EDATA_T30_TRAIN_OK: + if ((a->ncci_state[ncci] == INC_ACT_PENDING) + && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) + { + if (plci->B3_prot == 4) + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + else + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer); + plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; + } + break; + } + } + if (fax_send_edata_ack) + { + ((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code; + plci->fax_edata_ack_length = 1; + start_internal_command(Id, plci, fax_edata_ack_command); + } + } + else + { + dbug(1, dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci])); + } + break; + case N_CONNECT: + if (!a->ch_ncci[ch]) + { + ncci = get_ncci(plci, ch, 0); + Id = (Id & 0xffff) | (((dword) ncci) << 16); + } + dbug(1, dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d", + ch, a->ncci_state[ncci], a->ncci_plci[ncci], plci->Id, plci->State)); + + msg = _CONNECT_B3_I; + if (a->ncci_state[ncci] == IDLE) + plci->channels++; + else if (plci->B3_prot == 1) + msg = _CONNECT_B3_T90_ACTIVE_I; + + a->ncci_state[ncci] = INC_CON_PENDING; + if (plci->B3_prot == 4) + sendf(plci->appl, msg, Id, 0, "s", ""); + else + sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer); + break; + case N_CONNECT_ACK: + dbug(1, dprintf("N_connect_Ack")); + if (plci->internal_command_queue[0] + && ((plci->adjust_b_state == ADJUST_B_CONNECT_2) + || (plci->adjust_b_state == ADJUST_B_CONNECT_3) + || (plci->adjust_b_state == ADJUST_B_CONNECT_4))) + { + (*(plci->internal_command_queue[0]))(Id, plci, 0); + if (!plci->internal_command) + next_internal_command(Id, plci); + break; + } + msg = _CONNECT_B3_ACTIVE_I; + if (plci->B3_prot == 1) + { + if (a->ncci_state[ncci] != OUTG_CON_PENDING) + msg = _CONNECT_B3_T90_ACTIVE_I; + a->ncci_state[ncci] = INC_ACT_PENDING; + sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer); + } + else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7)) + { + if ((a->ncci_state[ncci] == OUTG_CON_PENDING) + && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) + { + a->ncci_state[ncci] = INC_ACT_PENDING; + if (plci->B3_prot == 4) + sendf(plci->appl, msg, Id, 0, "s", ""); + else + sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer); + plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; + } + } + else + { + a->ncci_state[ncci] = INC_ACT_PENDING; + sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer); + } + if (plci->adjust_b_restore) + { + plci->adjust_b_restore = false; + start_internal_command(Id, plci, adjust_b_restore); + } + break; + case N_DISC: + case N_DISC_ACK: + if (plci->internal_command_queue[0] + && ((plci->internal_command == FAX_DISCONNECT_COMMAND_1) + || (plci->internal_command == FAX_DISCONNECT_COMMAND_2) + || (plci->internal_command == FAX_DISCONNECT_COMMAND_3))) + { + (*(plci->internal_command_queue[0]))(Id, plci, 0); + if (!plci->internal_command) + next_internal_command(Id, plci); + } + ncci_state = a->ncci_state[ncci]; + ncci_remove(plci, ncci, false); + + /* with N_DISC or N_DISC_ACK the IDI frees the respective */ + /* channel, so we cannot store the state in ncci_state! The */ + /* information which channel we received a N_DISC is thus */ + /* stored in the inc_dis_ncci_table buffer. */ + for (i = 0; plci->inc_dis_ncci_table[i]; i++); + plci->inc_dis_ncci_table[i] = (byte) ncci; + + /* need a connect_b3_ind before a disconnect_b3_ind with FAX */ + if (!plci->channels + && (plci->B1_resource == 16) + && (plci->State <= CONNECTED)) + { + len = 9; + i = ((T30_INFO *)plci->fax_connect_info_buffer)->rate_div_2400 * 2400; + PUT_WORD(&plci->ncpi_buffer[1], i); + PUT_WORD(&plci->ncpi_buffer[3], 0); + i = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format; + PUT_WORD(&plci->ncpi_buffer[5], i); + PUT_WORD(&plci->ncpi_buffer[7], 0); + plci->ncpi_buffer[len] = 0; + plci->ncpi_buffer[0] = len; + if (plci->B3_prot == 4) + sendf(plci->appl, _CONNECT_B3_I, Id, 0, "s", ""); + else + { + + if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1]) + & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) + { + plci->ncpi_buffer[++len] = 0; + plci->ncpi_buffer[++len] = 0; + plci->ncpi_buffer[++len] = 0; + plci->ncpi_buffer[0] = len; + } + + sendf(plci->appl, _CONNECT_B3_I, Id, 0, "S", plci->ncpi_buffer); + } + sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer); + plci->ncpi_state = 0; + sig_req(plci, HANGUP, 0); + send_req(plci); + plci->State = OUTG_DIS_PENDING; + /* disc here */ + } + else if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) + && ((plci->B3_prot == 4) || (plci->B3_prot == 5)) + && ((ncci_state == INC_DIS_PENDING) || (ncci_state == IDLE))) + { + if (ncci_state == IDLE) + { + if (plci->channels) + plci->channels--; + if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) { + if (plci->State == SUSPENDING) { + sendf(plci->appl, + _FACILITY_I, + Id & 0xffffL, + 0, + "ws", (word)3, "\x03\x04\x00\x00"); + sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0); + } + plci_remove(plci); + plci->State = IDLE; + } + } + } + else if (plci->channels) + { + sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer); + plci->ncpi_state = 0; + if ((ncci_state == OUTG_REJ_PENDING) + && ((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))) + { + sig_req(plci, HANGUP, 0); + send_req(plci); + plci->State = OUTG_DIS_PENDING; + } + } + break; + case N_RESET: + a->ncci_state[ncci] = INC_RES_PENDING; + sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer); + break; + case N_RESET_ACK: + a->ncci_state[ncci] = CONNECTED; + sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer); + break; + + case N_UDATA: + if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f)))) + { + plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3); + plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE; + plci->NL.R = plci->RData; + plci->NL.RNum = 1; + return; + } + case N_BDATA: + case N_DATA: + if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */ + || (a->ncci_state[ncci] == IDLE) + || (a->ncci_state[ncci] == INC_DIS_PENDING)) + { + plci->NL.RNR = 2; + break; + } + if ((a->ncci_state[ncci] != CONNECTED) + && (a->ncci_state[ncci] != OUTG_DIS_PENDING) + && (a->ncci_state[ncci] != OUTG_REJ_PENDING)) + { + dbug(1, dprintf("flow control")); + plci->NL.RNR = 1; /* flow control */ + channel_x_off(plci, ch, 0); + break; + } + + NCCIcode = ncci | (((word)a->Id) << 8); + + /* count all buffers within the Application pool */ + /* belonging to the same NCCI. If this is below the */ + /* number of buffers available per NCCI we accept */ + /* this packet, otherwise we reject it */ + count = 0; + Num = 0xffff; + for (i = 0; i < APPLptr->MaxBuffer; i++) { + if (NCCIcode == APPLptr->DataNCCI[i]) count++; + if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i; + } + + if (count >= APPLptr->MaxNCCIData || Num == 0xffff) + { + dbug(3, dprintf("Flow-Control")); + plci->NL.RNR = 1; + if (++(APPLptr->NCCIDataFlowCtrlTimer) >= + (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000)) + { + plci->NL.RNR = 2; + dbug(3, dprintf("DiscardData")); + } else { + channel_x_off(plci, ch, 0); + } + break; + } + else + { + APPLptr->NCCIDataFlowCtrlTimer = 0; + } + + plci->RData[0].P = ReceiveBufferGet(APPLptr, Num); + if (!plci->RData[0].P) { + plci->NL.RNR = 1; + channel_x_off(plci, ch, 0); + break; + } + + APPLptr->DataNCCI[Num] = NCCIcode; + APPLptr->DataFlags[Num] = (plci->Id << 8) | (plci->NL.Ind >> 4); + dbug(3, dprintf("Buffer(%d), Max = %d", Num, APPLptr->MaxBuffer)); + + plci->RNum = Num; + plci->RFlags = plci->NL.Ind >> 4; + plci->RData[0].PLength = APPLptr->MaxDataLength; + plci->NL.R = plci->RData; + if ((plci->NL.RLength != 0) + && ((plci->B2_prot == B2_V120_ASYNC) + || (plci->B2_prot == B2_V120_ASYNC_V42BIS) + || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))) + { + plci->RData[1].P = plci->RData[0].P; + plci->RData[1].PLength = plci->RData[0].PLength; + plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3); + if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1)) + plci->RData[0].PLength = 1; + else + plci->RData[0].PLength = 2; + if (plci->NL.RBuffer->P[0] & V120_HEADER_BREAK_BIT) + plci->RFlags |= 0x0010; + if (plci->NL.RBuffer->P[0] & (V120_HEADER_C1_BIT | V120_HEADER_C2_BIT)) + plci->RFlags |= 0x8000; + plci->NL.RNum = 2; + } + else + { + if ((plci->NL.Ind & 0x0f) == N_UDATA) + plci->RFlags |= 0x0010; + + else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA)) + plci->RFlags |= 0x0001; + + plci->NL.RNum = 1; + } + break; + case N_DATA_ACK: + data_ack(plci, ch); + break; + default: + plci->NL.RNR = 2; + break; + } } /*------------------------------------------------------------------*/ -/* find a free PLCI */ +/* find a free PLCI */ /*------------------------------------------------------------------*/ -word get_plci(DIVA_CAPI_ADAPTER * a) -{ - word i,j; - PLCI * plci; - - dump_plcis (a); - for(i=0;i<a->max_plci && a->plci[i].Id;i++); - if(i==a->max_plci) { - dbug(1,dprintf("get_plci: out of PLCIs")); - return 0; - } - plci = &a->plci[i]; - plci->Id = (byte)(i+1); - - plci->Sig.Id = 0; - plci->NL.Id = 0; - plci->sig_req = 0; - plci->nl_req = 0; - - plci->appl = NULL; - plci->relatedPTYPLCI = NULL; - plci->State = IDLE; - plci->SuppState = IDLE; - plci->channels = 0; - plci->tel = 0; - plci->B1_resource = 0; - plci->B2_prot = 0; - plci->B3_prot = 0; - - plci->command = 0; - plci->m_command = 0; - init_internal_command_queue (plci); - plci->number = 0; - plci->req_in_start = 0; - plci->req_in = 0; - plci->req_out = 0; - plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; - plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; - plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; - - plci->data_sent = FALSE; - plci->send_disc = 0; - plci->sig_global_req = 0; - plci->sig_remove_id = 0; - plci->nl_global_req = 0; - plci->nl_remove_id = 0; - plci->adv_nl = 0; - plci->manufacturer = FALSE; - plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; - plci->spoofed_msg = 0; - plci->ptyState = 0; - plci->cr_enquiry = FALSE; - plci->hangup_flow_ctrl_timer = 0; - - plci->ncci_ring_list = 0; - for(j=0;j<MAX_CHANNELS_PER_PLCI;j++) plci->inc_dis_ncci_table[j] = 0; - clear_c_ind_mask (plci); - set_group_ind_mask (plci); - plci->fax_connect_info_length = 0; - plci->nsf_control_bits = 0; - plci->ncpi_state = 0x00; - plci->ncpi_buffer[0] = 0; - - plci->requested_options_conn = 0; - plci->requested_options = 0; - plci->notifiedcall = 0; - plci->vswitchstate = 0; - plci->vsprot = 0; - plci->vsprotdialect = 0; - init_b1_config (plci); - dbug(1,dprintf("get_plci(%x)",plci->Id)); - return i+1; +static word get_plci(DIVA_CAPI_ADAPTER *a) +{ + word i, j; + PLCI *plci; + + dump_plcis(a); + for (i = 0; i < a->max_plci && a->plci[i].Id; i++); + if (i == a->max_plci) { + dbug(1, dprintf("get_plci: out of PLCIs")); + return 0; + } + plci = &a->plci[i]; + plci->Id = (byte)(i + 1); + + plci->Sig.Id = 0; + plci->NL.Id = 0; + plci->sig_req = 0; + plci->nl_req = 0; + + plci->appl = NULL; + plci->relatedPTYPLCI = NULL; + plci->State = IDLE; + plci->SuppState = IDLE; + plci->channels = 0; + plci->tel = 0; + plci->B1_resource = 0; + plci->B2_prot = 0; + plci->B3_prot = 0; + + plci->command = 0; + plci->m_command = 0; + init_internal_command_queue(plci); + plci->number = 0; + plci->req_in_start = 0; + plci->req_in = 0; + plci->req_out = 0; + plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE; + plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE; + plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE; + + plci->data_sent = false; + plci->send_disc = 0; + plci->sig_global_req = 0; + plci->sig_remove_id = 0; + plci->nl_global_req = 0; + plci->nl_remove_id = 0; + plci->adv_nl = 0; + plci->manufacturer = false; + plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE; + plci->spoofed_msg = 0; + plci->ptyState = 0; + plci->cr_enquiry = false; + plci->hangup_flow_ctrl_timer = 0; + + plci->ncci_ring_list = 0; + for (j = 0; j < MAX_CHANNELS_PER_PLCI; j++) plci->inc_dis_ncci_table[j] = 0; + clear_c_ind_mask(plci); + set_group_ind_mask(plci); + plci->fax_connect_info_length = 0; + plci->nsf_control_bits = 0; + plci->ncpi_state = 0x00; + plci->ncpi_buffer[0] = 0; + + plci->requested_options_conn = 0; + plci->requested_options = 0; + plci->notifiedcall = 0; + plci->vswitchstate = 0; + plci->vsprot = 0; + plci->vsprotdialect = 0; + init_b1_config(plci); + dbug(1, dprintf("get_plci(%x)", plci->Id)); + return i + 1; } /*------------------------------------------------------------------*/ /* put a parameter in the parameter buffer */ /*------------------------------------------------------------------*/ -static void add_p(PLCI * plci, byte code, byte * p) +static void add_p(PLCI *plci, byte code, byte *p) { - word p_length; + word p_length; - p_length = 0; - if(p) p_length = p[0]; - add_ie(plci, code, p, p_length); + p_length = 0; + if (p) p_length = p[0]; + add_ie(plci, code, p, p_length); } /*------------------------------------------------------------------*/ /* put a structure in the parameter buffer */ /*------------------------------------------------------------------*/ -static void add_s(PLCI * plci, byte code, API_PARSE * p) +static void add_s(PLCI *plci, byte code, API_PARSE *p) { - if(p) add_ie(plci, code, p->info, (word)p->length); + if (p) add_ie(plci, code, p->info, (word)p->length); } /*------------------------------------------------------------------*/ /* put multiple structures in the parameter buffer */ /*------------------------------------------------------------------*/ -static void add_ss(PLCI * plci, byte code, API_PARSE * p) +static void add_ss(PLCI *plci, byte code, API_PARSE *p) { - byte i; + byte i; - if(p){ - dbug(1,dprintf("add_ss(%x,len=%d)",code,p->length)); - for(i=2;i<(byte)p->length;i+=p->info[i]+2){ - dbug(1,dprintf("add_ss_ie(%x,len=%d)",p->info[i-1],p->info[i])); - add_ie(plci, p->info[i-1], (byte *)&(p->info[i]), (word)p->info[i]); - } - } + if (p) { + dbug(1, dprintf("add_ss(%x,len=%d)", code, p->length)); + for (i = 2; i < (byte)p->length; i += p->info[i] + 2) { + dbug(1, dprintf("add_ss_ie(%x,len=%d)", p->info[i - 1], p->info[i])); + add_ie(plci, p->info[i - 1], (byte *)&(p->info[i]), (word)p->info[i]); + } + } } /*------------------------------------------------------------------*/ /* return the channel number sent by the application in a esc_chi */ /*------------------------------------------------------------------*/ -static byte getChannel(API_PARSE * p) +static byte getChannel(API_PARSE *p) { - byte i; + byte i; - if(p){ - for(i=2;i<(byte)p->length;i+=p->info[i]+2){ - if(p->info[i]==2){ - if(p->info[i-1]==ESC && p->info[i+1]==CHI) return (p->info[i+2]); - } - } - } - return 0; + if (p) { + for (i = 2; i < (byte)p->length; i += p->info[i] + 2) { + if (p->info[i] == 2) { + if (p->info[i - 1] == ESC && p->info[i + 1] == CHI) return (p->info[i + 2]); + } + } + } + return 0; } @@ -7381,43 +7400,43 @@ static byte getChannel(API_PARSE * p) /* put an information element in the parameter buffer */ /*------------------------------------------------------------------*/ -static void add_ie(PLCI * plci, byte code, byte * p, word p_length) +static void add_ie(PLCI *plci, byte code, byte *p, word p_length) { - word i; + word i; - if(!(code &0x80) && !p_length) return; + if (!(code & 0x80) && !p_length) return; - if(plci->req_in==plci->req_in_start) { - plci->req_in +=2; - } - else { - plci->req_in--; - } - plci->RBuffer[plci->req_in++] = code; + if (plci->req_in == plci->req_in_start) { + plci->req_in += 2; + } + else { + plci->req_in--; + } + plci->RBuffer[plci->req_in++] = code; - if(p) { - plci->RBuffer[plci->req_in++] = (byte)p_length; - for(i=0;i<p_length;i++) plci->RBuffer[plci->req_in++] = p[1+i]; - } + if (p) { + plci->RBuffer[plci->req_in++] = (byte)p_length; + for (i = 0; i < p_length; i++) plci->RBuffer[plci->req_in++] = p[1 + i]; + } - plci->RBuffer[plci->req_in++] = 0; + plci->RBuffer[plci->req_in++] = 0; } /*------------------------------------------------------------------*/ /* put a unstructured data into the buffer */ /*------------------------------------------------------------------*/ -void add_d(PLCI * plci, word length, byte * p) +static void add_d(PLCI *plci, word length, byte *p) { - word i; + word i; - if(plci->req_in==plci->req_in_start) { - plci->req_in +=2; - } - else { - plci->req_in--; - } - for(i=0;i<length;i++) plci->RBuffer[plci->req_in++] = p[i]; + if (plci->req_in == plci->req_in_start) { + plci->req_in += 2; + } + else { + plci->req_in--; + } + for (i = 0; i < length; i++) plci->RBuffer[plci->req_in++] = p[i]; } /*------------------------------------------------------------------*/ @@ -7425,1112 +7444,1112 @@ void add_d(PLCI * plci, word length, byte * p) /* parameter buffer */ /*------------------------------------------------------------------*/ -void add_ai(PLCI * plci, API_PARSE * ai) +static void add_ai(PLCI *plci, API_PARSE *ai) { - word i; - API_PARSE ai_parms[5]; + word i; + API_PARSE ai_parms[5]; - for(i=0;i<5;i++) ai_parms[i].length = 0; + for (i = 0; i < 5; i++) ai_parms[i].length = 0; - if(!ai->length) - return; - if(api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms)) - return; + if (!ai->length) + return; + if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms)) + return; - add_s (plci,KEY,&ai_parms[1]); - add_s (plci,UUI,&ai_parms[2]); - add_ss(plci,FTY,&ai_parms[3]); + add_s(plci, KEY, &ai_parms[1]); + add_s(plci, UUI, &ai_parms[2]); + add_ss(plci, FTY, &ai_parms[3]); } /*------------------------------------------------------------------*/ /* put parameter for b1 protocol in the parameter buffer */ /*------------------------------------------------------------------*/ -word add_b1(PLCI * plci, API_PARSE * bp, word b_channel_info, word b1_facilities) -{ - API_PARSE bp_parms[8]; - API_PARSE mdm_cfg[9]; - API_PARSE global_config[2]; - byte cai[256]; - byte resource[] = {5,9,13,12,16,39,9,17,17,18}; - byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08"; - word i; - - API_PARSE mdm_cfg_v18[4]; - word j, n, w; - dword d; - - - for(i=0;i<8;i++) bp_parms[i].length = 0; - for(i=0;i<2;i++) global_config[i].length = 0; - - dbug(1,dprintf("add_b1")); - api_save_msg(bp, "s", &plci->B_protocol); - - if(b_channel_info==2){ - plci->B1_resource = 0; - adjust_b1_facilities (plci, plci->B1_resource, b1_facilities); - add_p(plci, CAI, "\x01\x00"); - dbug(1,dprintf("Cai=1,0 (no resource)")); - return 0; - } - - if(plci->tel == CODEC_PERMANENT) return 0; - else if(plci->tel == CODEC){ - plci->B1_resource = 1; - adjust_b1_facilities (plci, plci->B1_resource, b1_facilities); - add_p(plci, CAI, "\x01\x01"); - dbug(1,dprintf("Cai=1,1 (Codec)")); - return 0; - } - else if(plci->tel == ADV_VOICE){ - plci->B1_resource = add_b1_facilities (plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE)); - adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE)); - voice_cai[1] = plci->B1_resource; - PUT_WORD (&voice_cai[5], plci->appl->MaxDataLength); - add_p(plci, CAI, voice_cai); - dbug(1,dprintf("Cai=1,0x%x (AdvVoice)",voice_cai[1])); - return 0; - } - plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER); - if (plci->call_dir & CALL_DIR_OUT) - plci->call_dir |= CALL_DIR_ORIGINATE; - else if (plci->call_dir & CALL_DIR_IN) - plci->call_dir |= CALL_DIR_ANSWER; - - if(!bp->length){ - plci->B1_resource = 0x5; - adjust_b1_facilities (plci, plci->B1_resource, b1_facilities); - add_p(plci, CAI, "\x01\x05"); - return 0; - } - - dbug(1,dprintf("b_prot_len=%d",(word)bp->length)); - if(bp->length>256) return _WRONG_MESSAGE_FORMAT; - if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms)) - { - bp_parms[6].length = 0; - if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms)) - { - dbug(1,dprintf("b-form.!")); - return _WRONG_MESSAGE_FORMAT; - } - } - else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms)) - { - dbug(1,dprintf("b-form.!")); - return _WRONG_MESSAGE_FORMAT; - } - - if(bp_parms[6].length) - { - if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config)) - { - return _WRONG_MESSAGE_FORMAT; - } - switch(GET_WORD(global_config[0].info)) - { - case 1: - plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE; - break; - case 2: - plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER; - break; - } - } - dbug(1,dprintf("call_dir=%04x", plci->call_dir)); - - - if ((GET_WORD(bp_parms[0].info) == B1_RTP) - && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP))) - { - plci->B1_resource = add_b1_facilities (plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE)); - adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); - cai[1] = plci->B1_resource; - cai[2] = 0; - cai[3] = 0; - cai[4] = 0; - PUT_WORD(&cai[5],plci->appl->MaxDataLength); - for (i = 0; i < bp_parms[3].length; i++) - cai[7+i] = bp_parms[3].info[1+i]; - cai[0] = 6 + bp_parms[3].length; - add_p(plci, CAI, cai); - return 0; - } - - - if ((GET_WORD(bp_parms[0].info) == B1_PIAFS) - && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS))) - { - plci->B1_resource = add_b1_facilities (plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE)); - adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); - cai[1] = plci->B1_resource; - cai[2] = 0; - cai[3] = 0; - cai[4] = 0; - PUT_WORD(&cai[5],plci->appl->MaxDataLength); - cai[0] = 6; - add_p(plci, CAI, cai); - return 0; - } - - - if ((GET_WORD(bp_parms[0].info) >= 32) - || (!((1L << GET_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols) - && ((GET_WORD(bp_parms[0].info) != 3) - || !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols) - || ((bp_parms[3].length != 0) && (GET_WORD(&bp_parms[3].info[1]) != 0) && (GET_WORD(&bp_parms[3].info[1]) != 56000))))) - { - return _B1_NOT_SUPPORTED; - } - plci->B1_resource = add_b1_facilities (plci, resource[GET_WORD(bp_parms[0].info)], - (word)(b1_facilities & ~B1_FACILITY_VOICE)); - adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); - cai[0] = 6; - cai[1] = plci->B1_resource; - for (i=2;i<sizeof(cai);i++) cai[i] = 0; - - if ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) - || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC) - || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC)) - { /* B1 - modem */ - for (i=0;i<7;i++) mdm_cfg[i].length = 0; - - if (bp_parms[3].length) - { - if(api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwww", mdm_cfg)) - { - return (_WRONG_MESSAGE_FORMAT); - } - - cai[2] = 0; /* Bit rate for adaptation */ - - dbug(1,dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info))); - - PUT_WORD (&cai[13], 0); /* Min Tx speed */ - PUT_WORD (&cai[15], GET_WORD(mdm_cfg[0].info)); /* Max Tx speed */ - PUT_WORD (&cai[17], 0); /* Min Rx speed */ - PUT_WORD (&cai[19], GET_WORD(mdm_cfg[0].info)); /* Max Rx speed */ - - cai[3] = 0; /* Async framing parameters */ - switch (GET_WORD (mdm_cfg[2].info)) - { /* Parity */ - case 1: /* odd parity */ - cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD); - dbug(1,dprintf("MDM: odd parity")); - break; - - case 2: /* even parity */ - cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN); - dbug(1,dprintf("MDM: even parity")); - break; - - default: - dbug(1,dprintf("MDM: no parity")); - break; - } - - switch (GET_WORD (mdm_cfg[3].info)) - { /* stop bits */ - case 1: /* 2 stop bits */ - cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS; - dbug(1,dprintf("MDM: 2 stop bits")); - break; - - default: - dbug(1,dprintf("MDM: 1 stop bit")); - break; - } - - switch (GET_WORD (mdm_cfg[1].info)) - { /* char length */ - case 5: - cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5; - dbug(1,dprintf("MDM: 5 bits")); - break; - - case 6: - cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6; - dbug(1,dprintf("MDM: 6 bits")); - break; - - case 7: - cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7; - dbug(1,dprintf("MDM: 7 bits")); - break; - - default: - dbug(1,dprintf("MDM: 8 bits")); - break; - } - - cai[7] = 0; /* Line taking options */ - cai[8] = 0; /* Modulation negotiation options */ - cai[9] = 0; /* Modulation options */ - - if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0)) - { - cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION; - dbug(1, dprintf("MDM: Reverse direction")); - } - - if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN) - { - cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN; - dbug(1, dprintf("MDM: Disable retrain")); - } - - if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE) - { - cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE; - dbug(1, dprintf("MDM: Disable ring tone")); - } - - if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_1800) - { - cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ; - dbug(1, dprintf("MDM: 1800 guard tone")); - } - else if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_550 ) - { - cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ; - dbug(1, dprintf("MDM: 550 guard tone")); - } - - if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100) - { - cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100; - dbug(1, dprintf("MDM: V100")); - } - else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS) - { - cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS; - dbug(1, dprintf("MDM: IN CLASS")); - } - else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED) - { - cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED; - dbug(1, dprintf("MDM: DISABLED")); - } - cai[0] = 20; - - if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18)) - && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */ - { - plci->requested_options |= 1L << PRIVATE_V18; - } - if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */ - plci->requested_options |= 1L << PRIVATE_VOWN; - - if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) - & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN))) - { - if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwws", mdm_cfg)) - { - i = 27; - if (mdm_cfg[6].length >= 4) - { - d = GET_DWORD(&mdm_cfg[6].info[1]); - cai[7] |= (byte) d; /* line taking options */ - cai[9] |= (byte)(d >> 8); /* modulation options */ - cai[++i] = (byte)(d >> 16); /* vown modulation options */ - cai[++i] = (byte)(d >> 24); - if (mdm_cfg[6].length >= 8) - { - d = GET_DWORD(&mdm_cfg[6].info[5]); - cai[10] |= (byte) d; /* disabled modulations mask */ - cai[11] |= (byte)(d >> 8); - if (mdm_cfg[6].length >= 12) - { - d = GET_DWORD(&mdm_cfg[6].info[9]); - cai[12] = (byte) d; /* enabled modulations mask */ - cai[++i] = (byte)(d >> 8); /* vown enabled modulations */ - cai[++i] = (byte)(d >> 16); - cai[++i] = (byte)(d >> 24); - cai[++i] = 0; - if (mdm_cfg[6].length >= 14) - { - w = GET_WORD(&mdm_cfg[6].info[13]); - if (w != 0) - PUT_WORD(&cai[13], w); /* min tx speed */ - if (mdm_cfg[6].length >= 16) - { - w = GET_WORD(&mdm_cfg[6].info[15]); - if (w != 0) - PUT_WORD(&cai[15], w); /* max tx speed */ - if (mdm_cfg[6].length >= 18) - { - w = GET_WORD(&mdm_cfg[6].info[17]); - if (w != 0) - PUT_WORD(&cai[17], w); /* min rx speed */ - if (mdm_cfg[6].length >= 20) - { - w = GET_WORD(&mdm_cfg[6].info[19]); - if (w != 0) - PUT_WORD(&cai[19], w); /* max rx speed */ - if (mdm_cfg[6].length >= 22) - { - w = GET_WORD(&mdm_cfg[6].info[21]); - cai[23] = (byte)(-((short) w)); /* transmit level */ - if (mdm_cfg[6].length >= 24) - { - w = GET_WORD(&mdm_cfg[6].info[23]); - cai[22] |= (byte) w; /* info options mask */ - cai[21] |= (byte)(w >> 8); /* disabled symbol rates */ - } - } - } - } - } - } - } - } - } - cai[27] = i - 27; - i++; - if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwwss", mdm_cfg)) - { - if (!api_parse(&mdm_cfg[7].info[1],(word)mdm_cfg[7].length,"sss", mdm_cfg_v18)) - { - for (n = 0; n < 3; n++) - { - cai[i] = (byte)(mdm_cfg_v18[n].length); - for (j = 1; j < ((word)(cai[i] + 1)); j++) - cai[i+j] = mdm_cfg_v18[n].info[j]; - i += cai[i] + 1; - } - } - } - cai[0] = (byte)(i - 1); - } - } - - } - } - if(GET_WORD(bp_parms[0].info)==2 || /* V.110 async */ - GET_WORD(bp_parms[0].info)==3 ) /* V.110 sync */ - { - if(bp_parms[3].length){ - dbug(1,dprintf("V.110,%d",GET_WORD(&bp_parms[3].info[1]))); - switch(GET_WORD(&bp_parms[3].info[1])){ /* Rate */ - case 0: - case 56000: - if(GET_WORD(bp_parms[0].info)==3){ /* V.110 sync 56k */ - dbug(1,dprintf("56k sync HSCX")); - cai[1] = 8; - cai[2] = 0; - cai[3] = 0; - } - else if(GET_WORD(bp_parms[0].info)==2){ - dbug(1,dprintf("56k async DSP")); - cai[2] = 9; - } - break; - case 50: cai[2] = 1; break; - case 75: cai[2] = 1; break; - case 110: cai[2] = 1; break; - case 150: cai[2] = 1; break; - case 200: cai[2] = 1; break; - case 300: cai[2] = 1; break; - case 600: cai[2] = 1; break; - case 1200: cai[2] = 2; break; - case 2400: cai[2] = 3; break; - case 4800: cai[2] = 4; break; - case 7200: cai[2] = 10; break; - case 9600: cai[2] = 5; break; - case 12000: cai[2] = 13; break; - case 24000: cai[2] = 0; break; - case 14400: cai[2] = 11; break; - case 19200: cai[2] = 6; break; - case 28800: cai[2] = 12; break; - case 38400: cai[2] = 7; break; - case 48000: cai[2] = 8; break; - case 76: cai[2] = 15; break; /* 75/1200 */ - case 1201: cai[2] = 14; break; /* 1200/75 */ - case 56001: cai[2] = 9; break; /* V.110 56000 */ - - default: - return _B1_PARM_NOT_SUPPORTED; - } - cai[3] = 0; - if (cai[1] == 13) /* v.110 async */ - { - if (bp_parms[3].length >= 8) - { - switch (GET_WORD (&bp_parms[3].info[3])) - { /* char length */ - case 5: - cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5; - break; - case 6: - cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6; - break; - case 7: - cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7; - break; - } - switch (GET_WORD (&bp_parms[3].info[5])) - { /* Parity */ - case 1: /* odd parity */ - cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD); - break; - case 2: /* even parity */ - cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN); - break; - } - switch (GET_WORD (&bp_parms[3].info[7])) - { /* stop bits */ - case 1: /* 2 stop bits */ - cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS; - break; - } - } - } - } - else if(cai[1]==8 || GET_WORD(bp_parms[0].info)==3 ){ - dbug(1,dprintf("V.110 default 56k sync")); - cai[1] = 8; - cai[2] = 0; - cai[3] = 0; - } - else { - dbug(1,dprintf("V.110 default 9600 async")); - cai[2] = 5; - } - } - PUT_WORD(&cai[5],plci->appl->MaxDataLength); - dbug(1,dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6])); +static word add_b1(PLCI *plci, API_PARSE *bp, word b_channel_info, + word b1_facilities) +{ + API_PARSE bp_parms[8]; + API_PARSE mdm_cfg[9]; + API_PARSE global_config[2]; + byte cai[256]; + byte resource[] = {5, 9, 13, 12, 16, 39, 9, 17, 17, 18}; + byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08"; + word i; + + API_PARSE mdm_cfg_v18[4]; + word j, n, w; + dword d; + + + for (i = 0; i < 8; i++) bp_parms[i].length = 0; + for (i = 0; i < 2; i++) global_config[i].length = 0; + + dbug(1, dprintf("add_b1")); + api_save_msg(bp, "s", &plci->B_protocol); + + if (b_channel_info == 2) { + plci->B1_resource = 0; + adjust_b1_facilities(plci, plci->B1_resource, b1_facilities); + add_p(plci, CAI, "\x01\x00"); + dbug(1, dprintf("Cai=1,0 (no resource)")); + return 0; + } + + if (plci->tel == CODEC_PERMANENT) return 0; + else if (plci->tel == CODEC) { + plci->B1_resource = 1; + adjust_b1_facilities(plci, plci->B1_resource, b1_facilities); + add_p(plci, CAI, "\x01\x01"); + dbug(1, dprintf("Cai=1,1 (Codec)")); + return 0; + } + else if (plci->tel == ADV_VOICE) { + plci->B1_resource = add_b1_facilities(plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE)); + adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE)); + voice_cai[1] = plci->B1_resource; + PUT_WORD(&voice_cai[5], plci->appl->MaxDataLength); + add_p(plci, CAI, voice_cai); + dbug(1, dprintf("Cai=1,0x%x (AdvVoice)", voice_cai[1])); + return 0; + } + plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER); + if (plci->call_dir & CALL_DIR_OUT) + plci->call_dir |= CALL_DIR_ORIGINATE; + else if (plci->call_dir & CALL_DIR_IN) + plci->call_dir |= CALL_DIR_ANSWER; + + if (!bp->length) { + plci->B1_resource = 0x5; + adjust_b1_facilities(plci, plci->B1_resource, b1_facilities); + add_p(plci, CAI, "\x01\x05"); + return 0; + } + + dbug(1, dprintf("b_prot_len=%d", (word)bp->length)); + if (bp->length > 256) return _WRONG_MESSAGE_FORMAT; + if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms)) + { + bp_parms[6].length = 0; + if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms)) + { + dbug(1, dprintf("b-form.!")); + return _WRONG_MESSAGE_FORMAT; + } + } + else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms)) + { + dbug(1, dprintf("b-form.!")); + return _WRONG_MESSAGE_FORMAT; + } + + if (bp_parms[6].length) + { + if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config)) + { + return _WRONG_MESSAGE_FORMAT; + } + switch (GET_WORD(global_config[0].info)) + { + case 1: + plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE; + break; + case 2: + plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER; + break; + } + } + dbug(1, dprintf("call_dir=%04x", plci->call_dir)); + + + if ((GET_WORD(bp_parms[0].info) == B1_RTP) + && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP))) + { + plci->B1_resource = add_b1_facilities(plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE)); + adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); + cai[1] = plci->B1_resource; + cai[2] = 0; + cai[3] = 0; + cai[4] = 0; + PUT_WORD(&cai[5], plci->appl->MaxDataLength); + for (i = 0; i < bp_parms[3].length; i++) + cai[7 + i] = bp_parms[3].info[1 + i]; + cai[0] = 6 + bp_parms[3].length; + add_p(plci, CAI, cai); + return 0; + } + + + if ((GET_WORD(bp_parms[0].info) == B1_PIAFS) + && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS))) + { + plci->B1_resource = add_b1_facilities(plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE)); + adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); + cai[1] = plci->B1_resource; + cai[2] = 0; + cai[3] = 0; + cai[4] = 0; + PUT_WORD(&cai[5], plci->appl->MaxDataLength); + cai[0] = 6; + add_p(plci, CAI, cai); + return 0; + } + + + if ((GET_WORD(bp_parms[0].info) >= 32) + || (!((1L << GET_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols) + && ((GET_WORD(bp_parms[0].info) != 3) + || !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols) + || ((bp_parms[3].length != 0) && (GET_WORD(&bp_parms[3].info[1]) != 0) && (GET_WORD(&bp_parms[3].info[1]) != 56000))))) + { + return _B1_NOT_SUPPORTED; + } + plci->B1_resource = add_b1_facilities(plci, resource[GET_WORD(bp_parms[0].info)], + (word)(b1_facilities & ~B1_FACILITY_VOICE)); + adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE)); + cai[0] = 6; + cai[1] = plci->B1_resource; + for (i = 2; i < sizeof(cai); i++) cai[i] = 0; + + if ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) + || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC) + || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC)) + { /* B1 - modem */ + for (i = 0; i < 7; i++) mdm_cfg[i].length = 0; + + if (bp_parms[3].length) + { + if (api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwww", mdm_cfg)) + { + return (_WRONG_MESSAGE_FORMAT); + } + + cai[2] = 0; /* Bit rate for adaptation */ + + dbug(1, dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info))); + + PUT_WORD(&cai[13], 0); /* Min Tx speed */ + PUT_WORD(&cai[15], GET_WORD(mdm_cfg[0].info)); /* Max Tx speed */ + PUT_WORD(&cai[17], 0); /* Min Rx speed */ + PUT_WORD(&cai[19], GET_WORD(mdm_cfg[0].info)); /* Max Rx speed */ + + cai[3] = 0; /* Async framing parameters */ + switch (GET_WORD(mdm_cfg[2].info)) + { /* Parity */ + case 1: /* odd parity */ + cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD); + dbug(1, dprintf("MDM: odd parity")); + break; + + case 2: /* even parity */ + cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN); + dbug(1, dprintf("MDM: even parity")); + break; + + default: + dbug(1, dprintf("MDM: no parity")); + break; + } + + switch (GET_WORD(mdm_cfg[3].info)) + { /* stop bits */ + case 1: /* 2 stop bits */ + cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS; + dbug(1, dprintf("MDM: 2 stop bits")); + break; + + default: + dbug(1, dprintf("MDM: 1 stop bit")); + break; + } + + switch (GET_WORD(mdm_cfg[1].info)) + { /* char length */ + case 5: + cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5; + dbug(1, dprintf("MDM: 5 bits")); + break; + + case 6: + cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6; + dbug(1, dprintf("MDM: 6 bits")); + break; + + case 7: + cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7; + dbug(1, dprintf("MDM: 7 bits")); + break; + + default: + dbug(1, dprintf("MDM: 8 bits")); + break; + } + + cai[7] = 0; /* Line taking options */ + cai[8] = 0; /* Modulation negotiation options */ + cai[9] = 0; /* Modulation options */ + + if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0)) + { + cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION; + dbug(1, dprintf("MDM: Reverse direction")); + } + + if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN) + { + cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN; + dbug(1, dprintf("MDM: Disable retrain")); + } + + if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE) + { + cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE; + dbug(1, dprintf("MDM: Disable ring tone")); + } + + if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_1800) + { + cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ; + dbug(1, dprintf("MDM: 1800 guard tone")); + } + else if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_550) + { + cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ; + dbug(1, dprintf("MDM: 550 guard tone")); + } + + if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100) + { + cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100; + dbug(1, dprintf("MDM: V100")); + } + else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS) + { + cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS; + dbug(1, dprintf("MDM: IN CLASS")); + } + else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED) + { + cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED; + dbug(1, dprintf("MDM: DISABLED")); + } + cai[0] = 20; + + if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18)) + && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */ + { + plci->requested_options |= 1L << PRIVATE_V18; + } + if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */ + plci->requested_options |= 1L << PRIVATE_VOWN; + + if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1]) + & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN))) + { + if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwws", mdm_cfg)) + { + i = 27; + if (mdm_cfg[6].length >= 4) + { + d = GET_DWORD(&mdm_cfg[6].info[1]); + cai[7] |= (byte) d; /* line taking options */ + cai[9] |= (byte)(d >> 8); /* modulation options */ + cai[++i] = (byte)(d >> 16); /* vown modulation options */ + cai[++i] = (byte)(d >> 24); + if (mdm_cfg[6].length >= 8) + { + d = GET_DWORD(&mdm_cfg[6].info[5]); + cai[10] |= (byte) d; /* disabled modulations mask */ + cai[11] |= (byte)(d >> 8); + if (mdm_cfg[6].length >= 12) + { + d = GET_DWORD(&mdm_cfg[6].info[9]); + cai[12] = (byte) d; /* enabled modulations mask */ + cai[++i] = (byte)(d >> 8); /* vown enabled modulations */ + cai[++i] = (byte)(d >> 16); + cai[++i] = (byte)(d >> 24); + cai[++i] = 0; + if (mdm_cfg[6].length >= 14) + { + w = GET_WORD(&mdm_cfg[6].info[13]); + if (w != 0) + PUT_WORD(&cai[13], w); /* min tx speed */ + if (mdm_cfg[6].length >= 16) + { + w = GET_WORD(&mdm_cfg[6].info[15]); + if (w != 0) + PUT_WORD(&cai[15], w); /* max tx speed */ + if (mdm_cfg[6].length >= 18) + { + w = GET_WORD(&mdm_cfg[6].info[17]); + if (w != 0) + PUT_WORD(&cai[17], w); /* min rx speed */ + if (mdm_cfg[6].length >= 20) + { + w = GET_WORD(&mdm_cfg[6].info[19]); + if (w != 0) + PUT_WORD(&cai[19], w); /* max rx speed */ + if (mdm_cfg[6].length >= 22) + { + w = GET_WORD(&mdm_cfg[6].info[21]); + cai[23] = (byte)(-((short) w)); /* transmit level */ + if (mdm_cfg[6].length >= 24) + { + w = GET_WORD(&mdm_cfg[6].info[23]); + cai[22] |= (byte) w; /* info options mask */ + cai[21] |= (byte)(w >> 8); /* disabled symbol rates */ + } + } + } + } + } + } + } + } + } + cai[27] = i - 27; + i++; + if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwwss", mdm_cfg)) + { + if (!api_parse(&mdm_cfg[7].info[1], (word)mdm_cfg[7].length, "sss", mdm_cfg_v18)) + { + for (n = 0; n < 3; n++) + { + cai[i] = (byte)(mdm_cfg_v18[n].length); + for (j = 1; j < ((word)(cai[i] + 1)); j++) + cai[i + j] = mdm_cfg_v18[n].info[j]; + i += cai[i] + 1; + } + } + } + cai[0] = (byte)(i - 1); + } + } + + } + } + if (GET_WORD(bp_parms[0].info) == 2 || /* V.110 async */ + GET_WORD(bp_parms[0].info) == 3) /* V.110 sync */ + { + if (bp_parms[3].length) { + dbug(1, dprintf("V.110,%d", GET_WORD(&bp_parms[3].info[1]))); + switch (GET_WORD(&bp_parms[3].info[1])) { /* Rate */ + case 0: + case 56000: + if (GET_WORD(bp_parms[0].info) == 3) { /* V.110 sync 56k */ + dbug(1, dprintf("56k sync HSCX")); + cai[1] = 8; + cai[2] = 0; + cai[3] = 0; + } + else if (GET_WORD(bp_parms[0].info) == 2) { + dbug(1, dprintf("56k async DSP")); + cai[2] = 9; + } + break; + case 50: cai[2] = 1; break; + case 75: cai[2] = 1; break; + case 110: cai[2] = 1; break; + case 150: cai[2] = 1; break; + case 200: cai[2] = 1; break; + case 300: cai[2] = 1; break; + case 600: cai[2] = 1; break; + case 1200: cai[2] = 2; break; + case 2400: cai[2] = 3; break; + case 4800: cai[2] = 4; break; + case 7200: cai[2] = 10; break; + case 9600: cai[2] = 5; break; + case 12000: cai[2] = 13; break; + case 24000: cai[2] = 0; break; + case 14400: cai[2] = 11; break; + case 19200: cai[2] = 6; break; + case 28800: cai[2] = 12; break; + case 38400: cai[2] = 7; break; + case 48000: cai[2] = 8; break; + case 76: cai[2] = 15; break; /* 75/1200 */ + case 1201: cai[2] = 14; break; /* 1200/75 */ + case 56001: cai[2] = 9; break; /* V.110 56000 */ + + default: + return _B1_PARM_NOT_SUPPORTED; + } + cai[3] = 0; + if (cai[1] == 13) /* v.110 async */ + { + if (bp_parms[3].length >= 8) + { + switch (GET_WORD(&bp_parms[3].info[3])) + { /* char length */ + case 5: + cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5; + break; + case 6: + cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6; + break; + case 7: + cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7; + break; + } + switch (GET_WORD(&bp_parms[3].info[5])) + { /* Parity */ + case 1: /* odd parity */ + cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD); + break; + case 2: /* even parity */ + cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN); + break; + } + switch (GET_WORD(&bp_parms[3].info[7])) + { /* stop bits */ + case 1: /* 2 stop bits */ + cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS; + break; + } + } + } + } + else if (cai[1] == 8 || GET_WORD(bp_parms[0].info) == 3) { + dbug(1, dprintf("V.110 default 56k sync")); + cai[1] = 8; + cai[2] = 0; + cai[3] = 0; + } + else { + dbug(1, dprintf("V.110 default 9600 async")); + cai[2] = 5; + } + } + PUT_WORD(&cai[5], plci->appl->MaxDataLength); + dbug(1, dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6])); /* HexDump ("CAI", sizeof(cai), &cai[0]); */ - add_p(plci, CAI, cai); - return 0; + add_p(plci, CAI, cai); + return 0; } /*------------------------------------------------------------------*/ /* put parameter for b2 and B3 protocol in the parameter buffer */ /*------------------------------------------------------------------*/ -word add_b23(PLCI * plci, API_PARSE * bp) -{ - word i, fax_control_bits; - byte pos, len; - byte SAPI = 0x40; /* default SAPI 16 for x.31 */ - API_PARSE bp_parms[8]; - API_PARSE * b1_config; - API_PARSE * b2_config; - API_PARSE b2_config_parms[8]; - API_PARSE * b3_config; - API_PARSE b3_config_parms[6]; - API_PARSE global_config[2]; - - static byte llc[3] = {2,0,0}; - static byte dlc[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - static byte nlc[256]; - static byte lli[12] = {1,1}; - - const byte llc2_out[] = {1,2,4,6,2,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6}; - const byte llc2_in[] = {1,3,4,6,3,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6}; - - const byte llc3[] = {4,3,2,2,6,6,0}; - const byte header[] = {0,2,3,3,0,0,0}; - - for(i=0;i<8;i++) bp_parms[i].length = 0; - for(i=0;i<6;i++) b2_config_parms[i].length = 0; - for(i=0;i<5;i++) b3_config_parms[i].length = 0; - - lli[0] = 1; - lli[1] = 1; - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) - lli[1] |= 2; - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) - lli[1] |= 4; - - if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) { - lli[1] |= 0x10; - if (plci->rx_dma_descriptor <= 0) { - plci->rx_dma_descriptor=diva_get_dma_descriptor(plci,&plci->rx_dma_magic); - if (plci->rx_dma_descriptor >= 0) - plci->rx_dma_descriptor++; - } - if (plci->rx_dma_descriptor > 0) { - lli[0] = 6; - lli[1] |= 0x40; - lli[2] = (byte)(plci->rx_dma_descriptor - 1); - lli[3] = (byte)plci->rx_dma_magic; - lli[4] = (byte)(plci->rx_dma_magic >> 8); - lli[5] = (byte)(plci->rx_dma_magic >> 16); - lli[6] = (byte)(plci->rx_dma_magic >> 24); - } - } - - if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) { - lli[1] |= 0x20; - } - - dbug(1,dprintf("add_b23")); - api_save_msg(bp, "s", &plci->B_protocol); - - if(!bp->length && plci->tel) - { - plci->adv_nl = TRUE; - dbug(1,dprintf("Default adv.Nl")); - add_p(plci,LLI,lli); - plci->B2_prot = 1 /*XPARENT*/; - plci->B3_prot = 0 /*XPARENT*/; - llc[1] = 2; - llc[2] = 4; - add_p(plci, LLC, llc); - dlc[0] = 2; - PUT_WORD(&dlc[1],plci->appl->MaxDataLength); - add_p(plci, DLC, dlc); - return 0; - } - - if(!bp->length) /*default*/ - { - dbug(1,dprintf("ret default")); - add_p(plci,LLI,lli); - plci->B2_prot = 0 /*X.75 */; - plci->B3_prot = 0 /*XPARENT*/; - llc[1] = 1; - llc[2] = 4; - add_p(plci, LLC, llc); - dlc[0] = 2; - PUT_WORD(&dlc[1],plci->appl->MaxDataLength); - add_p(plci, DLC, dlc); - return 0; - } - dbug(1,dprintf("b_prot_len=%d",(word)bp->length)); - if((word)bp->length > 256) return _WRONG_MESSAGE_FORMAT; - - if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms)) - { - bp_parms[6].length = 0; - if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms)) - { - dbug(1,dprintf("b-form.!")); - return _WRONG_MESSAGE_FORMAT; - } - } - else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms)) - { - dbug(1,dprintf("b-form.!")); - return _WRONG_MESSAGE_FORMAT; - } - - if(plci->tel==ADV_VOICE) /* transparent B on advanced voice */ - { - if(GET_WORD(bp_parms[1].info)!=1 - || GET_WORD(bp_parms[2].info)!=0) return _B2_NOT_SUPPORTED; - plci->adv_nl = TRUE; - } - else if(plci->tel) return _B2_NOT_SUPPORTED; - - - if ((GET_WORD(bp_parms[1].info) == B2_RTP) - && (GET_WORD(bp_parms[2].info) == B3_RTP) - && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP))) - { - add_p(plci,LLI,lli); - plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); - plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); - llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? 14 : 13; - llc[2] = 4; - add_p(plci, LLC, llc); - dlc[0] = 2; - PUT_WORD(&dlc[1],plci->appl->MaxDataLength); - dlc[3] = 3; /* Addr A */ - dlc[4] = 1; /* Addr B */ - dlc[5] = 7; /* modulo mode */ - dlc[6] = 7; /* window size */ - dlc[7] = 0; /* XID len Lo */ - dlc[8] = 0; /* XID len Hi */ - for (i = 0; i < bp_parms[4].length; i++) - dlc[9+i] = bp_parms[4].info[1+i]; - dlc[0] = (byte)(8 + bp_parms[4].length); - add_p(plci, DLC, dlc); - for (i = 0; i < bp_parms[5].length; i++) - nlc[1+i] = bp_parms[5].info[1+i]; - nlc[0] = (byte)(bp_parms[5].length); - add_p(plci, NLC, nlc); - return 0; - } - - - - if ((GET_WORD(bp_parms[1].info) >= 32) - || (!((1L << GET_WORD(bp_parms[1].info)) & plci->adapter->profile.B2_Protocols) - && ((GET_WORD(bp_parms[1].info) != B2_PIAFS) - || !(plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS))))) - - { - return _B2_NOT_SUPPORTED; - } - if ((GET_WORD(bp_parms[2].info) >= 32) - || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols)) - { - return _B3_NOT_SUPPORTED; - } - if ((GET_WORD(bp_parms[1].info) != B2_SDLC) - && ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) - || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC) - || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))) - { - return (add_modem_b23 (plci, bp_parms)); - } - - add_p(plci,LLI,lli); - - plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); - plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); - if(plci->B2_prot==12) SAPI = 0; /* default SAPI D-channel */ - - if(bp_parms[6].length) - { - if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config)) - { - return _WRONG_MESSAGE_FORMAT; - } - switch(GET_WORD(global_config[0].info)) - { - case 1: - plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE; - break; - case 2: - plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER; - break; - } - } - dbug(1,dprintf("call_dir=%04x", plci->call_dir)); - - - if (plci->B2_prot == B2_PIAFS) - llc[1] = PIAFS_CRC; - else +static word add_b23(PLCI *plci, API_PARSE *bp) +{ + word i, fax_control_bits; + byte pos, len; + byte SAPI = 0x40; /* default SAPI 16 for x.31 */ + API_PARSE bp_parms[8]; + API_PARSE *b1_config; + API_PARSE *b2_config; + API_PARSE b2_config_parms[8]; + API_PARSE *b3_config; + API_PARSE b3_config_parms[6]; + API_PARSE global_config[2]; + + static byte llc[3] = {2,0,0}; + static byte dlc[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + static byte nlc[256]; + static byte lli[12] = {1,1}; + + const byte llc2_out[] = {1,2,4,6,2,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6}; + const byte llc2_in[] = {1,3,4,6,3,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6}; + + const byte llc3[] = {4,3,2,2,6,6,0}; + const byte header[] = {0,2,3,3,0,0,0}; + + for (i = 0; i < 8; i++) bp_parms[i].length = 0; + for (i = 0; i < 6; i++) b2_config_parms[i].length = 0; + for (i = 0; i < 5; i++) b3_config_parms[i].length = 0; + + lli[0] = 1; + lli[1] = 1; + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) + lli[1] |= 2; + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) + lli[1] |= 4; + + if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) { + lli[1] |= 0x10; + if (plci->rx_dma_descriptor <= 0) { + plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic); + if (plci->rx_dma_descriptor >= 0) + plci->rx_dma_descriptor++; + } + if (plci->rx_dma_descriptor > 0) { + lli[0] = 6; + lli[1] |= 0x40; + lli[2] = (byte)(plci->rx_dma_descriptor - 1); + lli[3] = (byte)plci->rx_dma_magic; + lli[4] = (byte)(plci->rx_dma_magic >> 8); + lli[5] = (byte)(plci->rx_dma_magic >> 16); + lli[6] = (byte)(plci->rx_dma_magic >> 24); + } + } + + if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) { + lli[1] |= 0x20; + } + + dbug(1, dprintf("add_b23")); + api_save_msg(bp, "s", &plci->B_protocol); + + if (!bp->length && plci->tel) + { + plci->adv_nl = true; + dbug(1, dprintf("Default adv.Nl")); + add_p(plci, LLI, lli); + plci->B2_prot = 1 /*XPARENT*/; + plci->B3_prot = 0 /*XPARENT*/; + llc[1] = 2; + llc[2] = 4; + add_p(plci, LLC, llc); + dlc[0] = 2; + PUT_WORD(&dlc[1], plci->appl->MaxDataLength); + add_p(plci, DLC, dlc); + return 0; + } + + if (!bp->length) /*default*/ + { + dbug(1, dprintf("ret default")); + add_p(plci, LLI, lli); + plci->B2_prot = 0 /*X.75 */; + plci->B3_prot = 0 /*XPARENT*/; + llc[1] = 1; + llc[2] = 4; + add_p(plci, LLC, llc); + dlc[0] = 2; + PUT_WORD(&dlc[1], plci->appl->MaxDataLength); + add_p(plci, DLC, dlc); + return 0; + } + dbug(1, dprintf("b_prot_len=%d", (word)bp->length)); + if ((word)bp->length > 256) return _WRONG_MESSAGE_FORMAT; + + if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms)) + { + bp_parms[6].length = 0; + if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms)) + { + dbug(1, dprintf("b-form.!")); + return _WRONG_MESSAGE_FORMAT; + } + } + else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms)) + { + dbug(1, dprintf("b-form.!")); + return _WRONG_MESSAGE_FORMAT; + } + + if (plci->tel == ADV_VOICE) /* transparent B on advanced voice */ + { + if (GET_WORD(bp_parms[1].info) != 1 + || GET_WORD(bp_parms[2].info) != 0) return _B2_NOT_SUPPORTED; + plci->adv_nl = true; + } + else if (plci->tel) return _B2_NOT_SUPPORTED; + + + if ((GET_WORD(bp_parms[1].info) == B2_RTP) + && (GET_WORD(bp_parms[2].info) == B3_RTP) + && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP))) + { + add_p(plci, LLI, lli); + plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); + plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); + llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? 14 : 13; + llc[2] = 4; + add_p(plci, LLC, llc); + dlc[0] = 2; + PUT_WORD(&dlc[1], plci->appl->MaxDataLength); + dlc[3] = 3; /* Addr A */ + dlc[4] = 1; /* Addr B */ + dlc[5] = 7; /* modulo mode */ + dlc[6] = 7; /* window size */ + dlc[7] = 0; /* XID len Lo */ + dlc[8] = 0; /* XID len Hi */ + for (i = 0; i < bp_parms[4].length; i++) + dlc[9 + i] = bp_parms[4].info[1 + i]; + dlc[0] = (byte)(8 + bp_parms[4].length); + add_p(plci, DLC, dlc); + for (i = 0; i < bp_parms[5].length; i++) + nlc[1 + i] = bp_parms[5].info[1 + i]; + nlc[0] = (byte)(bp_parms[5].length); + add_p(plci, NLC, nlc); + return 0; + } + + + + if ((GET_WORD(bp_parms[1].info) >= 32) + || (!((1L << GET_WORD(bp_parms[1].info)) & plci->adapter->profile.B2_Protocols) + && ((GET_WORD(bp_parms[1].info) != B2_PIAFS) + || !(plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS))))) + + { + return _B2_NOT_SUPPORTED; + } + if ((GET_WORD(bp_parms[2].info) >= 32) + || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols)) + { + return _B3_NOT_SUPPORTED; + } + if ((GET_WORD(bp_parms[1].info) != B2_SDLC) + && ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) + || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC) + || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))) + { + return (add_modem_b23(plci, bp_parms)); + } + + add_p(plci, LLI, lli); + + plci->B2_prot = (byte)GET_WORD(bp_parms[1].info); + plci->B3_prot = (byte)GET_WORD(bp_parms[2].info); + if (plci->B2_prot == 12) SAPI = 0; /* default SAPI D-channel */ + + if (bp_parms[6].length) + { + if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config)) + { + return _WRONG_MESSAGE_FORMAT; + } + switch (GET_WORD(global_config[0].info)) + { + case 1: + plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE; + break; + case 2: + plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER; + break; + } + } + dbug(1, dprintf("call_dir=%04x", plci->call_dir)); + + + if (plci->B2_prot == B2_PIAFS) + llc[1] = PIAFS_CRC; + else /* IMPLEMENT_PIAFS */ - { - llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? - llc2_out[GET_WORD(bp_parms[1].info)] : llc2_in[GET_WORD(bp_parms[1].info)]; - } - llc[2] = llc3[GET_WORD(bp_parms[2].info)]; - - add_p(plci, LLC, llc); - - dlc[0] = 2; - PUT_WORD(&dlc[1], plci->appl->MaxDataLength + - header[GET_WORD(bp_parms[2].info)]); - - b1_config = &bp_parms[3]; - nlc[0] = 0; - if(plci->B3_prot == 4 - || plci->B3_prot == 5) - { - for (i=0;i<sizeof(T30_INFO);i++) nlc[i] = 0; - nlc[0] = sizeof(T30_INFO); - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) - ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI; - ((T30_INFO *)&nlc[1])->rate_div_2400 = 0xff; - if(b1_config->length>=2) - { - ((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1])/2400); - } - } - b2_config = &bp_parms[4]; - - - if (llc[1] == PIAFS_CRC) - { - if (plci->B3_prot != B3_TRANSPARENT) - { - return _B_STACK_NOT_SUPPORTED; - } - if(b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) { - return _WRONG_MESSAGE_FORMAT; - } - PUT_WORD(&dlc[1],plci->appl->MaxDataLength); - dlc[3] = 0; /* Addr A */ - dlc[4] = 0; /* Addr B */ - dlc[5] = 0; /* modulo mode */ - dlc[6] = 0; /* window size */ - if (b2_config->length >= 7){ - dlc[ 7] = 7; - dlc[ 8] = 0; - dlc[ 9] = b2_config_parms[0].info[0]; /* PIAFS protocol Speed configuration */ - dlc[10] = b2_config_parms[1].info[0]; /* V.42bis P0 */ - dlc[11] = b2_config_parms[1].info[1]; /* V.42bis P0 */ - dlc[12] = b2_config_parms[2].info[0]; /* V.42bis P1 */ - dlc[13] = b2_config_parms[2].info[1]; /* V.42bis P1 */ - dlc[14] = b2_config_parms[3].info[0]; /* V.42bis P2 */ - dlc[15] = b2_config_parms[3].info[1]; /* V.42bis P2 */ - dlc[ 0] = 15; - if(b2_config->length >= 8) { /* PIAFS control abilities */ - dlc[ 7] = 10; - dlc[16] = 2; /* Length of PIAFS extention */ - dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */ - dlc[18] = b2_config_parms[4].info[0]; /* value */ - dlc[ 0] = 18; - } - } - else /* default values, 64K, variable, no compression */ - { - dlc[ 7] = 7; - dlc[ 8] = 0; - dlc[ 9] = 0x03; /* PIAFS protocol Speed configuration */ - dlc[10] = 0x03; /* V.42bis P0 */ - dlc[11] = 0; /* V.42bis P0 */ - dlc[12] = 0; /* V.42bis P1 */ - dlc[13] = 0; /* V.42bis P1 */ - dlc[14] = 0; /* V.42bis P2 */ - dlc[15] = 0; /* V.42bis P2 */ - dlc[ 0] = 15; - } - add_p(plci, DLC, dlc); - } - else - - if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS)) - { - if (plci->B3_prot != B3_TRANSPARENT) - return _B_STACK_NOT_SUPPORTED; - - dlc[0] = 6; - PUT_WORD (&dlc[1], GET_WORD (&dlc[1]) + 2); - dlc[3] = 0x08; - dlc[4] = 0x01; - dlc[5] = 127; - dlc[6] = 7; - if (b2_config->length != 0) - { - if((llc[1]==V120_V42BIS) && api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) { - return _WRONG_MESSAGE_FORMAT; - } - dlc[3] = (byte)((b2_config->info[2] << 3) | ((b2_config->info[1] >> 5) & 0x04)); - dlc[4] = (byte)((b2_config->info[1] << 1) | 0x01); - if (b2_config->info[3] != 128) - { - dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); - return _B2_PARM_NOT_SUPPORTED; - } - dlc[5] = (byte)(b2_config->info[3] - 1); - dlc[6] = b2_config->info[4]; - if(llc[1]==V120_V42BIS){ - if (b2_config->length >= 10){ - dlc[ 7] = 6; - dlc[ 8] = 0; - dlc[ 9] = b2_config_parms[4].info[0]; - dlc[10] = b2_config_parms[4].info[1]; - dlc[11] = b2_config_parms[5].info[0]; - dlc[12] = b2_config_parms[5].info[1]; - dlc[13] = b2_config_parms[6].info[0]; - dlc[14] = b2_config_parms[6].info[1]; - dlc[ 0] = 14; - dbug(1,dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1])); - dbug(1,dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1])); - dbug(1,dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1])); - } - else { - dlc[ 6] = 14; - } - } - } - } - else - { - if(b2_config->length) - { - dbug(1,dprintf("B2-Config")); - if(llc[1]==X75_V42BIS){ - if(api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) - { - return _WRONG_MESSAGE_FORMAT; - } - } - else { - if(api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms)) - { - return _WRONG_MESSAGE_FORMAT; - } - } - /* if B2 Protocol is LAPD, b2_config structure is different */ - if(llc[1]==6) - { - dlc[0] = 4; - if(b2_config->length>=1) dlc[2] = b2_config->info[1]; /* TEI */ - else dlc[2] = 0x01; - if( (b2_config->length>=2) && (plci->B2_prot==12) ) - { - SAPI = b2_config->info[2]; /* SAPI */ - } - dlc[1] = SAPI; - if( (b2_config->length>=3) && (b2_config->info[3]==128) ) - { - dlc[3] = 127; /* Mode */ - } - else - { - dlc[3] = 7; /* Mode */ - } - - if(b2_config->length>=4) dlc[4] = b2_config->info[4]; /* Window */ - else dlc[4] = 1; - dbug(1,dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); - if(b2_config->length>5) return _B2_PARM_NOT_SUPPORTED; - } - else - { - dlc[0] = (byte)(b2_config_parms[4].length+6); - dlc[3] = b2_config->info[1]; - dlc[4] = b2_config->info[2]; - if(b2_config->info[3]!=8 && b2_config->info[3]!=128){ - dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); - return _B2_PARM_NOT_SUPPORTED; - } - - dlc[5] = (byte)(b2_config->info[3]-1); - dlc[6] = b2_config->info[4]; - if(dlc[6]>dlc[5]){ - dbug(1,dprintf("2D-dlc= %x %x %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4], dlc[5], dlc[6])); - return _B2_PARM_NOT_SUPPORTED; - } - - if(llc[1]==X75_V42BIS) { - if (b2_config->length >= 10){ - dlc[ 7] = 6; - dlc[ 8] = 0; - dlc[ 9] = b2_config_parms[4].info[0]; - dlc[10] = b2_config_parms[4].info[1]; - dlc[11] = b2_config_parms[5].info[0]; - dlc[12] = b2_config_parms[5].info[1]; - dlc[13] = b2_config_parms[6].info[0]; - dlc[14] = b2_config_parms[6].info[1]; - dlc[ 0] = 14; - dbug(1,dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1])); - dbug(1,dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1])); - dbug(1,dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1])); - } - else { - dlc[ 6] = 14; - } - - } - else { - PUT_WORD(&dlc[7], (word)b2_config_parms[4].length); - for(i=0; i<b2_config_parms[4].length; i++) - dlc[11+i] = b2_config_parms[4].info[1+i]; - } - } - } - } - add_p(plci, DLC, dlc); - - b3_config = &bp_parms[5]; - if(b3_config->length) - { - if(plci->B3_prot == 4 - || plci->B3_prot == 5) - { - if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms)) - { - return _WRONG_MESSAGE_FORMAT; - } - i = GET_WORD((byte *)(b3_config_parms[0].info)); - ((T30_INFO *)&nlc[1])->resolution = (byte)(((i & 0x0001) || - ((plci->B3_prot == 4) && (((byte)(GET_WORD((byte *)b3_config_parms[1].info))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200 : 0); - ((T30_INFO *)&nlc[1])->data_format = (byte)(GET_WORD((byte *)b3_config_parms[1].info)); - fax_control_bits = T30_CONTROL_BIT_ALL_FEATURES; - if ((((T30_INFO *)&nlc[1])->rate_div_2400 != 0) && (((T30_INFO *)&nlc[1])->rate_div_2400 <= 6)) - fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_V34FAX; - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) - { - - if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) - & (1L << PRIVATE_FAX_PAPER_FORMATS)) - { - ((T30_INFO *)&nlc[1])->resolution |= T30_RESOLUTION_R8_1540 | - T30_RESOLUTION_R16_1540_OR_400 | T30_RESOLUTION_300_300 | - T30_RESOLUTION_INCH_BASED | T30_RESOLUTION_METRIC_BASED; - } - - ((T30_INFO *)&nlc[1])->recording_properties = - T30_RECORDING_WIDTH_ISO_A3 | - (T30_RECORDING_LENGTH_UNLIMITED << 2) | - (T30_MIN_SCANLINE_TIME_00_00_00 << 4); - } - if(plci->B3_prot == 5) - { - if (i & 0x0002) /* Accept incoming fax-polling requests */ - fax_control_bits |= T30_CONTROL_BIT_ACCEPT_POLLING; - if (i & 0x2000) /* Do not use MR compression */ - fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_2D_CODING; - if (i & 0x4000) /* Do not use MMR compression */ - fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_T6_CODING; - if (i & 0x8000) /* Do not use ECM */ - fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_ECM; - if (plci->fax_connect_info_length != 0) - { - ((T30_INFO *)&nlc[1])->resolution = ((T30_INFO *)plci->fax_connect_info_buffer)->resolution; - ((T30_INFO *)&nlc[1])->data_format = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format; - ((T30_INFO *)&nlc[1])->recording_properties = ((T30_INFO *)plci->fax_connect_info_buffer)->recording_properties; - fax_control_bits |= GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) & - (T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS); - } - } - /* copy station id to NLC */ - for(i=0; i<20; i++) - { - if(i<b3_config_parms[2].length) - { - ((T30_INFO *)&nlc[1])->station_id[i] = ((byte *)b3_config_parms[2].info)[1+i]; - } - else - { - ((T30_INFO *)&nlc[1])->station_id[i] = ' '; - } - } - ((T30_INFO *)&nlc[1])->station_id_len = 20; - /* copy head line to NLC */ - if(b3_config_parms[3].length) - { - - pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20]))); - if (pos != 0) - { - if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE) - pos = 0; - else - { - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; - len = (byte)b3_config_parms[2].length; - if (len > 20) - len = 20; - if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE) - { - for (i = 0; i < len; i++) - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; - } - } - } - - len = (byte)b3_config_parms[3].length; - if (len > CAPI_MAX_HEAD_LINE_SPACE - pos) - len = (byte)(CAPI_MAX_HEAD_LINE_SPACE - pos); - ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len); - nlc[0] += (byte)(pos + len); - for (i = 0; i < len; i++) - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; - } - else - ((T30_INFO *)&nlc[1])->head_line_len = 0; - - plci->nsf_control_bits = 0; - if(plci->B3_prot == 5) - { - if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD)) - && (GET_WORD((byte *)b3_config_parms[1].info) & 0x8000)) /* Private SUB/SEP/PWD enable */ - { - plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD; - } - if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD)) - && (GET_WORD((byte *)b3_config_parms[1].info) & 0x4000)) /* Private non-standard facilities enable */ - { - plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD; - } - if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) - & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) - { - if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) - & (1L << PRIVATE_FAX_SUB_SEP_PWD)) - { - fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD; - if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING) - fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; - } - len = nlc[0]; - pos = ((byte)(((T30_INFO *) 0)->station_id + 20)); - if (pos < plci->fax_connect_info_length) - { - for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) - nlc[++len] = plci->fax_connect_info_buffer[pos++]; - } - else - nlc[++len] = 0; - if (pos < plci->fax_connect_info_length) - { - for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) - nlc[++len] = plci->fax_connect_info_buffer[pos++]; - } - else - nlc[++len] = 0; - if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1]) - & (1L << PRIVATE_FAX_NONSTANDARD)) - { - if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0)) - { - if ((plci->fax_connect_info_buffer[pos] >= 3) && (plci->fax_connect_info_buffer[pos+1] >= 2)) - plci->nsf_control_bits = GET_WORD(&plci->fax_connect_info_buffer[pos+2]); - for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) - nlc[++len] = plci->fax_connect_info_buffer[pos++]; - } - else - { - if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms)) - { - dbug(1,dprintf("non-standard facilities info missing or wrong format")); - nlc[++len] = 0; - } - else - { - if ((b3_config_parms[4].length >= 3) && (b3_config_parms[4].info[1] >= 2)) - plci->nsf_control_bits = GET_WORD(&b3_config_parms[4].info[2]); - nlc[++len] = (byte)(b3_config_parms[4].length); - for (i = 0; i < b3_config_parms[4].length; i++) - nlc[++len] = b3_config_parms[4].info[1+i]; - } - } - } - nlc[0] = len; - if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) - && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) - { - ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG; - } - } - } - - PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits); - len = ((byte)(((T30_INFO *) 0)->station_id + 20)); - for (i = 0; i < len; i++) - plci->fax_connect_info_buffer[i] = nlc[1+i]; - ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0; - i += ((T30_INFO *)&nlc[1])->head_line_len; - while (i < nlc[0]) - plci->fax_connect_info_buffer[len++] = nlc[++i]; - plci->fax_connect_info_length = len; - } - else - { - nlc[0] = 14; - if(b3_config->length!=16) - return _B3_PARM_NOT_SUPPORTED; - for(i=0; i<12; i++) nlc[1+i] = b3_config->info[1+i]; - if(GET_WORD(&b3_config->info[13])!=8 && GET_WORD(&b3_config->info[13])!=128) - return _B3_PARM_NOT_SUPPORTED; - nlc[13] = b3_config->info[13]; - if(GET_WORD(&b3_config->info[15])>=nlc[13]) - return _B3_PARM_NOT_SUPPORTED; - nlc[14] = b3_config->info[15]; - } - } - else - { - if (plci->B3_prot == 4 - || plci->B3_prot == 5 /*T.30 - FAX*/ ) return _B3_PARM_NOT_SUPPORTED; - } - add_p(plci, NLC, nlc); - return 0; + { + llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? + llc2_out[GET_WORD(bp_parms[1].info)] : llc2_in[GET_WORD(bp_parms[1].info)]; + } + llc[2] = llc3[GET_WORD(bp_parms[2].info)]; + + add_p(plci, LLC, llc); + + dlc[0] = 2; + PUT_WORD(&dlc[1], plci->appl->MaxDataLength + + header[GET_WORD(bp_parms[2].info)]); + + b1_config = &bp_parms[3]; + nlc[0] = 0; + if (plci->B3_prot == 4 + || plci->B3_prot == 5) + { + for (i = 0; i < sizeof(T30_INFO); i++) nlc[i] = 0; + nlc[0] = sizeof(T30_INFO); + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) + ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI; + ((T30_INFO *)&nlc[1])->rate_div_2400 = 0xff; + if (b1_config->length >= 2) + { + ((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1]) / 2400); + } + } + b2_config = &bp_parms[4]; + + + if (llc[1] == PIAFS_CRC) + { + if (plci->B3_prot != B3_TRANSPARENT) + { + return _B_STACK_NOT_SUPPORTED; + } + if (b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) { + return _WRONG_MESSAGE_FORMAT; + } + PUT_WORD(&dlc[1], plci->appl->MaxDataLength); + dlc[3] = 0; /* Addr A */ + dlc[4] = 0; /* Addr B */ + dlc[5] = 0; /* modulo mode */ + dlc[6] = 0; /* window size */ + if (b2_config->length >= 7) { + dlc[7] = 7; + dlc[8] = 0; + dlc[9] = b2_config_parms[0].info[0]; /* PIAFS protocol Speed configuration */ + dlc[10] = b2_config_parms[1].info[0]; /* V.42bis P0 */ + dlc[11] = b2_config_parms[1].info[1]; /* V.42bis P0 */ + dlc[12] = b2_config_parms[2].info[0]; /* V.42bis P1 */ + dlc[13] = b2_config_parms[2].info[1]; /* V.42bis P1 */ + dlc[14] = b2_config_parms[3].info[0]; /* V.42bis P2 */ + dlc[15] = b2_config_parms[3].info[1]; /* V.42bis P2 */ + dlc[0] = 15; + if (b2_config->length >= 8) { /* PIAFS control abilities */ + dlc[7] = 10; + dlc[16] = 2; /* Length of PIAFS extension */ + dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */ + dlc[18] = b2_config_parms[4].info[0]; /* value */ + dlc[0] = 18; + } + } + else /* default values, 64K, variable, no compression */ + { + dlc[7] = 7; + dlc[8] = 0; + dlc[9] = 0x03; /* PIAFS protocol Speed configuration */ + dlc[10] = 0x03; /* V.42bis P0 */ + dlc[11] = 0; /* V.42bis P0 */ + dlc[12] = 0; /* V.42bis P1 */ + dlc[13] = 0; /* V.42bis P1 */ + dlc[14] = 0; /* V.42bis P2 */ + dlc[15] = 0; /* V.42bis P2 */ + dlc[0] = 15; + } + add_p(plci, DLC, dlc); + } + else + + if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS)) + { + if (plci->B3_prot != B3_TRANSPARENT) + return _B_STACK_NOT_SUPPORTED; + + dlc[0] = 6; + PUT_WORD(&dlc[1], GET_WORD(&dlc[1]) + 2); + dlc[3] = 0x08; + dlc[4] = 0x01; + dlc[5] = 127; + dlc[6] = 7; + if (b2_config->length != 0) + { + if ((llc[1] == V120_V42BIS) && api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) { + return _WRONG_MESSAGE_FORMAT; + } + dlc[3] = (byte)((b2_config->info[2] << 3) | ((b2_config->info[1] >> 5) & 0x04)); + dlc[4] = (byte)((b2_config->info[1] << 1) | 0x01); + if (b2_config->info[3] != 128) + { + dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); + return _B2_PARM_NOT_SUPPORTED; + } + dlc[5] = (byte)(b2_config->info[3] - 1); + dlc[6] = b2_config->info[4]; + if (llc[1] == V120_V42BIS) { + if (b2_config->length >= 10) { + dlc[7] = 6; + dlc[8] = 0; + dlc[9] = b2_config_parms[4].info[0]; + dlc[10] = b2_config_parms[4].info[1]; + dlc[11] = b2_config_parms[5].info[0]; + dlc[12] = b2_config_parms[5].info[1]; + dlc[13] = b2_config_parms[6].info[0]; + dlc[14] = b2_config_parms[6].info[1]; + dlc[0] = 14; + dbug(1, dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1])); + dbug(1, dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1])); + dbug(1, dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1])); + } + else { + dlc[6] = 14; + } + } + } + } + else + { + if (b2_config->length) + { + dbug(1, dprintf("B2-Config")); + if (llc[1] == X75_V42BIS) { + if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) + { + return _WRONG_MESSAGE_FORMAT; + } + } + else { + if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms)) + { + return _WRONG_MESSAGE_FORMAT; + } + } + /* if B2 Protocol is LAPD, b2_config structure is different */ + if (llc[1] == 6) + { + dlc[0] = 4; + if (b2_config->length >= 1) dlc[2] = b2_config->info[1]; /* TEI */ + else dlc[2] = 0x01; + if ((b2_config->length >= 2) && (plci->B2_prot == 12)) + { + SAPI = b2_config->info[2]; /* SAPI */ + } + dlc[1] = SAPI; + if ((b2_config->length >= 3) && (b2_config->info[3] == 128)) + { + dlc[3] = 127; /* Mode */ + } + else + { + dlc[3] = 7; /* Mode */ + } + + if (b2_config->length >= 4) dlc[4] = b2_config->info[4]; /* Window */ + else dlc[4] = 1; + dbug(1, dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); + if (b2_config->length > 5) return _B2_PARM_NOT_SUPPORTED; + } + else + { + dlc[0] = (byte)(b2_config_parms[4].length + 6); + dlc[3] = b2_config->info[1]; + dlc[4] = b2_config->info[2]; + if (b2_config->info[3] != 8 && b2_config->info[3] != 128) { + dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4])); + return _B2_PARM_NOT_SUPPORTED; + } + + dlc[5] = (byte)(b2_config->info[3] - 1); + dlc[6] = b2_config->info[4]; + if (dlc[6] > dlc[5]) { + dbug(1, dprintf("2D-dlc= %x %x %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4], dlc[5], dlc[6])); + return _B2_PARM_NOT_SUPPORTED; + } + + if (llc[1] == X75_V42BIS) { + if (b2_config->length >= 10) { + dlc[7] = 6; + dlc[8] = 0; + dlc[9] = b2_config_parms[4].info[0]; + dlc[10] = b2_config_parms[4].info[1]; + dlc[11] = b2_config_parms[5].info[0]; + dlc[12] = b2_config_parms[5].info[1]; + dlc[13] = b2_config_parms[6].info[0]; + dlc[14] = b2_config_parms[6].info[1]; + dlc[0] = 14; + dbug(1, dprintf("b2_config_parms[4].info[0] [1]: %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1])); + dbug(1, dprintf("b2_config_parms[5].info[0] [1]: %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1])); + dbug(1, dprintf("b2_config_parms[6].info[0] [1]: %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1])); + } + else { + dlc[6] = 14; + } + + } + else { + PUT_WORD(&dlc[7], (word)b2_config_parms[4].length); + for (i = 0; i < b2_config_parms[4].length; i++) + dlc[11 + i] = b2_config_parms[4].info[1 + i]; + } + } + } + } + add_p(plci, DLC, dlc); + + b3_config = &bp_parms[5]; + if (b3_config->length) + { + if (plci->B3_prot == 4 + || plci->B3_prot == 5) + { + if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms)) + { + return _WRONG_MESSAGE_FORMAT; + } + i = GET_WORD((byte *)(b3_config_parms[0].info)); + ((T30_INFO *)&nlc[1])->resolution = (byte)(((i & 0x0001) || + ((plci->B3_prot == 4) && (((byte)(GET_WORD((byte *)b3_config_parms[1].info))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200 : 0); + ((T30_INFO *)&nlc[1])->data_format = (byte)(GET_WORD((byte *)b3_config_parms[1].info)); + fax_control_bits = T30_CONTROL_BIT_ALL_FEATURES; + if ((((T30_INFO *)&nlc[1])->rate_div_2400 != 0) && (((T30_INFO *)&nlc[1])->rate_div_2400 <= 6)) + fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_V34FAX; + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS) + { + + if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1]) + & (1L << PRIVATE_FAX_PAPER_FORMATS)) + { + ((T30_INFO *)&nlc[1])->resolution |= T30_RESOLUTION_R8_1540 | + T30_RESOLUTION_R16_1540_OR_400 | T30_RESOLUTION_300_300 | + T30_RESOLUTION_INCH_BASED | T30_RESOLUTION_METRIC_BASED; + } + + ((T30_INFO *)&nlc[1])->recording_properties = + T30_RECORDING_WIDTH_ISO_A3 | + (T30_RECORDING_LENGTH_UNLIMITED << 2) | + (T30_MIN_SCANLINE_TIME_00_00_00 << 4); + } + if (plci->B3_prot == 5) + { + if (i & 0x0002) /* Accept incoming fax-polling requests */ + fax_control_bits |= T30_CONTROL_BIT_ACCEPT_POLLING; + if (i & 0x2000) /* Do not use MR compression */ + fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_2D_CODING; + if (i & 0x4000) /* Do not use MMR compression */ + fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_T6_CODING; + if (i & 0x8000) /* Do not use ECM */ + fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_ECM; + if (plci->fax_connect_info_length != 0) + { + ((T30_INFO *)&nlc[1])->resolution = ((T30_INFO *)plci->fax_connect_info_buffer)->resolution; + ((T30_INFO *)&nlc[1])->data_format = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format; + ((T30_INFO *)&nlc[1])->recording_properties = ((T30_INFO *)plci->fax_connect_info_buffer)->recording_properties; + fax_control_bits |= GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) & + (T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS); + } + } + /* copy station id to NLC */ + for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++) + { + if (i < b3_config_parms[2].length) + { + ((T30_INFO *)&nlc[1])->station_id[i] = ((byte *)b3_config_parms[2].info)[1 + i]; + } + else + { + ((T30_INFO *)&nlc[1])->station_id[i] = ' '; + } + } + ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH; + /* copy head line to NLC */ + if (b3_config_parms[3].length) + { + + pos = (byte)(fax_head_line_time(&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH]))); + if (pos != 0) + { + if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE) + pos = 0; + else + { + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + len = (byte)b3_config_parms[2].length; + if (len > 20) + len = 20; + if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE) + { + for (i = 0; i < len; i++) + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1 + i]; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + } + } + } + + len = (byte)b3_config_parms[3].length; + if (len > CAPI_MAX_HEAD_LINE_SPACE - pos) + len = (byte)(CAPI_MAX_HEAD_LINE_SPACE - pos); + ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len); + nlc[0] += (byte)(pos + len); + for (i = 0; i < len; i++) + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[3].info)[1 + i]; + } else + ((T30_INFO *)&nlc[1])->head_line_len = 0; + + plci->nsf_control_bits = 0; + if (plci->B3_prot == 5) + { + if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD)) + && (GET_WORD((byte *)b3_config_parms[1].info) & 0x8000)) /* Private SUB/SEP/PWD enable */ + { + plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD; + } + if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD)) + && (GET_WORD((byte *)b3_config_parms[1].info) & 0x4000)) /* Private non-standard facilities enable */ + { + plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD; + } + if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1]) + & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) + { + if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1]) + & (1L << PRIVATE_FAX_SUB_SEP_PWD)) + { + fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD; + if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING) + fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; + } + len = nlc[0]; + pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + if (pos < plci->fax_connect_info_length) + { + for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) + nlc[++len] = plci->fax_connect_info_buffer[pos++]; + } + else + nlc[++len] = 0; + if (pos < plci->fax_connect_info_length) + { + for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) + nlc[++len] = plci->fax_connect_info_buffer[pos++]; + } + else + nlc[++len] = 0; + if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1]) + & (1L << PRIVATE_FAX_NONSTANDARD)) + { + if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0)) + { + if ((plci->fax_connect_info_buffer[pos] >= 3) && (plci->fax_connect_info_buffer[pos + 1] >= 2)) + plci->nsf_control_bits = GET_WORD(&plci->fax_connect_info_buffer[pos + 2]); + for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) + nlc[++len] = plci->fax_connect_info_buffer[pos++]; + } + else + { + if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms)) + { + dbug(1, dprintf("non-standard facilities info missing or wrong format")); + nlc[++len] = 0; + } + else + { + if ((b3_config_parms[4].length >= 3) && (b3_config_parms[4].info[1] >= 2)) + plci->nsf_control_bits = GET_WORD(&b3_config_parms[4].info[2]); + nlc[++len] = (byte)(b3_config_parms[4].length); + for (i = 0; i < b3_config_parms[4].length; i++) + nlc[++len] = b3_config_parms[4].info[1 + i]; + } + } + } + nlc[0] = len; + if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) + && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) + { + ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG; + } + } + } + + PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits); + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; + for (i = 0; i < len; i++) + plci->fax_connect_info_buffer[i] = nlc[1 + i]; + ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0; + i += ((T30_INFO *)&nlc[1])->head_line_len; + while (i < nlc[0]) + plci->fax_connect_info_buffer[len++] = nlc[++i]; + plci->fax_connect_info_length = len; + } + else + { + nlc[0] = 14; + if (b3_config->length != 16) + return _B3_PARM_NOT_SUPPORTED; + for (i = 0; i < 12; i++) nlc[1 + i] = b3_config->info[1 + i]; + if (GET_WORD(&b3_config->info[13]) != 8 && GET_WORD(&b3_config->info[13]) != 128) + return _B3_PARM_NOT_SUPPORTED; + nlc[13] = b3_config->info[13]; + if (GET_WORD(&b3_config->info[15]) >= nlc[13]) + return _B3_PARM_NOT_SUPPORTED; + nlc[14] = b3_config->info[15]; + } + } + else + { + if (plci->B3_prot == 4 + || plci->B3_prot == 5 /*T.30 - FAX*/) return _B3_PARM_NOT_SUPPORTED; + } + add_p(plci, NLC, nlc); + return 0; } /*----------------------------------------------------------------*/ @@ -8548,136 +8567,136 @@ word add_b23(PLCI * plci, API_PARSE * bp) /* B3 Configuration for modem: */ /* empty */ /*----------------------------------------------------------------*/ -static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms) -{ - static byte lli[12] = {1,1}; - static byte llc[3] = {2,0,0}; - static byte dlc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - API_PARSE mdm_config[2]; - word i; - word b2_config = 0; - - for(i=0;i<2;i++) mdm_config[i].length = 0; - for(i=0;i<sizeof(dlc);i++) dlc[i] = 0; - - if (((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) - && (GET_WORD(bp_parms[1].info) != B2_MODEM_EC_COMPRESSION)) - || ((GET_WORD(bp_parms[0].info) != B1_MODEM_ALL_NEGOTIATE) - && (GET_WORD(bp_parms[1].info) != B2_TRANSPARENT))) - { - return (_B_STACK_NOT_SUPPORTED); - } - if ((GET_WORD(bp_parms[2].info) != B3_MODEM) - && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT)) - { - return (_B_STACK_NOT_SUPPORTED); - } - - plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); - plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); - - if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length) - { - if (api_parse (&bp_parms[4].info[1], - (word)bp_parms[4].length, "w", - mdm_config)) - { - return (_WRONG_MESSAGE_FORMAT); - } - b2_config = GET_WORD(mdm_config[0].info); - } - - /* OK, L2 is modem */ - - lli[0] = 1; - lli[1] = 1; - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) - lli[1] |= 2; - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) - lli[1] |= 4; - - if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) { - lli[1] |= 0x10; - if (plci->rx_dma_descriptor <= 0) { - plci->rx_dma_descriptor=diva_get_dma_descriptor(plci,&plci->rx_dma_magic); - if (plci->rx_dma_descriptor >= 0) - plci->rx_dma_descriptor++; - } - if (plci->rx_dma_descriptor > 0) { - lli[1] |= 0x40; - lli[0] = 6; - lli[2] = (byte)(plci->rx_dma_descriptor - 1); - lli[3] = (byte)plci->rx_dma_magic; - lli[4] = (byte)(plci->rx_dma_magic >> 8); - lli[5] = (byte)(plci->rx_dma_magic >> 16); - lli[6] = (byte)(plci->rx_dma_magic >> 24); - } - } - - if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) { - lli[1] |= 0x20; - } - - llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? - /*V42*/ 10 : /*V42_IN*/ 9; - llc[2] = 4; /* pass L3 always transparent */ - add_p(plci, LLI, lli); - add_p(plci, LLC, llc); - i = 1; - PUT_WORD (&dlc[i], plci->appl->MaxDataLength); - i += 2; - if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) - { - if (bp_parms[4].length) - { - dbug(1, dprintf("MDM b2_config=%02x", b2_config)); - dlc[i++] = 3; /* Addr A */ - dlc[i++] = 1; /* Addr B */ - dlc[i++] = 7; /* modulo mode */ - dlc[i++] = 7; /* window size */ - dlc[i++] = 0; /* XID len Lo */ - dlc[i++] = 0; /* XID len Hi */ - - if (b2_config & MDM_B2_DISABLE_V42bis) - { - dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS; - } - if (b2_config & MDM_B2_DISABLE_MNP) - { - dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5; - } - if (b2_config & MDM_B2_DISABLE_TRANS) - { - dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL; - } - if (b2_config & MDM_B2_DISABLE_V42) - { - dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT; - } - if (b2_config & MDM_B2_DISABLE_COMP) - { - dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION; - } - i++; - } - } - else - { - dlc[i++] = 3; /* Addr A */ - dlc[i++] = 1; /* Addr B */ - dlc[i++] = 7; /* modulo mode */ - dlc[i++] = 7; /* window size */ - dlc[i++] = 0; /* XID len Lo */ - dlc[i++] = 0; /* XID len Hi */ - dlc[i++] = DLC_MODEMPROT_DISABLE_V42_V42BIS | - DLC_MODEMPROT_DISABLE_MNP_MNP5 | - DLC_MODEMPROT_DISABLE_V42_DETECT | - DLC_MODEMPROT_DISABLE_COMPRESSION; - } - dlc[0] = (byte)(i - 1); +static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms) +{ + static byte lli[12] = {1,1}; + static byte llc[3] = {2,0,0}; + static byte dlc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + API_PARSE mdm_config[2]; + word i; + word b2_config = 0; + + for (i = 0; i < 2; i++) mdm_config[i].length = 0; + for (i = 0; i < sizeof(dlc); i++) dlc[i] = 0; + + if (((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE) + && (GET_WORD(bp_parms[1].info) != B2_MODEM_EC_COMPRESSION)) + || ((GET_WORD(bp_parms[0].info) != B1_MODEM_ALL_NEGOTIATE) + && (GET_WORD(bp_parms[1].info) != B2_TRANSPARENT))) + { + return (_B_STACK_NOT_SUPPORTED); + } + if ((GET_WORD(bp_parms[2].info) != B3_MODEM) + && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT)) + { + return (_B_STACK_NOT_SUPPORTED); + } + + plci->B2_prot = (byte) GET_WORD(bp_parms[1].info); + plci->B3_prot = (byte) GET_WORD(bp_parms[2].info); + + if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length) + { + if (api_parse(&bp_parms[4].info[1], + (word)bp_parms[4].length, "w", + mdm_config)) + { + return (_WRONG_MESSAGE_FORMAT); + } + b2_config = GET_WORD(mdm_config[0].info); + } + + /* OK, L2 is modem */ + + lli[0] = 1; + lli[1] = 1; + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) + lli[1] |= 2; + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) + lli[1] |= 4; + + if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) { + lli[1] |= 0x10; + if (plci->rx_dma_descriptor <= 0) { + plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic); + if (plci->rx_dma_descriptor >= 0) + plci->rx_dma_descriptor++; + } + if (plci->rx_dma_descriptor > 0) { + lli[1] |= 0x40; + lli[0] = 6; + lli[2] = (byte)(plci->rx_dma_descriptor - 1); + lli[3] = (byte)plci->rx_dma_magic; + lli[4] = (byte)(plci->rx_dma_magic >> 8); + lli[5] = (byte)(plci->rx_dma_magic >> 16); + lli[6] = (byte)(plci->rx_dma_magic >> 24); + } + } + + if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) { + lli[1] |= 0x20; + } + + llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? + /*V42*/ 10 : /*V42_IN*/ 9; + llc[2] = 4; /* pass L3 always transparent */ + add_p(plci, LLI, lli); + add_p(plci, LLC, llc); + i = 1; + PUT_WORD(&dlc[i], plci->appl->MaxDataLength); + i += 2; + if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) + { + if (bp_parms[4].length) + { + dbug(1, dprintf("MDM b2_config=%02x", b2_config)); + dlc[i++] = 3; /* Addr A */ + dlc[i++] = 1; /* Addr B */ + dlc[i++] = 7; /* modulo mode */ + dlc[i++] = 7; /* window size */ + dlc[i++] = 0; /* XID len Lo */ + dlc[i++] = 0; /* XID len Hi */ + + if (b2_config & MDM_B2_DISABLE_V42bis) + { + dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS; + } + if (b2_config & MDM_B2_DISABLE_MNP) + { + dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5; + } + if (b2_config & MDM_B2_DISABLE_TRANS) + { + dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL; + } + if (b2_config & MDM_B2_DISABLE_V42) + { + dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT; + } + if (b2_config & MDM_B2_DISABLE_COMP) + { + dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION; + } + i++; + } + } + else + { + dlc[i++] = 3; /* Addr A */ + dlc[i++] = 1; /* Addr B */ + dlc[i++] = 7; /* modulo mode */ + dlc[i++] = 7; /* window size */ + dlc[i++] = 0; /* XID len Lo */ + dlc[i++] = 0; /* XID len Hi */ + dlc[i++] = DLC_MODEMPROT_DISABLE_V42_V42BIS | + DLC_MODEMPROT_DISABLE_MNP_MNP5 | + DLC_MODEMPROT_DISABLE_V42_DETECT | + DLC_MODEMPROT_DISABLE_COMPRESSION; + } + dlc[0] = (byte)(i - 1); /* HexDump ("DLC", sizeof(dlc), &dlc[0]); */ - add_p(plci, DLC, dlc); - return (0); + add_p(plci, DLC, dlc); + return (0); } @@ -8685,604 +8704,605 @@ static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms) /* send a request for the signaling entity */ /*------------------------------------------------------------------*/ -void sig_req(PLCI * plci, byte req, byte Id) +static void sig_req(PLCI *plci, byte req, byte Id) { - if(!plci) return; - if(plci->adapter->adapter_disabled) return; - dbug(1,dprintf("sig_req(%x)",req)); - if (req == REMOVE) - plci->sig_remove_id = plci->Sig.Id; - if(plci->req_in==plci->req_in_start) { - plci->req_in +=2; - plci->RBuffer[plci->req_in++] = 0; - } - PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start-2); - plci->RBuffer[plci->req_in++] = Id; /* sig/nl flag */ - plci->RBuffer[plci->req_in++] = req; /* request */ - plci->RBuffer[plci->req_in++] = 0; /* channel */ - plci->req_in_start = plci->req_in; + if (!plci) return; + if (plci->adapter->adapter_disabled) return; + dbug(1, dprintf("sig_req(%x)", req)); + if (req == REMOVE) + plci->sig_remove_id = plci->Sig.Id; + if (plci->req_in == plci->req_in_start) { + plci->req_in += 2; + plci->RBuffer[plci->req_in++] = 0; + } + PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2); + plci->RBuffer[plci->req_in++] = Id; /* sig/nl flag */ + plci->RBuffer[plci->req_in++] = req; /* request */ + plci->RBuffer[plci->req_in++] = 0; /* channel */ + plci->req_in_start = plci->req_in; } /*------------------------------------------------------------------*/ /* send a request for the network layer entity */ /*------------------------------------------------------------------*/ -void nl_req_ncci(PLCI * plci, byte req, byte ncci) -{ - if(!plci) return; - if(plci->adapter->adapter_disabled) return; - dbug(1,dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci)); - if (req == REMOVE) - { - plci->nl_remove_id = plci->NL.Id; - ncci_remove (plci, 0, (byte)(ncci != 0)); - ncci = 0; - } - if(plci->req_in==plci->req_in_start) { - plci->req_in +=2; - plci->RBuffer[plci->req_in++] = 0; - } - PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start-2); - plci->RBuffer[plci->req_in++] = 1; /* sig/nl flag */ - plci->RBuffer[plci->req_in++] = req; /* request */ - plci->RBuffer[plci->req_in++] = plci->adapter->ncci_ch[ncci]; /* channel */ - plci->req_in_start = plci->req_in; -} - -void send_req(PLCI * plci) -{ - ENTITY * e; - word l; +static void nl_req_ncci(PLCI *plci, byte req, byte ncci) +{ + if (!plci) return; + if (plci->adapter->adapter_disabled) return; + dbug(1, dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci)); + if (req == REMOVE) + { + plci->nl_remove_id = plci->NL.Id; + ncci_remove(plci, 0, (byte)(ncci != 0)); + ncci = 0; + } + if (plci->req_in == plci->req_in_start) { + plci->req_in += 2; + plci->RBuffer[plci->req_in++] = 0; + } + PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2); + plci->RBuffer[plci->req_in++] = 1; /* sig/nl flag */ + plci->RBuffer[plci->req_in++] = req; /* request */ + plci->RBuffer[plci->req_in++] = plci->adapter->ncci_ch[ncci]; /* channel */ + plci->req_in_start = plci->req_in; +} + +static void send_req(PLCI *plci) +{ + ENTITY *e; + word l; /* word i; */ - if(!plci) return; - if(plci->adapter->adapter_disabled) return; - channel_xmit_xon (plci); - - /* if nothing to do, return */ - if(plci->req_in==plci->req_out) return; - dbug(1,dprintf("send_req(in=%d,out=%d)",plci->req_in,plci->req_out)); - - if(plci->nl_req || plci->sig_req) return; - - l = GET_WORD(&plci->RBuffer[plci->req_out]); - plci->req_out += 2; - plci->XData[0].P = &plci->RBuffer[plci->req_out]; - plci->req_out += l; - if(plci->RBuffer[plci->req_out]==1) - { - e = &plci->NL; - plci->req_out++; - e->Req = plci->nl_req = plci->RBuffer[plci->req_out++]; - e->ReqCh = plci->RBuffer[plci->req_out++]; - if(!(e->Id & 0x1f)) - { - e->Id = NL_ID; - plci->RBuffer[plci->req_out-4] = CAI; - plci->RBuffer[plci->req_out-3] = 1; - plci->RBuffer[plci->req_out-2] = (plci->Sig.Id==0xff) ? 0 : plci->Sig.Id; - plci->RBuffer[plci->req_out-1] = 0; - l+=3; - plci->nl_global_req = plci->nl_req; - } - dbug(1,dprintf("%x:NLREQ(%x:%x:%x)",plci->adapter->Id,e->Id,e->Req,e->ReqCh)); - } - else - { - e = &plci->Sig; - if(plci->RBuffer[plci->req_out]) - e->Id = plci->RBuffer[plci->req_out]; - plci->req_out++; - e->Req = plci->sig_req = plci->RBuffer[plci->req_out++]; - e->ReqCh = plci->RBuffer[plci->req_out++]; - if(!(e->Id & 0x1f)) - plci->sig_global_req = plci->sig_req; - dbug(1,dprintf("%x:SIGREQ(%x:%x:%x)",plci->adapter->Id,e->Id,e->Req,e->ReqCh)); - } - plci->XData[0].PLength = l; - e->X = plci->XData; - plci->adapter->request(e); - dbug(1,dprintf("send_ok")); -} - -void send_data(PLCI * plci) -{ - DIVA_CAPI_ADAPTER * a; - DATA_B3_DESC * data; - NCCI *ncci_ptr; - word ncci; - - if (!plci->nl_req && plci->ncci_ring_list) - { - a = plci->adapter; - ncci = plci->ncci_ring_list; - do - { - ncci = a->ncci_next[ncci]; - ncci_ptr = &(a->ncci[ncci]); - if (!(a->ncci_ch[ncci] - && (a->ch_flow_control[a->ncci_ch[ncci]] & N_OK_FC_PENDING))) - { - if (ncci_ptr->data_pending) - { - if ((a->ncci_state[ncci] == CONNECTED) - || (a->ncci_state[ncci] == INC_ACT_PENDING) - || (plci->send_disc == ncci)) - { - data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]); - if ((plci->B2_prot == B2_V120_ASYNC) - || (plci->B2_prot == B2_V120_ASYNC_V42BIS) - || (plci->B2_prot == B2_V120_BIT_TRANSPARENT)) - { - plci->NData[1].P = TransmitBufferGet (plci->appl, data->P); - plci->NData[1].PLength = data->Length; - if (data->Flags & 0x10) - plci->NData[0].P = v120_break_header; - else - plci->NData[0].P = v120_default_header; - plci->NData[0].PLength = 1 ; - plci->NL.XNum = 2; - plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA); - } - else - { - plci->NData[0].P = TransmitBufferGet (plci->appl, data->P); - plci->NData[0].PLength = data->Length; - if (data->Flags & 0x10) - plci->NL.Req = plci->nl_req = (byte)N_UDATA; - - else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01)) - plci->NL.Req = plci->nl_req = (byte)N_BDATA; - - else - plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA); - } - plci->NL.X = plci->NData; - plci->NL.ReqCh = a->ncci_ch[ncci]; - dbug(1,dprintf("%x:DREQ(%x:%x)",a->Id,plci->NL.Id,plci->NL.Req)); - plci->data_sent = TRUE; - plci->data_sent_ptr = data->P; - a->request(&plci->NL); - } - else { - cleanup_ncci_data (plci, ncci); - } - } - else if (plci->send_disc == ncci) - { - /* dprintf("N_DISC"); */ - plci->NData[0].PLength = 0; - plci->NL.ReqCh = a->ncci_ch[ncci]; - plci->NL.Req = plci->nl_req = N_DISC; - a->request(&plci->NL); - plci->command = _DISCONNECT_B3_R; - plci->send_disc = 0; - } - } - } while (!plci->nl_req && (ncci != plci->ncci_ring_list)); - plci->ncci_ring_list = ncci; - } -} - -void listen_check(DIVA_CAPI_ADAPTER * a) -{ - word i,j; - PLCI * plci; - byte activnotifiedcalls = 0; - - dbug(1,dprintf("listen_check(%d,%d)",a->listen_active,a->max_listen)); - if (!remove_started && !a->adapter_disabled) - { - for(i=0;i<a->max_plci;i++) - { - plci = &(a->plci[i]); - if(plci->notifiedcall) activnotifiedcalls++; - } - dbug(1,dprintf("listen_check(%d)",activnotifiedcalls)); - - for(i=a->listen_active; i < ((word)(a->max_listen+activnotifiedcalls)); i++) { - if((j=get_plci(a))) { - a->listen_active++; - plci = &a->plci[j-1]; - plci->State = LISTENING; - - add_p(plci,OAD,"\x01\xfd"); - - add_p(plci,KEY,"\x04\x43\x41\x32\x30"); - - add_p(plci,CAI,"\x01\xc0"); - add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - add_p(plci,LLI,"\x01\xc4"); /* support Dummy CR FAC + MWI + SpoofNotify */ - add_p(plci,SHIFT|6,NULL); - add_p(plci,SIN,"\x02\x00\x00"); - plci->internal_command = LISTEN_SIG_ASSIGN_PEND; /* do indicate_req if OK */ - sig_req(plci,ASSIGN,DSIG_ID); - send_req(plci); - } - } - } + if (!plci) return; + if (plci->adapter->adapter_disabled) return; + channel_xmit_xon(plci); + + /* if nothing to do, return */ + if (plci->req_in == plci->req_out) return; + dbug(1, dprintf("send_req(in=%d,out=%d)", plci->req_in, plci->req_out)); + + if (plci->nl_req || plci->sig_req) return; + + l = GET_WORD(&plci->RBuffer[plci->req_out]); + plci->req_out += 2; + plci->XData[0].P = &plci->RBuffer[plci->req_out]; + plci->req_out += l; + if (plci->RBuffer[plci->req_out] == 1) + { + e = &plci->NL; + plci->req_out++; + e->Req = plci->nl_req = plci->RBuffer[plci->req_out++]; + e->ReqCh = plci->RBuffer[plci->req_out++]; + if (!(e->Id & 0x1f)) + { + e->Id = NL_ID; + plci->RBuffer[plci->req_out - 4] = CAI; + plci->RBuffer[plci->req_out - 3] = 1; + plci->RBuffer[plci->req_out - 2] = (plci->Sig.Id == 0xff) ? 0 : plci->Sig.Id; + plci->RBuffer[plci->req_out - 1] = 0; + l += 3; + plci->nl_global_req = plci->nl_req; + } + dbug(1, dprintf("%x:NLREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh)); + } + else + { + e = &plci->Sig; + if (plci->RBuffer[plci->req_out]) + e->Id = plci->RBuffer[plci->req_out]; + plci->req_out++; + e->Req = plci->sig_req = plci->RBuffer[plci->req_out++]; + e->ReqCh = plci->RBuffer[plci->req_out++]; + if (!(e->Id & 0x1f)) + plci->sig_global_req = plci->sig_req; + dbug(1, dprintf("%x:SIGREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh)); + } + plci->XData[0].PLength = l; + e->X = plci->XData; + plci->adapter->request(e); + dbug(1, dprintf("send_ok")); +} + +static void send_data(PLCI *plci) +{ + DIVA_CAPI_ADAPTER *a; + DATA_B3_DESC *data; + NCCI *ncci_ptr; + word ncci; + + if (!plci->nl_req && plci->ncci_ring_list) + { + a = plci->adapter; + ncci = plci->ncci_ring_list; + do + { + ncci = a->ncci_next[ncci]; + ncci_ptr = &(a->ncci[ncci]); + if (!(a->ncci_ch[ncci] + && (a->ch_flow_control[a->ncci_ch[ncci]] & N_OK_FC_PENDING))) + { + if (ncci_ptr->data_pending) + { + if ((a->ncci_state[ncci] == CONNECTED) + || (a->ncci_state[ncci] == INC_ACT_PENDING) + || (plci->send_disc == ncci)) + { + data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]); + if ((plci->B2_prot == B2_V120_ASYNC) + || (plci->B2_prot == B2_V120_ASYNC_V42BIS) + || (plci->B2_prot == B2_V120_BIT_TRANSPARENT)) + { + plci->NData[1].P = TransmitBufferGet(plci->appl, data->P); + plci->NData[1].PLength = data->Length; + if (data->Flags & 0x10) + plci->NData[0].P = v120_break_header; + else + plci->NData[0].P = v120_default_header; + plci->NData[0].PLength = 1; + plci->NL.XNum = 2; + plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA); + } + else + { + plci->NData[0].P = TransmitBufferGet(plci->appl, data->P); + plci->NData[0].PLength = data->Length; + if (data->Flags & 0x10) + plci->NL.Req = plci->nl_req = (byte)N_UDATA; + + else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01)) + plci->NL.Req = plci->nl_req = (byte)N_BDATA; + + else + plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA); + } + plci->NL.X = plci->NData; + plci->NL.ReqCh = a->ncci_ch[ncci]; + dbug(1, dprintf("%x:DREQ(%x:%x)", a->Id, plci->NL.Id, plci->NL.Req)); + plci->data_sent = true; + plci->data_sent_ptr = data->P; + a->request(&plci->NL); + } + else { + cleanup_ncci_data(plci, ncci); + } + } + else if (plci->send_disc == ncci) + { + /* dprintf("N_DISC"); */ + plci->NData[0].PLength = 0; + plci->NL.ReqCh = a->ncci_ch[ncci]; + plci->NL.Req = plci->nl_req = N_DISC; + a->request(&plci->NL); + plci->command = _DISCONNECT_B3_R; + plci->send_disc = 0; + } + } + } while (!plci->nl_req && (ncci != plci->ncci_ring_list)); + plci->ncci_ring_list = ncci; + } +} + +static void listen_check(DIVA_CAPI_ADAPTER *a) +{ + word i, j; + PLCI *plci; + byte activnotifiedcalls = 0; + + dbug(1, dprintf("listen_check(%d,%d)", a->listen_active, a->max_listen)); + if (!remove_started && !a->adapter_disabled) + { + for (i = 0; i < a->max_plci; i++) + { + plci = &(a->plci[i]); + if (plci->notifiedcall) activnotifiedcalls++; + } + dbug(1, dprintf("listen_check(%d)", activnotifiedcalls)); + + for (i = a->listen_active; i < ((word)(a->max_listen + activnotifiedcalls)); i++) { + if ((j = get_plci(a))) { + a->listen_active++; + plci = &a->plci[j - 1]; + plci->State = LISTENING; + + add_p(plci, OAD, "\x01\xfd"); + + add_p(plci, KEY, "\x04\x43\x41\x32\x30"); + + add_p(plci, CAI, "\x01\xc0"); + add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + add_p(plci, LLI, "\x01\xc4"); /* support Dummy CR FAC + MWI + SpoofNotify */ + add_p(plci, SHIFT | 6, NULL); + add_p(plci, SIN, "\x02\x00\x00"); + plci->internal_command = LISTEN_SIG_ASSIGN_PEND; /* do indicate_req if OK */ + sig_req(plci, ASSIGN, DSIG_ID); + send_req(plci); + } + } + } } /*------------------------------------------------------------------*/ /* functions for all parameters sent in INDs */ /*------------------------------------------------------------------*/ -void IndParse(PLCI * plci, word * parms_id, byte ** parms, byte multiIEsize) -{ - word ploc; /* points to current location within packet */ - byte w; - byte wlen; - byte codeset,lock; - byte * in; - word i; - word code; - word mIEindex = 0; - ploc = 0; - codeset = 0; - lock = 0; - - in = plci->Sig.RBuffer->P; - for(i=0; i<parms_id[0]; i++) /* multiIE parms_id contains just the 1st */ - { /* element but parms array is larger */ - parms[i] = (byte *)""; - } - for(i=0; i<multiIEsize; i++) - { - parms[i] = (byte *)""; - } - - while(ploc<plci->Sig.RBuffer->length-1) { - - /* read information element id and length */ - w = in[ploc]; - - if(w & 0x80) { +static void IndParse(PLCI *plci, word *parms_id, byte **parms, byte multiIEsize) +{ + word ploc; /* points to current location within packet */ + byte w; + byte wlen; + byte codeset, lock; + byte *in; + word i; + word code; + word mIEindex = 0; + ploc = 0; + codeset = 0; + lock = 0; + + in = plci->Sig.RBuffer->P; + for (i = 0; i < parms_id[0]; i++) /* multiIE parms_id contains just the 1st */ + { /* element but parms array is larger */ + parms[i] = (byte *)""; + } + for (i = 0; i < multiIEsize; i++) + { + parms[i] = (byte *)""; + } + + while (ploc < plci->Sig.RBuffer->length - 1) { + + /* read information element id and length */ + w = in[ploc]; + + if (w & 0x80) { /* w &=0xf0; removed, cannot detect congestion levels */ /* upper 4 bit masked with w==SHIFT now */ - wlen = 0; - } - else { - wlen = (byte)(in[ploc+1]+1); - } - /* check if length valid (not exceeding end of packet) */ - if((ploc+wlen) > 270) return ; - if(lock & 0x80) lock &=0x7f; - else codeset = lock; - - if((w&0xf0)==SHIFT) { - codeset = in[ploc]; - if(!(codeset & 0x08)) lock = (byte)(codeset & 7); - codeset &=7; - lock |=0x80; - } - else { - if(w==ESC && wlen>=3) code = in[ploc+2] |0x800; - else code = w; - code |= (codeset<<8); - - for(i=1; i<parms_id[0]+1 && parms_id[i]!=code; i++); - - if(i<parms_id[0]+1) { - if(!multiIEsize) { /* with multiIEs use next field index, */ - mIEindex = i-1; /* with normal IEs use same index like parms_id */ - } - - parms[mIEindex] = &in[ploc+1]; - dbug(1,dprintf("mIE[%d]=0x%x",*parms[mIEindex],in[ploc])); - if(parms_id[i]==OAD - || parms_id[i]==CONN_NR - || parms_id[i]==CAD) { - if(in[ploc+2] &0x80) { - in[ploc+0] = (byte)(in[ploc+1]+1); - in[ploc+1] = (byte)(in[ploc+2] &0x7f); - in[ploc+2] = 0x80; - parms[mIEindex] = &in[ploc]; - } - } - mIEindex++; /* effects multiIEs only */ - } - } - - ploc +=(wlen+1); - } - return ; + wlen = 0; + } + else { + wlen = (byte)(in[ploc + 1] + 1); + } + /* check if length valid (not exceeding end of packet) */ + if ((ploc + wlen) > 270) return; + if (lock & 0x80) lock &= 0x7f; + else codeset = lock; + + if ((w & 0xf0) == SHIFT) { + codeset = in[ploc]; + if (!(codeset & 0x08)) lock = (byte)(codeset & 7); + codeset &= 7; + lock |= 0x80; + } + else { + if (w == ESC && wlen >= 3) code = in[ploc + 2] | 0x800; + else code = w; + code |= (codeset << 8); + + for (i = 1; i < parms_id[0] + 1 && parms_id[i] != code; i++); + + if (i < parms_id[0] + 1) { + if (!multiIEsize) { /* with multiIEs use next field index, */ + mIEindex = i - 1; /* with normal IEs use same index like parms_id */ + } + + parms[mIEindex] = &in[ploc + 1]; + dbug(1, dprintf("mIE[%d]=0x%x", *parms[mIEindex], in[ploc])); + if (parms_id[i] == OAD + || parms_id[i] == CONN_NR + || parms_id[i] == CAD) { + if (in[ploc + 2] & 0x80) { + in[ploc + 0] = (byte)(in[ploc + 1] + 1); + in[ploc + 1] = (byte)(in[ploc + 2] & 0x7f); + in[ploc + 2] = 0x80; + parms[mIEindex] = &in[ploc]; + } + } + mIEindex++; /* effects multiIEs only */ + } + } + + ploc += (wlen + 1); + } + return; } /*------------------------------------------------------------------*/ /* try to match a cip from received BC and HLC */ /*------------------------------------------------------------------*/ -byte ie_compare(byte * ie1, byte * ie2) -{ - word i; - if(!ie1 || ! ie2) return FALSE; - if(!ie1[0]) return FALSE; - for(i=0;i<(word)(ie1[0]+1);i++) if(ie1[i]!=ie2[i]) return FALSE; - return TRUE; -} - -word find_cip(DIVA_CAPI_ADAPTER * a, byte * bc, byte * hlc) -{ - word i; - word j; - - for(i=9;i && !ie_compare(bc,cip_bc[i][a->u_law]);i--); - - for(j=16;j<29 && - (!ie_compare(bc,cip_bc[j][a->u_law]) || !ie_compare(hlc,cip_hlc[j])); j++); - if(j==29) return i; - return j; -} - - -static byte AddInfo(byte **add_i, - byte **fty_i, - byte *esc_chi, - byte *facility) -{ - byte i; - byte j; - byte k; - byte flen; - byte len=0; - /* facility is a nested structure */ - /* FTY can be more than once */ - - if(esc_chi[0] && !(esc_chi[esc_chi[0]])&0x7f ) - { - add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */ - } - - else - { - add_i[0] = (byte *)""; - } - if(!fty_i[0][0]) - { - add_i[3] = (byte *)""; - } - else - { /* facility array found */ - for(i=0,j=1;i<MAX_MULTI_IE && fty_i[i][0];i++) - { - dbug(1,dprintf("AddIFac[%d]",fty_i[i][0])); - len += fty_i[i][0]; - len += 2; - flen=fty_i[i][0]; - facility[j++]=0x1c; /* copy fac IE */ - for(k=0;k<=flen;k++,j++) - { - facility[j]=fty_i[i][k]; -/* dbug(1,dprintf("%x ",facility[j])); */ - } - } - facility[0] = len; - add_i[3] = facility; - } -/* dbug(1,dprintf("FacArrLen=%d ",len)); */ - len = add_i[0][0]+add_i[1][0]+add_i[2][0]+add_i[3][0]; - len += 4; /* calculate length of all */ - return(len); +static byte ie_compare(byte *ie1, byte *ie2) +{ + word i; + if (!ie1 || !ie2) return false; + if (!ie1[0]) return false; + for (i = 0; i < (word)(ie1[0] + 1); i++) if (ie1[i] != ie2[i]) return false; + return true; +} + +static word find_cip(DIVA_CAPI_ADAPTER *a, byte *bc, byte *hlc) +{ + word i; + word j; + + for (i = 9; i && !ie_compare(bc, cip_bc[i][a->u_law]); i--); + + for (j = 16; j < 29 && + (!ie_compare(bc, cip_bc[j][a->u_law]) || !ie_compare(hlc, cip_hlc[j])); j++); + if (j == 29) return i; + return j; +} + + +static byte AddInfo(byte **add_i, + byte **fty_i, + byte *esc_chi, + byte *facility) +{ + byte i; + byte j; + byte k; + byte flen; + byte len = 0; + /* facility is a nested structure */ + /* FTY can be more than once */ + + if (esc_chi[0] && !(esc_chi[esc_chi[0]] & 0x7f)) + { + add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */ + } + + else + { + add_i[0] = (byte *)""; + } + if (!fty_i[0][0]) + { + add_i[3] = (byte *)""; + } + else + { /* facility array found */ + for (i = 0, j = 1; i < MAX_MULTI_IE && fty_i[i][0]; i++) + { + dbug(1, dprintf("AddIFac[%d]", fty_i[i][0])); + len += fty_i[i][0]; + len += 2; + flen = fty_i[i][0]; + facility[j++] = 0x1c; /* copy fac IE */ + for (k = 0; k <= flen; k++, j++) + { + facility[j] = fty_i[i][k]; +/* dbug(1, dprintf("%x ",facility[j])); */ + } + } + facility[0] = len; + add_i[3] = facility; + } +/* dbug(1, dprintf("FacArrLen=%d ",len)); */ + len = add_i[0][0] + add_i[1][0] + add_i[2][0] + add_i[3][0]; + len += 4; /* calculate length of all */ + return (len); } /*------------------------------------------------------------------*/ /* voice and codec features */ /*------------------------------------------------------------------*/ -void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER * a) -{ - byte voice_chi[] = "\x02\x18\x01"; - byte channel; - - channel = chi[chi[0]]&0x3; - dbug(1,dprintf("ExtDevON(Ch=0x%x)",channel)); - voice_chi[2] = (channel) ? channel : 1; - add_p(plci,FTY,"\x02\x01\x07"); /* B On, default on 1 */ - add_p(plci,ESC,voice_chi); /* Channel */ - sig_req(plci,TEL_CTRL,0); - send_req(plci); - if(a->AdvSignalPLCI) - { - adv_voice_write_coefs (a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION); - } -} - -void VoiceChannelOff(PLCI *plci) -{ - dbug(1,dprintf("ExtDevOFF")); - add_p(plci,FTY,"\x02\x01\x08"); /* B Off */ - sig_req(plci,TEL_CTRL,0); - send_req(plci); - if(plci->adapter->AdvSignalPLCI) - { - adv_voice_clear_config (plci->adapter->AdvSignalPLCI); - } -} - - -word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, byte hook_listen) -{ - word j; - PLCI *splci; - - /* check if hardware supports handset with hook states (adv.codec) */ - /* or if just a on board codec is supported */ - /* the advanced codec plci is just for internal use */ - - /* diva Pro with on-board codec: */ - if(a->profile.Global_Options & HANDSET) - { - /* new call, but hook states are already signalled */ - if(a->AdvCodecFLAG) - { - if(a->AdvSignalAppl!=appl || a->AdvSignalPLCI) - { - dbug(1,dprintf("AdvSigPlci=0x%x",a->AdvSignalPLCI)); - return 0x2001; /* codec in use by another application */ - } - if(plci!=0) - { - a->AdvSignalPLCI = plci; - plci->tel=ADV_VOICE; - } - return 0; /* adv codec still used */ - } - if((j=get_plci(a))) - { - splci = &a->plci[j-1]; - splci->tel = CODEC_PERMANENT; - /* hook_listen indicates if a facility_req with handset/hook support */ - /* was sent. Otherwise if just a call on an external device was made */ - /* the codec will be used but the hook info will be discarded (just */ - /* the external controller is in use */ - if(hook_listen) splci->State = ADVANCED_VOICE_SIG; - else - { - splci->State = ADVANCED_VOICE_NOSIG; - if(plci) - { - plci->spoofed_msg = SPOOFING_REQUIRED; - } - /* indicate D-ch connect if */ - } /* codec is connected OK */ - if(plci!=0) - { - a->AdvSignalPLCI = plci; - plci->tel=ADV_VOICE; - } - a->AdvSignalAppl = appl; - a->AdvCodecFLAG = TRUE; - a->AdvCodecPLCI = splci; - add_p(splci,CAI,"\x01\x15"); - add_p(splci,LLI,"\x01\x00"); - add_p(splci,ESC,"\x02\x18\x00"); - add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - splci->internal_command = PERM_COD_ASSIGN; - dbug(1,dprintf("Codec Assign")); - sig_req(splci,ASSIGN,DSIG_ID); - send_req(splci); - } - else - { - return 0x2001; /* wrong state, no more plcis */ - } - } - else if(a->profile.Global_Options & ON_BOARD_CODEC) - { - if(hook_listen) return 0x300B; /* Facility not supported */ - /* no hook with SCOM */ - if(plci!=0) plci->tel = CODEC; - dbug(1,dprintf("S/SCOM codec")); - /* first time we use the scom-s codec we must shut down the internal */ - /* handset application of the card. This can be done by an assign with */ - /* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/ - if(!a->scom_appl_disable){ - if((j=get_plci(a))) { - splci = &a->plci[j-1]; - add_p(splci,CAI,"\x01\x80"); - add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - sig_req(splci,ASSIGN,0xC0); /* 0xc0 is the TEL_ID */ - send_req(splci); - a->scom_appl_disable = TRUE; - } - else{ - return 0x2001; /* wrong state, no more plcis */ - } - } - } - else return 0x300B; /* Facility not supported */ - - return 0; -} - - -void CodecIdCheck(DIVA_CAPI_ADAPTER *a, PLCI *plci) -{ - - dbug(1,dprintf("CodecIdCheck")); - - if(a->AdvSignalPLCI == plci) - { - dbug(1,dprintf("PLCI owns codec")); - VoiceChannelOff(a->AdvCodecPLCI); - if(a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG) - { - dbug(1,dprintf("remove temp codec PLCI")); - plci_remove(a->AdvCodecPLCI); - a->AdvCodecFLAG = 0; - a->AdvCodecPLCI = NULL; - a->AdvSignalAppl = NULL; - } - a->AdvSignalPLCI = NULL; - } +static void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER *a) +{ + byte voice_chi[] = "\x02\x18\x01"; + byte channel; + + channel = chi[chi[0]] & 0x3; + dbug(1, dprintf("ExtDevON(Ch=0x%x)", channel)); + voice_chi[2] = (channel) ? channel : 1; + add_p(plci, FTY, "\x02\x01\x07"); /* B On, default on 1 */ + add_p(plci, ESC, voice_chi); /* Channel */ + sig_req(plci, TEL_CTRL, 0); + send_req(plci); + if (a->AdvSignalPLCI) + { + adv_voice_write_coefs(a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION); + } +} + +static void VoiceChannelOff(PLCI *plci) +{ + dbug(1, dprintf("ExtDevOFF")); + add_p(plci, FTY, "\x02\x01\x08"); /* B Off */ + sig_req(plci, TEL_CTRL, 0); + send_req(plci); + if (plci->adapter->AdvSignalPLCI) + { + adv_voice_clear_config(plci->adapter->AdvSignalPLCI); + } +} + + +static word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, + byte hook_listen) +{ + word j; + PLCI *splci; + + /* check if hardware supports handset with hook states (adv.codec) */ + /* or if just a on board codec is supported */ + /* the advanced codec plci is just for internal use */ + + /* diva Pro with on-board codec: */ + if (a->profile.Global_Options & HANDSET) + { + /* new call, but hook states are already signalled */ + if (a->AdvCodecFLAG) + { + if (a->AdvSignalAppl != appl || a->AdvSignalPLCI) + { + dbug(1, dprintf("AdvSigPlci=0x%x", a->AdvSignalPLCI)); + return 0x2001; /* codec in use by another application */ + } + if (plci != NULL) + { + a->AdvSignalPLCI = plci; + plci->tel = ADV_VOICE; + } + return 0; /* adv codec still used */ + } + if ((j = get_plci(a))) + { + splci = &a->plci[j - 1]; + splci->tel = CODEC_PERMANENT; + /* hook_listen indicates if a facility_req with handset/hook support */ + /* was sent. Otherwise if just a call on an external device was made */ + /* the codec will be used but the hook info will be discarded (just */ + /* the external controller is in use */ + if (hook_listen) splci->State = ADVANCED_VOICE_SIG; + else + { + splci->State = ADVANCED_VOICE_NOSIG; + if (plci) + { + plci->spoofed_msg = SPOOFING_REQUIRED; + } + /* indicate D-ch connect if */ + } /* codec is connected OK */ + if (plci != NULL) + { + a->AdvSignalPLCI = plci; + plci->tel = ADV_VOICE; + } + a->AdvSignalAppl = appl; + a->AdvCodecFLAG = true; + a->AdvCodecPLCI = splci; + add_p(splci, CAI, "\x01\x15"); + add_p(splci, LLI, "\x01\x00"); + add_p(splci, ESC, "\x02\x18\x00"); + add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + splci->internal_command = PERM_COD_ASSIGN; + dbug(1, dprintf("Codec Assign")); + sig_req(splci, ASSIGN, DSIG_ID); + send_req(splci); + } + else + { + return 0x2001; /* wrong state, no more plcis */ + } + } + else if (a->profile.Global_Options & ON_BOARD_CODEC) + { + if (hook_listen) return 0x300B; /* Facility not supported */ + /* no hook with SCOM */ + if (plci != NULL) plci->tel = CODEC; + dbug(1, dprintf("S/SCOM codec")); + /* first time we use the scom-s codec we must shut down the internal */ + /* handset application of the card. This can be done by an assign with */ + /* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/ + if (!a->scom_appl_disable) { + if ((j = get_plci(a))) { + splci = &a->plci[j - 1]; + add_p(splci, CAI, "\x01\x80"); + add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + sig_req(splci, ASSIGN, 0xC0); /* 0xc0 is the TEL_ID */ + send_req(splci); + a->scom_appl_disable = true; + } + else{ + return 0x2001; /* wrong state, no more plcis */ + } + } + } + else return 0x300B; /* Facility not supported */ + + return 0; +} + + +static void CodecIdCheck(DIVA_CAPI_ADAPTER *a, PLCI *plci) +{ + + dbug(1, dprintf("CodecIdCheck")); + + if (a->AdvSignalPLCI == plci) + { + dbug(1, dprintf("PLCI owns codec")); + VoiceChannelOff(a->AdvCodecPLCI); + if (a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG) + { + dbug(1, dprintf("remove temp codec PLCI")); + plci_remove(a->AdvCodecPLCI); + a->AdvCodecFLAG = 0; + a->AdvCodecPLCI = NULL; + a->AdvSignalAppl = NULL; + } + a->AdvSignalPLCI = NULL; + } } /* ------------------------------------------------------------------- - Ask for physical address of card on PCI bus + Ask for physical address of card on PCI bus ------------------------------------------------------------------- */ -static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER * a, - IDI_SYNC_REQ * preq) { - a->sdram_bar = 0; - if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) { - ENTITY * e = (ENTITY *)preq; +static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *a, + IDI_SYNC_REQ *preq) { + a->sdram_bar = 0; + if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) { + ENTITY *e = (ENTITY *)preq; - e->user[0] = a->Id - 1; - preq->xdi_sdram_bar.info.bar = 0; - preq->xdi_sdram_bar.Req = 0; - preq->xdi_sdram_bar.Rc = IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR; + e->user[0] = a->Id - 1; + preq->xdi_sdram_bar.info.bar = 0; + preq->xdi_sdram_bar.Req = 0; + preq->xdi_sdram_bar.Rc = IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR; - (*(a->request))(e); + (*(a->request))(e); - a->sdram_bar = preq->xdi_sdram_bar.info.bar; - dbug(3,dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar)); - } + a->sdram_bar = preq->xdi_sdram_bar.info.bar; + dbug(3, dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar)); + } } /* ------------------------------------------------------------------- - Ask XDI about extended features + Ask XDI about extended features ------------------------------------------------------------------- */ -static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER * a) { - IDI_SYNC_REQ * preq; - char buffer[ ((sizeof(preq->xdi_extended_features)+4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features)+4) : sizeof(ENTITY)]; - - char features[4]; - preq = (IDI_SYNC_REQ *)&buffer[0]; - - if (!diva_xdi_extended_features) { - ENTITY * e = (ENTITY *)preq; - diva_xdi_extended_features |= 0x80000000; - - e->user[0] = a->Id - 1; - preq->xdi_extended_features.Req = 0; - preq->xdi_extended_features.Rc = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES; - preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features); - preq->xdi_extended_features.info.features = &features[0]; - - (*(a->request))(e); - - if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) { - /* - Check features located in the byte '0' - */ - if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) { - diva_xdi_extended_features |= DIVA_CAPI_USE_CMA; - } - if (features[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA) { - diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_RX_DMA; - dbug(1,dprintf("XDI provides RxDMA")); - } - if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) { - diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR; - } - if (features[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC) { - diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL; - dbug(3,dprintf("XDI provides NO_CANCEL_RC feature")); - } - - } - } - - diva_ask_for_xdi_sdram_bar (a, preq); +static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a) { + IDI_SYNC_REQ *preq; + char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)]; + + char features[4]; + preq = (IDI_SYNC_REQ *)&buffer[0]; + + if (!diva_xdi_extended_features) { + ENTITY *e = (ENTITY *)preq; + diva_xdi_extended_features |= 0x80000000; + + e->user[0] = a->Id - 1; + preq->xdi_extended_features.Req = 0; + preq->xdi_extended_features.Rc = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES; + preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features); + preq->xdi_extended_features.info.features = &features[0]; + + (*(a->request))(e); + + if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) { + /* + Check features located in the byte '0' + */ + if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) { + diva_xdi_extended_features |= DIVA_CAPI_USE_CMA; + } + if (features[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA) { + diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_RX_DMA; + dbug(1, dprintf("XDI provides RxDMA")); + } + if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) { + diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR; + } + if (features[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC) { + diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL; + dbug(3, dprintf("XDI provides NO_CANCEL_RC feature")); + } + + } + } + + diva_ask_for_xdi_sdram_bar(a, preq); } /*------------------------------------------------------------------*/ @@ -9290,188 +9310,188 @@ static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER * a) { /*------------------------------------------------------------------*/ /* called from OS specific part after init time to get the Law */ /* a-law (Euro) and u-law (us,japan) use different BCs in the Setup message */ -void AutomaticLaw(DIVA_CAPI_ADAPTER *a) -{ - word j; - PLCI *splci; - - if(a->automatic_law) { - return; - } - if((j=get_plci(a))) { - diva_get_extended_adapter_features (a); - splci = &a->plci[j-1]; - a->automatic_lawPLCI = splci; - a->automatic_law = 1; - add_p(splci,CAI,"\x01\x80"); - add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - splci->internal_command = USELAW_REQ; - splci->command = 0; - splci->number = 0; - sig_req(splci,ASSIGN,DSIG_ID); - send_req(splci); - } +void AutomaticLaw(DIVA_CAPI_ADAPTER *a) +{ + word j; + PLCI *splci; + + if (a->automatic_law) { + return; + } + if ((j = get_plci(a))) { + diva_get_extended_adapter_features(a); + splci = &a->plci[j - 1]; + a->automatic_lawPLCI = splci; + a->automatic_law = 1; + add_p(splci, CAI, "\x01\x80"); + add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + splci->internal_command = USELAW_REQ; + splci->command = 0; + splci->number = 0; + sig_req(splci, ASSIGN, DSIG_ID); + send_req(splci); + } } /* called from OS specific part if an application sends an Capi20Release */ word CapiRelease(word Id) { - word i, j, appls_found; - PLCI *plci; - APPL *this; - DIVA_CAPI_ADAPTER *a; - - if (!Id) - { - dbug(0,dprintf("A: CapiRelease(Id==0)")); - return (_WRONG_APPL_ID); - } - - this = &application[Id-1]; /* get application pointer */ - - for(i=0,appls_found=0; i<max_appl; i++) - { - if(application[i].Id) /* an application has been found */ - { - appls_found++; - } - } - - for(i=0; i<max_adapter; i++) /* scan all adapters... */ - { - a = &adapter[i]; - if (a->request) - { - a->Info_Mask[Id-1] = 0; - a->CIP_Mask[Id-1] = 0; - a->Notification_Mask[Id-1] = 0; - a->codec_listen[Id-1] = NULL; - a->requested_options_table[Id-1] = 0; - for(j=0; j<a->max_plci; j++) /* and all PLCIs connected */ - { /* with this application */ - plci = &a->plci[j]; - if(plci->Id) /* if plci owns no application */ - { /* it may be not jet connected */ - if(plci->State==INC_CON_PENDING - || plci->State==INC_CON_ALERT) - { - if(test_c_ind_mask_bit (plci, (word)(Id-1))) - { - clear_c_ind_mask_bit (plci, (word)(Id-1)); - if(c_ind_mask_empty (plci)) - { - sig_req(plci,HANGUP,0); - send_req(plci); - plci->State = OUTG_DIS_PENDING; - } - } - } - if(test_c_ind_mask_bit (plci, (word)(Id-1))) - { - clear_c_ind_mask_bit (plci, (word)(Id-1)); - if(c_ind_mask_empty (plci)) - { - if(!plci->appl) - { - plci_remove(plci); - plci->State = IDLE; - } - } - } - if(plci->appl==this) - { - plci->appl = NULL; - plci_remove(plci); - plci->State = IDLE; - } - } - } - listen_check(a); - - if(a->flag_dynamic_l1_down) - { - if(appls_found==1) /* last application does a capi release */ - { - if((j=get_plci(a))) - { - plci = &a->plci[j-1]; - plci->command = 0; - add_p(plci,OAD,"\x01\xfd"); - add_p(plci,CAI,"\x01\x80"); - add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - add_p(plci,SHIFT|6,NULL); - add_p(plci,SIN,"\x02\x00\x00"); - plci->internal_command = REM_L1_SIG_ASSIGN_PEND; - sig_req(plci,ASSIGN,DSIG_ID); - add_p(plci,FTY,"\x02\xff\x06"); /* l1 down */ - sig_req(plci,SIG_CTRL,0); - send_req(plci); - } - } - } - if(a->AdvSignalAppl==this) - { - this->NullCREnable = FALSE; - if (a->AdvCodecPLCI) - { - plci_remove(a->AdvCodecPLCI); - a->AdvCodecPLCI->tel = 0; - a->AdvCodecPLCI->adv_nl = 0; - } - a->AdvSignalAppl = NULL; - a->AdvSignalPLCI = NULL; - a->AdvCodecFLAG = 0; - a->AdvCodecPLCI = NULL; - } - } - } - - this->Id = 0; - - return GOOD; -} - -static word plci_remove_check(PLCI *plci) -{ - if(!plci) return TRUE; - if(!plci->NL.Id && c_ind_mask_empty (plci)) - { - if(plci->Sig.Id == 0xff) - plci->Sig.Id = 0; - if(!plci->Sig.Id) - { - dbug(1,dprintf("plci_remove_complete(%x)",plci->Id)); - dbug(1,dprintf("tel=0x%x,Sig=0x%x",plci->tel,plci->Sig.Id)); - if (plci->Id) - { - CodecIdCheck(plci->adapter, plci); - clear_b1_config (plci); - ncci_remove (plci, 0, FALSE); - plci_free_msg_in_queue (plci); - channel_flow_control_remove (plci); - plci->Id = 0; - plci->State = IDLE; - plci->channels = 0; - plci->appl = NULL; - plci->notifiedcall = 0; - } - listen_check(plci->adapter); - return TRUE; - } - } - return FALSE; + word i, j, appls_found; + PLCI *plci; + APPL *this; + DIVA_CAPI_ADAPTER *a; + + if (!Id) + { + dbug(0, dprintf("A: CapiRelease(Id==0)")); + return (_WRONG_APPL_ID); + } + + this = &application[Id - 1]; /* get application pointer */ + + for (i = 0, appls_found = 0; i < max_appl; i++) + { + if (application[i].Id) /* an application has been found */ + { + appls_found++; + } + } + + for (i = 0; i < max_adapter; i++) /* scan all adapters... */ + { + a = &adapter[i]; + if (a->request) + { + a->Info_Mask[Id - 1] = 0; + a->CIP_Mask[Id - 1] = 0; + a->Notification_Mask[Id - 1] = 0; + a->codec_listen[Id - 1] = NULL; + a->requested_options_table[Id - 1] = 0; + for (j = 0; j < a->max_plci; j++) /* and all PLCIs connected */ + { /* with this application */ + plci = &a->plci[j]; + if (plci->Id) /* if plci owns no application */ + { /* it may be not jet connected */ + if (plci->State == INC_CON_PENDING + || plci->State == INC_CON_ALERT) + { + if (test_c_ind_mask_bit(plci, (word)(Id - 1))) + { + clear_c_ind_mask_bit(plci, (word)(Id - 1)); + if (c_ind_mask_empty(plci)) + { + sig_req(plci, HANGUP, 0); + send_req(plci); + plci->State = OUTG_DIS_PENDING; + } + } + } + if (test_c_ind_mask_bit(plci, (word)(Id - 1))) + { + clear_c_ind_mask_bit(plci, (word)(Id - 1)); + if (c_ind_mask_empty(plci)) + { + if (!plci->appl) + { + plci_remove(plci); + plci->State = IDLE; + } + } + } + if (plci->appl == this) + { + plci->appl = NULL; + plci_remove(plci); + plci->State = IDLE; + } + } + } + listen_check(a); + + if (a->flag_dynamic_l1_down) + { + if (appls_found == 1) /* last application does a capi release */ + { + if ((j = get_plci(a))) + { + plci = &a->plci[j - 1]; + plci->command = 0; + add_p(plci, OAD, "\x01\xfd"); + add_p(plci, CAI, "\x01\x80"); + add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + add_p(plci, SHIFT | 6, NULL); + add_p(plci, SIN, "\x02\x00\x00"); + plci->internal_command = REM_L1_SIG_ASSIGN_PEND; + sig_req(plci, ASSIGN, DSIG_ID); + add_p(plci, FTY, "\x02\xff\x06"); /* l1 down */ + sig_req(plci, SIG_CTRL, 0); + send_req(plci); + } + } + } + if (a->AdvSignalAppl == this) + { + this->NullCREnable = false; + if (a->AdvCodecPLCI) + { + plci_remove(a->AdvCodecPLCI); + a->AdvCodecPLCI->tel = 0; + a->AdvCodecPLCI->adv_nl = 0; + } + a->AdvSignalAppl = NULL; + a->AdvSignalPLCI = NULL; + a->AdvCodecFLAG = 0; + a->AdvCodecPLCI = NULL; + } + } + } + + this->Id = 0; + + return GOOD; +} + +static word plci_remove_check(PLCI *plci) +{ + if (!plci) return true; + if (!plci->NL.Id && c_ind_mask_empty(plci)) + { + if (plci->Sig.Id == 0xff) + plci->Sig.Id = 0; + if (!plci->Sig.Id) + { + dbug(1, dprintf("plci_remove_complete(%x)", plci->Id)); + dbug(1, dprintf("tel=0x%x,Sig=0x%x", plci->tel, plci->Sig.Id)); + if (plci->Id) + { + CodecIdCheck(plci->adapter, plci); + clear_b1_config(plci); + ncci_remove(plci, 0, false); + plci_free_msg_in_queue(plci); + channel_flow_control_remove(plci); + plci->Id = 0; + plci->State = IDLE; + plci->channels = 0; + plci->appl = NULL; + plci->notifiedcall = 0; + } + listen_check(plci->adapter); + return true; + } + } + return false; } /*------------------------------------------------------------------*/ -static byte plci_nl_busy (PLCI *plci) +static byte plci_nl_busy(PLCI *plci) { - /* only applicable for non-multiplexed protocols */ - return (plci->nl_req - || (plci->ncci_ring_list - && plci->adapter->ncci_ch[plci->ncci_ring_list] - && (plci->adapter->ch_flow_control[plci->adapter->ncci_ch[plci->ncci_ring_list]] & N_OK_FC_PENDING))); + /* only applicable for non-multiplexed protocols */ + return (plci->nl_req + || (plci->ncci_ring_list + && plci->adapter->ncci_ch[plci->ncci_ring_list] + && (plci->adapter->ch_flow_control[plci->adapter->ncci_ch[plci->ncci_ring_list]] & N_OK_FC_PENDING))); } @@ -9482,684 +9502,681 @@ static byte plci_nl_busy (PLCI *plci) static struct { - byte send_mask; - byte listen_mask; - byte character; - byte code; + byte send_mask; + byte listen_mask; + byte character; + byte code; } dtmf_digit_map[] = { - { 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK }, - { 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR }, - { 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0 }, - { 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1 }, - { 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2 }, - { 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3 }, - { 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4 }, - { 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5 }, - { 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6 }, - { 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7 }, - { 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8 }, - { 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9 }, - { 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A }, - { 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B }, - { 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C }, - { 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D }, - { 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A }, - { 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B }, - { 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C }, - { 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D }, - - { 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE }, - { 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE }, - { 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE }, - { 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE }, - { 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE }, - { 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE }, - { 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE }, - { 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE }, - { 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE }, - { 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE }, - { 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE }, - { 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE }, - { 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE }, - { 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE }, - { 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE }, - { 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE }, - { 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE }, - { 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE }, - { 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE }, - { 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE }, - { 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE }, - { 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE }, - { 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE }, - { 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL }, - { 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE }, - { 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE }, - { 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE }, - { 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE }, - { 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE }, - { 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE }, - { 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE }, - { 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE }, - { 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE }, - { 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS }, - { 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID }, - { 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH }, - { 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390 }, - { 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1 }, - { 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2 }, - { 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3 }, - { 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4 }, - { 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5 }, - { 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6 }, - { 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7 }, - { 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8 }, - { 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9 }, - { 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0 }, - { 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1 }, - { 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2 }, - { 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP }, - { 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1 }, - { 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST }, + { 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK }, + { 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR }, + { 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0 }, + { 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1 }, + { 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2 }, + { 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3 }, + { 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4 }, + { 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5 }, + { 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6 }, + { 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7 }, + { 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8 }, + { 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9 }, + { 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A }, + { 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B }, + { 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C }, + { 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D }, + { 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A }, + { 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B }, + { 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C }, + { 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D }, + + { 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE }, + { 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE }, + { 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE }, + { 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE }, + { 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE }, + { 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE }, + { 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE }, + { 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE }, + { 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE }, + { 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE }, + { 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE }, + { 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE }, + { 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE }, + { 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE }, + { 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE }, + { 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE }, + { 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE }, + { 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE }, + { 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE }, + { 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE }, + { 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE }, + { 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE }, + { 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE }, + { 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL }, + { 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE }, + { 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE }, + { 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE }, + { 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE }, + { 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE }, + { 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE }, + { 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE }, + { 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE }, + { 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE }, + { 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS }, + { 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID }, + { 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH }, + { 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390 }, + { 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1 }, + { 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2 }, + { 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3 }, + { 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4 }, + { 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5 }, + { 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6 }, + { 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7 }, + { 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8 }, + { 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9 }, + { 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0 }, + { 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1 }, + { 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2 }, + { 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP }, + { 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1 }, + { 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST }, }; -#define DTMF_DIGIT_MAP_ENTRIES (sizeof(dtmf_digit_map) / sizeof(dtmf_digit_map[0])) +#define DTMF_DIGIT_MAP_ENTRIES ARRAY_SIZE(dtmf_digit_map) -static void dtmf_enable_receiver (PLCI *plci, byte enable_mask) +static void dtmf_enable_receiver(PLCI *plci, byte enable_mask) { - word min_digit_duration, min_gap_duration; + word min_digit_duration, min_gap_duration; - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_enable_receiver %02x", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, enable_mask)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_enable_receiver %02x", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, enable_mask)); - if (enable_mask != 0) - { - min_digit_duration = (plci->dtmf_rec_pulse_ms == 0) ? 40 : plci->dtmf_rec_pulse_ms; - min_gap_duration = (plci->dtmf_rec_pause_ms == 0) ? 40 : plci->dtmf_rec_pause_ms; - plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER; - PUT_WORD (&plci->internal_req_buffer[1], min_digit_duration); - PUT_WORD (&plci->internal_req_buffer[3], min_gap_duration); - plci->NData[0].PLength = 5; + if (enable_mask != 0) + { + min_digit_duration = (plci->dtmf_rec_pulse_ms == 0) ? 40 : plci->dtmf_rec_pulse_ms; + min_gap_duration = (plci->dtmf_rec_pause_ms == 0) ? 40 : plci->dtmf_rec_pause_ms; + plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER; + PUT_WORD(&plci->internal_req_buffer[1], min_digit_duration); + PUT_WORD(&plci->internal_req_buffer[3], min_gap_duration); + plci->NData[0].PLength = 5; - PUT_WORD (&plci->internal_req_buffer[5], INTERNAL_IND_BUFFER_SIZE); - plci->NData[0].PLength += 2; - capidtmf_recv_enable (&(plci->capidtmf_state), min_digit_duration, min_gap_duration); + PUT_WORD(&plci->internal_req_buffer[5], INTERNAL_IND_BUFFER_SIZE); + plci->NData[0].PLength += 2; + capidtmf_recv_enable(&(plci->capidtmf_state), min_digit_duration, min_gap_duration); - } - else - { - plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER; - plci->NData[0].PLength = 1; + } + else + { + plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER; + plci->NData[0].PLength = 1; - capidtmf_recv_disable (&(plci->capidtmf_state)); + capidtmf_recv_disable(&(plci->capidtmf_state)); - } - plci->NData[0].P = plci->internal_req_buffer; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_UDATA; - plci->adapter->request (&plci->NL); + } + plci->NData[0].P = plci->internal_req_buffer; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_UDATA; + plci->adapter->request(&plci->NL); } -static void dtmf_send_digits (PLCI *plci, byte *digit_buffer, word digit_count) +static void dtmf_send_digits(PLCI *plci, byte *digit_buffer, word digit_count) { - word w, i; + word w, i; - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_digits %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, digit_count)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_digits %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, digit_count)); - plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_SEND_DIGITS; - w = (plci->dtmf_send_pulse_ms == 0) ? 40 : plci->dtmf_send_pulse_ms; - PUT_WORD (&plci->internal_req_buffer[1], w); - w = (plci->dtmf_send_pause_ms == 0) ? 40 : plci->dtmf_send_pause_ms; - PUT_WORD (&plci->internal_req_buffer[3], w); - for (i = 0; i < digit_count; i++) - { - w = 0; - while ((w < DTMF_DIGIT_MAP_ENTRIES) - && (digit_buffer[i] != dtmf_digit_map[w].character)) - { - w++; - } - plci->internal_req_buffer[5+i] = (w < DTMF_DIGIT_MAP_ENTRIES) ? - dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR; - } - plci->NData[0].PLength = 5 + digit_count; - plci->NData[0].P = plci->internal_req_buffer; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_UDATA; - plci->adapter->request (&plci->NL); + plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_SEND_DIGITS; + w = (plci->dtmf_send_pulse_ms == 0) ? 40 : plci->dtmf_send_pulse_ms; + PUT_WORD(&plci->internal_req_buffer[1], w); + w = (plci->dtmf_send_pause_ms == 0) ? 40 : plci->dtmf_send_pause_ms; + PUT_WORD(&plci->internal_req_buffer[3], w); + for (i = 0; i < digit_count; i++) + { + w = 0; + while ((w < DTMF_DIGIT_MAP_ENTRIES) + && (digit_buffer[i] != dtmf_digit_map[w].character)) + { + w++; + } + plci->internal_req_buffer[5 + i] = (w < DTMF_DIGIT_MAP_ENTRIES) ? + dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR; + } + plci->NData[0].PLength = 5 + digit_count; + plci->NData[0].P = plci->internal_req_buffer; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_UDATA; + plci->adapter->request(&plci->NL); } -static void dtmf_rec_clear_config (PLCI *plci) +static void dtmf_rec_clear_config(PLCI *plci) { - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_rec_clear_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_rec_clear_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); - plci->dtmf_rec_active = 0; - plci->dtmf_rec_pulse_ms = 0; - plci->dtmf_rec_pause_ms = 0; + plci->dtmf_rec_active = 0; + plci->dtmf_rec_pulse_ms = 0; + plci->dtmf_rec_pause_ms = 0; - capidtmf_init (&(plci->capidtmf_state), plci->adapter->u_law); + capidtmf_init(&(plci->capidtmf_state), plci->adapter->u_law); } -static void dtmf_send_clear_config (PLCI *plci) +static void dtmf_send_clear_config(PLCI *plci) { - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_clear_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_clear_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); - plci->dtmf_send_requests = 0; - plci->dtmf_send_pulse_ms = 0; - plci->dtmf_send_pause_ms = 0; + plci->dtmf_send_requests = 0; + plci->dtmf_send_pulse_ms = 0; + plci->dtmf_send_pause_ms = 0; } -static void dtmf_prepare_switch (dword Id, PLCI *plci) +static void dtmf_prepare_switch(dword Id, PLCI *plci) { - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_prepare_switch", - UnMapId (Id), (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_prepare_switch", + UnMapId(Id), (char *)(FILE_), __LINE__)); - while (plci->dtmf_send_requests != 0) - dtmf_confirmation (Id, plci); + while (plci->dtmf_send_requests != 0) + dtmf_confirmation(Id, plci); } -static word dtmf_save_config (dword Id, PLCI *plci, byte Rc) +static word dtmf_save_config(dword Id, PLCI *plci, byte Rc) { - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_save_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_save_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - return (GOOD); + return (GOOD); } -static word dtmf_restore_config (dword Id, PLCI *plci, byte Rc) +static word dtmf_restore_config(dword Id, PLCI *plci, byte Rc) { - word Info; - - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_restore_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - - Info = GOOD; - if (plci->B1_facilities & B1_FACILITY_DTMFR) - { - switch (plci->adjust_b_state) - { - case ADJUST_B_RESTORE_DTMF_1: - plci->internal_command = plci->adjust_b_command; - if (plci_nl_busy (plci)) - { - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; - break; - } - dtmf_enable_receiver (plci, plci->dtmf_rec_active); - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2; - break; - case ADJUST_B_RESTORE_DTMF_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Reenable DTMF receiver failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - break; - } - } - return (Info); -} - - -static void dtmf_command (dword Id, PLCI *plci, byte Rc) -{ - word internal_command, Info; - byte mask; - byte result[4]; - - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, - plci->dtmf_cmd, plci->dtmf_rec_pulse_ms, plci->dtmf_rec_pause_ms, - plci->dtmf_send_pulse_ms, plci->dtmf_send_pause_ms)); + word Info; - Info = GOOD; - result[0] = 2; - PUT_WORD (&result[1], DTMF_SUCCESS); - internal_command = plci->internal_command; - plci->internal_command = 0; - mask = 0x01; - switch (plci->dtmf_cmd) - { + dbug(1, dprintf("[%06lx] %s,%d: dtmf_restore_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - case DTMF_LISTEN_TONE_START: - mask <<= 1; - case DTMF_LISTEN_MF_START: - mask <<= 1; - - case DTMF_LISTEN_START: - switch (internal_command) - { - default: - adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | - B1_FACILITY_DTMFR), DTMF_COMMAND_1); - case DTMF_COMMAND_1: - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - case DTMF_COMMAND_2: - if (plci_nl_busy (plci)) - { - plci->internal_command = DTMF_COMMAND_2; - return; - } - plci->internal_command = DTMF_COMMAND_3; - dtmf_enable_receiver (plci, (byte)(plci->dtmf_rec_active | mask)); - return; - case DTMF_COMMAND_3: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Enable DTMF receiver failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - - plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE; - - plci->dtmf_rec_active |= mask; - break; - } - break; - - - case DTMF_LISTEN_TONE_STOP: - mask <<= 1; - case DTMF_LISTEN_MF_STOP: - mask <<= 1; - - case DTMF_LISTEN_STOP: - switch (internal_command) - { - default: - plci->dtmf_rec_active &= ~mask; - if (plci->dtmf_rec_active) - break; -/* - case DTMF_COMMAND_1: - if (plci->dtmf_rec_active) - { - if (plci_nl_busy (plci)) - { - plci->internal_command = DTMF_COMMAND_1; - return; - } - plci->dtmf_rec_active &= ~mask; - plci->internal_command = DTMF_COMMAND_2; - dtmf_enable_receiver (plci, FALSE); - return; - } - Rc = OK; - case DTMF_COMMAND_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Disable DTMF receiver failed %02x", - UnMapId (Id), (char far *)(FILE_), __LINE__, Rc)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } -*/ - adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities & - ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3); - case DTMF_COMMAND_3: - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Unload DTMF failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - break; - } - break; - - - case DTMF_SEND_TONE: - mask <<= 1; - case DTMF_SEND_MF: - mask <<= 1; - - case DTMF_DIGITS_SEND: - switch (internal_command) - { - default: - adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | - ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)), - DTMF_COMMAND_1); - case DTMF_COMMAND_1: - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - case DTMF_COMMAND_2: - if (plci_nl_busy (plci)) - { - plci->internal_command = DTMF_COMMAND_2; - return; - } - plci->dtmf_msg_number_queue[(plci->dtmf_send_requests)++] = plci->number; - plci->internal_command = DTMF_COMMAND_3; - dtmf_send_digits (plci, &plci->saved_msg.parms[3].info[1], plci->saved_msg.parms[3].length); - return; - case DTMF_COMMAND_3: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Send DTMF digits failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - if (plci->dtmf_send_requests != 0) - (plci->dtmf_send_requests)--; - Info = _FACILITY_NOT_SUPPORTED; - break; - } - return; - } - break; - } - sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number, - "wws", Info, SELECTOR_DTMF, result); + Info = GOOD; + if (plci->B1_facilities & B1_FACILITY_DTMFR) + { + switch (plci->adjust_b_state) + { + case ADJUST_B_RESTORE_DTMF_1: + plci->internal_command = plci->adjust_b_command; + if (plci_nl_busy(plci)) + { + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; + break; + } + dtmf_enable_receiver(plci, plci->dtmf_rec_active); + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2; + break; + case ADJUST_B_RESTORE_DTMF_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Reenable DTMF receiver failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + break; + } + } + return (Info); } -static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg) +static void dtmf_command(dword Id, PLCI *plci, byte Rc) { - word Info; - word i, j; - byte mask; - API_PARSE dtmf_parms[5]; - byte result[40]; + word internal_command, Info; + byte mask; + byte result[4]; - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_request", - UnMapId (Id), (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, + plci->dtmf_cmd, plci->dtmf_rec_pulse_ms, plci->dtmf_rec_pause_ms, + plci->dtmf_send_pulse_ms, plci->dtmf_send_pause_ms)); - Info = GOOD; - result[0] = 2; - PUT_WORD (&result[1], DTMF_SUCCESS); - if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - } - else if (api_parse (&msg[1].info[1], msg[1].length, "w", dtmf_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - } + Info = GOOD; + result[0] = 2; + PUT_WORD(&result[1], DTMF_SUCCESS); + internal_command = plci->internal_command; + plci->internal_command = 0; + mask = 0x01; + switch (plci->dtmf_cmd) + { - else if ((GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES) - || (GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_SEND_CODES)) - { - if (!((a->requested_options_table[appl->Id-1]) - & (1L << PRIVATE_DTMF_TONE))) - { - dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info))); - PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); - } - else - { - for (i = 0; i < 32; i++) - result[4 + i] = 0; - if (GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES) - { - for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++) - { - if (dtmf_digit_map[i].listen_mask != 0) - result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7)); - } - } - else - { - for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++) - { - if (dtmf_digit_map[i].send_mask != 0) - result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7)); - } - } - result[0] = 3 + 32; - result[3] = 32; - } - } + case DTMF_LISTEN_TONE_START: + mask <<= 1; + case DTMF_LISTEN_MF_START: + mask <<= 1; - else if (plci == NULL) + case DTMF_LISTEN_START: + switch (internal_command) + { + default: + adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | + B1_FACILITY_DTMFR), DTMF_COMMAND_1); + case DTMF_COMMAND_1: + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + if (plci->internal_command) + return; + case DTMF_COMMAND_2: + if (plci_nl_busy(plci)) + { + plci->internal_command = DTMF_COMMAND_2; + return; + } + plci->internal_command = DTMF_COMMAND_3; + dtmf_enable_receiver(plci, (byte)(plci->dtmf_rec_active | mask)); + return; + case DTMF_COMMAND_3: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Enable DTMF receiver failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + + plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE; + + plci->dtmf_rec_active |= mask; + break; + } + break; + + + case DTMF_LISTEN_TONE_STOP: + mask <<= 1; + case DTMF_LISTEN_MF_STOP: + mask <<= 1; + + case DTMF_LISTEN_STOP: + switch (internal_command) + { + default: + plci->dtmf_rec_active &= ~mask; + if (plci->dtmf_rec_active) + break; +/* + case DTMF_COMMAND_1: + if (plci->dtmf_rec_active) { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_IDENTIFIER; - } - else + if (plci_nl_busy (plci)) { - if (!plci->State - || !plci->NL.Id || plci->nl_remove_id) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_STATE; - } - else - { - plci->command = 0; - plci->dtmf_cmd = GET_WORD (dtmf_parms[0].info); - mask = 0x01; - switch (plci->dtmf_cmd) - { - - case DTMF_LISTEN_TONE_START: - case DTMF_LISTEN_TONE_STOP: - mask <<= 1; - case DTMF_LISTEN_MF_START: - case DTMF_LISTEN_MF_STOP: - mask <<= 1; - if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1]) - & (1L << PRIVATE_DTMF_TONE))) - { - dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info))); - PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); - break; - } - - case DTMF_LISTEN_START: - case DTMF_LISTEN_STOP: - if (!(a->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF) - && !(a->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (mask & DTMF_LISTEN_ACTIVE_FLAG) - { - if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms)) - { - plci->dtmf_rec_pulse_ms = 0; - plci->dtmf_rec_pause_ms = 0; - } - else - { - plci->dtmf_rec_pulse_ms = GET_WORD (dtmf_parms[1].info); - plci->dtmf_rec_pause_ms = GET_WORD (dtmf_parms[2].info); - } - } - start_internal_command (Id, plci, dtmf_command); - return (FALSE); - - - case DTMF_SEND_TONE: - mask <<= 1; - case DTMF_SEND_MF: - mask <<= 1; - if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1]) - & (1L << PRIVATE_DTMF_TONE))) - { - dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info))); - PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); - break; - } - - case DTMF_DIGITS_SEND: - if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - if (mask & DTMF_LISTEN_ACTIVE_FLAG) - { - plci->dtmf_send_pulse_ms = GET_WORD (dtmf_parms[1].info); - plci->dtmf_send_pause_ms = GET_WORD (dtmf_parms[2].info); - } - i = 0; - j = 0; - while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES)) - { - j = 0; - while ((j < DTMF_DIGIT_MAP_ENTRIES) - && ((dtmf_parms[3].info[i+1] != dtmf_digit_map[j].character) - || ((dtmf_digit_map[j].send_mask & mask) == 0))) - { - j++; - } - i++; - } - if (j == DTMF_DIGIT_MAP_ENTRIES) - { - dbug (1, dprintf ("[%06lx] %s,%d: Incorrect DTMF digit %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, dtmf_parms[3].info[i])); - PUT_WORD (&result[1], DTMF_INCORRECT_DIGIT); - break; - } - if (plci->dtmf_send_requests >= - sizeof(plci->dtmf_msg_number_queue) / sizeof(plci->dtmf_msg_number_queue[0])) - { - dbug (1, dprintf ("[%06lx] %s,%d: DTMF request overrun", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_STATE; - break; - } - api_save_msg (dtmf_parms, "wwws", &plci->saved_msg); - start_internal_command (Id, plci, dtmf_command); - return (FALSE); - - default: - dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, plci->dtmf_cmd)); - PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST); - } - } - } - sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, - "wws", Info, SELECTOR_DTMF, result); - return (FALSE); -} - - -static void dtmf_confirmation (dword Id, PLCI *plci) -{ - word Info; - word i; - byte result[4]; - - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation", - UnMapId (Id), (char *)(FILE_), __LINE__)); - - Info = GOOD; - result[0] = 2; - PUT_WORD (&result[1], DTMF_SUCCESS); - if (plci->dtmf_send_requests != 0) - { - sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->dtmf_msg_number_queue[0], - "wws", GOOD, SELECTOR_DTMF, result); - (plci->dtmf_send_requests)--; - for (i = 0; i < plci->dtmf_send_requests; i++) - plci->dtmf_msg_number_queue[i] = plci->dtmf_msg_number_queue[i+1]; + plci->internal_command = DTMF_COMMAND_1; + return; } -} - - -static void dtmf_indication (dword Id, PLCI *plci, byte *msg, word length) -{ - word i, j, n; - - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_indication", - UnMapId (Id), (char *)(FILE_), __LINE__)); - - n = 0; - for (i = 1; i < length; i++) - { - j = 0; - while ((j < DTMF_DIGIT_MAP_ENTRIES) - && ((msg[i] != dtmf_digit_map[j].code) - || ((dtmf_digit_map[j].listen_mask & plci->dtmf_rec_active) == 0))) - { - j++; - } - if (j < DTMF_DIGIT_MAP_ENTRIES) - { - - if ((dtmf_digit_map[j].listen_mask & DTMF_TONE_LISTEN_ACTIVE_FLAG) - && (plci->tone_last_indication_code == DTMF_SIGNAL_NO_TONE) - && (dtmf_digit_map[j].character != DTMF_SIGNAL_UNIDENTIFIED_TONE)) - { - if (n + 1 == i) - { - for (i = length; i > n + 1; i--) - msg[i] = msg[i - 1]; - length++; - i++; - } - msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE; - } - plci->tone_last_indication_code = dtmf_digit_map[j].character; - - msg[++n] = dtmf_digit_map[j].character; - } + plci->dtmf_rec_active &= ~mask; + plci->internal_command = DTMF_COMMAND_2; + dtmf_enable_receiver (plci, false); + return; } - if (n != 0) + Rc = OK; + case DTMF_COMMAND_2: + if ((Rc != OK) && (Rc != OK_FC)) { - msg[0] = (byte) n; - sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg); + dbug (1, dprintf("[%06lx] %s,%d: Disable DTMF receiver failed %02x", + UnMapId (Id), (char far *)(FILE_), __LINE__, Rc)); + Info = _FACILITY_NOT_SUPPORTED; + break; } +*/ + adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities & + ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3); + case DTMF_COMMAND_3: + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Unload DTMF failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + if (plci->internal_command) + return; + break; + } + break; + + + case DTMF_SEND_TONE: + mask <<= 1; + case DTMF_SEND_MF: + mask <<= 1; + + case DTMF_DIGITS_SEND: + switch (internal_command) + { + default: + adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | + ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)), + DTMF_COMMAND_1); + case DTMF_COMMAND_1: + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + if (plci->internal_command) + return; + case DTMF_COMMAND_2: + if (plci_nl_busy(plci)) + { + plci->internal_command = DTMF_COMMAND_2; + return; + } + plci->dtmf_msg_number_queue[(plci->dtmf_send_requests)++] = plci->number; + plci->internal_command = DTMF_COMMAND_3; + dtmf_send_digits(plci, &plci->saved_msg.parms[3].info[1], plci->saved_msg.parms[3].length); + return; + case DTMF_COMMAND_3: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Send DTMF digits failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + if (plci->dtmf_send_requests != 0) + (plci->dtmf_send_requests)--; + Info = _FACILITY_NOT_SUPPORTED; + break; + } + return; + } + break; + } + sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number, + "wws", Info, SELECTOR_DTMF, result); +} + + +static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word Info; + word i, j; + byte mask; + API_PARSE dtmf_parms[5]; + byte result[40]; + + dbug(1, dprintf("[%06lx] %s,%d: dtmf_request", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + Info = GOOD; + result[0] = 2; + PUT_WORD(&result[1], DTMF_SUCCESS); + if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED)) + { + dbug(1, dprintf("[%06lx] %s,%d: Facility not supported", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + } + else if (api_parse(&msg[1].info[1], msg[1].length, "w", dtmf_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + } + + else if ((GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES) + || (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_SEND_CODES)) + { + if (!((a->requested_options_table[appl->Id - 1]) + & (1L << PRIVATE_DTMF_TONE))) + { + dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info))); + PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST); + } + else + { + for (i = 0; i < 32; i++) + result[4 + i] = 0; + if (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES) + { + for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++) + { + if (dtmf_digit_map[i].listen_mask != 0) + result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7)); + } + } + else + { + for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++) + { + if (dtmf_digit_map[i].send_mask != 0) + result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7)); + } + } + result[0] = 3 + 32; + result[3] = 32; + } + } + + else if (plci == NULL) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_IDENTIFIER; + } + else + { + if (!plci->State + || !plci->NL.Id || plci->nl_remove_id) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong state", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_STATE; + } + else + { + plci->command = 0; + plci->dtmf_cmd = GET_WORD(dtmf_parms[0].info); + mask = 0x01; + switch (plci->dtmf_cmd) + { + + case DTMF_LISTEN_TONE_START: + case DTMF_LISTEN_TONE_STOP: + mask <<= 1; + case DTMF_LISTEN_MF_START: + case DTMF_LISTEN_MF_STOP: + mask <<= 1; + if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1]) + & (1L << PRIVATE_DTMF_TONE))) + { + dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info))); + PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST); + break; + } + + case DTMF_LISTEN_START: + case DTMF_LISTEN_STOP: + if (!(a->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF) + && !(a->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) + { + dbug(1, dprintf("[%06lx] %s,%d: Facility not supported", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + if (mask & DTMF_LISTEN_ACTIVE_FLAG) + { + if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms)) + { + plci->dtmf_rec_pulse_ms = 0; + plci->dtmf_rec_pause_ms = 0; + } + else + { + plci->dtmf_rec_pulse_ms = GET_WORD(dtmf_parms[1].info); + plci->dtmf_rec_pause_ms = GET_WORD(dtmf_parms[2].info); + } + } + start_internal_command(Id, plci, dtmf_command); + return (false); + + + case DTMF_SEND_TONE: + mask <<= 1; + case DTMF_SEND_MF: + mask <<= 1; + if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1]) + & (1L << PRIVATE_DTMF_TONE))) + { + dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info))); + PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST); + break; + } + + case DTMF_DIGITS_SEND: + if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + if (mask & DTMF_LISTEN_ACTIVE_FLAG) + { + plci->dtmf_send_pulse_ms = GET_WORD(dtmf_parms[1].info); + plci->dtmf_send_pause_ms = GET_WORD(dtmf_parms[2].info); + } + i = 0; + j = 0; + while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES)) + { + j = 0; + while ((j < DTMF_DIGIT_MAP_ENTRIES) + && ((dtmf_parms[3].info[i + 1] != dtmf_digit_map[j].character) + || ((dtmf_digit_map[j].send_mask & mask) == 0))) + { + j++; + } + i++; + } + if (j == DTMF_DIGIT_MAP_ENTRIES) + { + dbug(1, dprintf("[%06lx] %s,%d: Incorrect DTMF digit %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, dtmf_parms[3].info[i])); + PUT_WORD(&result[1], DTMF_INCORRECT_DIGIT); + break; + } + if (plci->dtmf_send_requests >= ARRAY_SIZE(plci->dtmf_msg_number_queue)) + { + dbug(1, dprintf("[%06lx] %s,%d: DTMF request overrun", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_STATE; + break; + } + api_save_msg(dtmf_parms, "wwws", &plci->saved_msg); + start_internal_command(Id, plci, dtmf_command); + return (false); + + default: + dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, plci->dtmf_cmd)); + PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST); + } + } + } + sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, + "wws", Info, SELECTOR_DTMF, result); + return (false); +} + + +static void dtmf_confirmation(dword Id, PLCI *plci) +{ + word i; + byte result[4]; + + dbug(1, dprintf("[%06lx] %s,%d: dtmf_confirmation", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + result[0] = 2; + PUT_WORD(&result[1], DTMF_SUCCESS); + if (plci->dtmf_send_requests != 0) + { + sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->dtmf_msg_number_queue[0], + "wws", GOOD, SELECTOR_DTMF, result); + (plci->dtmf_send_requests)--; + for (i = 0; i < plci->dtmf_send_requests; i++) + plci->dtmf_msg_number_queue[i] = plci->dtmf_msg_number_queue[i + 1]; + } +} + + +static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length) +{ + word i, j, n; + + dbug(1, dprintf("[%06lx] %s,%d: dtmf_indication", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + n = 0; + for (i = 1; i < length; i++) + { + j = 0; + while ((j < DTMF_DIGIT_MAP_ENTRIES) + && ((msg[i] != dtmf_digit_map[j].code) + || ((dtmf_digit_map[j].listen_mask & plci->dtmf_rec_active) == 0))) + { + j++; + } + if (j < DTMF_DIGIT_MAP_ENTRIES) + { + + if ((dtmf_digit_map[j].listen_mask & DTMF_TONE_LISTEN_ACTIVE_FLAG) + && (plci->tone_last_indication_code == DTMF_SIGNAL_NO_TONE) + && (dtmf_digit_map[j].character != DTMF_SIGNAL_UNIDENTIFIED_TONE)) + { + if (n + 1 == i) + { + for (i = length; i > n + 1; i--) + msg[i] = msg[i - 1]; + length++; + i++; + } + msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE; + } + plci->tone_last_indication_code = dtmf_digit_map[j].character; + + msg[++n] = dtmf_digit_map[j].character; + } + } + if (n != 0) + { + msg[0] = (byte) n; + sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg); + } } @@ -10167,90 +10184,90 @@ static void dtmf_indication (dword Id, PLCI *plci, byte *msg, word length) /* DTMF parameters */ /*------------------------------------------------------------------*/ -static void dtmf_parameter_write (PLCI *plci) +static void dtmf_parameter_write(PLCI *plci) { - word i; - byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2]; + word i; + byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2]; - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_write", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_write", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); - parameter_buffer[0] = plci->dtmf_parameter_length + 1; - parameter_buffer[1] = DSP_CTRL_SET_DTMF_PARAMETERS; - for (i = 0; i < plci->dtmf_parameter_length; i++) - parameter_buffer[2+i] = plci->dtmf_parameter_buffer[i]; - add_p (plci, FTY, parameter_buffer); - sig_req (plci, TEL_CTRL, 0); - send_req (plci); + parameter_buffer[0] = plci->dtmf_parameter_length + 1; + parameter_buffer[1] = DSP_CTRL_SET_DTMF_PARAMETERS; + for (i = 0; i < plci->dtmf_parameter_length; i++) + parameter_buffer[2 + i] = plci->dtmf_parameter_buffer[i]; + add_p(plci, FTY, parameter_buffer); + sig_req(plci, TEL_CTRL, 0); + send_req(plci); } -static void dtmf_parameter_clear_config (PLCI *plci) +static void dtmf_parameter_clear_config(PLCI *plci) { - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_clear_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_clear_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); - plci->dtmf_parameter_length = 0; + plci->dtmf_parameter_length = 0; } -static void dtmf_parameter_prepare_switch (dword Id, PLCI *plci) +static void dtmf_parameter_prepare_switch(dword Id, PLCI *plci) { - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_prepare_switch", - UnMapId (Id), (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_prepare_switch", + UnMapId(Id), (char *)(FILE_), __LINE__)); } -static word dtmf_parameter_save_config (dword Id, PLCI *plci, byte Rc) +static word dtmf_parameter_save_config(dword Id, PLCI *plci, byte Rc) { - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - return (GOOD); + return (GOOD); } -static word dtmf_parameter_restore_config (dword Id, PLCI *plci, byte Rc) +static word dtmf_parameter_restore_config(dword Id, PLCI *plci, byte Rc) { - word Info; + word Info; - dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - Info = GOOD; - if ((plci->B1_facilities & B1_FACILITY_DTMFR) - && (plci->dtmf_parameter_length != 0)) - { - switch (plci->adjust_b_state) - { - case ADJUST_B_RESTORE_DTMF_PARAMETER_1: - plci->internal_command = plci->adjust_b_command; - if (plci->sig_req) - { - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1; - break; - } - dtmf_parameter_write (plci); - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2; - break; - case ADJUST_B_RESTORE_DTMF_PARAMETER_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Restore DTMF parameters failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - break; - } - } - return (Info); + Info = GOOD; + if ((plci->B1_facilities & B1_FACILITY_DTMFR) + && (plci->dtmf_parameter_length != 0)) + { + switch (plci->adjust_b_state) + { + case ADJUST_B_RESTORE_DTMF_PARAMETER_1: + plci->internal_command = plci->adjust_b_command; + if (plci->sig_req) + { + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1; + break; + } + dtmf_parameter_write(plci); + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2; + break; + case ADJUST_B_RESTORE_DTMF_PARAMETER_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Restore DTMF parameters failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + break; + } + } + return (Info); } @@ -10273,2335 +10290,2329 @@ word li_total_channels; /* if channels is provided we accept more than one channel. */ /*------------------------------------------------------------------*/ -static byte chi_to_channel (byte *chi, dword *pchannelmap) -{ - int p; - int i; - dword map; - byte excl; - byte ofs; - byte ch; - - if (pchannelmap) *pchannelmap = 0; - if(!chi[0]) return 0xff; - excl = 0; - - if(chi[1] & 0x20) { - if(chi[0]==1 && chi[1]==0xac) return 0xfd; /* exclusive d-channel */ - for(i=1; i<chi[0] && !(chi[i] &0x80); i++); - if(i==chi[0] || !(chi[i] &0x80)) return 0xfe; - if((chi[1] |0xc8)!=0xe9) return 0xfe; - if(chi[1] &0x08) excl = 0x40; - - /* int. id present */ - if(chi[1] &0x40) { - p=i+1; - for(i=p; i<chi[0] && !(chi[i] &0x80); i++); - if(i==chi[0] || !(chi[i] &0x80)) return 0xfe; - } - - /* coding standard, Number/Map, Channel Type */ - p=i+1; - for(i=p; i<chi[0] && !(chi[i] &0x80); i++); - if(i==chi[0] || !(chi[i] &0x80)) return 0xfe; - if((chi[p]|0xd0)!=0xd3) return 0xfe; - - /* Number/Map */ - if(chi[p] &0x10) { - - /* map */ - if((chi[0]-p)==4) ofs = 0; - else if((chi[0]-p)==3) ofs = 1; - else return 0xfe; - ch = 0; - map = 0; - for(i=0; i<4 && p<chi[0]; i++) { - p++; - ch += 8; - map <<= 8; - if(chi[p]) { - for (ch=0; !(chi[p] & (1 << ch)); ch++); - map |= chi[p]; - } - } - ch += ofs; - map <<= ofs; - } - else { - - /* number */ - p=i+1; - ch = chi[p] &0x3f; - if(pchannelmap) { - if((byte)(chi[0]-p)>30) return 0xfe; - map = 0; - for(i=p; i<=chi[0]; i++) { - if ((chi[i] &0x7f) > 31) return 0xfe; - map |= (1L << (chi[i] &0x7f)); - } - } - else { - if(p!=chi[0]) return 0xfe; - if (ch > 31) return 0xfe; - map = (1L << ch); - } - if(chi[p] &0x40) return 0xfe; - } - if (pchannelmap) *pchannelmap = map; - else if (map != ((dword)(1L << ch))) return 0xfe; - return (byte)(excl | ch); - } - else { /* not PRI */ - for(i=1; i<chi[0] && !(chi[i] &0x80); i++); - if(i!=chi[0] || !(chi[i] &0x80)) return 0xfe; - if(chi[1] &0x08) excl = 0x40; - - switch(chi[1] |0x98) { - case 0x98: return 0; - case 0x99: - if (pchannelmap) *pchannelmap = 2; - return excl |1; - case 0x9a: - if (pchannelmap) *pchannelmap = 4; - return excl |2; - case 0x9b: return 0xff; - case 0x9c: return 0xfd; /* d-ch */ - default: return 0xfe; - } - } -} - - -static void mixer_set_bchannel_id_esc (PLCI *plci, byte bchannel_id) -{ - DIVA_CAPI_ADAPTER *a; - PLCI *splci; - byte old_id; - - a = plci->adapter; - old_id = plci->li_bchannel_id; - if (a->li_pri) - { - if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) - li_config_table[a->li_base + (old_id - 1)].plci = NULL; - plci->li_bchannel_id = (bchannel_id & 0x1f) + 1; - if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) - li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; - } - else - { - if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2)) - { - if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) - li_config_table[a->li_base + (old_id - 1)].plci = NULL; - plci->li_bchannel_id = bchannel_id & 0x03; - if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE)) - { - splci = a->AdvSignalPLCI; - if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL) - { - if ((splci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci)) - { - li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL; - } - splci->li_bchannel_id = 3 - plci->li_bchannel_id; - li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci; - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d", - (dword)((splci->Id << 8) | UnMapController (splci->adapter->Id)), - (char *)(FILE_), __LINE__, splci->li_bchannel_id)); - } - } - if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) - li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; - } - } - if ((old_id == 0) && (plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - mixer_clear_config (plci); - } - dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, bchannel_id, plci->li_bchannel_id)); -} - - -static void mixer_set_bchannel_id (PLCI *plci, byte *chi) -{ - DIVA_CAPI_ADAPTER *a; - PLCI *splci; - byte ch, old_id; - - a = plci->adapter; - old_id = plci->li_bchannel_id; - ch = chi_to_channel (chi, NULL); - if (!(ch & 0x80)) - { - if (a->li_pri) - { - if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) - li_config_table[a->li_base + (old_id - 1)].plci = NULL; - plci->li_bchannel_id = (ch & 0x1f) + 1; - if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) - li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; - } - else - { - if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2)) - { - if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) - li_config_table[a->li_base + (old_id - 1)].plci = NULL; - plci->li_bchannel_id = ch & 0x1f; - if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE)) - { - splci = a->AdvSignalPLCI; - if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL) - { - if ((splci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci)) - { - li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL; - } - splci->li_bchannel_id = 3 - plci->li_bchannel_id; - li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci; - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", - (dword)((splci->Id << 8) | UnMapController (splci->adapter->Id)), - (char *)(FILE_), __LINE__, splci->li_bchannel_id)); - } - } - if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) - li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; - } - } - } - if ((old_id == 0) && (plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - mixer_clear_config (plci); - } - dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, ch, plci->li_bchannel_id)); +static byte chi_to_channel(byte *chi, dword *pchannelmap) +{ + int p; + int i; + dword map; + byte excl; + byte ofs; + byte ch; + + if (pchannelmap) *pchannelmap = 0; + if (!chi[0]) return 0xff; + excl = 0; + + if (chi[1] & 0x20) { + if (chi[0] == 1 && chi[1] == 0xac) return 0xfd; /* exclusive d-channel */ + for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++); + if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe; + if ((chi[1] | 0xc8) != 0xe9) return 0xfe; + if (chi[1] & 0x08) excl = 0x40; + + /* int. id present */ + if (chi[1] & 0x40) { + p = i + 1; + for (i = p; i < chi[0] && !(chi[i] & 0x80); i++); + if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe; + } + + /* coding standard, Number/Map, Channel Type */ + p = i + 1; + for (i = p; i < chi[0] && !(chi[i] & 0x80); i++); + if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe; + if ((chi[p] | 0xd0) != 0xd3) return 0xfe; + + /* Number/Map */ + if (chi[p] & 0x10) { + + /* map */ + if ((chi[0] - p) == 4) ofs = 0; + else if ((chi[0] - p) == 3) ofs = 1; + else return 0xfe; + ch = 0; + map = 0; + for (i = 0; i < 4 && p < chi[0]; i++) { + p++; + ch += 8; + map <<= 8; + if (chi[p]) { + for (ch = 0; !(chi[p] & (1 << ch)); ch++); + map |= chi[p]; + } + } + ch += ofs; + map <<= ofs; + } + else { + + /* number */ + p = i + 1; + ch = chi[p] & 0x3f; + if (pchannelmap) { + if ((byte)(chi[0] - p) > 30) return 0xfe; + map = 0; + for (i = p; i <= chi[0]; i++) { + if ((chi[i] & 0x7f) > 31) return 0xfe; + map |= (1L << (chi[i] & 0x7f)); + } + } + else { + if (p != chi[0]) return 0xfe; + if (ch > 31) return 0xfe; + map = (1L << ch); + } + if (chi[p] & 0x40) return 0xfe; + } + if (pchannelmap) *pchannelmap = map; + else if (map != ((dword)(1L << ch))) return 0xfe; + return (byte)(excl | ch); + } + else { /* not PRI */ + for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++); + if (i != chi[0] || !(chi[i] & 0x80)) return 0xfe; + if (chi[1] & 0x08) excl = 0x40; + + switch (chi[1] | 0x98) { + case 0x98: return 0; + case 0x99: + if (pchannelmap) *pchannelmap = 2; + return excl | 1; + case 0x9a: + if (pchannelmap) *pchannelmap = 4; + return excl | 2; + case 0x9b: return 0xff; + case 0x9c: return 0xfd; /* d-ch */ + default: return 0xfe; + } + } +} + + +static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id) +{ + DIVA_CAPI_ADAPTER *a; + PLCI *splci; + byte old_id; + + a = plci->adapter; + old_id = plci->li_bchannel_id; + if (a->li_pri) + { + if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) + li_config_table[a->li_base + (old_id - 1)].plci = NULL; + plci->li_bchannel_id = (bchannel_id & 0x1f) + 1; + if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) + li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; + } + else + { + if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2)) + { + if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) + li_config_table[a->li_base + (old_id - 1)].plci = NULL; + plci->li_bchannel_id = bchannel_id & 0x03; + if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE)) + { + splci = a->AdvSignalPLCI; + if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL) + { + if ((splci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci)) + { + li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL; + } + splci->li_bchannel_id = 3 - plci->li_bchannel_id; + li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci; + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d", + (dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)), + (char *)(FILE_), __LINE__, splci->li_bchannel_id)); + } + } + if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) + li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; + } + } + if ((old_id == 0) && (plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + mixer_clear_config(plci); + } + dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, bchannel_id, plci->li_bchannel_id)); +} + + +static void mixer_set_bchannel_id(PLCI *plci, byte *chi) +{ + DIVA_CAPI_ADAPTER *a; + PLCI *splci; + byte ch, old_id; + + a = plci->adapter; + old_id = plci->li_bchannel_id; + ch = chi_to_channel(chi, NULL); + if (!(ch & 0x80)) + { + if (a->li_pri) + { + if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) + li_config_table[a->li_base + (old_id - 1)].plci = NULL; + plci->li_bchannel_id = (ch & 0x1f) + 1; + if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) + li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; + } + else + { + if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2)) + { + if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci)) + li_config_table[a->li_base + (old_id - 1)].plci = NULL; + plci->li_bchannel_id = ch & 0x1f; + if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE)) + { + splci = a->AdvSignalPLCI; + if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL) + { + if ((splci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci)) + { + li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL; + } + splci->li_bchannel_id = 3 - plci->li_bchannel_id; + li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci; + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", + (dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)), + (char *)(FILE_), __LINE__, splci->li_bchannel_id)); + } + } + if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL) + li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci; + } + } + } + if ((old_id == 0) && (plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + mixer_clear_config(plci); + } + dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, ch, plci->li_bchannel_id)); } #define MIXER_MAX_DUMP_CHANNELS 34 -static void mixer_calculate_coefs (DIVA_CAPI_ADAPTER *a) -{ -static char hex_digit_table[0x10] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; - word n, i, j; - char *p; - char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4]; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_calculate_coefs", - (dword)(UnMapController (a->Id)), (char *)(FILE_), __LINE__)); - - for (i = 0; i < li_total_channels; i++) - { - li_config_table[i].channel &= LI_CHANNEL_ADDRESSES_SET; - if (li_config_table[i].chflags != 0) - li_config_table[i].channel |= LI_CHANNEL_INVOLVED; - else - { - for (j = 0; j < li_total_channels; j++) - { - if (((li_config_table[i].flag_table[j]) != 0) - || ((li_config_table[j].flag_table[i]) != 0)) - { - li_config_table[i].channel |= LI_CHANNEL_INVOLVED; - } - if (((li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) != 0) - || ((li_config_table[j].flag_table[i] & LI_FLAG_CONFERENCE) != 0)) - { - li_config_table[i].channel |= LI_CHANNEL_CONFERENCE; - } - } - } - } - for (i = 0; i < li_total_channels; i++) - { - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC); - if (li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) - li_config_table[i].coef_table[j] |= LI_COEF_CH_CH; - } - } - for (n = 0; n < li_total_channels; n++) - { - if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE) - { - for (i = 0; i < li_total_channels; i++) - { - if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE) - { - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].coef_table[j] |= - li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j]; - } - } - } - } - } - for (i = 0; i < li_total_channels; i++) - { - if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) - { - li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH; - for (j = 0; j < li_total_channels; j++) - { - if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH) - li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE; - } - if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE) - li_config_table[i].coef_table[i] |= LI_COEF_CH_CH; - } - } - for (i = 0; i < li_total_channels; i++) - { - if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) - { - for (j = 0; j < li_total_channels; j++) - { - if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) - li_config_table[i].coef_table[j] |= LI_COEF_CH_CH; - if (li_config_table[i].flag_table[j] & LI_FLAG_MONITOR) - li_config_table[i].coef_table[j] |= LI_COEF_CH_PC; - if (li_config_table[i].flag_table[j] & LI_FLAG_MIX) - li_config_table[i].coef_table[j] |= LI_COEF_PC_CH; - if (li_config_table[i].flag_table[j] & LI_FLAG_PCCONNECT) - li_config_table[i].coef_table[j] |= LI_COEF_PC_PC; - } - if (li_config_table[i].chflags & LI_CHFLAG_MONITOR) - { - for (j = 0; j < li_total_channels; j++) - { - if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) - { - li_config_table[i].coef_table[j] |= LI_COEF_CH_PC; - if (li_config_table[j].chflags & LI_CHFLAG_MIX) - li_config_table[i].coef_table[j] |= LI_COEF_PC_CH | LI_COEF_PC_PC; - } - } - } - if (li_config_table[i].chflags & LI_CHFLAG_MIX) - { - for (j = 0; j < li_total_channels; j++) - { - if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT) - li_config_table[j].coef_table[i] |= LI_COEF_PC_CH; - } - } - if (li_config_table[i].chflags & LI_CHFLAG_LOOP) - { - for (j = 0; j < li_total_channels; j++) - { - if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) - { - for (n = 0; n < li_total_channels; n++) - { - if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT) - { - li_config_table[n].coef_table[j] |= LI_COEF_CH_CH; - if (li_config_table[j].chflags & LI_CHFLAG_MIX) - { - li_config_table[n].coef_table[j] |= LI_COEF_PC_CH; - if (li_config_table[n].chflags & LI_CHFLAG_MONITOR) - li_config_table[n].coef_table[j] |= LI_COEF_CH_PC | LI_COEF_PC_PC; - } - else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR) - li_config_table[n].coef_table[j] |= LI_COEF_CH_PC; - } - } - } - } - } - } - } - for (i = 0; i < li_total_channels; i++) - { - if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) - { - if (li_config_table[i].chflags & (LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP)) - li_config_table[i].channel |= LI_CHANNEL_ACTIVE; - if (li_config_table[i].chflags & LI_CHFLAG_MONITOR) - li_config_table[i].channel |= LI_CHANNEL_RX_DATA; - if (li_config_table[i].chflags & LI_CHFLAG_MIX) - li_config_table[i].channel |= LI_CHANNEL_TX_DATA; - for (j = 0; j < li_total_channels; j++) - { - if ((li_config_table[i].flag_table[j] & - (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_MONITOR)) - || (li_config_table[j].flag_table[i] & - (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX))) - { - li_config_table[i].channel |= LI_CHANNEL_ACTIVE; - } - if (li_config_table[i].flag_table[j] & (LI_FLAG_PCCONNECT | LI_FLAG_MONITOR)) - li_config_table[i].channel |= LI_CHANNEL_RX_DATA; - if (li_config_table[j].flag_table[i] & (LI_FLAG_PCCONNECT | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX)) - li_config_table[i].channel |= LI_CHANNEL_TX_DATA; - } - if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE)) - { - li_config_table[i].coef_table[i] |= LI_COEF_PC_CH | LI_COEF_CH_PC; - li_config_table[i].channel |= LI_CHANNEL_TX_DATA | LI_CHANNEL_RX_DATA; - } - } - } - for (i = 0; i < li_total_channels; i++) - { - if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) - { - j = 0; - while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT)) - j++; - if (j < li_total_channels) - { - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_PC_CH); - if (li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT) - li_config_table[i].coef_table[j] |= LI_COEF_PC_CH; - } - } - } - } - n = li_total_channels; - if (n > MIXER_MAX_DUMP_CHANNELS) - n = MIXER_MAX_DUMP_CHANNELS; - p = hex_line; - for (j = 0; j < n; j++) - { - if ((j & 0x7) == 0) - *(p++) = ' '; - *(p++) = hex_digit_table[li_config_table[j].curchnl >> 4]; - *(p++) = hex_digit_table[li_config_table[j].curchnl & 0xf]; - } - *p = '\0'; - dbug (1, dprintf ("[%06lx] CURRENT %s", - (dword)(UnMapController (a->Id)), (char *) hex_line)); - p = hex_line; - for (j = 0; j < n; j++) - { - if ((j & 0x7) == 0) - *(p++) = ' '; - *(p++) = hex_digit_table[li_config_table[j].channel >> 4]; - *(p++) = hex_digit_table[li_config_table[j].channel & 0xf]; - } - *p = '\0'; - dbug (1, dprintf ("[%06lx] CHANNEL %s", - (dword)(UnMapController (a->Id)), (char *) hex_line)); - p = hex_line; - for (j = 0; j < n; j++) - { - if ((j & 0x7) == 0) - *(p++) = ' '; - *(p++) = hex_digit_table[li_config_table[j].chflags >> 4]; - *(p++) = hex_digit_table[li_config_table[j].chflags & 0xf]; - } - *p = '\0'; - dbug (1, dprintf ("[%06lx] CHFLAG %s", - (dword)(UnMapController (a->Id)), (char *) hex_line)); - for (i = 0; i < n; i++) - { - p = hex_line; - for (j = 0; j < n; j++) - { - if ((j & 0x7) == 0) - *(p++) = ' '; - *(p++) = hex_digit_table[li_config_table[i].flag_table[j] >> 4]; - *(p++) = hex_digit_table[li_config_table[i].flag_table[j] & 0xf]; - } - *p = '\0'; - dbug (1, dprintf ("[%06lx] FLAG[%02x]%s", - (dword)(UnMapController (a->Id)), i, (char *) hex_line)); - } - for (i = 0; i < n; i++) - { - p = hex_line; - for (j = 0; j < n; j++) - { - if ((j & 0x7) == 0) - *(p++) = ' '; - *(p++) = hex_digit_table[li_config_table[i].coef_table[j] >> 4]; - *(p++) = hex_digit_table[li_config_table[i].coef_table[j] & 0xf]; - } - *p = '\0'; - dbug (1, dprintf ("[%06lx] COEF[%02x]%s", - (dword)(UnMapController (a->Id)), i, (char *) hex_line)); - } +static void mixer_calculate_coefs(DIVA_CAPI_ADAPTER *a) +{ + static char hex_digit_table[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + word n, i, j; + char *p; + char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4]; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_calculate_coefs", + (dword)(UnMapController(a->Id)), (char *)(FILE_), __LINE__)); + + for (i = 0; i < li_total_channels; i++) + { + li_config_table[i].channel &= LI_CHANNEL_ADDRESSES_SET; + if (li_config_table[i].chflags != 0) + li_config_table[i].channel |= LI_CHANNEL_INVOLVED; + else + { + for (j = 0; j < li_total_channels; j++) + { + if (((li_config_table[i].flag_table[j]) != 0) + || ((li_config_table[j].flag_table[i]) != 0)) + { + li_config_table[i].channel |= LI_CHANNEL_INVOLVED; + } + if (((li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) != 0) + || ((li_config_table[j].flag_table[i] & LI_FLAG_CONFERENCE) != 0)) + { + li_config_table[i].channel |= LI_CHANNEL_CONFERENCE; + } + } + } + } + for (i = 0; i < li_total_channels; i++) + { + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC); + if (li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) + li_config_table[i].coef_table[j] |= LI_COEF_CH_CH; + } + } + for (n = 0; n < li_total_channels; n++) + { + if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE) + { + for (i = 0; i < li_total_channels; i++) + { + if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE) + { + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].coef_table[j] |= + li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j]; + } + } + } + } + } + for (i = 0; i < li_total_channels; i++) + { + if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) + { + li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH; + for (j = 0; j < li_total_channels; j++) + { + if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH) + li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE; + } + if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE) + li_config_table[i].coef_table[i] |= LI_COEF_CH_CH; + } + } + for (i = 0; i < li_total_channels; i++) + { + if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) + { + for (j = 0; j < li_total_channels; j++) + { + if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) + li_config_table[i].coef_table[j] |= LI_COEF_CH_CH; + if (li_config_table[i].flag_table[j] & LI_FLAG_MONITOR) + li_config_table[i].coef_table[j] |= LI_COEF_CH_PC; + if (li_config_table[i].flag_table[j] & LI_FLAG_MIX) + li_config_table[i].coef_table[j] |= LI_COEF_PC_CH; + if (li_config_table[i].flag_table[j] & LI_FLAG_PCCONNECT) + li_config_table[i].coef_table[j] |= LI_COEF_PC_PC; + } + if (li_config_table[i].chflags & LI_CHFLAG_MONITOR) + { + for (j = 0; j < li_total_channels; j++) + { + if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) + { + li_config_table[i].coef_table[j] |= LI_COEF_CH_PC; + if (li_config_table[j].chflags & LI_CHFLAG_MIX) + li_config_table[i].coef_table[j] |= LI_COEF_PC_CH | LI_COEF_PC_PC; + } + } + } + if (li_config_table[i].chflags & LI_CHFLAG_MIX) + { + for (j = 0; j < li_total_channels; j++) + { + if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT) + li_config_table[j].coef_table[i] |= LI_COEF_PC_CH; + } + } + if (li_config_table[i].chflags & LI_CHFLAG_LOOP) + { + for (j = 0; j < li_total_channels; j++) + { + if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) + { + for (n = 0; n < li_total_channels; n++) + { + if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT) + { + li_config_table[n].coef_table[j] |= LI_COEF_CH_CH; + if (li_config_table[j].chflags & LI_CHFLAG_MIX) + { + li_config_table[n].coef_table[j] |= LI_COEF_PC_CH; + if (li_config_table[n].chflags & LI_CHFLAG_MONITOR) + li_config_table[n].coef_table[j] |= LI_COEF_CH_PC | LI_COEF_PC_PC; + } + else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR) + li_config_table[n].coef_table[j] |= LI_COEF_CH_PC; + } + } + } + } + } + } + } + for (i = 0; i < li_total_channels; i++) + { + if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) + { + if (li_config_table[i].chflags & (LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP)) + li_config_table[i].channel |= LI_CHANNEL_ACTIVE; + if (li_config_table[i].chflags & LI_CHFLAG_MONITOR) + li_config_table[i].channel |= LI_CHANNEL_RX_DATA; + if (li_config_table[i].chflags & LI_CHFLAG_MIX) + li_config_table[i].channel |= LI_CHANNEL_TX_DATA; + for (j = 0; j < li_total_channels; j++) + { + if ((li_config_table[i].flag_table[j] & + (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_MONITOR)) + || (li_config_table[j].flag_table[i] & + (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX))) + { + li_config_table[i].channel |= LI_CHANNEL_ACTIVE; + } + if (li_config_table[i].flag_table[j] & (LI_FLAG_PCCONNECT | LI_FLAG_MONITOR)) + li_config_table[i].channel |= LI_CHANNEL_RX_DATA; + if (li_config_table[j].flag_table[i] & (LI_FLAG_PCCONNECT | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX)) + li_config_table[i].channel |= LI_CHANNEL_TX_DATA; + } + if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE)) + { + li_config_table[i].coef_table[i] |= LI_COEF_PC_CH | LI_COEF_CH_PC; + li_config_table[i].channel |= LI_CHANNEL_TX_DATA | LI_CHANNEL_RX_DATA; + } + } + } + for (i = 0; i < li_total_channels; i++) + { + if (li_config_table[i].channel & LI_CHANNEL_INVOLVED) + { + j = 0; + while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT)) + j++; + if (j < li_total_channels) + { + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_PC_CH); + if (li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT) + li_config_table[i].coef_table[j] |= LI_COEF_PC_CH; + } + } + } + } + n = li_total_channels; + if (n > MIXER_MAX_DUMP_CHANNELS) + n = MIXER_MAX_DUMP_CHANNELS; + p = hex_line; + for (j = 0; j < n; j++) + { + if ((j & 0x7) == 0) + *(p++) = ' '; + *(p++) = hex_digit_table[li_config_table[j].curchnl >> 4]; + *(p++) = hex_digit_table[li_config_table[j].curchnl & 0xf]; + } + *p = '\0'; + dbug(1, dprintf("[%06lx] CURRENT %s", + (dword)(UnMapController(a->Id)), (char *)hex_line)); + p = hex_line; + for (j = 0; j < n; j++) + { + if ((j & 0x7) == 0) + *(p++) = ' '; + *(p++) = hex_digit_table[li_config_table[j].channel >> 4]; + *(p++) = hex_digit_table[li_config_table[j].channel & 0xf]; + } + *p = '\0'; + dbug(1, dprintf("[%06lx] CHANNEL %s", + (dword)(UnMapController(a->Id)), (char *)hex_line)); + p = hex_line; + for (j = 0; j < n; j++) + { + if ((j & 0x7) == 0) + *(p++) = ' '; + *(p++) = hex_digit_table[li_config_table[j].chflags >> 4]; + *(p++) = hex_digit_table[li_config_table[j].chflags & 0xf]; + } + *p = '\0'; + dbug(1, dprintf("[%06lx] CHFLAG %s", + (dword)(UnMapController(a->Id)), (char *)hex_line)); + for (i = 0; i < n; i++) + { + p = hex_line; + for (j = 0; j < n; j++) + { + if ((j & 0x7) == 0) + *(p++) = ' '; + *(p++) = hex_digit_table[li_config_table[i].flag_table[j] >> 4]; + *(p++) = hex_digit_table[li_config_table[i].flag_table[j] & 0xf]; + } + *p = '\0'; + dbug(1, dprintf("[%06lx] FLAG[%02x]%s", + (dword)(UnMapController(a->Id)), i, (char *)hex_line)); + } + for (i = 0; i < n; i++) + { + p = hex_line; + for (j = 0; j < n; j++) + { + if ((j & 0x7) == 0) + *(p++) = ' '; + *(p++) = hex_digit_table[li_config_table[i].coef_table[j] >> 4]; + *(p++) = hex_digit_table[li_config_table[i].coef_table[j] & 0xf]; + } + *p = '\0'; + dbug(1, dprintf("[%06lx] COEF[%02x]%s", + (dword)(UnMapController(a->Id)), i, (char *)hex_line)); + } } static struct { - byte mask; - byte line_flags; + byte mask; + byte line_flags; } mixer_write_prog_pri[] = { - { LI_COEF_CH_CH, 0 }, - { LI_COEF_CH_PC, MIXER_COEF_LINE_TO_PC_FLAG }, - { LI_COEF_PC_CH, MIXER_COEF_LINE_FROM_PC_FLAG }, - { LI_COEF_PC_PC, MIXER_COEF_LINE_TO_PC_FLAG | MIXER_COEF_LINE_FROM_PC_FLAG } + { LI_COEF_CH_CH, 0 }, + { LI_COEF_CH_PC, MIXER_COEF_LINE_TO_PC_FLAG }, + { LI_COEF_PC_CH, MIXER_COEF_LINE_FROM_PC_FLAG }, + { LI_COEF_PC_PC, MIXER_COEF_LINE_TO_PC_FLAG | MIXER_COEF_LINE_FROM_PC_FLAG } }; static struct { - byte from_ch; - byte to_ch; - byte mask; - byte xconnect_override; + byte from_ch; + byte to_ch; + byte mask; + byte xconnect_override; } mixer_write_prog_bri[] = { - { 0, 0, LI_COEF_CH_CH, 0x01 }, /* B to B */ - { 1, 0, LI_COEF_CH_CH, 0x01 }, /* Alt B to B */ - { 0, 0, LI_COEF_PC_CH, 0x80 }, /* PC to B */ - { 1, 0, LI_COEF_PC_CH, 0x01 }, /* Alt PC to B */ - { 2, 0, LI_COEF_CH_CH, 0x00 }, /* IC to B */ - { 3, 0, LI_COEF_CH_CH, 0x00 }, /* Alt IC to B */ - { 0, 0, LI_COEF_CH_PC, 0x80 }, /* B to PC */ - { 1, 0, LI_COEF_CH_PC, 0x01 }, /* Alt B to PC */ - { 0, 0, LI_COEF_PC_PC, 0x01 }, /* PC to PC */ - { 1, 0, LI_COEF_PC_PC, 0x01 }, /* Alt PC to PC */ - { 2, 0, LI_COEF_CH_PC, 0x00 }, /* IC to PC */ - { 3, 0, LI_COEF_CH_PC, 0x00 }, /* Alt IC to PC */ - { 0, 2, LI_COEF_CH_CH, 0x00 }, /* B to IC */ - { 1, 2, LI_COEF_CH_CH, 0x00 }, /* Alt B to IC */ - { 0, 2, LI_COEF_PC_CH, 0x00 }, /* PC to IC */ - { 1, 2, LI_COEF_PC_CH, 0x00 }, /* Alt PC to IC */ - { 2, 2, LI_COEF_CH_CH, 0x00 }, /* IC to IC */ - { 3, 2, LI_COEF_CH_CH, 0x00 }, /* Alt IC to IC */ - { 1, 1, LI_COEF_CH_CH, 0x01 }, /* Alt B to Alt B */ - { 0, 1, LI_COEF_CH_CH, 0x01 }, /* B to Alt B */ - { 1, 1, LI_COEF_PC_CH, 0x80 }, /* Alt PC to Alt B */ - { 0, 1, LI_COEF_PC_CH, 0x01 }, /* PC to Alt B */ - { 3, 1, LI_COEF_CH_CH, 0x00 }, /* Alt IC to Alt B */ - { 2, 1, LI_COEF_CH_CH, 0x00 }, /* IC to Alt B */ - { 1, 1, LI_COEF_CH_PC, 0x80 }, /* Alt B to Alt PC */ - { 0, 1, LI_COEF_CH_PC, 0x01 }, /* B to Alt PC */ - { 1, 1, LI_COEF_PC_PC, 0x01 }, /* Alt PC to Alt PC */ - { 0, 1, LI_COEF_PC_PC, 0x01 }, /* PC to Alt PC */ - { 3, 1, LI_COEF_CH_PC, 0x00 }, /* Alt IC to Alt PC */ - { 2, 1, LI_COEF_CH_PC, 0x00 }, /* IC to Alt PC */ - { 1, 3, LI_COEF_CH_CH, 0x00 }, /* Alt B to Alt IC */ - { 0, 3, LI_COEF_CH_CH, 0x00 }, /* B to Alt IC */ - { 1, 3, LI_COEF_PC_CH, 0x00 }, /* Alt PC to Alt IC */ - { 0, 3, LI_COEF_PC_CH, 0x00 }, /* PC to Alt IC */ - { 3, 3, LI_COEF_CH_CH, 0x00 }, /* Alt IC to Alt IC */ - { 2, 3, LI_COEF_CH_CH, 0x00 } /* IC to Alt IC */ + { 0, 0, LI_COEF_CH_CH, 0x01 }, /* B to B */ + { 1, 0, LI_COEF_CH_CH, 0x01 }, /* Alt B to B */ + { 0, 0, LI_COEF_PC_CH, 0x80 }, /* PC to B */ + { 1, 0, LI_COEF_PC_CH, 0x01 }, /* Alt PC to B */ + { 2, 0, LI_COEF_CH_CH, 0x00 }, /* IC to B */ + { 3, 0, LI_COEF_CH_CH, 0x00 }, /* Alt IC to B */ + { 0, 0, LI_COEF_CH_PC, 0x80 }, /* B to PC */ + { 1, 0, LI_COEF_CH_PC, 0x01 }, /* Alt B to PC */ + { 0, 0, LI_COEF_PC_PC, 0x01 }, /* PC to PC */ + { 1, 0, LI_COEF_PC_PC, 0x01 }, /* Alt PC to PC */ + { 2, 0, LI_COEF_CH_PC, 0x00 }, /* IC to PC */ + { 3, 0, LI_COEF_CH_PC, 0x00 }, /* Alt IC to PC */ + { 0, 2, LI_COEF_CH_CH, 0x00 }, /* B to IC */ + { 1, 2, LI_COEF_CH_CH, 0x00 }, /* Alt B to IC */ + { 0, 2, LI_COEF_PC_CH, 0x00 }, /* PC to IC */ + { 1, 2, LI_COEF_PC_CH, 0x00 }, /* Alt PC to IC */ + { 2, 2, LI_COEF_CH_CH, 0x00 }, /* IC to IC */ + { 3, 2, LI_COEF_CH_CH, 0x00 }, /* Alt IC to IC */ + { 1, 1, LI_COEF_CH_CH, 0x01 }, /* Alt B to Alt B */ + { 0, 1, LI_COEF_CH_CH, 0x01 }, /* B to Alt B */ + { 1, 1, LI_COEF_PC_CH, 0x80 }, /* Alt PC to Alt B */ + { 0, 1, LI_COEF_PC_CH, 0x01 }, /* PC to Alt B */ + { 3, 1, LI_COEF_CH_CH, 0x00 }, /* Alt IC to Alt B */ + { 2, 1, LI_COEF_CH_CH, 0x00 }, /* IC to Alt B */ + { 1, 1, LI_COEF_CH_PC, 0x80 }, /* Alt B to Alt PC */ + { 0, 1, LI_COEF_CH_PC, 0x01 }, /* B to Alt PC */ + { 1, 1, LI_COEF_PC_PC, 0x01 }, /* Alt PC to Alt PC */ + { 0, 1, LI_COEF_PC_PC, 0x01 }, /* PC to Alt PC */ + { 3, 1, LI_COEF_CH_PC, 0x00 }, /* Alt IC to Alt PC */ + { 2, 1, LI_COEF_CH_PC, 0x00 }, /* IC to Alt PC */ + { 1, 3, LI_COEF_CH_CH, 0x00 }, /* Alt B to Alt IC */ + { 0, 3, LI_COEF_CH_CH, 0x00 }, /* B to Alt IC */ + { 1, 3, LI_COEF_PC_CH, 0x00 }, /* Alt PC to Alt IC */ + { 0, 3, LI_COEF_PC_CH, 0x00 }, /* PC to Alt IC */ + { 3, 3, LI_COEF_CH_CH, 0x00 }, /* Alt IC to Alt IC */ + { 2, 3, LI_COEF_CH_CH, 0x00 } /* IC to Alt IC */ }; static byte mixer_swapped_index_bri[] = { - 18, /* B to B */ - 19, /* Alt B to B */ - 20, /* PC to B */ - 21, /* Alt PC to B */ - 22, /* IC to B */ - 23, /* Alt IC to B */ - 24, /* B to PC */ - 25, /* Alt B to PC */ - 26, /* PC to PC */ - 27, /* Alt PC to PC */ - 28, /* IC to PC */ - 29, /* Alt IC to PC */ - 30, /* B to IC */ - 31, /* Alt B to IC */ - 32, /* PC to IC */ - 33, /* Alt PC to IC */ - 34, /* IC to IC */ - 35, /* Alt IC to IC */ - 0, /* Alt B to Alt B */ - 1, /* B to Alt B */ - 2, /* Alt PC to Alt B */ - 3, /* PC to Alt B */ - 4, /* Alt IC to Alt B */ - 5, /* IC to Alt B */ - 6, /* Alt B to Alt PC */ - 7, /* B to Alt PC */ - 8, /* Alt PC to Alt PC */ - 9, /* PC to Alt PC */ - 10, /* Alt IC to Alt PC */ - 11, /* IC to Alt PC */ - 12, /* Alt B to Alt IC */ - 13, /* B to Alt IC */ - 14, /* Alt PC to Alt IC */ - 15, /* PC to Alt IC */ - 16, /* Alt IC to Alt IC */ - 17 /* IC to Alt IC */ + 18, /* B to B */ + 19, /* Alt B to B */ + 20, /* PC to B */ + 21, /* Alt PC to B */ + 22, /* IC to B */ + 23, /* Alt IC to B */ + 24, /* B to PC */ + 25, /* Alt B to PC */ + 26, /* PC to PC */ + 27, /* Alt PC to PC */ + 28, /* IC to PC */ + 29, /* Alt IC to PC */ + 30, /* B to IC */ + 31, /* Alt B to IC */ + 32, /* PC to IC */ + 33, /* Alt PC to IC */ + 34, /* IC to IC */ + 35, /* Alt IC to IC */ + 0, /* Alt B to Alt B */ + 1, /* B to Alt B */ + 2, /* Alt PC to Alt B */ + 3, /* PC to Alt B */ + 4, /* Alt IC to Alt B */ + 5, /* IC to Alt B */ + 6, /* Alt B to Alt PC */ + 7, /* B to Alt PC */ + 8, /* Alt PC to Alt PC */ + 9, /* PC to Alt PC */ + 10, /* Alt IC to Alt PC */ + 11, /* IC to Alt PC */ + 12, /* Alt B to Alt IC */ + 13, /* B to Alt IC */ + 14, /* Alt PC to Alt IC */ + 15, /* PC to Alt IC */ + 16, /* Alt IC to Alt IC */ + 17 /* IC to Alt IC */ }; static struct { - byte mask; - byte from_pc; - byte to_pc; + byte mask; + byte from_pc; + byte to_pc; } xconnect_write_prog[] = { - { LI_COEF_CH_CH, FALSE, FALSE }, - { LI_COEF_CH_PC, FALSE, TRUE }, - { LI_COEF_PC_CH, TRUE, FALSE }, - { LI_COEF_PC_PC, TRUE, TRUE } + { LI_COEF_CH_CH, false, false }, + { LI_COEF_CH_PC, false, true }, + { LI_COEF_PC_CH, true, false }, + { LI_COEF_PC_PC, true, true } }; -static void xconnect_query_addresses (PLCI *plci) -{ - DIVA_CAPI_ADAPTER *a; - word w, ch; - byte *p; - - dbug (1, dprintf ("[%06lx] %s,%d: xconnect_query_addresses", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - a = plci->adapter; - if (a->li_pri && ((plci->li_bchannel_id == 0) - || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))) - { - dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - return; - } - p = plci->internal_req_buffer; - ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0; - *(p++) = UDATA_REQUEST_XCONNECT_FROM; - w = ch; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - w = ch | XCONNECT_CHANNEL_PORT_PC; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - plci->NData[0].P = plci->internal_req_buffer; - plci->NData[0].PLength = p - plci->internal_req_buffer; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_UDATA; - plci->adapter->request (&plci->NL); -} - - -static void xconnect_write_coefs (PLCI *plci, word internal_command) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: xconnect_write_coefs %04x", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, internal_command)); - - plci->li_write_command = internal_command; - plci->li_write_channel = 0; -} - - -static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc) -{ - DIVA_CAPI_ADAPTER *a; - word w, n, i, j, r, s, to_ch; - dword d; - byte *p; - struct xconnect_transfer_address_s *transfer_address; - byte ch_map[MIXER_CHANNELS_BRI]; - - dbug (1, dprintf ("[%06x] %s,%d: xconnect_write_coefs_process %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->li_write_channel)); - - a = plci->adapter; - if ((plci->li_bchannel_id == 0) - || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)) - { - dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out", - UnMapId (Id), (char *)(FILE_), __LINE__)); - return (TRUE); - } - i = a->li_base + (plci->li_bchannel_id - 1); - j = plci->li_write_channel; - p = plci->internal_req_buffer; - if (j != 0) - { - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI write coefs failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - return (FALSE); - } - } - if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - { - r = 0; - s = 0; - if (j < li_total_channels) - { - if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET) - { - s = ((li_config_table[i].send_b.card_address.low | li_config_table[i].send_b.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_PC | LI_COEF_PC_PC)) & - ((li_config_table[i].send_pc.card_address.low | li_config_table[i].send_pc.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_PC_CH)); - } - r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); - while ((j < li_total_channels) - && ((r == 0) - || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET)) - || (!li_config_table[j].adapter->li_pri - && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI)) - || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low) - || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high)) - && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT) - || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT))) - || ((li_config_table[j].adapter->li_base != a->li_base) - && !(r & s & - ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & - ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)))))) - { - j++; - if (j < li_total_channels) - r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); - } - } - if (j < li_total_channels) - { - plci->internal_command = plci->li_write_command; - if (plci_nl_busy (plci)) - return (TRUE); - to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0; - *(p++) = UDATA_REQUEST_XCONNECT_TO; - do - { - if (li_config_table[j].adapter->li_base != a->li_base) - { - r &= s & - ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & - ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)); - } - n = 0; - do - { - if (r & xconnect_write_prog[n].mask) - { - if (xconnect_write_prog[n].from_pc) - transfer_address = &(li_config_table[j].send_pc); - else - transfer_address = &(li_config_table[j].send_b); - d = transfer_address->card_address.low; - *(p++) = (byte) d; - *(p++) = (byte)(d >> 8); - *(p++) = (byte)(d >> 16); - *(p++) = (byte)(d >> 24); - d = transfer_address->card_address.high; - *(p++) = (byte) d; - *(p++) = (byte)(d >> 8); - *(p++) = (byte)(d >> 16); - *(p++) = (byte)(d >> 24); - d = transfer_address->offset; - *(p++) = (byte) d; - *(p++) = (byte)(d >> 8); - *(p++) = (byte)(d >> 16); - *(p++) = (byte)(d >> 24); - w = xconnect_write_prog[n].to_pc ? to_ch | XCONNECT_CHANNEL_PORT_PC : to_ch; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - w = ((li_config_table[i].coef_table[j] & xconnect_write_prog[n].mask) == 0) ? 0x01 : - (li_config_table[i].adapter->u_law ? - (li_config_table[j].adapter->u_law ? 0x80 : 0x86) : - (li_config_table[j].adapter->u_law ? 0x7a : 0x80)); - *(p++) = (byte) w; - *(p++) = (byte) 0; - li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4; - } - n++; - } while ((n < sizeof(xconnect_write_prog) / sizeof(xconnect_write_prog[0])) - && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE)); - if (n == sizeof(xconnect_write_prog) / sizeof(xconnect_write_prog[0])) - { - do - { - j++; - if (j < li_total_channels) - r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); - } while ((j < li_total_channels) - && ((r == 0) - || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET)) - || (!li_config_table[j].adapter->li_pri - && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI)) - || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low) - || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high)) - && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT) - || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT))) - || ((li_config_table[j].adapter->li_base != a->li_base) - && !(r & s & - ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & - ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? - (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)))))); - } - } while ((j < li_total_channels) - && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE)); - } - else if (j == li_total_channels) - { - plci->internal_command = plci->li_write_command; - if (plci_nl_busy (plci)) - return (TRUE); - if (a->li_pri) - { - *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC; - w = 0; - if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) - w |= MIXER_FEATURE_ENABLE_TX_DATA; - if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) - w |= MIXER_FEATURE_ENABLE_RX_DATA; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - } - else - { - *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI; - w = 0; - if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI) - && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)) - { - w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); - } - if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) - w |= MIXER_FEATURE_ENABLE_TX_DATA; - if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) - w |= MIXER_FEATURE_ENABLE_RX_DATA; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - for (j = 0; j < sizeof(ch_map); j += 2) - { - if (plci->li_bchannel_id == 2) - { - ch_map[j] = (byte)(j+1); - ch_map[j+1] = (byte) j; - } - else - { - ch_map[j] = (byte) j; - ch_map[j+1] = (byte)(j+1); - } - } - for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++) - { - i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; - j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; - if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) - { - *p = (mixer_write_prog_bri[n].xconnect_override != 0) ? - mixer_write_prog_bri[n].xconnect_override : - ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); - if ((i >= a->li_base + MIXER_BCHANNELS_BRI) || (j >= a->li_base + MIXER_BCHANNELS_BRI)) - { - w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); - li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; - } - } - else - { - *p = 0x00; - if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE)) - { - w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n]; - if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length) - *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w]; - } - } - p++; - } - } - j = li_total_channels + 1; - } - } - else - { - if (j <= li_total_channels) - { - plci->internal_command = plci->li_write_command; - if (plci_nl_busy (plci)) - return (TRUE); - if (j < a->li_base) - j = a->li_base; - if (a->li_pri) - { - *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC; - w = 0; - if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) - w |= MIXER_FEATURE_ENABLE_TX_DATA; - if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) - w |= MIXER_FEATURE_ENABLE_RX_DATA; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - for (n = 0; n < sizeof(mixer_write_prog_pri) / sizeof(mixer_write_prog_pri[0]); n++) - { - *(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags); - for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++) - { - w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); - if (w & mixer_write_prog_pri[n].mask) - { - *(p++) = (li_config_table[i].coef_table[j] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01; - li_config_table[i].coef_table[j] ^= mixer_write_prog_pri[n].mask << 4; - } - else - *(p++) = 0x00; - } - *(p++) = (byte)((plci->li_bchannel_id - 1) | MIXER_COEF_LINE_ROW_FLAG | mixer_write_prog_pri[n].line_flags); - for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++) - { - w = ((li_config_table[j].coef_table[i] & 0xf) ^ (li_config_table[j].coef_table[i] >> 4)); - if (w & mixer_write_prog_pri[n].mask) - { - *(p++) = (li_config_table[j].coef_table[i] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01; - li_config_table[j].coef_table[i] ^= mixer_write_prog_pri[n].mask << 4; - } - else - *(p++) = 0x00; - } - } - } - else - { - *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI; - w = 0; - if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI) - && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)) - { - w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); - } - if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) - w |= MIXER_FEATURE_ENABLE_TX_DATA; - if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) - w |= MIXER_FEATURE_ENABLE_RX_DATA; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - for (j = 0; j < sizeof(ch_map); j += 2) - { - if (plci->li_bchannel_id == 2) - { - ch_map[j] = (byte)(j+1); - ch_map[j+1] = (byte) j; - } - else - { - ch_map[j] = (byte) j; - ch_map[j+1] = (byte)(j+1); - } - } - for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++) - { - i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; - j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; - if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) - { - *p = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); - w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); - li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; - } - else - { - *p = 0x00; - if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE)) - { - w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n]; - if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length) - *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w]; - } - } - p++; - } - } - j = li_total_channels + 1; - } - } - plci->li_write_channel = j; - if (p != plci->internal_req_buffer) - { - plci->NData[0].P = plci->internal_req_buffer; - plci->NData[0].PLength = p - plci->internal_req_buffer; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_UDATA; - plci->adapter->request (&plci->NL); - } - return (TRUE); -} - - -static void mixer_notify_update (PLCI *plci, byte others) -{ - DIVA_CAPI_ADAPTER *a; - word i, w; - PLCI *notify_plci; - byte msg[sizeof(CAPI_MSG_HEADER) + 6]; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_notify_update %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, others)); - - a = plci->adapter; - if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED) - { - if (others) - plci->li_notify_update = TRUE; - i = 0; - do - { - notify_plci = NULL; - if (others) - { - while ((i < li_total_channels) && (li_config_table[i].plci == NULL)) - i++; - if (i < li_total_channels) - notify_plci = li_config_table[i++].plci; - } - else - { - if ((plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - notify_plci = plci; - } - } - if ((notify_plci != NULL) - && !notify_plci->li_notify_update - && (notify_plci->appl != NULL) - && (notify_plci->State) - && notify_plci->NL.Id && !notify_plci->nl_remove_id) - { - notify_plci->li_notify_update = TRUE; - ((CAPI_MSG *) msg)->header.length = 18; - ((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id; - ((CAPI_MSG *) msg)->header.command = _FACILITY_R; - ((CAPI_MSG *) msg)->header.number = 0; - ((CAPI_MSG *) msg)->header.controller = notify_plci->adapter->Id; - ((CAPI_MSG *) msg)->header.plci = notify_plci->Id; - ((CAPI_MSG *) msg)->header.ncci = 0; - ((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT; - ((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3; - PUT_WORD (&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_SILENT_UPDATE); - ((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0; - w = api_put (notify_plci->appl, (CAPI_MSG *) msg); - if (w != _QUEUE_FULL) - { - if (w != 0) - { - dbug (1, dprintf ("[%06lx] %s,%d: Interconnect notify failed %06x %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, - (dword)((notify_plci->Id << 8) | UnMapController (notify_plci->adapter->Id)), w)); - } - notify_plci->li_notify_update = FALSE; - } - } - } while (others && (notify_plci != NULL)); - if (others) - plci->li_notify_update = FALSE; - } -} - - -static void mixer_clear_config (PLCI *plci) -{ - DIVA_CAPI_ADAPTER *a; - word i, j; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_clear_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - plci->li_notify_update = FALSE; - plci->li_plci_b_write_pos = 0; - plci->li_plci_b_read_pos = 0; - plci->li_plci_b_req_pos = 0; - a = plci->adapter; - if ((plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - i = a->li_base + (plci->li_bchannel_id - 1); - li_config_table[i].curchnl = 0; - li_config_table[i].channel = 0; - li_config_table[i].chflags = 0; - for (j = 0; j < li_total_channels; j++) - { - li_config_table[j].flag_table[i] = 0; - li_config_table[i].flag_table[j] = 0; - li_config_table[i].coef_table[j] = 0; - li_config_table[j].coef_table[i] = 0; - } - if (!a->li_pri) - { - li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; - if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) - { - i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); - li_config_table[i].curchnl = 0; - li_config_table[i].channel = 0; - li_config_table[i].chflags = 0; - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].flag_table[j] = 0; - li_config_table[j].flag_table[i] = 0; - li_config_table[i].coef_table[j] = 0; - li_config_table[j].coef_table[i] = 0; - } - if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) - { - i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); - li_config_table[i].curchnl = 0; - li_config_table[i].channel = 0; - li_config_table[i].chflags = 0; - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].flag_table[j] = 0; - li_config_table[j].flag_table[i] = 0; - li_config_table[i].coef_table[j] = 0; - li_config_table[j].coef_table[i] = 0; - } - } - } - } - } -} - - -static void mixer_prepare_switch (dword Id, PLCI *plci) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_prepare_switch", - UnMapId (Id), (char *)(FILE_), __LINE__)); - - do - { - mixer_indication_coefs_set (Id, plci); - } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos); -} - - -static word mixer_save_config (dword Id, PLCI *plci, byte Rc) -{ - DIVA_CAPI_ADAPTER *a; - word i, j; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_save_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - - a = plci->adapter; - if ((plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - i = a->li_base + (plci->li_bchannel_id - 1); - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].coef_table[j] &= 0xf; - li_config_table[j].coef_table[i] &= 0xf; - } - if (!a->li_pri) - li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; - } - return (GOOD); -} - - -static word mixer_restore_config (dword Id, PLCI *plci, byte Rc) -{ - DIVA_CAPI_ADAPTER *a; - word Info; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_restore_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - - Info = GOOD; - a = plci->adapter; - if ((plci->B1_facilities & B1_FACILITY_MIXER) - && (plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - switch (plci->adjust_b_state) - { - case ADJUST_B_RESTORE_MIXER_1: - if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - { - plci->internal_command = plci->adjust_b_command; - if (plci_nl_busy (plci)) - { - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1; - break; - } - xconnect_query_addresses (plci); - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2; - break; - } - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; - Rc = OK; - case ADJUST_B_RESTORE_MIXER_2: - case ADJUST_B_RESTORE_MIXER_3: - case ADJUST_B_RESTORE_MIXER_4: - if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B query addresses failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - if (Rc == OK) - { - if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_3; - else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4) - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; - } - else if (Rc == 0) - { - if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_4; - else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3) - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; - } - if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5) - { - plci->internal_command = plci->adjust_b_command; - break; - } - case ADJUST_B_RESTORE_MIXER_5: - xconnect_write_coefs (plci, plci->adjust_b_command); - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6; - Rc = OK; - case ADJUST_B_RESTORE_MIXER_6: - if (!xconnect_write_coefs_process (Id, plci, Rc)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - break; - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7; - case ADJUST_B_RESTORE_MIXER_7: - break; - } - } - return (Info); -} - - -static void mixer_command (dword Id, PLCI *plci, byte Rc) -{ - DIVA_CAPI_ADAPTER *a; - word i, internal_command, Info; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, - plci->li_cmd)); - - Info = GOOD; - a = plci->adapter; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (plci->li_cmd) - { - case LI_REQ_CONNECT: - case LI_REQ_DISCONNECT: - case LI_REQ_SILENT_UPDATE: - switch (internal_command) - { - default: - if (plci->li_channel_bits & LI_CHANNEL_INVOLVED) - { - adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | - B1_FACILITY_MIXER), MIXER_COMMAND_1); - } - case MIXER_COMMAND_1: - if (plci->li_channel_bits & LI_CHANNEL_INVOLVED) - { - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - } - plci->li_plci_b_req_pos = plci->li_plci_b_write_pos; - if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED) - || ((get_b1_facilities (plci, plci->B1_resource) & B1_FACILITY_MIXER) - && (add_b1_facilities (plci, plci->B1_resource, (word)(plci->B1_facilities & - ~B1_FACILITY_MIXER)) == plci->B1_resource))) - { - xconnect_write_coefs (plci, MIXER_COMMAND_2); - } - else - { - do - { - mixer_indication_coefs_set (Id, plci); - } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos); - } - case MIXER_COMMAND_2: - if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED) - || ((get_b1_facilities (plci, plci->B1_resource) & B1_FACILITY_MIXER) - && (add_b1_facilities (plci, plci->B1_resource, (word)(plci->B1_facilities & - ~B1_FACILITY_MIXER)) == plci->B1_resource))) - { - if (!xconnect_write_coefs_process (Id, plci, Rc)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - if (plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) - { - do - { - plci->li_plci_b_write_pos = (plci->li_plci_b_write_pos == 0) ? - LI_PLCI_B_QUEUE_ENTRIES-1 : plci->li_plci_b_write_pos - 1; - i = (plci->li_plci_b_write_pos == 0) ? - LI_PLCI_B_QUEUE_ENTRIES-1 : plci->li_plci_b_write_pos - 1; - } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) - && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)); - } - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - } - if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED)) - { - adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities & - ~B1_FACILITY_MIXER), MIXER_COMMAND_3); - } - case MIXER_COMMAND_3: - if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED)) - { - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - } - break; - } - break; - } - if ((plci->li_bchannel_id == 0) - || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)) - { - dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out %d", - UnMapId (Id), (char *)(FILE_), __LINE__, (int)(plci->li_bchannel_id))); - } - else - { - i = a->li_base + (plci->li_bchannel_id - 1); - li_config_table[i].curchnl = plci->li_channel_bits; - if (!a->li_pri && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) - { - i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); - li_config_table[i].curchnl = plci->li_channel_bits; - if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) - { - i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); - li_config_table[i].curchnl = plci->li_channel_bits; - } - } - } -} - - -static void li_update_connect (dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci, - dword plci_b_id, byte connect, dword li_flags) -{ - word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s; - PLCI *plci_b; - DIVA_CAPI_ADAPTER *a_b; - - a_b = &(adapter[MapController ((byte)(plci_b_id & 0x7f)) - 1]); - plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]); - ch_a = a->li_base + (plci->li_bchannel_id - 1); - if (!a->li_pri && (plci->tel == ADV_VOICE) - && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER)) - { - ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE; - ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? - a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v; - } - else - { - ch_a_v = ch_a; - ch_a_s = ch_a; - } - ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1); - if (!a_b->li_pri && (plci_b->tel == ADV_VOICE) - && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER)) - { - ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE; - ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? - a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v; - } - else - { - ch_b_v = ch_b; - ch_b_s = ch_b; - } - if (connect) - { - li_config_table[ch_a].flag_table[ch_a_v] &= ~LI_FLAG_MONITOR; - li_config_table[ch_a].flag_table[ch_a_s] &= ~LI_FLAG_MONITOR; - li_config_table[ch_a_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); - li_config_table[ch_a_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); - } - li_config_table[ch_a].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR; - li_config_table[ch_a].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR; - li_config_table[ch_b_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); - li_config_table[ch_b_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); - if (ch_a_v == ch_b_v) - { - li_config_table[ch_a_v].flag_table[ch_b_v] &= ~LI_FLAG_CONFERENCE; - li_config_table[ch_a_s].flag_table[ch_b_s] &= ~LI_FLAG_CONFERENCE; - } - else - { - if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE) - { - for (i = 0; i < li_total_channels; i++) - { - if (i != ch_a_v) - li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE; - } - } - if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE) - { - for (i = 0; i < li_total_channels; i++) - { - if (i != ch_a_s) - li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE; - } - } - if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE) - { - for (i = 0; i < li_total_channels; i++) - { - if (i != ch_a_v) - li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE; - } - } - if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE) - { - for (i = 0; i < li_total_channels; i++) - { - if (i != ch_a_s) - li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE; - } - } - } - if (li_flags & LI_FLAG_CONFERENCE_A_B) - { - li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; - li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; - li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; - li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; - } - if (li_flags & LI_FLAG_CONFERENCE_B_A) - { - li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; - li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; - li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; - li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; - } - if (li_flags & LI_FLAG_MONITOR_A) - { - li_config_table[ch_a].flag_table[ch_a_v] |= LI_FLAG_MONITOR; - li_config_table[ch_a].flag_table[ch_a_s] |= LI_FLAG_MONITOR; - } - if (li_flags & LI_FLAG_MONITOR_B) - { - li_config_table[ch_a].flag_table[ch_b_v] |= LI_FLAG_MONITOR; - li_config_table[ch_a].flag_table[ch_b_s] |= LI_FLAG_MONITOR; - } - if (li_flags & LI_FLAG_ANNOUNCEMENT_A) - { - li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; - li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; - } - if (li_flags & LI_FLAG_ANNOUNCEMENT_B) - { - li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; - li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; - } - if (li_flags & LI_FLAG_MIX_A) - { - li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_MIX; - li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_MIX; - } - if (li_flags & LI_FLAG_MIX_B) - { - li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_MIX; - li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_MIX; - } - if (ch_a_v != ch_a_s) - { - li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; - li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; - } - if (ch_b_v != ch_b_s) - { - li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; - li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; - } -} - - -static void li2_update_connect (dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci, - dword plci_b_id, byte connect, dword li_flags) -{ - word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s; - PLCI *plci_b; - DIVA_CAPI_ADAPTER *a_b; - - a_b = &(adapter[MapController ((byte)(plci_b_id & 0x7f)) - 1]); - plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]); - ch_a = a->li_base + (plci->li_bchannel_id - 1); - if (!a->li_pri && (plci->tel == ADV_VOICE) - && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER)) - { - ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE; - ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? - a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v; - } - else - { - ch_a_v = ch_a; - ch_a_s = ch_a; - } - ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1); - if (!a_b->li_pri && (plci_b->tel == ADV_VOICE) - && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER)) - { - ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE; - ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? - a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v; - } - else - { - ch_b_v = ch_b; - ch_b_s = ch_b; - } - if (connect) - { - li_config_table[ch_b].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR; - li_config_table[ch_b].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR; - li_config_table[ch_b_v].flag_table[ch_b] &= ~LI_FLAG_MIX; - li_config_table[ch_b_s].flag_table[ch_b] &= ~LI_FLAG_MIX; - li_config_table[ch_b].flag_table[ch_b] &= ~LI_FLAG_PCCONNECT; - li_config_table[ch_b].chflags &= ~(LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP); - } - li_config_table[ch_b_v].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - li_config_table[ch_b_s].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - li_config_table[ch_b_v].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - li_config_table[ch_b_s].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - li_config_table[ch_a_v].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - li_config_table[ch_a_v].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - li_config_table[ch_a_s].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - li_config_table[ch_a_s].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); - if (li_flags & LI2_FLAG_INTERCONNECT_A_B) - { - li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT; - } - if (li_flags & LI2_FLAG_INTERCONNECT_B_A) - { - li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; - } - if (li_flags & LI2_FLAG_MONITOR_B) - { - li_config_table[ch_b].flag_table[ch_b_v] |= LI_FLAG_MONITOR; - li_config_table[ch_b].flag_table[ch_b_s] |= LI_FLAG_MONITOR; - } - if (li_flags & LI2_FLAG_MIX_B) - { - li_config_table[ch_b_v].flag_table[ch_b] |= LI_FLAG_MIX; - li_config_table[ch_b_s].flag_table[ch_b] |= LI_FLAG_MIX; - } - if (li_flags & LI2_FLAG_MONITOR_X) - li_config_table[ch_b].chflags |= LI_CHFLAG_MONITOR; - if (li_flags & LI2_FLAG_MIX_X) - li_config_table[ch_b].chflags |= LI_CHFLAG_MIX; - if (li_flags & LI2_FLAG_LOOP_B) - { - li_config_table[ch_b_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; - li_config_table[ch_b_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; - } - if (li_flags & LI2_FLAG_LOOP_PC) - li_config_table[ch_b].flag_table[ch_b] |= LI_FLAG_PCCONNECT; - if (li_flags & LI2_FLAG_LOOP_X) - li_config_table[ch_b].chflags |= LI_CHFLAG_LOOP; - if (li_flags & LI2_FLAG_PCCONNECT_A_B) - li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_PCCONNECT; - if (li_flags & LI2_FLAG_PCCONNECT_B_A) - li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_PCCONNECT; - if (ch_a_v != ch_a_s) - { - li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; - li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; - } - if (ch_b_v != ch_b_s) - { - li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; - li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; - } -} - - -static word li_check_main_plci (dword Id, PLCI *plci) -{ - if (plci == NULL) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", - UnMapId (Id), (char *)(FILE_), __LINE__)); - return (_WRONG_IDENTIFIER); - } - if (!plci->State - || !plci->NL.Id || plci->nl_remove_id - || (plci->li_bchannel_id == 0)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", - UnMapId (Id), (char *)(FILE_), __LINE__)); - return (_WRONG_STATE); - } - li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci; - return (GOOD); -} - - -static PLCI *li_check_plci_b (dword Id, PLCI *plci, - dword plci_b_id, word plci_b_write_pos, byte *p_result) -{ - byte ctlr_b; - PLCI *plci_b; - - if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : - LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); - return (NULL); - } - ctlr_b = 0; - if ((plci_b_id & 0x7f) != 0) - { - ctlr_b = MapController ((byte)(plci_b_id & 0x7f)); - if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL))) - ctlr_b = 0; - } - if ((ctlr_b == 0) - || (((plci_b_id >> 8) & 0xff) == 0) - || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci)) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b_id)); - PUT_WORD (p_result, _WRONG_IDENTIFIER); - return (NULL); - } - plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]); - if (!plci_b->State - || !plci_b->NL.Id || plci_b->nl_remove_id - || (plci_b->li_bchannel_id == 0)) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b_id)); - PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); - return (NULL); - } - li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci = plci_b; - if (((byte)(plci_b_id & ~EXT_CONTROLLER)) != - ((byte)(UnMapController (plci->adapter->Id) & ~EXT_CONTROLLER)) - && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT))) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b_id)); - PUT_WORD (p_result, _WRONG_IDENTIFIER); - return (NULL); - } - if (!(get_b1_facilities (plci_b, add_b1_facilities (plci_b, plci_b->B1_resource, - (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b->B1_resource)); - PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); - return (NULL); - } - return (plci_b); -} - - -static PLCI *li2_check_plci_b (dword Id, PLCI *plci, - dword plci_b_id, word plci_b_write_pos, byte *p_result) -{ - byte ctlr_b; - PLCI *plci_b; - - if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : - LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (p_result, _WRONG_STATE); - return (NULL); - } - ctlr_b = 0; - if ((plci_b_id & 0x7f) != 0) - { - ctlr_b = MapController ((byte)(plci_b_id & 0x7f)); - if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL))) - ctlr_b = 0; - } - if ((ctlr_b == 0) - || (((plci_b_id >> 8) & 0xff) == 0) - || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci)) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b_id)); - PUT_WORD (p_result, _WRONG_IDENTIFIER); - return (NULL); - } - plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]); - if (!plci_b->State - || !plci_b->NL.Id || plci_b->nl_remove_id - || (plci_b->li_bchannel_id == 0) - || (li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci != plci_b)) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b_id)); - PUT_WORD (p_result, _WRONG_STATE); - return (NULL); - } - if (((byte)(plci_b_id & ~EXT_CONTROLLER)) != - ((byte)(UnMapController (plci->adapter->Id) & ~EXT_CONTROLLER)) - && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT))) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b_id)); - PUT_WORD (p_result, _WRONG_IDENTIFIER); - return (NULL); - } - if (!(get_b1_facilities (plci_b, add_b1_facilities (plci_b, plci_b->B1_resource, - (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d", - UnMapId (Id), (char *)(FILE_), __LINE__, plci_b->B1_resource)); - PUT_WORD (p_result, _WRONG_STATE); - return (NULL); - } - return (plci_b); -} - - -static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg) -{ - word Info; - word i; - dword d, li_flags, plci_b_id; - PLCI *plci_b; - API_PARSE li_parms[3]; - API_PARSE li_req_parms[3]; - API_PARSE li_participant_struct[2]; - API_PARSE li_participant_parms[3]; - word participant_parms_pos; - byte result_buffer[32]; - byte *result; - word result_pos; - word plci_b_write_pos; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_request", - UnMapId (Id), (char *)(FILE_), __LINE__)); - - Info = GOOD; - result = result_buffer; - result_buffer[0] = 0; - if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - } - else if (api_parse (&msg[1].info[1], msg[1].length, "ws", li_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - } - else - { - result_buffer[0] = 3; - PUT_WORD (&result_buffer[1], GET_WORD (li_parms[0].info)); - result_buffer[3] = 0; - switch (GET_WORD (li_parms[0].info)) - { - case LI_GET_SUPPORTED_SERVICES: - if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) - { - result_buffer[0] = 17; - result_buffer[3] = 14; - PUT_WORD (&result_buffer[4], GOOD); - d = 0; - if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_CH) - d |= LI_CONFERENCING_SUPPORTED; - if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC) - d |= LI_MONITORING_SUPPORTED; - if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH) - d |= LI_ANNOUNCEMENTS_SUPPORTED | LI_MIXING_SUPPORTED; - if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - d |= LI_CROSS_CONTROLLER_SUPPORTED; - PUT_DWORD (&result_buffer[6], d); - if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - { - d = 0; - for (i = 0; i < li_total_channels; i++) - { - if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - && (li_config_table[i].adapter->li_pri - || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI))) - { - d++; - } - } - } - else - { - d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI; - } - PUT_DWORD (&result_buffer[10], d / 2); - PUT_DWORD (&result_buffer[14], d); - } - else - { - result_buffer[0] = 25; - result_buffer[3] = 22; - PUT_WORD (&result_buffer[4], GOOD); - d = LI2_ASYMMETRIC_SUPPORTED | LI2_B_LOOPING_SUPPORTED | LI2_X_LOOPING_SUPPORTED; - if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC) - d |= LI2_MONITORING_SUPPORTED | LI2_REMOTE_MONITORING_SUPPORTED; - if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH) - d |= LI2_MIXING_SUPPORTED | LI2_REMOTE_MIXING_SUPPORTED; - if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_PC) - d |= LI2_PC_LOOPING_SUPPORTED; - if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - d |= LI2_CROSS_CONTROLLER_SUPPORTED; - PUT_DWORD (&result_buffer[6], d); - d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI; - PUT_DWORD (&result_buffer[10], d / 2); - PUT_DWORD (&result_buffer[14], d - 1); - if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - { - d = 0; - for (i = 0; i < li_total_channels; i++) - { - if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) - && (li_config_table[i].adapter->li_pri - || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI))) - { - d++; - } - } - } - PUT_DWORD (&result_buffer[18], d / 2); - PUT_DWORD (&result_buffer[22], d - 1); - } - break; - - case LI_REQ_CONNECT: - if (li_parms[1].length == 8) - { - appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC; - if (api_parse (&li_parms[1].info[1], li_parms[1].length, "dd", li_req_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - plci_b_id = GET_DWORD (li_req_parms[0].info) & 0xffff; - li_flags = GET_DWORD (li_req_parms[1].info); - Info = li_check_main_plci (Id, plci); - result_buffer[0] = 9; - result_buffer[3] = 6; - PUT_DWORD (&result_buffer[4], plci_b_id); - PUT_WORD (&result_buffer[8], GOOD); - if (Info != GOOD) - break; - result = plci->saved_msg.info; - for (i = 0; i <= result_buffer[0]; i++) - result[i] = result_buffer[i]; - plci_b_write_pos = plci->li_plci_b_write_pos; - plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]); - if (plci_b == NULL) - break; - li_update_connect (Id, a, plci, plci_b_id, TRUE, li_flags); - plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG; - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - plci->li_plci_b_write_pos = plci_b_write_pos; - } - else - { - appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC; - if (api_parse (&li_parms[1].info[1], li_parms[1].length, "ds", li_req_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - li_flags = GET_DWORD (li_req_parms[0].info) & ~(LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A); - Info = li_check_main_plci (Id, plci); - result_buffer[0] = 7; - result_buffer[3] = 4; - PUT_WORD (&result_buffer[4], Info); - result_buffer[6] = 0; - if (Info != GOOD) - break; - result = plci->saved_msg.info; - for (i = 0; i <= result_buffer[0]; i++) - result[i] = result_buffer[i]; - plci_b_write_pos = plci->li_plci_b_write_pos; - participant_parms_pos = 0; - result_pos = 7; - li2_update_connect (Id, a, plci, UnMapId (Id), TRUE, li_flags); - while (participant_parms_pos < li_req_parms[1].length) - { - result[result_pos] = 6; - result_pos += 7; - PUT_DWORD (&result[result_pos - 6], 0); - PUT_WORD (&result[result_pos - 2], GOOD); - if (api_parse (&li_req_parms[1].info[1 + participant_parms_pos], - (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); - break; - } - if (api_parse (&li_participant_struct[0].info[1], - li_participant_struct[0].length, "dd", li_participant_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); - break; - } - plci_b_id = GET_DWORD (li_participant_parms[0].info) & 0xffff; - li_flags = GET_DWORD (li_participant_parms[1].info); - PUT_DWORD (&result[result_pos - 6], plci_b_id); - if (sizeof(result) - result_pos < 7) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (&result[result_pos - 2], _WRONG_STATE); - break; - } - plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]); - if (plci_b != NULL) - { - li2_update_connect (Id, a, plci, plci_b_id, TRUE, li_flags); - plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | - ((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A | - LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG); - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - } - participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) - - (&li_req_parms[1].info[1])); - } - result[0] = (byte)(result_pos - 1); - result[3] = (byte)(result_pos - 4); - result[6] = (byte)(result_pos - 7); - i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1; - if ((plci_b_write_pos == plci->li_plci_b_read_pos) - || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) - { - plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - } - else - plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; - plci->li_plci_b_write_pos = plci_b_write_pos; - } - mixer_calculate_coefs (a); - plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; - mixer_notify_update (plci, TRUE); - sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, - "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); - plci->command = 0; - plci->li_cmd = GET_WORD (li_parms[0].info); - start_internal_command (Id, plci, mixer_command); - return (FALSE); - - case LI_REQ_DISCONNECT: - if (li_parms[1].length == 4) - { - appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC; - if (api_parse (&li_parms[1].info[1], li_parms[1].length, "d", li_req_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - plci_b_id = GET_DWORD (li_req_parms[0].info) & 0xffff; - Info = li_check_main_plci (Id, plci); - result_buffer[0] = 9; - result_buffer[3] = 6; - PUT_DWORD (&result_buffer[4], GET_DWORD (li_req_parms[0].info)); - PUT_WORD (&result_buffer[8], GOOD); - if (Info != GOOD) - break; - result = plci->saved_msg.info; - for (i = 0; i <= result_buffer[0]; i++) - result[i] = result_buffer[i]; - plci_b_write_pos = plci->li_plci_b_write_pos; - plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]); - if (plci_b == NULL) - break; - li_update_connect (Id, a, plci, plci_b_id, FALSE, 0); - plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG; - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - plci->li_plci_b_write_pos = plci_b_write_pos; - } - else - { - appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC; - if (api_parse (&li_parms[1].info[1], li_parms[1].length, "s", li_req_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - break; - } - Info = li_check_main_plci (Id, plci); - result_buffer[0] = 7; - result_buffer[3] = 4; - PUT_WORD (&result_buffer[4], Info); - result_buffer[6] = 0; - if (Info != GOOD) - break; - result = plci->saved_msg.info; - for (i = 0; i <= result_buffer[0]; i++) - result[i] = result_buffer[i]; - plci_b_write_pos = plci->li_plci_b_write_pos; - participant_parms_pos = 0; - result_pos = 7; - while (participant_parms_pos < li_req_parms[0].length) - { - result[result_pos] = 6; - result_pos += 7; - PUT_DWORD (&result[result_pos - 6], 0); - PUT_WORD (&result[result_pos - 2], GOOD); - if (api_parse (&li_req_parms[0].info[1 + participant_parms_pos], - (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); - break; - } - if (api_parse (&li_participant_struct[0].info[1], - li_participant_struct[0].length, "d", li_participant_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); - break; - } - plci_b_id = GET_DWORD (li_participant_parms[0].info) & 0xffff; - PUT_DWORD (&result[result_pos - 6], plci_b_id); - if (sizeof(result) - result_pos < 7) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun", - UnMapId (Id), (char *)(FILE_), __LINE__)); - PUT_WORD (&result[result_pos - 2], _WRONG_STATE); - break; - } - plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]); - if (plci_b != NULL) - { - li2_update_connect (Id, a, plci, plci_b_id, FALSE, 0); - plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG; - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - } - participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) - - (&li_req_parms[0].info[1])); - } - result[0] = (byte)(result_pos - 1); - result[3] = (byte)(result_pos - 4); - result[6] = (byte)(result_pos - 7); - i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1; - if ((plci_b_write_pos == plci->li_plci_b_read_pos) - || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) - { - plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - } - else - plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; - plci->li_plci_b_write_pos = plci_b_write_pos; - } - mixer_calculate_coefs (a); - plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; - mixer_notify_update (plci, TRUE); - sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, - "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); - plci->command = 0; - plci->li_cmd = GET_WORD (li_parms[0].info); - start_internal_command (Id, plci, mixer_command); - return (FALSE); - - case LI_REQ_SILENT_UPDATE: - if (!plci || !plci->State - || !plci->NL.Id || plci->nl_remove_id - || (plci->li_bchannel_id == 0) - || (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci != plci)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", - UnMapId (Id), (char *)(FILE_), __LINE__)); - return (FALSE); - } - plci_b_write_pos = plci->li_plci_b_write_pos; - if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : - LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", - UnMapId (Id), (char *)(FILE_), __LINE__)); - return (FALSE); - } - i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1; - if ((plci_b_write_pos == plci->li_plci_b_read_pos) - || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) - { - plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - } - else - plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; - plci->li_plci_b_write_pos = plci_b_write_pos; - plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; - plci->command = 0; - plci->li_cmd = GET_WORD (li_parms[0].info); - start_internal_command (Id, plci, mixer_command); - return (FALSE); - - default: - dbug (1, dprintf ("[%06lx] %s,%d: LI unknown request %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, GET_WORD (li_parms[0].info))); - Info = _FACILITY_NOT_SUPPORTED; - } - } - sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, - "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); - return (FALSE); -} - - -static void mixer_indication_coefs_set (dword Id, PLCI *plci) -{ - dword d; - DIVA_CAPI_ADAPTER *a; - byte result[12]; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set", - UnMapId (Id), (char *)(FILE_), __LINE__)); - - a = plci->adapter; - if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos) - { - do - { - d = plci->li_plci_b_queue[plci->li_plci_b_read_pos]; - if (!(d & LI_PLCI_B_SKIP_FLAG)) - { - if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) - { - if (d & LI_PLCI_B_DISC_FLAG) - { - result[0] = 5; - PUT_WORD (&result[1], LI_IND_DISCONNECT); - result[3] = 2; - PUT_WORD (&result[4], _LI_USER_INITIATED); - } - else - { - result[0] = 7; - PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE); - result[3] = 4; - PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK); - } - } - else - { - if (d & LI_PLCI_B_DISC_FLAG) - { - result[0] = 9; - PUT_WORD (&result[1], LI_IND_DISCONNECT); - result[3] = 6; - PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK); - PUT_WORD (&result[8], _LI_USER_INITIATED); - } - else - { - result[0] = 7; - PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE); - result[3] = 4; - PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK); - } - } - sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, - "ws", SELECTOR_LINE_INTERCONNECT, result); - } - plci->li_plci_b_read_pos = (plci->li_plci_b_read_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? - 0 : plci->li_plci_b_read_pos + 1; - } while (!(d & LI_PLCI_B_LAST_FLAG) && (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)); - } -} - - -static void mixer_indication_xconnect_from (dword Id, PLCI *plci, byte *msg, word length) -{ - word i, j, ch; - struct xconnect_transfer_address_s s, *p; - DIVA_CAPI_ADAPTER *a; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_from %d", - UnMapId (Id), (char *)(FILE_), __LINE__, (int) length)); - - a = plci->adapter; - i = 1; - for (i = 1; i < length; i += 16) - { - s.card_address.low = msg[i] | (msg[i+1] << 8) | (((dword)(msg[i+2])) << 16) | (((dword)(msg[i+3])) << 24); - s.card_address.high = msg[i+4] | (msg[i+5] << 8) | (((dword)(msg[i+6])) << 16) | (((dword)(msg[i+7])) << 24); - s.offset = msg[i+8] | (msg[i+9] << 8) | (((dword)(msg[i+10])) << 16) | (((dword)(msg[i+11])) << 24); - ch = msg[i+12] | (msg[i+13] << 8); - j = ch & XCONNECT_CHANNEL_NUMBER_MASK; - if (!a->li_pri && (plci->li_bchannel_id == 2)) - j = 1 - j; - j += a->li_base; - if (ch & XCONNECT_CHANNEL_PORT_PC) - p = &(li_config_table[j].send_pc); - else - p = &(li_config_table[j].send_b); - p->card_address.low = s.card_address.low; - p->card_address.high = s.card_address.high; - p->offset = s.offset; - li_config_table[j].channel |= LI_CHANNEL_ADDRESSES_SET; - } - if (plci->internal_command_queue[0] - && ((plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) - || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3) - || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4))) - { - (*(plci->internal_command_queue[0]))(Id, plci, 0); - if (!plci->internal_command) - next_internal_command (Id, plci); - } - mixer_notify_update (plci, TRUE); -} - - -static void mixer_indication_xconnect_to (dword Id, PLCI *plci, byte *msg, word length) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_to %d", - UnMapId (Id), (char *)(FILE_), __LINE__, (int) length)); - -} - - -static byte mixer_notify_source_removed (PLCI *plci, dword plci_b_id) -{ - word plci_b_write_pos; - - plci_b_write_pos = plci->li_plci_b_write_pos; - if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : - LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 1) - { - dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - return (FALSE); - } - plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG; - plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1; - plci->li_plci_b_write_pos = plci_b_write_pos; - return (TRUE); -} - - -static void mixer_remove (PLCI *plci) -{ - DIVA_CAPI_ADAPTER *a; - PLCI *notify_plci; - dword plci_b_id; - word i, j; - - dbug (1, dprintf ("[%06lx] %s,%d: mixer_remove", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - a = plci->adapter; - plci_b_id = (plci->Id << 8) | UnMapController (plci->adapter->Id); - if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED) - { - if ((plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - i = a->li_base + (plci->li_bchannel_id - 1); - if ((li_config_table[i].curchnl | li_config_table[i].channel) & LI_CHANNEL_INVOLVED) - { - for (j = 0; j < li_total_channels; j++) - { - if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) - || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)) - { - notify_plci = li_config_table[j].plci; - if ((notify_plci != NULL) - && (notify_plci != plci) - && (notify_plci->appl != NULL) - && !(notify_plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) - && (notify_plci->State) - && notify_plci->NL.Id && !notify_plci->nl_remove_id) - { - mixer_notify_source_removed (notify_plci, plci_b_id); - } - } - } - mixer_clear_config (plci); - mixer_calculate_coefs (a); - mixer_notify_update (plci, TRUE); - } - li_config_table[i].plci = NULL; - plci->li_bchannel_id = 0; - } - } +static void xconnect_query_addresses(PLCI *plci) +{ + DIVA_CAPI_ADAPTER *a; + word w, ch; + byte *p; + + dbug(1, dprintf("[%06lx] %s,%d: xconnect_query_addresses", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + + a = plci->adapter; + if (a->li_pri && ((plci->li_bchannel_id == 0) + || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))) + { + dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + return; + } + p = plci->internal_req_buffer; + ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0; + *(p++) = UDATA_REQUEST_XCONNECT_FROM; + w = ch; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + w = ch | XCONNECT_CHANNEL_PORT_PC; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + plci->NData[0].P = plci->internal_req_buffer; + plci->NData[0].PLength = p - plci->internal_req_buffer; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_UDATA; + plci->adapter->request(&plci->NL); +} + + +static void xconnect_write_coefs(PLCI *plci, word internal_command) +{ + + dbug(1, dprintf("[%06lx] %s,%d: xconnect_write_coefs %04x", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, internal_command)); + + plci->li_write_command = internal_command; + plci->li_write_channel = 0; +} + + +static byte xconnect_write_coefs_process(dword Id, PLCI *plci, byte Rc) +{ + DIVA_CAPI_ADAPTER *a; + word w, n, i, j, r, s, to_ch; + dword d; + byte *p; + struct xconnect_transfer_address_s *transfer_address; + byte ch_map[MIXER_CHANNELS_BRI]; + + dbug(1, dprintf("[%06x] %s,%d: xconnect_write_coefs_process %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->li_write_channel)); + + a = plci->adapter; + if ((plci->li_bchannel_id == 0) + || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)) + { + dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out", + UnMapId(Id), (char *)(FILE_), __LINE__)); + return (true); + } + i = a->li_base + (plci->li_bchannel_id - 1); + j = plci->li_write_channel; + p = plci->internal_req_buffer; + if (j != 0) + { + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: LI write coefs failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + return (false); + } + } + if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + { + r = 0; + s = 0; + if (j < li_total_channels) + { + if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET) + { + s = ((li_config_table[i].send_b.card_address.low | li_config_table[i].send_b.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_PC | LI_COEF_PC_PC)) & + ((li_config_table[i].send_pc.card_address.low | li_config_table[i].send_pc.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_PC_CH)); + } + r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); + while ((j < li_total_channels) + && ((r == 0) + || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET)) + || (!li_config_table[j].adapter->li_pri + && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI)) + || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low) + || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high)) + && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT) + || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT))) + || ((li_config_table[j].adapter->li_base != a->li_base) + && !(r & s & + ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & + ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)))))) + { + j++; + if (j < li_total_channels) + r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); + } + } + if (j < li_total_channels) + { + plci->internal_command = plci->li_write_command; + if (plci_nl_busy(plci)) + return (true); + to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0; + *(p++) = UDATA_REQUEST_XCONNECT_TO; + do + { + if (li_config_table[j].adapter->li_base != a->li_base) + { + r &= s & + ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & + ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)); + } + n = 0; + do + { + if (r & xconnect_write_prog[n].mask) + { + if (xconnect_write_prog[n].from_pc) + transfer_address = &(li_config_table[j].send_pc); + else + transfer_address = &(li_config_table[j].send_b); + d = transfer_address->card_address.low; + *(p++) = (byte) d; + *(p++) = (byte)(d >> 8); + *(p++) = (byte)(d >> 16); + *(p++) = (byte)(d >> 24); + d = transfer_address->card_address.high; + *(p++) = (byte) d; + *(p++) = (byte)(d >> 8); + *(p++) = (byte)(d >> 16); + *(p++) = (byte)(d >> 24); + d = transfer_address->offset; + *(p++) = (byte) d; + *(p++) = (byte)(d >> 8); + *(p++) = (byte)(d >> 16); + *(p++) = (byte)(d >> 24); + w = xconnect_write_prog[n].to_pc ? to_ch | XCONNECT_CHANNEL_PORT_PC : to_ch; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + w = ((li_config_table[i].coef_table[j] & xconnect_write_prog[n].mask) == 0) ? 0x01 : + (li_config_table[i].adapter->u_law ? + (li_config_table[j].adapter->u_law ? 0x80 : 0x86) : + (li_config_table[j].adapter->u_law ? 0x7a : 0x80)); + *(p++) = (byte) w; + *(p++) = (byte) 0; + li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4; + } + n++; + } while ((n < ARRAY_SIZE(xconnect_write_prog)) + && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE)); + if (n == ARRAY_SIZE(xconnect_write_prog)) + { + do + { + j++; + if (j < li_total_channels) + r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); + } while ((j < li_total_channels) + && ((r == 0) + || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET)) + || (!li_config_table[j].adapter->li_pri + && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI)) + || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low) + || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high)) + && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT) + || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT))) + || ((li_config_table[j].adapter->li_base != a->li_base) + && !(r & s & + ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) & + ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ? + (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC)))))); + } + } while ((j < li_total_channels) + && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE)); + } + else if (j == li_total_channels) + { + plci->internal_command = plci->li_write_command; + if (plci_nl_busy(plci)) + return (true); + if (a->li_pri) + { + *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC; + w = 0; + if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) + w |= MIXER_FEATURE_ENABLE_TX_DATA; + if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) + w |= MIXER_FEATURE_ENABLE_RX_DATA; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + } + else + { + *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI; + w = 0; + if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI) + && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)) + { + w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); + } + if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) + w |= MIXER_FEATURE_ENABLE_TX_DATA; + if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) + w |= MIXER_FEATURE_ENABLE_RX_DATA; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + for (j = 0; j < sizeof(ch_map); j += 2) + { + if (plci->li_bchannel_id == 2) + { + ch_map[j] = (byte)(j + 1); + ch_map[j + 1] = (byte) j; + } + else + { + ch_map[j] = (byte) j; + ch_map[j + 1] = (byte)(j + 1); + } + } + for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++) + { + i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; + j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; + if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) + { + *p = (mixer_write_prog_bri[n].xconnect_override != 0) ? + mixer_write_prog_bri[n].xconnect_override : + ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); + if ((i >= a->li_base + MIXER_BCHANNELS_BRI) || (j >= a->li_base + MIXER_BCHANNELS_BRI)) + { + w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); + li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; + } + } + else + { + *p = 0x00; + if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE)) + { + w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n]; + if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length) + *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w]; + } + } + p++; + } + } + j = li_total_channels + 1; + } + } + else + { + if (j <= li_total_channels) + { + plci->internal_command = plci->li_write_command; + if (plci_nl_busy(plci)) + return (true); + if (j < a->li_base) + j = a->li_base; + if (a->li_pri) + { + *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC; + w = 0; + if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) + w |= MIXER_FEATURE_ENABLE_TX_DATA; + if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) + w |= MIXER_FEATURE_ENABLE_RX_DATA; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + for (n = 0; n < ARRAY_SIZE(mixer_write_prog_pri); n++) + { + *(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags); + for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++) + { + w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); + if (w & mixer_write_prog_pri[n].mask) + { + *(p++) = (li_config_table[i].coef_table[j] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01; + li_config_table[i].coef_table[j] ^= mixer_write_prog_pri[n].mask << 4; + } + else + *(p++) = 0x00; + } + *(p++) = (byte)((plci->li_bchannel_id - 1) | MIXER_COEF_LINE_ROW_FLAG | mixer_write_prog_pri[n].line_flags); + for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++) + { + w = ((li_config_table[j].coef_table[i] & 0xf) ^ (li_config_table[j].coef_table[i] >> 4)); + if (w & mixer_write_prog_pri[n].mask) + { + *(p++) = (li_config_table[j].coef_table[i] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01; + li_config_table[j].coef_table[i] ^= mixer_write_prog_pri[n].mask << 4; + } + else + *(p++) = 0x00; + } + } + } + else + { + *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI; + w = 0; + if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI) + && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)) + { + w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); + } + if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) + w |= MIXER_FEATURE_ENABLE_TX_DATA; + if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) + w |= MIXER_FEATURE_ENABLE_RX_DATA; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + for (j = 0; j < sizeof(ch_map); j += 2) + { + if (plci->li_bchannel_id == 2) + { + ch_map[j] = (byte)(j + 1); + ch_map[j + 1] = (byte) j; + } + else + { + ch_map[j] = (byte) j; + ch_map[j + 1] = (byte)(j + 1); + } + } + for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++) + { + i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; + j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; + if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) + { + *p = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); + w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); + li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; + } + else + { + *p = 0x00; + if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE)) + { + w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n]; + if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length) + *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w]; + } + } + p++; + } + } + j = li_total_channels + 1; + } + } + plci->li_write_channel = j; + if (p != plci->internal_req_buffer) + { + plci->NData[0].P = plci->internal_req_buffer; + plci->NData[0].PLength = p - plci->internal_req_buffer; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_UDATA; + plci->adapter->request(&plci->NL); + } + return (true); +} + + +static void mixer_notify_update(PLCI *plci, byte others) +{ + DIVA_CAPI_ADAPTER *a; + word i, w; + PLCI *notify_plci; + byte msg[sizeof(CAPI_MSG_HEADER) + 6]; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_notify_update %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, others)); + + a = plci->adapter; + if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED) + { + if (others) + plci->li_notify_update = true; + i = 0; + do + { + notify_plci = NULL; + if (others) + { + while ((i < li_total_channels) && (li_config_table[i].plci == NULL)) + i++; + if (i < li_total_channels) + notify_plci = li_config_table[i++].plci; + } + else + { + if ((plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + notify_plci = plci; + } + } + if ((notify_plci != NULL) + && !notify_plci->li_notify_update + && (notify_plci->appl != NULL) + && (notify_plci->State) + && notify_plci->NL.Id && !notify_plci->nl_remove_id) + { + notify_plci->li_notify_update = true; + ((CAPI_MSG *) msg)->header.length = 18; + ((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id; + ((CAPI_MSG *) msg)->header.command = _FACILITY_R; + ((CAPI_MSG *) msg)->header.number = 0; + ((CAPI_MSG *) msg)->header.controller = notify_plci->adapter->Id; + ((CAPI_MSG *) msg)->header.plci = notify_plci->Id; + ((CAPI_MSG *) msg)->header.ncci = 0; + ((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT; + ((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3; + PUT_WORD(&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_SILENT_UPDATE); + ((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0; + w = api_put(notify_plci->appl, (CAPI_MSG *) msg); + if (w != _QUEUE_FULL) + { + if (w != 0) + { + dbug(1, dprintf("[%06lx] %s,%d: Interconnect notify failed %06x %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, + (dword)((notify_plci->Id << 8) | UnMapController(notify_plci->adapter->Id)), w)); + } + notify_plci->li_notify_update = false; + } + } + } while (others && (notify_plci != NULL)); + if (others) + plci->li_notify_update = false; + } +} + + +static void mixer_clear_config(PLCI *plci) +{ + DIVA_CAPI_ADAPTER *a; + word i, j; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_clear_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + + plci->li_notify_update = false; + plci->li_plci_b_write_pos = 0; + plci->li_plci_b_read_pos = 0; + plci->li_plci_b_req_pos = 0; + a = plci->adapter; + if ((plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + i = a->li_base + (plci->li_bchannel_id - 1); + li_config_table[i].curchnl = 0; + li_config_table[i].channel = 0; + li_config_table[i].chflags = 0; + for (j = 0; j < li_total_channels; j++) + { + li_config_table[j].flag_table[i] = 0; + li_config_table[i].flag_table[j] = 0; + li_config_table[i].coef_table[j] = 0; + li_config_table[j].coef_table[i] = 0; + } + if (!a->li_pri) + { + li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; + if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) + { + i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); + li_config_table[i].curchnl = 0; + li_config_table[i].channel = 0; + li_config_table[i].chflags = 0; + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].flag_table[j] = 0; + li_config_table[j].flag_table[i] = 0; + li_config_table[i].coef_table[j] = 0; + li_config_table[j].coef_table[i] = 0; + } + if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) + { + i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); + li_config_table[i].curchnl = 0; + li_config_table[i].channel = 0; + li_config_table[i].chflags = 0; + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].flag_table[j] = 0; + li_config_table[j].flag_table[i] = 0; + li_config_table[i].coef_table[j] = 0; + li_config_table[j].coef_table[i] = 0; + } + } + } + } + } +} + + +static void mixer_prepare_switch(dword Id, PLCI *plci) +{ + + dbug(1, dprintf("[%06lx] %s,%d: mixer_prepare_switch", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + do + { + mixer_indication_coefs_set(Id, plci); + } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos); +} + + +static word mixer_save_config(dword Id, PLCI *plci, byte Rc) +{ + DIVA_CAPI_ADAPTER *a; + word i, j; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_save_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + + a = plci->adapter; + if ((plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + i = a->li_base + (plci->li_bchannel_id - 1); + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].coef_table[j] &= 0xf; + li_config_table[j].coef_table[i] &= 0xf; + } + if (!a->li_pri) + li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; + } + return (GOOD); +} + + +static word mixer_restore_config(dword Id, PLCI *plci, byte Rc) +{ + DIVA_CAPI_ADAPTER *a; + word Info; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_restore_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + + Info = GOOD; + a = plci->adapter; + if ((plci->B1_facilities & B1_FACILITY_MIXER) + && (plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + switch (plci->adjust_b_state) + { + case ADJUST_B_RESTORE_MIXER_1: + if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + { + plci->internal_command = plci->adjust_b_command; + if (plci_nl_busy(plci)) + { + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1; + break; + } + xconnect_query_addresses(plci); + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2; + break; + } + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; + Rc = OK; + case ADJUST_B_RESTORE_MIXER_2: + case ADJUST_B_RESTORE_MIXER_3: + case ADJUST_B_RESTORE_MIXER_4: + if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B query addresses failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + if (Rc == OK) + { + if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_3; + else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4) + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; + } + else if (Rc == 0) + { + if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_4; + else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3) + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5; + } + if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5) + { + plci->internal_command = plci->adjust_b_command; + break; + } + case ADJUST_B_RESTORE_MIXER_5: + xconnect_write_coefs(plci, plci->adjust_b_command); + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6; + Rc = OK; + case ADJUST_B_RESTORE_MIXER_6: + if (!xconnect_write_coefs_process(Id, plci, Rc)) + { + dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + if (plci->internal_command) + break; + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7; + case ADJUST_B_RESTORE_MIXER_7: + break; + } + } + return (Info); +} + + +static void mixer_command(dword Id, PLCI *plci, byte Rc) +{ + DIVA_CAPI_ADAPTER *a; + word i, internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_command %02x %04x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, + plci->li_cmd)); + + a = plci->adapter; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (plci->li_cmd) + { + case LI_REQ_CONNECT: + case LI_REQ_DISCONNECT: + case LI_REQ_SILENT_UPDATE: + switch (internal_command) + { + default: + if (plci->li_channel_bits & LI_CHANNEL_INVOLVED) + { + adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | + B1_FACILITY_MIXER), MIXER_COMMAND_1); + } + case MIXER_COMMAND_1: + if (plci->li_channel_bits & LI_CHANNEL_INVOLVED) + { + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Load mixer failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + break; + } + if (plci->internal_command) + return; + } + plci->li_plci_b_req_pos = plci->li_plci_b_write_pos; + if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED) + || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER) + && (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities & + ~B1_FACILITY_MIXER)) == plci->B1_resource))) + { + xconnect_write_coefs(plci, MIXER_COMMAND_2); + } + else + { + do + { + mixer_indication_coefs_set(Id, plci); + } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos); + } + case MIXER_COMMAND_2: + if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED) + || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER) + && (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities & + ~B1_FACILITY_MIXER)) == plci->B1_resource))) + { + if (!xconnect_write_coefs_process(Id, plci, Rc)) + { + dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + if (plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) + { + do + { + plci->li_plci_b_write_pos = (plci->li_plci_b_write_pos == 0) ? + LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1; + i = (plci->li_plci_b_write_pos == 0) ? + LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1; + } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos) + && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)); + } + break; + } + if (plci->internal_command) + return; + } + if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED)) + { + adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities & + ~B1_FACILITY_MIXER), MIXER_COMMAND_3); + } + case MIXER_COMMAND_3: + if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED)) + { + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Unload mixer failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + break; + } + if (plci->internal_command) + return; + } + break; + } + break; + } + if ((plci->li_bchannel_id == 0) + || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)) + { + dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out %d", + UnMapId(Id), (char *)(FILE_), __LINE__, (int)(plci->li_bchannel_id))); + } + else + { + i = a->li_base + (plci->li_bchannel_id - 1); + li_config_table[i].curchnl = plci->li_channel_bits; + if (!a->li_pri && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) + { + i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); + li_config_table[i].curchnl = plci->li_channel_bits; + if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) + { + i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); + li_config_table[i].curchnl = plci->li_channel_bits; + } + } + } +} + + +static void li_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci, + dword plci_b_id, byte connect, dword li_flags) +{ + word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s; + PLCI *plci_b; + DIVA_CAPI_ADAPTER *a_b; + + a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]); + plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]); + ch_a = a->li_base + (plci->li_bchannel_id - 1); + if (!a->li_pri && (plci->tel == ADV_VOICE) + && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER)) + { + ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE; + ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? + a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v; + } + else + { + ch_a_v = ch_a; + ch_a_s = ch_a; + } + ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1); + if (!a_b->li_pri && (plci_b->tel == ADV_VOICE) + && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER)) + { + ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE; + ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? + a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v; + } + else + { + ch_b_v = ch_b; + ch_b_s = ch_b; + } + if (connect) + { + li_config_table[ch_a].flag_table[ch_a_v] &= ~LI_FLAG_MONITOR; + li_config_table[ch_a].flag_table[ch_a_s] &= ~LI_FLAG_MONITOR; + li_config_table[ch_a_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); + li_config_table[ch_a_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); + } + li_config_table[ch_a].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR; + li_config_table[ch_a].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR; + li_config_table[ch_b_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); + li_config_table[ch_b_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX); + if (ch_a_v == ch_b_v) + { + li_config_table[ch_a_v].flag_table[ch_b_v] &= ~LI_FLAG_CONFERENCE; + li_config_table[ch_a_s].flag_table[ch_b_s] &= ~LI_FLAG_CONFERENCE; + } + else + { + if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE) + { + for (i = 0; i < li_total_channels; i++) + { + if (i != ch_a_v) + li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE; + } + } + if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE) + { + for (i = 0; i < li_total_channels; i++) + { + if (i != ch_a_s) + li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE; + } + } + if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE) + { + for (i = 0; i < li_total_channels; i++) + { + if (i != ch_a_v) + li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE; + } + } + if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE) + { + for (i = 0; i < li_total_channels; i++) + { + if (i != ch_a_s) + li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE; + } + } + } + if (li_flags & LI_FLAG_CONFERENCE_A_B) + { + li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; + li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; + li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; + li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; + } + if (li_flags & LI_FLAG_CONFERENCE_B_A) + { + li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; + li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; + li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; + li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; + } + if (li_flags & LI_FLAG_MONITOR_A) + { + li_config_table[ch_a].flag_table[ch_a_v] |= LI_FLAG_MONITOR; + li_config_table[ch_a].flag_table[ch_a_s] |= LI_FLAG_MONITOR; + } + if (li_flags & LI_FLAG_MONITOR_B) + { + li_config_table[ch_a].flag_table[ch_b_v] |= LI_FLAG_MONITOR; + li_config_table[ch_a].flag_table[ch_b_s] |= LI_FLAG_MONITOR; + } + if (li_flags & LI_FLAG_ANNOUNCEMENT_A) + { + li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; + li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; + } + if (li_flags & LI_FLAG_ANNOUNCEMENT_B) + { + li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; + li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT; + } + if (li_flags & LI_FLAG_MIX_A) + { + li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_MIX; + li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_MIX; + } + if (li_flags & LI_FLAG_MIX_B) + { + li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_MIX; + li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_MIX; + } + if (ch_a_v != ch_a_s) + { + li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; + li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; + } + if (ch_b_v != ch_b_s) + { + li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; + li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; + } +} + + +static void li2_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci, + dword plci_b_id, byte connect, dword li_flags) +{ + word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s; + PLCI *plci_b; + DIVA_CAPI_ADAPTER *a_b; + + a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]); + plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]); + ch_a = a->li_base + (plci->li_bchannel_id - 1); + if (!a->li_pri && (plci->tel == ADV_VOICE) + && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER)) + { + ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE; + ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? + a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v; + } + else + { + ch_a_v = ch_a; + ch_a_s = ch_a; + } + ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1); + if (!a_b->li_pri && (plci_b->tel == ADV_VOICE) + && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER)) + { + ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE; + ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ? + a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v; + } + else + { + ch_b_v = ch_b; + ch_b_s = ch_b; + } + if (connect) + { + li_config_table[ch_b].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR; + li_config_table[ch_b].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR; + li_config_table[ch_b_v].flag_table[ch_b] &= ~LI_FLAG_MIX; + li_config_table[ch_b_s].flag_table[ch_b] &= ~LI_FLAG_MIX; + li_config_table[ch_b].flag_table[ch_b] &= ~LI_FLAG_PCCONNECT; + li_config_table[ch_b].chflags &= ~(LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP); + } + li_config_table[ch_b_v].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + li_config_table[ch_b_s].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + li_config_table[ch_b_v].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + li_config_table[ch_b_s].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + li_config_table[ch_a_v].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + li_config_table[ch_a_v].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + li_config_table[ch_a_s].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + li_config_table[ch_a_s].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE); + if (li_flags & LI2_FLAG_INTERCONNECT_A_B) + { + li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT; + } + if (li_flags & LI2_FLAG_INTERCONNECT_B_A) + { + li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; + } + if (li_flags & LI2_FLAG_MONITOR_B) + { + li_config_table[ch_b].flag_table[ch_b_v] |= LI_FLAG_MONITOR; + li_config_table[ch_b].flag_table[ch_b_s] |= LI_FLAG_MONITOR; + } + if (li_flags & LI2_FLAG_MIX_B) + { + li_config_table[ch_b_v].flag_table[ch_b] |= LI_FLAG_MIX; + li_config_table[ch_b_s].flag_table[ch_b] |= LI_FLAG_MIX; + } + if (li_flags & LI2_FLAG_MONITOR_X) + li_config_table[ch_b].chflags |= LI_CHFLAG_MONITOR; + if (li_flags & LI2_FLAG_MIX_X) + li_config_table[ch_b].chflags |= LI_CHFLAG_MIX; + if (li_flags & LI2_FLAG_LOOP_B) + { + li_config_table[ch_b_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; + li_config_table[ch_b_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT; + } + if (li_flags & LI2_FLAG_LOOP_PC) + li_config_table[ch_b].flag_table[ch_b] |= LI_FLAG_PCCONNECT; + if (li_flags & LI2_FLAG_LOOP_X) + li_config_table[ch_b].chflags |= LI_CHFLAG_LOOP; + if (li_flags & LI2_FLAG_PCCONNECT_A_B) + li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_PCCONNECT; + if (li_flags & LI2_FLAG_PCCONNECT_B_A) + li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_PCCONNECT; + if (ch_a_v != ch_a_s) + { + li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE; + li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE; + } + if (ch_b_v != ch_b_s) + { + li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE; + li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE; + } +} + + +static word li_check_main_plci(dword Id, PLCI *plci) +{ + if (plci == NULL) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI", + UnMapId(Id), (char *)(FILE_), __LINE__)); + return (_WRONG_IDENTIFIER); + } + if (!plci->State + || !plci->NL.Id || plci->nl_remove_id + || (plci->li_bchannel_id == 0)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong state", + UnMapId(Id), (char *)(FILE_), __LINE__)); + return (_WRONG_STATE); + } + li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci; + return (GOOD); +} + + +static PLCI *li_check_plci_b(dword Id, PLCI *plci, + dword plci_b_id, word plci_b_write_pos, byte *p_result) +{ + byte ctlr_b; + PLCI *plci_b; + + if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : + LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) + { + dbug(1, dprintf("[%06lx] %s,%d: LI request overrun", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); + return (NULL); + } + ctlr_b = 0; + if ((plci_b_id & 0x7f) != 0) + { + ctlr_b = MapController((byte)(plci_b_id & 0x7f)); + if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL))) + ctlr_b = 0; + } + if ((ctlr_b == 0) + || (((plci_b_id >> 8) & 0xff) == 0) + || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci)) + { + dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id)); + PUT_WORD(p_result, _WRONG_IDENTIFIER); + return (NULL); + } + plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]); + if (!plci_b->State + || !plci_b->NL.Id || plci_b->nl_remove_id + || (plci_b->li_bchannel_id == 0)) + { + dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id)); + PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); + return (NULL); + } + li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci = plci_b; + if (((byte)(plci_b_id & ~EXT_CONTROLLER)) != + ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER)) + && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT))) + { + dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id)); + PUT_WORD(p_result, _WRONG_IDENTIFIER); + return (NULL); + } + if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource, + (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER)) + { + dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource)); + PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE); + return (NULL); + } + return (plci_b); +} + + +static PLCI *li2_check_plci_b(dword Id, PLCI *plci, + dword plci_b_id, word plci_b_write_pos, byte *p_result) +{ + byte ctlr_b; + PLCI *plci_b; + + if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : + LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) + { + dbug(1, dprintf("[%06lx] %s,%d: LI request overrun", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(p_result, _WRONG_STATE); + return (NULL); + } + ctlr_b = 0; + if ((plci_b_id & 0x7f) != 0) + { + ctlr_b = MapController((byte)(plci_b_id & 0x7f)); + if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL))) + ctlr_b = 0; + } + if ((ctlr_b == 0) + || (((plci_b_id >> 8) & 0xff) == 0) + || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci)) + { + dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id)); + PUT_WORD(p_result, _WRONG_IDENTIFIER); + return (NULL); + } + plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]); + if (!plci_b->State + || !plci_b->NL.Id || plci_b->nl_remove_id + || (plci_b->li_bchannel_id == 0) + || (li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci != plci_b)) + { + dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id)); + PUT_WORD(p_result, _WRONG_STATE); + return (NULL); + } + if (((byte)(plci_b_id & ~EXT_CONTROLLER)) != + ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER)) + && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT))) + { + dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id)); + PUT_WORD(p_result, _WRONG_IDENTIFIER); + return (NULL); + } + if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource, + (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER)) + { + dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d", + UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource)); + PUT_WORD(p_result, _WRONG_STATE); + return (NULL); + } + return (plci_b); +} + + +static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word Info; + word i; + dword d, li_flags, plci_b_id; + PLCI *plci_b; + API_PARSE li_parms[3]; + API_PARSE li_req_parms[3]; + API_PARSE li_participant_struct[2]; + API_PARSE li_participant_parms[3]; + word participant_parms_pos; + byte result_buffer[32]; + byte *result; + word result_pos; + word plci_b_write_pos; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_request", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + Info = GOOD; + result = result_buffer; + result_buffer[0] = 0; + if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)) + { + dbug(1, dprintf("[%06lx] %s,%d: Facility not supported", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + } + else if (api_parse(&msg[1].info[1], msg[1].length, "ws", li_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + } + else + { + result_buffer[0] = 3; + PUT_WORD(&result_buffer[1], GET_WORD(li_parms[0].info)); + result_buffer[3] = 0; + switch (GET_WORD(li_parms[0].info)) + { + case LI_GET_SUPPORTED_SERVICES: + if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) + { + result_buffer[0] = 17; + result_buffer[3] = 14; + PUT_WORD(&result_buffer[4], GOOD); + d = 0; + if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_CH) + d |= LI_CONFERENCING_SUPPORTED; + if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC) + d |= LI_MONITORING_SUPPORTED; + if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH) + d |= LI_ANNOUNCEMENTS_SUPPORTED | LI_MIXING_SUPPORTED; + if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + d |= LI_CROSS_CONTROLLER_SUPPORTED; + PUT_DWORD(&result_buffer[6], d); + if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + { + d = 0; + for (i = 0; i < li_total_channels; i++) + { + if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + && (li_config_table[i].adapter->li_pri + || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI))) + { + d++; + } + } + } + else + { + d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI; + } + PUT_DWORD(&result_buffer[10], d / 2); + PUT_DWORD(&result_buffer[14], d); + } + else + { + result_buffer[0] = 25; + result_buffer[3] = 22; + PUT_WORD(&result_buffer[4], GOOD); + d = LI2_ASYMMETRIC_SUPPORTED | LI2_B_LOOPING_SUPPORTED | LI2_X_LOOPING_SUPPORTED; + if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC) + d |= LI2_MONITORING_SUPPORTED | LI2_REMOTE_MONITORING_SUPPORTED; + if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH) + d |= LI2_MIXING_SUPPORTED | LI2_REMOTE_MIXING_SUPPORTED; + if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_PC) + d |= LI2_PC_LOOPING_SUPPORTED; + if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + d |= LI2_CROSS_CONTROLLER_SUPPORTED; + PUT_DWORD(&result_buffer[6], d); + d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI; + PUT_DWORD(&result_buffer[10], d / 2); + PUT_DWORD(&result_buffer[14], d - 1); + if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + { + d = 0; + for (i = 0; i < li_total_channels; i++) + { + if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT) + && (li_config_table[i].adapter->li_pri + || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI))) + { + d++; + } + } + } + PUT_DWORD(&result_buffer[18], d / 2); + PUT_DWORD(&result_buffer[22], d - 1); + } + break; + + case LI_REQ_CONNECT: + if (li_parms[1].length == 8) + { + appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC; + if (api_parse(&li_parms[1].info[1], li_parms[1].length, "dd", li_req_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff; + li_flags = GET_DWORD(li_req_parms[1].info); + Info = li_check_main_plci(Id, plci); + result_buffer[0] = 9; + result_buffer[3] = 6; + PUT_DWORD(&result_buffer[4], plci_b_id); + PUT_WORD(&result_buffer[8], GOOD); + if (Info != GOOD) + break; + result = plci->saved_msg.info; + for (i = 0; i <= result_buffer[0]; i++) + result[i] = result_buffer[i]; + plci_b_write_pos = plci->li_plci_b_write_pos; + plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]); + if (plci_b == NULL) + break; + li_update_connect(Id, a, plci, plci_b_id, true, li_flags); + plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG; + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + plci->li_plci_b_write_pos = plci_b_write_pos; + } + else + { + appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC; + if (api_parse(&li_parms[1].info[1], li_parms[1].length, "ds", li_req_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + li_flags = GET_DWORD(li_req_parms[0].info) & ~(LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A); + Info = li_check_main_plci(Id, plci); + result_buffer[0] = 7; + result_buffer[3] = 4; + PUT_WORD(&result_buffer[4], Info); + result_buffer[6] = 0; + if (Info != GOOD) + break; + result = plci->saved_msg.info; + for (i = 0; i <= result_buffer[0]; i++) + result[i] = result_buffer[i]; + plci_b_write_pos = plci->li_plci_b_write_pos; + participant_parms_pos = 0; + result_pos = 7; + li2_update_connect(Id, a, plci, UnMapId(Id), true, li_flags); + while (participant_parms_pos < li_req_parms[1].length) + { + result[result_pos] = 6; + result_pos += 7; + PUT_DWORD(&result[result_pos - 6], 0); + PUT_WORD(&result[result_pos - 2], GOOD); + if (api_parse(&li_req_parms[1].info[1 + participant_parms_pos], + (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); + break; + } + if (api_parse(&li_participant_struct[0].info[1], + li_participant_struct[0].length, "dd", li_participant_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); + break; + } + plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff; + li_flags = GET_DWORD(li_participant_parms[1].info); + PUT_DWORD(&result[result_pos - 6], plci_b_id); + if (sizeof(result) - result_pos < 7) + { + dbug(1, dprintf("[%06lx] %s,%d: LI result overrun", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(&result[result_pos - 2], _WRONG_STATE); + break; + } + plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]); + if (plci_b != NULL) + { + li2_update_connect(Id, a, plci, plci_b_id, true, li_flags); + plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | + ((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A | + LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG); + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + } + participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) - + (&li_req_parms[1].info[1])); + } + result[0] = (byte)(result_pos - 1); + result[3] = (byte)(result_pos - 4); + result[6] = (byte)(result_pos - 7); + i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1; + if ((plci_b_write_pos == plci->li_plci_b_read_pos) + || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) + { + plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + } + else + plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; + plci->li_plci_b_write_pos = plci_b_write_pos; + } + mixer_calculate_coefs(a); + plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; + mixer_notify_update(plci, true); + sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, + "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); + plci->command = 0; + plci->li_cmd = GET_WORD(li_parms[0].info); + start_internal_command(Id, plci, mixer_command); + return (false); + + case LI_REQ_DISCONNECT: + if (li_parms[1].length == 4) + { + appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC; + if (api_parse(&li_parms[1].info[1], li_parms[1].length, "d", li_req_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff; + Info = li_check_main_plci(Id, plci); + result_buffer[0] = 9; + result_buffer[3] = 6; + PUT_DWORD(&result_buffer[4], GET_DWORD(li_req_parms[0].info)); + PUT_WORD(&result_buffer[8], GOOD); + if (Info != GOOD) + break; + result = plci->saved_msg.info; + for (i = 0; i <= result_buffer[0]; i++) + result[i] = result_buffer[i]; + plci_b_write_pos = plci->li_plci_b_write_pos; + plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]); + if (plci_b == NULL) + break; + li_update_connect(Id, a, plci, plci_b_id, false, 0); + plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG; + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + plci->li_plci_b_write_pos = plci_b_write_pos; + } + else + { + appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC; + if (api_parse(&li_parms[1].info[1], li_parms[1].length, "s", li_req_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + break; + } + Info = li_check_main_plci(Id, plci); + result_buffer[0] = 7; + result_buffer[3] = 4; + PUT_WORD(&result_buffer[4], Info); + result_buffer[6] = 0; + if (Info != GOOD) + break; + result = plci->saved_msg.info; + for (i = 0; i <= result_buffer[0]; i++) + result[i] = result_buffer[i]; + plci_b_write_pos = plci->li_plci_b_write_pos; + participant_parms_pos = 0; + result_pos = 7; + while (participant_parms_pos < li_req_parms[0].length) + { + result[result_pos] = 6; + result_pos += 7; + PUT_DWORD(&result[result_pos - 6], 0); + PUT_WORD(&result[result_pos - 2], GOOD); + if (api_parse(&li_req_parms[0].info[1 + participant_parms_pos], + (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); + break; + } + if (api_parse(&li_participant_struct[0].info[1], + li_participant_struct[0].length, "d", li_participant_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT); + break; + } + plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff; + PUT_DWORD(&result[result_pos - 6], plci_b_id); + if (sizeof(result) - result_pos < 7) + { + dbug(1, dprintf("[%06lx] %s,%d: LI result overrun", + UnMapId(Id), (char *)(FILE_), __LINE__)); + PUT_WORD(&result[result_pos - 2], _WRONG_STATE); + break; + } + plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]); + if (plci_b != NULL) + { + li2_update_connect(Id, a, plci, plci_b_id, false, 0); + plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG; + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + } + participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) - + (&li_req_parms[0].info[1])); + } + result[0] = (byte)(result_pos - 1); + result[3] = (byte)(result_pos - 4); + result[6] = (byte)(result_pos - 7); + i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1; + if ((plci_b_write_pos == plci->li_plci_b_read_pos) + || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) + { + plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + } + else + plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; + plci->li_plci_b_write_pos = plci_b_write_pos; + } + mixer_calculate_coefs(a); + plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; + mixer_notify_update(plci, true); + sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, + "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); + plci->command = 0; + plci->li_cmd = GET_WORD(li_parms[0].info); + start_internal_command(Id, plci, mixer_command); + return (false); + + case LI_REQ_SILENT_UPDATE: + if (!plci || !plci->State + || !plci->NL.Id || plci->nl_remove_id + || (plci->li_bchannel_id == 0) + || (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci != plci)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong state", + UnMapId(Id), (char *)(FILE_), __LINE__)); + return (false); + } + plci_b_write_pos = plci->li_plci_b_write_pos; + if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : + LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2) + { + dbug(1, dprintf("[%06lx] %s,%d: LI request overrun", + UnMapId(Id), (char *)(FILE_), __LINE__)); + return (false); + } + i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1; + if ((plci_b_write_pos == plci->li_plci_b_read_pos) + || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG)) + { + plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG; + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + } + else + plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG; + plci->li_plci_b_write_pos = plci_b_write_pos; + plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel; + plci->command = 0; + plci->li_cmd = GET_WORD(li_parms[0].info); + start_internal_command(Id, plci, mixer_command); + return (false); + + default: + dbug(1, dprintf("[%06lx] %s,%d: LI unknown request %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(li_parms[0].info))); + Info = _FACILITY_NOT_SUPPORTED; + } + } + sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, + "wwS", Info, SELECTOR_LINE_INTERCONNECT, result); + return (false); +} + + +static void mixer_indication_coefs_set(dword Id, PLCI *plci) +{ + dword d; + byte result[12]; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_coefs_set", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos) + { + do + { + d = plci->li_plci_b_queue[plci->li_plci_b_read_pos]; + if (!(d & LI_PLCI_B_SKIP_FLAG)) + { + if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) + { + if (d & LI_PLCI_B_DISC_FLAG) + { + result[0] = 5; + PUT_WORD(&result[1], LI_IND_DISCONNECT); + result[3] = 2; + PUT_WORD(&result[4], _LI_USER_INITIATED); + } + else + { + result[0] = 7; + PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE); + result[3] = 4; + PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK); + } + } + else + { + if (d & LI_PLCI_B_DISC_FLAG) + { + result[0] = 9; + PUT_WORD(&result[1], LI_IND_DISCONNECT); + result[3] = 6; + PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK); + PUT_WORD(&result[8], _LI_USER_INITIATED); + } + else + { + result[0] = 7; + PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE); + result[3] = 4; + PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK); + } + } + sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, + "ws", SELECTOR_LINE_INTERCONNECT, result); + } + plci->li_plci_b_read_pos = (plci->li_plci_b_read_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? + 0 : plci->li_plci_b_read_pos + 1; + } while (!(d & LI_PLCI_B_LAST_FLAG) && (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)); + } +} + + +static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length) +{ + word i, j, ch; + struct xconnect_transfer_address_s s, *p; + DIVA_CAPI_ADAPTER *a; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_from %d", + UnMapId(Id), (char *)(FILE_), __LINE__, (int)length)); + + a = plci->adapter; + i = 1; + for (i = 1; i < length; i += 16) + { + s.card_address.low = msg[i] | (msg[i + 1] << 8) | (((dword)(msg[i + 2])) << 16) | (((dword)(msg[i + 3])) << 24); + s.card_address.high = msg[i + 4] | (msg[i + 5] << 8) | (((dword)(msg[i + 6])) << 16) | (((dword)(msg[i + 7])) << 24); + s.offset = msg[i + 8] | (msg[i + 9] << 8) | (((dword)(msg[i + 10])) << 16) | (((dword)(msg[i + 11])) << 24); + ch = msg[i + 12] | (msg[i + 13] << 8); + j = ch & XCONNECT_CHANNEL_NUMBER_MASK; + if (!a->li_pri && (plci->li_bchannel_id == 2)) + j = 1 - j; + j += a->li_base; + if (ch & XCONNECT_CHANNEL_PORT_PC) + p = &(li_config_table[j].send_pc); + else + p = &(li_config_table[j].send_b); + p->card_address.low = s.card_address.low; + p->card_address.high = s.card_address.high; + p->offset = s.offset; + li_config_table[j].channel |= LI_CHANNEL_ADDRESSES_SET; + } + if (plci->internal_command_queue[0] + && ((plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2) + || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3) + || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4))) + { + (*(plci->internal_command_queue[0]))(Id, plci, 0); + if (!plci->internal_command) + next_internal_command(Id, plci); + } + mixer_notify_update(plci, true); +} + + +static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length) +{ + + dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_to %d", + UnMapId(Id), (char *)(FILE_), __LINE__, (int) length)); + +} + + +static byte mixer_notify_source_removed(PLCI *plci, dword plci_b_id) +{ + word plci_b_write_pos; + + plci_b_write_pos = plci->li_plci_b_write_pos; + if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos : + LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 1) + { + dbug(1, dprintf("[%06lx] %s,%d: LI request overrun", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + return (false); + } + plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG; + plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1; + plci->li_plci_b_write_pos = plci_b_write_pos; + return (true); +} + + +static void mixer_remove(PLCI *plci) +{ + DIVA_CAPI_ADAPTER *a; + PLCI *notify_plci; + dword plci_b_id; + word i, j; + + dbug(1, dprintf("[%06lx] %s,%d: mixer_remove", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + + a = plci->adapter; + plci_b_id = (plci->Id << 8) | UnMapController(plci->adapter->Id); + if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED) + { + if ((plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + i = a->li_base + (plci->li_bchannel_id - 1); + if ((li_config_table[i].curchnl | li_config_table[i].channel) & LI_CHANNEL_INVOLVED) + { + for (j = 0; j < li_total_channels; j++) + { + if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT) + || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)) + { + notify_plci = li_config_table[j].plci; + if ((notify_plci != NULL) + && (notify_plci != plci) + && (notify_plci->appl != NULL) + && !(notify_plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC) + && (notify_plci->State) + && notify_plci->NL.Id && !notify_plci->nl_remove_id) + { + mixer_notify_source_removed(notify_plci, plci_b_id); + } + } + } + mixer_clear_config(plci); + mixer_calculate_coefs(a); + mixer_notify_update(plci, true); + } + li_config_table[i].plci = NULL; + plci->li_bchannel_id = 0; + } + } } @@ -12610,447 +12621,447 @@ static void mixer_remove (PLCI *plci) /*------------------------------------------------------------------*/ -static void ec_write_parameters (PLCI *plci) -{ - word w; - byte parameter_buffer[6]; - - dbug (1, dprintf ("[%06lx] %s,%d: ec_write_parameters", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - parameter_buffer[0] = 5; - parameter_buffer[1] = DSP_CTRL_SET_LEC_PARAMETERS; - PUT_WORD (¶meter_buffer[2], plci->ec_idi_options); - plci->ec_idi_options &= ~LEC_RESET_COEFFICIENTS; - w = (plci->ec_tail_length == 0) ? 128 : plci->ec_tail_length; - PUT_WORD (¶meter_buffer[4], w); - add_p (plci, FTY, parameter_buffer); - sig_req (plci, TEL_CTRL, 0); - send_req (plci); -} - - -static void ec_clear_config (PLCI *plci) +static void ec_write_parameters(PLCI *plci) { + word w; + byte parameter_buffer[6]; - dbug (1, dprintf ("[%06lx] %s,%d: ec_clear_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: ec_write_parameters", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); - plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | - LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING; - plci->ec_tail_length = 0; + parameter_buffer[0] = 5; + parameter_buffer[1] = DSP_CTRL_SET_LEC_PARAMETERS; + PUT_WORD(¶meter_buffer[2], plci->ec_idi_options); + plci->ec_idi_options &= ~LEC_RESET_COEFFICIENTS; + w = (plci->ec_tail_length == 0) ? 128 : plci->ec_tail_length; + PUT_WORD(¶meter_buffer[4], w); + add_p(plci, FTY, parameter_buffer); + sig_req(plci, TEL_CTRL, 0); + send_req(plci); } -static void ec_prepare_switch (dword Id, PLCI *plci) +static void ec_clear_config(PLCI *plci) { - dbug (1, dprintf ("[%06lx] %s,%d: ec_prepare_switch", - UnMapId (Id), (char *)(FILE_), __LINE__)); + dbug(1, dprintf("[%06lx] %s,%d: ec_clear_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | + LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING; + plci->ec_tail_length = 0; } -static word ec_save_config (dword Id, PLCI *plci, byte Rc) +static void ec_prepare_switch(dword Id, PLCI *plci) { - dbug (1, dprintf ("[%06lx] %s,%d: ec_save_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + dbug(1, dprintf("[%06lx] %s,%d: ec_prepare_switch", + UnMapId(Id), (char *)(FILE_), __LINE__)); - return (GOOD); } - - -static word ec_restore_config (dword Id, PLCI *plci, byte Rc) -{ - word Info; - - dbug (1, dprintf ("[%06lx] %s,%d: ec_restore_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - - Info = GOOD; - if (plci->B1_facilities & B1_FACILITY_EC) - { - switch (plci->adjust_b_state) - { - case ADJUST_B_RESTORE_EC_1: - plci->internal_command = plci->adjust_b_command; - if (plci->sig_req) - { - plci->adjust_b_state = ADJUST_B_RESTORE_EC_1; - break; - } - ec_write_parameters (plci); - plci->adjust_b_state = ADJUST_B_RESTORE_EC_2; - break; - case ADJUST_B_RESTORE_EC_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Restore EC failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - break; - } - } - return (Info); -} - - -static void ec_command (dword Id, PLCI *plci, byte Rc) -{ - word internal_command, Info; - byte result[8]; - - dbug (1, dprintf ("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, - plci->ec_cmd, plci->ec_idi_options, plci->ec_tail_length)); - - Info = GOOD; - if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) - { - result[0] = 2; - PUT_WORD (&result[1], EC_SUCCESS); - } - else - { - result[0] = 5; - PUT_WORD (&result[1], plci->ec_cmd); - result[3] = 2; - PUT_WORD (&result[4], GOOD); - } - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (plci->ec_cmd) - { - case EC_ENABLE_OPERATION: - case EC_FREEZE_COEFFICIENTS: - case EC_RESUME_COEFFICIENT_UPDATE: - case EC_RESET_COEFFICIENTS: - switch (internal_command) - { - default: - adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities | - B1_FACILITY_EC), EC_COMMAND_1); - case EC_COMMAND_1: - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Load EC failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - case EC_COMMAND_2: - if (plci->sig_req) - { - plci->internal_command = EC_COMMAND_2; - return; - } - plci->internal_command = EC_COMMAND_3; - ec_write_parameters (plci); - return; - case EC_COMMAND_3: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Enable EC failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - break; - } - break; - - case EC_DISABLE_OPERATION: - switch (internal_command) - { - default: - case EC_COMMAND_1: - if (plci->B1_facilities & B1_FACILITY_EC) - { - if (plci->sig_req) - { - plci->internal_command = EC_COMMAND_1; - return; - } - plci->internal_command = EC_COMMAND_2; - ec_write_parameters (plci); - return; - } - Rc = OK; - case EC_COMMAND_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Disable EC failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities & - ~B1_FACILITY_EC), EC_COMMAND_3); - case EC_COMMAND_3: - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Unload EC failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - break; - } - if (plci->internal_command) - return; - break; - } - break; - } - sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number, - "wws", Info, (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? - PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); -} - - -static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg) -{ - word Info; - word opt; - API_PARSE ec_parms[3]; - byte result[16]; - - dbug (1, dprintf ("[%06lx] %s,%d: ec_request", - UnMapId (Id), (char *)(FILE_), __LINE__)); - - Info = GOOD; - result[0] = 0; - if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER))) - { - dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _FACILITY_NOT_SUPPORTED; - } - else - { - if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) - { - if (api_parse (&msg[1].info[1], msg[1].length, "w", ec_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - } - else - { - if (plci == NULL) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_IDENTIFIER; - } - else if (!plci->State || !plci->NL.Id || plci->nl_remove_id) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_STATE; - } - else - { - plci->command = 0; - plci->ec_cmd = GET_WORD (ec_parms[0].info); - plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS); - result[0] = 2; - PUT_WORD (&result[1], EC_SUCCESS); - if (msg[1].length >= 4) - { - opt = GET_WORD (&ec_parms[0].info[2]); - plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING | - LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS); - if (!(opt & EC_DISABLE_NON_LINEAR_PROCESSING)) - plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING; - if (opt & EC_DETECT_DISABLE_TONE) - plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR; - if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS)) - plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS; - if (msg[1].length >= 6) - { - plci->ec_tail_length = GET_WORD (&ec_parms[0].info[4]); - } - } - switch (plci->ec_cmd) - { - case EC_ENABLE_OPERATION: - plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; - start_internal_command (Id, plci, ec_command); - return (FALSE); - - case EC_DISABLE_OPERATION: - plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | - LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING | - LEC_RESET_COEFFICIENTS; - start_internal_command (Id, plci, ec_command); - return (FALSE); - - case EC_FREEZE_COEFFICIENTS: - plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS; - start_internal_command (Id, plci, ec_command); - return (FALSE); - - case EC_RESUME_COEFFICIENT_UPDATE: - plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; - start_internal_command (Id, plci, ec_command); - return (FALSE); - - case EC_RESET_COEFFICIENTS: - plci->ec_idi_options |= LEC_RESET_COEFFICIENTS; - start_internal_command (Id, plci, ec_command); - return (FALSE); - - default: - dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, plci->ec_cmd)); - PUT_WORD (&result[1], EC_UNSUPPORTED_OPERATION); - } - } - } - } - else - { - if (api_parse (&msg[1].info[1], msg[1].length, "ws", ec_parms)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_MESSAGE_FORMAT; - } - else - { - if (GET_WORD (ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES) - { - result[0] = 11; - PUT_WORD (&result[1], EC_GET_SUPPORTED_SERVICES); - result[3] = 8; - PUT_WORD (&result[4], GOOD); - PUT_WORD (&result[6], 0x0007); - PUT_WORD (&result[8], LEC_MAX_SUPPORTED_TAIL_LENGTH); - PUT_WORD (&result[10], 0); - } - else if (plci == NULL) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_IDENTIFIER; - } - else if (!plci->State || !plci->NL.Id || plci->nl_remove_id) - { - dbug (1, dprintf ("[%06lx] %s,%d: Wrong state", - UnMapId (Id), (char *)(FILE_), __LINE__)); - Info = _WRONG_STATE; - } - else - { - plci->command = 0; - plci->ec_cmd = GET_WORD (ec_parms[0].info); - plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS); - result[0] = 5; - PUT_WORD (&result[1], plci->ec_cmd); - result[3] = 2; - PUT_WORD (&result[4], GOOD); - plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING | - LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS); - plci->ec_tail_length = 0; - if (ec_parms[1].length >= 2) - { - opt = GET_WORD (&ec_parms[1].info[1]); - if (opt & EC_ENABLE_NON_LINEAR_PROCESSING) - plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING; - if (opt & EC_DETECT_DISABLE_TONE) - plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR; - if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS)) - plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS; - if (ec_parms[1].length >= 4) - { - plci->ec_tail_length = GET_WORD (&ec_parms[1].info[3]); - } - } - switch (plci->ec_cmd) - { - case EC_ENABLE_OPERATION: - plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; - start_internal_command (Id, plci, ec_command); - return (FALSE); - - case EC_DISABLE_OPERATION: - plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | - LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING | - LEC_RESET_COEFFICIENTS; - start_internal_command (Id, plci, ec_command); - return (FALSE); - - default: - dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, plci->ec_cmd)); - PUT_WORD (&result[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP); - } - } - } - } - } - sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, - "wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? - PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); - return (FALSE); -} - - -static void ec_indication (dword Id, PLCI *plci, byte *msg, word length) -{ - byte result[8]; - - dbug (1, dprintf ("[%06lx] %s,%d: ec_indication", - UnMapId (Id), (char *)(FILE_), __LINE__)); - - if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE)) - { - if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) - { - result[0] = 2; - PUT_WORD (&result[1], 0); - switch (msg[1]) - { - case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ: - PUT_WORD (&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ); - break; - case LEC_DISABLE_TYPE_REVERSED_2100HZ: - PUT_WORD (&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ); - break; - case LEC_DISABLE_RELEASED: - PUT_WORD (&result[1], EC_BYPASS_RELEASED); - break; - } - } - else - { - result[0] = 5; - PUT_WORD (&result[1], EC_BYPASS_INDICATION); - result[3] = 2; - PUT_WORD (&result[4], 0); - switch (msg[1]) - { - case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ: - PUT_WORD (&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ); - break; - case LEC_DISABLE_TYPE_REVERSED_2100HZ: - PUT_WORD (&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ); - break; - case LEC_DISABLE_RELEASED: - PUT_WORD (&result[4], EC_BYPASS_RELEASED); - break; - } - } - sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? - PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); - } + + +static word ec_save_config(dword Id, PLCI *plci, byte Rc) +{ + + dbug(1, dprintf("[%06lx] %s,%d: ec_save_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + + return (GOOD); +} + + +static word ec_restore_config(dword Id, PLCI *plci, byte Rc) +{ + word Info; + + dbug(1, dprintf("[%06lx] %s,%d: ec_restore_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + + Info = GOOD; + if (plci->B1_facilities & B1_FACILITY_EC) + { + switch (plci->adjust_b_state) + { + case ADJUST_B_RESTORE_EC_1: + plci->internal_command = plci->adjust_b_command; + if (plci->sig_req) + { + plci->adjust_b_state = ADJUST_B_RESTORE_EC_1; + break; + } + ec_write_parameters(plci); + plci->adjust_b_state = ADJUST_B_RESTORE_EC_2; + break; + case ADJUST_B_RESTORE_EC_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Restore EC failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + break; + } + } + return (Info); +} + + +static void ec_command(dword Id, PLCI *plci, byte Rc) +{ + word internal_command, Info; + byte result[8]; + + dbug(1, dprintf("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command, + plci->ec_cmd, plci->ec_idi_options, plci->ec_tail_length)); + + Info = GOOD; + if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) + { + result[0] = 2; + PUT_WORD(&result[1], EC_SUCCESS); + } + else + { + result[0] = 5; + PUT_WORD(&result[1], plci->ec_cmd); + result[3] = 2; + PUT_WORD(&result[4], GOOD); + } + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (plci->ec_cmd) + { + case EC_ENABLE_OPERATION: + case EC_FREEZE_COEFFICIENTS: + case EC_RESUME_COEFFICIENT_UPDATE: + case EC_RESET_COEFFICIENTS: + switch (internal_command) + { + default: + adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities | + B1_FACILITY_EC), EC_COMMAND_1); + case EC_COMMAND_1: + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Load EC failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + if (plci->internal_command) + return; + case EC_COMMAND_2: + if (plci->sig_req) + { + plci->internal_command = EC_COMMAND_2; + return; + } + plci->internal_command = EC_COMMAND_3; + ec_write_parameters(plci); + return; + case EC_COMMAND_3: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Enable EC failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + break; + } + break; + + case EC_DISABLE_OPERATION: + switch (internal_command) + { + default: + case EC_COMMAND_1: + if (plci->B1_facilities & B1_FACILITY_EC) + { + if (plci->sig_req) + { + plci->internal_command = EC_COMMAND_1; + return; + } + plci->internal_command = EC_COMMAND_2; + ec_write_parameters(plci); + return; + } + Rc = OK; + case EC_COMMAND_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Disable EC failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities & + ~B1_FACILITY_EC), EC_COMMAND_3); + case EC_COMMAND_3: + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Unload EC failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + break; + } + if (plci->internal_command) + return; + break; + } + break; + } + sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number, + "wws", Info, (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? + PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); +} + + +static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg) +{ + word Info; + word opt; + API_PARSE ec_parms[3]; + byte result[16]; + + dbug(1, dprintf("[%06lx] %s,%d: ec_request", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + Info = GOOD; + result[0] = 0; + if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER))) + { + dbug(1, dprintf("[%06lx] %s,%d: Facility not supported", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _FACILITY_NOT_SUPPORTED; + } + else + { + if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) + { + if (api_parse(&msg[1].info[1], msg[1].length, "w", ec_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + } + else + { + if (plci == NULL) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_IDENTIFIER; + } + else if (!plci->State || !plci->NL.Id || plci->nl_remove_id) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong state", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_STATE; + } + else + { + plci->command = 0; + plci->ec_cmd = GET_WORD(ec_parms[0].info); + plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS); + result[0] = 2; + PUT_WORD(&result[1], EC_SUCCESS); + if (msg[1].length >= 4) + { + opt = GET_WORD(&ec_parms[0].info[2]); + plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING | + LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS); + if (!(opt & EC_DISABLE_NON_LINEAR_PROCESSING)) + plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING; + if (opt & EC_DETECT_DISABLE_TONE) + plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR; + if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS)) + plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS; + if (msg[1].length >= 6) + { + plci->ec_tail_length = GET_WORD(&ec_parms[0].info[4]); + } + } + switch (plci->ec_cmd) + { + case EC_ENABLE_OPERATION: + plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; + start_internal_command(Id, plci, ec_command); + return (false); + + case EC_DISABLE_OPERATION: + plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | + LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING | + LEC_RESET_COEFFICIENTS; + start_internal_command(Id, plci, ec_command); + return (false); + + case EC_FREEZE_COEFFICIENTS: + plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS; + start_internal_command(Id, plci, ec_command); + return (false); + + case EC_RESUME_COEFFICIENT_UPDATE: + plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; + start_internal_command(Id, plci, ec_command); + return (false); + + case EC_RESET_COEFFICIENTS: + plci->ec_idi_options |= LEC_RESET_COEFFICIENTS; + start_internal_command(Id, plci, ec_command); + return (false); + + default: + dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd)); + PUT_WORD(&result[1], EC_UNSUPPORTED_OPERATION); + } + } + } + } + else + { + if (api_parse(&msg[1].info[1], msg[1].length, "ws", ec_parms)) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong message format", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_MESSAGE_FORMAT; + } + else + { + if (GET_WORD(ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES) + { + result[0] = 11; + PUT_WORD(&result[1], EC_GET_SUPPORTED_SERVICES); + result[3] = 8; + PUT_WORD(&result[4], GOOD); + PUT_WORD(&result[6], 0x0007); + PUT_WORD(&result[8], LEC_MAX_SUPPORTED_TAIL_LENGTH); + PUT_WORD(&result[10], 0); + } + else if (plci == NULL) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_IDENTIFIER; + } + else if (!plci->State || !plci->NL.Id || plci->nl_remove_id) + { + dbug(1, dprintf("[%06lx] %s,%d: Wrong state", + UnMapId(Id), (char *)(FILE_), __LINE__)); + Info = _WRONG_STATE; + } + else + { + plci->command = 0; + plci->ec_cmd = GET_WORD(ec_parms[0].info); + plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS); + result[0] = 5; + PUT_WORD(&result[1], plci->ec_cmd); + result[3] = 2; + PUT_WORD(&result[4], GOOD); + plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING | + LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS); + plci->ec_tail_length = 0; + if (ec_parms[1].length >= 2) + { + opt = GET_WORD(&ec_parms[1].info[1]); + if (opt & EC_ENABLE_NON_LINEAR_PROCESSING) + plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING; + if (opt & EC_DETECT_DISABLE_TONE) + plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR; + if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS)) + plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS; + if (ec_parms[1].length >= 4) + { + plci->ec_tail_length = GET_WORD(&ec_parms[1].info[3]); + } + } + switch (plci->ec_cmd) + { + case EC_ENABLE_OPERATION: + plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS; + start_internal_command(Id, plci, ec_command); + return (false); + + case EC_DISABLE_OPERATION: + plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER | + LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING | + LEC_RESET_COEFFICIENTS; + start_internal_command(Id, plci, ec_command); + return (false); + + default: + dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd)); + PUT_WORD(&result[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP); + } + } + } + } + } + sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number, + "wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? + PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); + return (false); +} + + +static void ec_indication(dword Id, PLCI *plci, byte *msg, word length) +{ + byte result[8]; + + dbug(1, dprintf("[%06lx] %s,%d: ec_indication", + UnMapId(Id), (char *)(FILE_), __LINE__)); + + if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE)) + { + if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) + { + result[0] = 2; + PUT_WORD(&result[1], 0); + switch (msg[1]) + { + case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ: + PUT_WORD(&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ); + break; + case LEC_DISABLE_TYPE_REVERSED_2100HZ: + PUT_WORD(&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ); + break; + case LEC_DISABLE_RELEASED: + PUT_WORD(&result[1], EC_BYPASS_RELEASED); + break; + } + } + else + { + result[0] = 5; + PUT_WORD(&result[1], EC_BYPASS_INDICATION); + result[3] = 2; + PUT_WORD(&result[4], 0); + switch (msg[1]) + { + case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ: + PUT_WORD(&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ); + break; + case LEC_DISABLE_TYPE_REVERSED_2100HZ: + PUT_WORD(&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ); + break; + case LEC_DISABLE_RELEASED: + PUT_WORD(&result[4], EC_BYPASS_RELEASED); + break; + } + } + sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ? + PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result); + } } @@ -13059,279 +13070,279 @@ static void ec_indication (dword Id, PLCI *plci, byte *msg, word length) /* Advanced voice */ /*------------------------------------------------------------------*/ -static void adv_voice_write_coefs (PLCI *plci, word write_command) -{ - DIVA_CAPI_ADAPTER *a; - word i; - byte *p; +static void adv_voice_write_coefs(PLCI *plci, word write_command) +{ + DIVA_CAPI_ADAPTER *a; + word i; + byte *p; + + word w, n, j, k; + byte ch_map[MIXER_CHANNELS_BRI]; + + byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2]; + + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_write_coefs %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, write_command)); + + a = plci->adapter; + p = coef_buffer + 1; + *(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS; + i = 0; + while (i + sizeof(word) <= a->adv_voice_coef_length) + { + PUT_WORD(p, GET_WORD(a->adv_voice_coef_buffer + i)); + p += 2; + i += 2; + } + while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word)) + { + PUT_WORD(p, 0x8000); + p += 2; + i += 2; + } + + if (!a->li_pri && (plci->li_bchannel_id == 0)) + { + if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL)) + { + plci->li_bchannel_id = 1; + li_config_table[a->li_base].plci = plci; + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, plci->li_bchannel_id)); + } + else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL)) + { + plci->li_bchannel_id = 2; + li_config_table[a->li_base + 1].plci = plci; + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, plci->li_bchannel_id)); + } + } + if (!a->li_pri && (plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + i = a->li_base + (plci->li_bchannel_id - 1); + switch (write_command) + { + case ADV_VOICE_WRITE_ACTIVATION: + j = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); + k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); + if (!(plci->B1_facilities & B1_FACILITY_MIXER)) + { + li_config_table[j].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX; + li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR; + } + if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) + { + li_config_table[k].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX; + li_config_table[i].flag_table[k] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR; + li_config_table[k].flag_table[j] |= LI_FLAG_CONFERENCE; + li_config_table[j].flag_table[k] |= LI_FLAG_CONFERENCE; + } + mixer_calculate_coefs(a); + li_config_table[i].curchnl = li_config_table[i].channel; + li_config_table[j].curchnl = li_config_table[j].channel; + if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) + li_config_table[k].curchnl = li_config_table[k].channel; + break; + + case ADV_VOICE_WRITE_DEACTIVATION: + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].flag_table[j] = 0; + li_config_table[j].flag_table[i] = 0; + } + k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); + for (j = 0; j < li_total_channels; j++) + { + li_config_table[k].flag_table[j] = 0; + li_config_table[j].flag_table[k] = 0; + } + if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) + { + k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); + for (j = 0; j < li_total_channels; j++) + { + li_config_table[k].flag_table[j] = 0; + li_config_table[j].flag_table[k] = 0; + } + } + mixer_calculate_coefs(a); + break; + } + if (plci->B1_facilities & B1_FACILITY_MIXER) + { + w = 0; + if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length) + w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); + if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) + w |= MIXER_FEATURE_ENABLE_TX_DATA; + if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) + w |= MIXER_FEATURE_ENABLE_RX_DATA; + *(p++) = (byte) w; + *(p++) = (byte)(w >> 8); + for (j = 0; j < sizeof(ch_map); j += 2) + { + ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1)); + ch_map[j + 1] = (byte)(j + (2 - plci->li_bchannel_id)); + } + for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++) + { + i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; + j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; + if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) + { + *(p++) = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); + w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); + li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; + } + else + { + *(p++) = (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n < a->adv_voice_coef_length) ? + a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n] : 0x00; + } + } + } + else + { + for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++) + *(p++) = a->adv_voice_coef_buffer[i]; + } + } + else + + { + for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++) + *(p++) = a->adv_voice_coef_buffer[i]; + } + coef_buffer[0] = (p - coef_buffer) - 1; + add_p(plci, FTY, coef_buffer); + sig_req(plci, TEL_CTRL, 0); + send_req(plci); +} + + +static void adv_voice_clear_config(PLCI *plci) +{ + DIVA_CAPI_ADAPTER *a; + + word i, j; + + + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_clear_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + + a = plci->adapter; + if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) + { + a->adv_voice_coef_length = 0; + + if (!a->li_pri && (plci->li_bchannel_id != 0) + && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + i = a->li_base + (plci->li_bchannel_id - 1); + li_config_table[i].curchnl = 0; + li_config_table[i].channel = 0; + li_config_table[i].chflags = 0; + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].flag_table[j] = 0; + li_config_table[j].flag_table[i] = 0; + li_config_table[i].coef_table[j] = 0; + li_config_table[j].coef_table[i] = 0; + } + li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; + i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); + li_config_table[i].curchnl = 0; + li_config_table[i].channel = 0; + li_config_table[i].chflags = 0; + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].flag_table[j] = 0; + li_config_table[j].flag_table[i] = 0; + li_config_table[i].coef_table[j] = 0; + li_config_table[j].coef_table[i] = 0; + } + if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) + { + i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); + li_config_table[i].curchnl = 0; + li_config_table[i].channel = 0; + li_config_table[i].chflags = 0; + for (j = 0; j < li_total_channels; j++) + { + li_config_table[i].flag_table[j] = 0; + li_config_table[j].flag_table[i] = 0; + li_config_table[i].coef_table[j] = 0; + li_config_table[j].coef_table[i] = 0; + } + } + } + + } +} + + +static void adv_voice_prepare_switch(dword Id, PLCI *plci) +{ + + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_prepare_switch", + UnMapId(Id), (char *)(FILE_), __LINE__)); + +} + + +static word adv_voice_save_config(dword Id, PLCI *plci, byte Rc) +{ + + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_save_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + + return (GOOD); +} + + +static word adv_voice_restore_config(dword Id, PLCI *plci, byte Rc) +{ + DIVA_CAPI_ADAPTER *a; + word Info; - word w, n, j, k; - byte ch_map[MIXER_CHANNELS_BRI]; + dbug(1, dprintf("[%06lx] %s,%d: adv_voice_restore_config %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2]; - - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_write_coefs %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, write_command)); - - a = plci->adapter; - p = coef_buffer + 1; - *(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS; - i = 0; - while (i + sizeof(word) <= a->adv_voice_coef_length) - { - PUT_WORD (p, GET_WORD (a->adv_voice_coef_buffer + i)); - p += 2; - i += 2; - } - while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word)) - { - PUT_WORD (p, 0x8000); - p += 2; - i += 2; - } - - if (!a->li_pri && (plci->li_bchannel_id == 0)) - { - if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL)) - { - plci->li_bchannel_id = 1; - li_config_table[a->li_base].plci = plci; - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, plci->li_bchannel_id)); - } - else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL)) - { - plci->li_bchannel_id = 2; - li_config_table[a->li_base + 1].plci = plci; - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, plci->li_bchannel_id)); - } - } - if (!a->li_pri && (plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - i = a->li_base + (plci->li_bchannel_id - 1); - switch (write_command) - { - case ADV_VOICE_WRITE_ACTIVATION: - j = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); - k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); - if (!(plci->B1_facilities & B1_FACILITY_MIXER)) - { - li_config_table[j].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX; - li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR; - } - if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) - { - li_config_table[k].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX; - li_config_table[i].flag_table[k] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR; - li_config_table[k].flag_table[j] |= LI_FLAG_CONFERENCE; - li_config_table[j].flag_table[k] |= LI_FLAG_CONFERENCE; - } - mixer_calculate_coefs (a); - li_config_table[i].curchnl = li_config_table[i].channel; - li_config_table[j].curchnl = li_config_table[j].channel; - if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) - li_config_table[k].curchnl = li_config_table[k].channel; - break; - - case ADV_VOICE_WRITE_DEACTIVATION: - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].flag_table[j] = 0; - li_config_table[j].flag_table[i] = 0; - } - k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); - for (j = 0; j < li_total_channels; j++) - { - li_config_table[k].flag_table[j] = 0; - li_config_table[j].flag_table[k] = 0; - } - if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) - { - k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); - for (j = 0; j < li_total_channels; j++) - { - li_config_table[k].flag_table[j] = 0; - li_config_table[j].flag_table[k] = 0; - } - } - mixer_calculate_coefs (a); - break; - } - if (plci->B1_facilities & B1_FACILITY_MIXER) - { - w = 0; - if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length) - w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE); - if (li_config_table[i].channel & LI_CHANNEL_TX_DATA) - w |= MIXER_FEATURE_ENABLE_TX_DATA; - if (li_config_table[i].channel & LI_CHANNEL_RX_DATA) - w |= MIXER_FEATURE_ENABLE_RX_DATA; - *(p++) = (byte) w; - *(p++) = (byte)(w >> 8); - for (j = 0; j < sizeof(ch_map); j += 2) - { - ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1)); - ch_map[j+1] = (byte)(j + (2 - plci->li_bchannel_id)); - } - for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++) - { - i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch]; - j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch]; - if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED) - { - *(p++) = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01); - w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4)); - li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4; - } - else - { - *(p++) = (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n < a->adv_voice_coef_length) ? - a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n] : 0x00; - } - } - } - else - { - for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++) - *(p++) = a->adv_voice_coef_buffer[i]; - } - } - else - - { - for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++) - *(p++) = a->adv_voice_coef_buffer[i]; - } - coef_buffer[0] = (p - coef_buffer) - 1; - add_p (plci, FTY, coef_buffer); - sig_req (plci, TEL_CTRL, 0); - send_req (plci); -} - - -static void adv_voice_clear_config (PLCI *plci) -{ - DIVA_CAPI_ADAPTER *a; - - word i, j; - - - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_clear_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - a = plci->adapter; - if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) - { - a->adv_voice_coef_length = 0; - - if (!a->li_pri && (plci->li_bchannel_id != 0) - && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - i = a->li_base + (plci->li_bchannel_id - 1); - li_config_table[i].curchnl = 0; - li_config_table[i].channel = 0; - li_config_table[i].chflags = 0; - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].flag_table[j] = 0; - li_config_table[j].flag_table[i] = 0; - li_config_table[i].coef_table[j] = 0; - li_config_table[j].coef_table[i] = 0; - } - li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET; - i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1); - li_config_table[i].curchnl = 0; - li_config_table[i].channel = 0; - li_config_table[i].chflags = 0; - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].flag_table[j] = 0; - li_config_table[j].flag_table[i] = 0; - li_config_table[i].coef_table[j] = 0; - li_config_table[j].coef_table[i] = 0; - } - if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) - { - i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id); - li_config_table[i].curchnl = 0; - li_config_table[i].channel = 0; - li_config_table[i].chflags = 0; - for (j = 0; j < li_total_channels; j++) - { - li_config_table[i].flag_table[j] = 0; - li_config_table[j].flag_table[i] = 0; - li_config_table[i].coef_table[j] = 0; - li_config_table[j].coef_table[i] = 0; - } - } - } - - } -} - - -static void adv_voice_prepare_switch (dword Id, PLCI *plci) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_prepare_switch", - UnMapId (Id), (char *)(FILE_), __LINE__)); - -} - - -static word adv_voice_save_config (dword Id, PLCI *plci, byte Rc) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_save_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - - return (GOOD); -} - - -static word adv_voice_restore_config (dword Id, PLCI *plci, byte Rc) -{ - DIVA_CAPI_ADAPTER *a; - word Info; - - dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_restore_config %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - - Info = GOOD; - a = plci->adapter; - if ((plci->B1_facilities & B1_FACILITY_VOICE) - && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) - { - switch (plci->adjust_b_state) - { - case ADJUST_B_RESTORE_VOICE_1: - plci->internal_command = plci->adjust_b_command; - if (plci->sig_req) - { - plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1; - break; - } - adv_voice_write_coefs (plci, ADV_VOICE_WRITE_UPDATE); - plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2; - break; - case ADJUST_B_RESTORE_VOICE_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Restore voice config failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - break; - } - } - return (Info); + Info = GOOD; + a = plci->adapter; + if ((plci->B1_facilities & B1_FACILITY_VOICE) + && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)) + { + switch (plci->adjust_b_state) + { + case ADJUST_B_RESTORE_VOICE_1: + plci->internal_command = plci->adjust_b_command; + if (plci->sig_req) + { + plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1; + break; + } + adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE); + plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2; + break; + case ADJUST_B_RESTORE_VOICE_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Restore voice config failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + break; + } + } + return (Info); } @@ -13343,1380 +13354,1373 @@ static word adv_voice_restore_config (dword Id, PLCI *plci, byte Rc) static byte b1_facilities_table[] = { - 0x00, /* 0 No bchannel resources */ - 0x00, /* 1 Codec (automatic law) */ - 0x00, /* 2 Codec (A-law) */ - 0x00, /* 3 Codec (y-law) */ - 0x00, /* 4 HDLC for X.21 */ - 0x00, /* 5 HDLC */ - 0x00, /* 6 External Device 0 */ - 0x00, /* 7 External Device 1 */ - 0x00, /* 8 HDLC 56k */ - 0x00, /* 9 Transparent */ - 0x00, /* 10 Loopback to network */ - 0x00, /* 11 Test pattern to net */ - 0x00, /* 12 Rate adaptation sync */ - 0x00, /* 13 Rate adaptation async */ - 0x00, /* 14 R-Interface */ - 0x00, /* 15 HDLC 128k leased line */ - 0x00, /* 16 FAX */ - 0x00, /* 17 Modem async */ - 0x00, /* 18 Modem sync HDLC */ - 0x00, /* 19 V.110 async HDLC */ - 0x12, /* 20 Adv voice (Trans,mixer) */ - 0x00, /* 21 Codec connected to IC */ - 0x0c, /* 22 Trans,DTMF */ - 0x1e, /* 23 Trans,DTMF+mixer */ - 0x1f, /* 24 Trans,DTMF+mixer+local */ - 0x13, /* 25 Trans,mixer+local */ - 0x12, /* 26 HDLC,mixer */ - 0x12, /* 27 HDLC 56k,mixer */ - 0x2c, /* 28 Trans,LEC+DTMF */ - 0x3e, /* 29 Trans,LEC+DTMF+mixer */ - 0x3f, /* 30 Trans,LEC+DTMF+mixer+local */ - 0x2c, /* 31 RTP,LEC+DTMF */ - 0x3e, /* 32 RTP,LEC+DTMF+mixer */ - 0x3f, /* 33 RTP,LEC+DTMF+mixer+local */ - 0x00, /* 34 Signaling task */ - 0x00, /* 35 PIAFS */ - 0x0c, /* 36 Trans,DTMF+TONE */ - 0x1e, /* 37 Trans,DTMF+TONE+mixer */ - 0x1f /* 38 Trans,DTMF+TONE+mixer+local*/ + 0x00, /* 0 No bchannel resources */ + 0x00, /* 1 Codec (automatic law) */ + 0x00, /* 2 Codec (A-law) */ + 0x00, /* 3 Codec (y-law) */ + 0x00, /* 4 HDLC for X.21 */ + 0x00, /* 5 HDLC */ + 0x00, /* 6 External Device 0 */ + 0x00, /* 7 External Device 1 */ + 0x00, /* 8 HDLC 56k */ + 0x00, /* 9 Transparent */ + 0x00, /* 10 Loopback to network */ + 0x00, /* 11 Test pattern to net */ + 0x00, /* 12 Rate adaptation sync */ + 0x00, /* 13 Rate adaptation async */ + 0x00, /* 14 R-Interface */ + 0x00, /* 15 HDLC 128k leased line */ + 0x00, /* 16 FAX */ + 0x00, /* 17 Modem async */ + 0x00, /* 18 Modem sync HDLC */ + 0x00, /* 19 V.110 async HDLC */ + 0x12, /* 20 Adv voice (Trans,mixer) */ + 0x00, /* 21 Codec connected to IC */ + 0x0c, /* 22 Trans,DTMF */ + 0x1e, /* 23 Trans,DTMF+mixer */ + 0x1f, /* 24 Trans,DTMF+mixer+local */ + 0x13, /* 25 Trans,mixer+local */ + 0x12, /* 26 HDLC,mixer */ + 0x12, /* 27 HDLC 56k,mixer */ + 0x2c, /* 28 Trans,LEC+DTMF */ + 0x3e, /* 29 Trans,LEC+DTMF+mixer */ + 0x3f, /* 30 Trans,LEC+DTMF+mixer+local */ + 0x2c, /* 31 RTP,LEC+DTMF */ + 0x3e, /* 32 RTP,LEC+DTMF+mixer */ + 0x3f, /* 33 RTP,LEC+DTMF+mixer+local */ + 0x00, /* 34 Signaling task */ + 0x00, /* 35 PIAFS */ + 0x0c, /* 36 Trans,DTMF+TONE */ + 0x1e, /* 37 Trans,DTMF+TONE+mixer */ + 0x1f /* 38 Trans,DTMF+TONE+mixer+local*/ }; -static word get_b1_facilities (PLCI * plci, byte b1_resource) +static word get_b1_facilities(PLCI *plci, byte b1_resource) { - word b1_facilities; + word b1_facilities; - b1_facilities = b1_facilities_table[b1_resource]; - if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25)) - { + b1_facilities = b1_facilities_table[b1_resource]; + if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25)) + { - if (!(((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE)) - || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id-1] & (1L << PRIVATE_DTMF_TONE))))) + if (!(((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE)) + || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE))))) - { - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND) - b1_facilities |= B1_FACILITY_DTMFX; - if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE) - b1_facilities |= B1_FACILITY_DTMFR; - } - } - if ((b1_resource == 17) || (b1_resource == 18)) - { - if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN)) - b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR; - } + { + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND) + b1_facilities |= B1_FACILITY_DTMFX; + if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE) + b1_facilities |= B1_FACILITY_DTMFR; + } + } + if ((b1_resource == 17) || (b1_resource == 18)) + { + if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN)) + b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR; + } /* - dbug (1, dprintf ("[%06lx] %s,%d: get_b1_facilities %d %04x", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char far *)(FILE_), __LINE__, b1_resource, b1_facilites)); + dbug (1, dprintf("[%06lx] %s,%d: get_b1_facilities %d %04x", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char far *)(FILE_), __LINE__, b1_resource, b1_facilites)); */ - return (b1_facilities); -} - - -static byte add_b1_facilities (PLCI * plci, byte b1_resource, word b1_facilities) -{ - byte b; - - switch (b1_resource) - { - case 5: - case 26: - if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) - b = 26; - else - b = 5; - break; - - case 8: - case 27: - if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) - b = 27; - else - b = 8; - break; - - case 9: - case 20: - case 22: - case 23: - case 24: - case 25: - case 28: - case 29: - case 30: - case 36: - case 37: - case 38: - if (b1_facilities & B1_FACILITY_EC) - { - if (b1_facilities & B1_FACILITY_LOCAL) - b = 30; - else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) - b = 29; - else - b = 28; - } - - else if ((b1_facilities & (B1_FACILITY_DTMFX | B1_FACILITY_DTMFR | B1_FACILITY_MIXER)) - && (((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE)) - || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id-1] & (1L << PRIVATE_DTMF_TONE))))) - { - if (b1_facilities & B1_FACILITY_LOCAL) - b = 38; - else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) - b = 37; - else - b = 36; - } - - else if (((plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF) - && !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) - || ((b1_facilities & B1_FACILITY_DTMFR) - && ((b1_facilities & B1_FACILITY_MIXER) - || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))) - || ((b1_facilities & B1_FACILITY_DTMFX) - && ((b1_facilities & B1_FACILITY_MIXER) - || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND)))) - { - if (b1_facilities & B1_FACILITY_LOCAL) - b = 24; - else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) - b = 23; - else - b = 22; - } - else - { - if (b1_facilities & B1_FACILITY_LOCAL) - b = 25; - else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) - b = 20; - else - b = 9; - } - break; - - case 31: - case 32: - case 33: - if (b1_facilities & B1_FACILITY_LOCAL) - b = 33; - else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) - b = 32; - else - b = 31; - break; - - default: - b = b1_resource; - } - dbug (1, dprintf ("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, - b1_resource, b1_facilities, b, get_b1_facilities (plci, b))); - return (b); -} - - -static void adjust_b1_facilities (PLCI *plci, byte new_b1_resource, word new_b1_facilities) -{ - word removed_facilities; - - dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__, new_b1_resource, new_b1_facilities, - new_b1_facilities & get_b1_facilities (plci, new_b1_resource))); - - new_b1_facilities &= get_b1_facilities (plci, new_b1_resource); - removed_facilities = plci->B1_facilities & ~new_b1_facilities; - - if (removed_facilities & B1_FACILITY_EC) - ec_clear_config (plci); - - - if (removed_facilities & B1_FACILITY_DTMFR) - { - dtmf_rec_clear_config (plci); - dtmf_parameter_clear_config (plci); - } - if (removed_facilities & B1_FACILITY_DTMFX) - dtmf_send_clear_config (plci); - - - if (removed_facilities & B1_FACILITY_MIXER) - mixer_clear_config (plci); - - if (removed_facilities & B1_FACILITY_VOICE) - adv_voice_clear_config (plci); - plci->B1_facilities = new_b1_facilities; -} - - -static void adjust_b_clear (PLCI *plci) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_clear", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - plci->adjust_b_restore = FALSE; -} - - -static word adjust_b_process (dword Id, PLCI *plci, byte Rc) -{ - word Info; - byte b1_resource; - NCCI * ncci_ptr; - API_PARSE bp[2]; - - dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_process %02x %d", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); - - Info = GOOD; - switch (plci->adjust_b_state) - { - case ADJUST_B_START: - if ((plci->adjust_b_parms_msg == NULL) - && (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1) - && ((plci->adjust_b_mode & ~(ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | - ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_RESTORE)) == 0)) - { - b1_resource = (plci->adjust_b_mode == ADJUST_B_MODE_NO_RESOURCE) ? - 0 : add_b1_facilities (plci, plci->B1_resource, plci->adjust_b_facilities); - if (b1_resource == plci->B1_resource) - { - adjust_b1_facilities (plci, b1_resource, plci->adjust_b_facilities); - break; - } - if (plci->adjust_b_facilities & ~get_b1_facilities (plci, b1_resource)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, - plci->B1_resource, b1_resource, plci->adjust_b_facilities)); - Info = _WRONG_STATE; - break; - } - } - if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) - { - - mixer_prepare_switch (Id, plci); - - - dtmf_prepare_switch (Id, plci); - dtmf_parameter_prepare_switch (Id, plci); - - - ec_prepare_switch (Id, plci); - - adv_voice_prepare_switch (Id, plci); - } - plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1; - Rc = OK; - case ADJUST_B_SAVE_MIXER_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) - { - - Info = mixer_save_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1; - Rc = OK; - case ADJUST_B_SAVE_DTMF_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) - { - - Info = dtmf_save_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_REMOVE_L23_1; - case ADJUST_B_REMOVE_L23_1: - if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23) - && plci->NL.Id && !plci->nl_remove_id) - { - plci->internal_command = plci->adjust_b_command; - if (plci->adjust_b_ncci != 0) - { - ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]); - while (ncci_ptr->data_pending) - { - plci->data_sent_ptr = ncci_ptr->DBuffer[ncci_ptr->data_out].P; - data_rc (plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]); - } - while (ncci_ptr->data_ack_pending) - data_ack (plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]); - } - nl_req_ncci (plci, REMOVE, - (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0)); - send_req (plci); - plci->adjust_b_state = ADJUST_B_REMOVE_L23_2; - break; - } - plci->adjust_b_state = ADJUST_B_REMOVE_L23_2; - Rc = OK; - case ADJUST_B_REMOVE_L23_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B remove failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23) - { - if (plci_nl_busy (plci)) - { - plci->internal_command = plci->adjust_b_command; - break; - } - } - plci->adjust_b_state = ADJUST_B_SAVE_EC_1; - Rc = OK; - case ADJUST_B_SAVE_EC_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) - { - - Info = ec_save_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1; - Rc = OK; - case ADJUST_B_SAVE_DTMF_PARAMETER_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) - { - - Info = dtmf_parameter_save_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1; - Rc = OK; - case ADJUST_B_SAVE_VOICE_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) - { - Info = adv_voice_save_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - } - plci->adjust_b_state = ADJUST_B_SWITCH_L1_1; - case ADJUST_B_SWITCH_L1_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1) - { - if (plci->sig_req) - { - plci->internal_command = plci->adjust_b_command; - break; - } - if (plci->adjust_b_parms_msg != NULL) - api_load_msg (plci->adjust_b_parms_msg, bp); - else - api_load_msg (&plci->B_protocol, bp); - Info = add_b1 (plci, bp, - (word)((plci->adjust_b_mode & ADJUST_B_MODE_NO_RESOURCE) ? 2 : 0), - plci->adjust_b_facilities); - if (Info != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, - plci->B1_resource, plci->adjust_b_facilities)); - break; - } - plci->internal_command = plci->adjust_b_command; - sig_req (plci, RESOURCES, 0); - send_req (plci); - plci->adjust_b_state = ADJUST_B_SWITCH_L1_2; - break; - } - plci->adjust_b_state = ADJUST_B_SWITCH_L1_2; - Rc = OK; - case ADJUST_B_SWITCH_L1_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, - Rc, plci->B1_resource, plci->adjust_b_facilities)); - Info = _WRONG_STATE; - break; - } - plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1; - Rc = OK; - case ADJUST_B_RESTORE_VOICE_1: - case ADJUST_B_RESTORE_VOICE_2: - if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) - { - Info = adv_voice_restore_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - } - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1; - Rc = OK; - case ADJUST_B_RESTORE_DTMF_PARAMETER_1: - case ADJUST_B_RESTORE_DTMF_PARAMETER_2: - if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) - { - - Info = dtmf_parameter_restore_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_RESTORE_EC_1; - Rc = OK; - case ADJUST_B_RESTORE_EC_1: - case ADJUST_B_RESTORE_EC_2: - if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) - { - - Info = ec_restore_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1; - case ADJUST_B_ASSIGN_L23_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23) - { - if (plci_nl_busy (plci)) - { - plci->internal_command = plci->adjust_b_command; - break; - } - if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) - plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; - if (plci->adjust_b_parms_msg != NULL) - api_load_msg (plci->adjust_b_parms_msg, bp); - else - api_load_msg (&plci->B_protocol, bp); - Info = add_b23 (plci, bp); - if (Info != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Info)); - break; - } - plci->internal_command = plci->adjust_b_command; - nl_req_ncci (plci, ASSIGN, 0); - send_req (plci); - plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2; - break; - } - plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2; - Rc = ASSIGN_OK; - case ADJUST_B_ASSIGN_L23_2: - if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B assign failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23) - { - if (Rc != ASSIGN_OK) - { - plci->internal_command = plci->adjust_b_command; - break; - } - } - if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT) - { - plci->adjust_b_restore = TRUE; - break; - } - plci->adjust_b_state = ADJUST_B_CONNECT_1; - case ADJUST_B_CONNECT_1: - if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) - { - plci->internal_command = plci->adjust_b_command; - if (plci_nl_busy (plci)) - break; - nl_req_ncci (plci, N_CONNECT, 0); - send_req (plci); - plci->adjust_b_state = ADJUST_B_CONNECT_2; - break; - } - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; - Rc = OK; - case ADJUST_B_CONNECT_2: - case ADJUST_B_CONNECT_3: - case ADJUST_B_CONNECT_4: - if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B connect failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - if (Rc == OK) - { - if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) - { - get_ncci (plci, (byte)(Id >> 16), plci->adjust_b_ncci); - Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16); - } - if (plci->adjust_b_state == ADJUST_B_CONNECT_2) - plci->adjust_b_state = ADJUST_B_CONNECT_3; - else if (plci->adjust_b_state == ADJUST_B_CONNECT_4) - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; - } - else if (Rc == 0) - { - if (plci->adjust_b_state == ADJUST_B_CONNECT_2) - plci->adjust_b_state = ADJUST_B_CONNECT_4; - else if (plci->adjust_b_state == ADJUST_B_CONNECT_3) - plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; - } - if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1) - { - plci->internal_command = plci->adjust_b_command; - break; - } - Rc = OK; - case ADJUST_B_RESTORE_DTMF_1: - case ADJUST_B_RESTORE_DTMF_2: - if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) - { - - Info = dtmf_restore_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1; - Rc = OK; - case ADJUST_B_RESTORE_MIXER_1: - case ADJUST_B_RESTORE_MIXER_2: - case ADJUST_B_RESTORE_MIXER_3: - case ADJUST_B_RESTORE_MIXER_4: - case ADJUST_B_RESTORE_MIXER_5: - case ADJUST_B_RESTORE_MIXER_6: - case ADJUST_B_RESTORE_MIXER_7: - if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) - { - - Info = mixer_restore_config (Id, plci, Rc); - if ((Info != GOOD) || plci->internal_command) - break; - - } - plci->adjust_b_state = ADJUST_B_END; - case ADJUST_B_END: - break; - } - return (Info); -} - - -static void adjust_b1_resource (dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_resource %d %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, - plci->B1_resource, b1_facilities)); - - plci->adjust_b_parms_msg = bp_msg; - plci->adjust_b_facilities = b1_facilities; - plci->adjust_b_command = internal_command; - plci->adjust_b_ncci = (word)(Id >> 16); - if ((bp_msg == NULL) && (plci->B1_resource == 0)) - plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_SWITCH_L1; - else - plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | ADJUST_B_MODE_RESTORE; - plci->adjust_b_state = ADJUST_B_START; - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B1 resource %d %04x...", - UnMapId (Id), (char *)(FILE_), __LINE__, - plci->B1_resource, b1_facilities)); -} - - -static void adjust_b_restore (dword Id, PLCI *plci, byte Rc) -{ - word internal_command; - - dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_restore %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - if (plci->req_in != 0) - { - plci->internal_command = ADJUST_B_RESTORE_1; - break; - } - Rc = OK; - case ADJUST_B_RESTORE_1: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B enqueued failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - } - plci->adjust_b_parms_msg = NULL; - plci->adjust_b_facilities = plci->B1_facilities; - plci->adjust_b_command = ADJUST_B_RESTORE_2; - plci->adjust_b_ncci = (word)(Id >> 16); - plci->adjust_b_mode = ADJUST_B_MODE_RESTORE; - plci->adjust_b_state = ADJUST_B_START; - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore...", - UnMapId (Id), (char *)(FILE_), __LINE__)); - case ADJUST_B_RESTORE_2: - if (adjust_b_process (Id, plci, Rc) != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - } - if (plci->internal_command) - break; - break; - } -} - - -static void reset_b3_command (dword Id, PLCI *plci, byte Rc) -{ - word Info; - word internal_command; - - dbug (1, dprintf ("[%06lx] %s,%d: reset_b3_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - plci->adjust_b_parms_msg = NULL; - plci->adjust_b_facilities = plci->B1_facilities; - plci->adjust_b_command = RESET_B3_COMMAND_1; - plci->adjust_b_ncci = (word)(Id >> 16); - plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_CONNECT; - plci->adjust_b_state = ADJUST_B_START; - dbug (1, dprintf ("[%06lx] %s,%d: Reset B3...", - UnMapId (Id), (char *)(FILE_), __LINE__)); - case RESET_B3_COMMAND_1: - Info = adjust_b_process (Id, plci, Rc); - if (Info != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Reset failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - break; - } - if (plci->internal_command) - return; - break; - } + return (b1_facilities); +} + + +static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities) +{ + byte b; + + switch (b1_resource) + { + case 5: + case 26: + if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) + b = 26; + else + b = 5; + break; + + case 8: + case 27: + if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) + b = 27; + else + b = 8; + break; + + case 9: + case 20: + case 22: + case 23: + case 24: + case 25: + case 28: + case 29: + case 30: + case 36: + case 37: + case 38: + if (b1_facilities & B1_FACILITY_EC) + { + if (b1_facilities & B1_FACILITY_LOCAL) + b = 30; + else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) + b = 29; + else + b = 28; + } + + else if ((b1_facilities & (B1_FACILITY_DTMFX | B1_FACILITY_DTMFR | B1_FACILITY_MIXER)) + && (((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE)) + || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE))))) + { + if (b1_facilities & B1_FACILITY_LOCAL) + b = 38; + else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) + b = 37; + else + b = 36; + } + + else if (((plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF) + && !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)) + || ((b1_facilities & B1_FACILITY_DTMFR) + && ((b1_facilities & B1_FACILITY_MIXER) + || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))) + || ((b1_facilities & B1_FACILITY_DTMFX) + && ((b1_facilities & B1_FACILITY_MIXER) + || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND)))) + { + if (b1_facilities & B1_FACILITY_LOCAL) + b = 24; + else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) + b = 23; + else + b = 22; + } + else + { + if (b1_facilities & B1_FACILITY_LOCAL) + b = 25; + else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) + b = 20; + else + b = 9; + } + break; + + case 31: + case 32: + case 33: + if (b1_facilities & B1_FACILITY_LOCAL) + b = 33; + else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE)) + b = 32; + else + b = 31; + break; + + default: + b = b1_resource; + } + dbug(1, dprintf("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, + b1_resource, b1_facilities, b, get_b1_facilities(plci, b))); + return (b); +} + + +static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities) +{ + word removed_facilities; + + dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__, new_b1_resource, new_b1_facilities, + new_b1_facilities & get_b1_facilities(plci, new_b1_resource))); + + new_b1_facilities &= get_b1_facilities(plci, new_b1_resource); + removed_facilities = plci->B1_facilities & ~new_b1_facilities; + + if (removed_facilities & B1_FACILITY_EC) + ec_clear_config(plci); + + + if (removed_facilities & B1_FACILITY_DTMFR) + { + dtmf_rec_clear_config(plci); + dtmf_parameter_clear_config(plci); + } + if (removed_facilities & B1_FACILITY_DTMFX) + dtmf_send_clear_config(plci); + + + if (removed_facilities & B1_FACILITY_MIXER) + mixer_clear_config(plci); + + if (removed_facilities & B1_FACILITY_VOICE) + adv_voice_clear_config(plci); + plci->B1_facilities = new_b1_facilities; +} + + +static void adjust_b_clear(PLCI *plci) +{ + + dbug(1, dprintf("[%06lx] %s,%d: adjust_b_clear", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + + plci->adjust_b_restore = false; +} + + +static word adjust_b_process(dword Id, PLCI *plci, byte Rc) +{ + word Info; + byte b1_resource; + NCCI *ncci_ptr; + API_PARSE bp[2]; + + dbug(1, dprintf("[%06lx] %s,%d: adjust_b_process %02x %d", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state)); + + Info = GOOD; + switch (plci->adjust_b_state) + { + case ADJUST_B_START: + if ((plci->adjust_b_parms_msg == NULL) + && (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1) + && ((plci->adjust_b_mode & ~(ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | + ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_RESTORE)) == 0)) + { + b1_resource = (plci->adjust_b_mode == ADJUST_B_MODE_NO_RESOURCE) ? + 0 : add_b1_facilities(plci, plci->B1_resource, plci->adjust_b_facilities); + if (b1_resource == plci->B1_resource) + { + adjust_b1_facilities(plci, b1_resource, plci->adjust_b_facilities); + break; + } + if (plci->adjust_b_facilities & ~get_b1_facilities(plci, b1_resource)) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, + plci->B1_resource, b1_resource, plci->adjust_b_facilities)); + Info = _WRONG_STATE; + break; + } + } + if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) + { + + mixer_prepare_switch(Id, plci); + + + dtmf_prepare_switch(Id, plci); + dtmf_parameter_prepare_switch(Id, plci); + + + ec_prepare_switch(Id, plci); + + adv_voice_prepare_switch(Id, plci); + } + plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1; + Rc = OK; + case ADJUST_B_SAVE_MIXER_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) + { + + Info = mixer_save_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1; + Rc = OK; + case ADJUST_B_SAVE_DTMF_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) + { + + Info = dtmf_save_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_REMOVE_L23_1; + case ADJUST_B_REMOVE_L23_1: + if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23) + && plci->NL.Id && !plci->nl_remove_id) + { + plci->internal_command = plci->adjust_b_command; + if (plci->adjust_b_ncci != 0) + { + ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]); + while (ncci_ptr->data_pending) + { + plci->data_sent_ptr = ncci_ptr->DBuffer[ncci_ptr->data_out].P; + data_rc(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]); + } + while (ncci_ptr->data_ack_pending) + data_ack(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]); + } + nl_req_ncci(plci, REMOVE, + (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0)); + send_req(plci); + plci->adjust_b_state = ADJUST_B_REMOVE_L23_2; + break; + } + plci->adjust_b_state = ADJUST_B_REMOVE_L23_2; + Rc = OK; + case ADJUST_B_REMOVE_L23_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B remove failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23) + { + if (plci_nl_busy(plci)) + { + plci->internal_command = plci->adjust_b_command; + break; + } + } + plci->adjust_b_state = ADJUST_B_SAVE_EC_1; + Rc = OK; + case ADJUST_B_SAVE_EC_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) + { + + Info = ec_save_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1; + Rc = OK; + case ADJUST_B_SAVE_DTMF_PARAMETER_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) + { + + Info = dtmf_parameter_save_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1; + Rc = OK; + case ADJUST_B_SAVE_VOICE_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE) + { + Info = adv_voice_save_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + } + plci->adjust_b_state = ADJUST_B_SWITCH_L1_1; + case ADJUST_B_SWITCH_L1_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1) + { + if (plci->sig_req) + { + plci->internal_command = plci->adjust_b_command; + break; + } + if (plci->adjust_b_parms_msg != NULL) + api_load_msg(plci->adjust_b_parms_msg, bp); + else + api_load_msg(&plci->B_protocol, bp); + Info = add_b1(plci, bp, + (word)((plci->adjust_b_mode & ADJUST_B_MODE_NO_RESOURCE) ? 2 : 0), + plci->adjust_b_facilities); + if (Info != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, + plci->B1_resource, plci->adjust_b_facilities)); + break; + } + plci->internal_command = plci->adjust_b_command; + sig_req(plci, RESOURCES, 0); + send_req(plci); + plci->adjust_b_state = ADJUST_B_SWITCH_L1_2; + break; + } + plci->adjust_b_state = ADJUST_B_SWITCH_L1_2; + Rc = OK; + case ADJUST_B_SWITCH_L1_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, + Rc, plci->B1_resource, plci->adjust_b_facilities)); + Info = _WRONG_STATE; + break; + } + plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1; + Rc = OK; + case ADJUST_B_RESTORE_VOICE_1: + case ADJUST_B_RESTORE_VOICE_2: + if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) + { + Info = adv_voice_restore_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + } + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1; + Rc = OK; + case ADJUST_B_RESTORE_DTMF_PARAMETER_1: + case ADJUST_B_RESTORE_DTMF_PARAMETER_2: + if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) + { + + Info = dtmf_parameter_restore_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_RESTORE_EC_1; + Rc = OK; + case ADJUST_B_RESTORE_EC_1: + case ADJUST_B_RESTORE_EC_2: + if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) + { + + Info = ec_restore_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1; + case ADJUST_B_ASSIGN_L23_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23) + { + if (plci_nl_busy(plci)) + { + plci->internal_command = plci->adjust_b_command; + break; + } + if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) + plci->call_dir |= CALL_DIR_FORCE_OUTG_NL; + if (plci->adjust_b_parms_msg != NULL) + api_load_msg(plci->adjust_b_parms_msg, bp); + else + api_load_msg(&plci->B_protocol, bp); + Info = add_b23(plci, bp); + if (Info != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Info)); + break; + } + plci->internal_command = plci->adjust_b_command; + nl_req_ncci(plci, ASSIGN, 0); + send_req(plci); + plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2; + break; + } + plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2; + Rc = ASSIGN_OK; + case ADJUST_B_ASSIGN_L23_2: + if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK)) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B assign failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23) + { + if (Rc != ASSIGN_OK) + { + plci->internal_command = plci->adjust_b_command; + break; + } + } + if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT) + { + plci->adjust_b_restore = true; + break; + } + plci->adjust_b_state = ADJUST_B_CONNECT_1; + case ADJUST_B_CONNECT_1: + if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) + { + plci->internal_command = plci->adjust_b_command; + if (plci_nl_busy(plci)) + break; + nl_req_ncci(plci, N_CONNECT, 0); + send_req(plci); + plci->adjust_b_state = ADJUST_B_CONNECT_2; + break; + } + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; + Rc = OK; + case ADJUST_B_CONNECT_2: + case ADJUST_B_CONNECT_3: + case ADJUST_B_CONNECT_4: + if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B connect failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + if (Rc == OK) + { + if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) + { + get_ncci(plci, (byte)(Id >> 16), plci->adjust_b_ncci); + Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16); + } + if (plci->adjust_b_state == ADJUST_B_CONNECT_2) + plci->adjust_b_state = ADJUST_B_CONNECT_3; + else if (plci->adjust_b_state == ADJUST_B_CONNECT_4) + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; + } + else if (Rc == 0) + { + if (plci->adjust_b_state == ADJUST_B_CONNECT_2) + plci->adjust_b_state = ADJUST_B_CONNECT_4; + else if (plci->adjust_b_state == ADJUST_B_CONNECT_3) + plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1; + } + if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1) + { + plci->internal_command = plci->adjust_b_command; + break; + } + Rc = OK; + case ADJUST_B_RESTORE_DTMF_1: + case ADJUST_B_RESTORE_DTMF_2: + if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) + { + + Info = dtmf_restore_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1; + Rc = OK; + case ADJUST_B_RESTORE_MIXER_1: + case ADJUST_B_RESTORE_MIXER_2: + case ADJUST_B_RESTORE_MIXER_3: + case ADJUST_B_RESTORE_MIXER_4: + case ADJUST_B_RESTORE_MIXER_5: + case ADJUST_B_RESTORE_MIXER_6: + case ADJUST_B_RESTORE_MIXER_7: + if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE) + { + + Info = mixer_restore_config(Id, plci, Rc); + if ((Info != GOOD) || plci->internal_command) + break; + + } + plci->adjust_b_state = ADJUST_B_END; + case ADJUST_B_END: + break; + } + return (Info); +} + + +static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command) +{ + + dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_resource %d %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, + plci->B1_resource, b1_facilities)); + + plci->adjust_b_parms_msg = bp_msg; + plci->adjust_b_facilities = b1_facilities; + plci->adjust_b_command = internal_command; + plci->adjust_b_ncci = (word)(Id >> 16); + if ((bp_msg == NULL) && (plci->B1_resource == 0)) + plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_SWITCH_L1; + else + plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | ADJUST_B_MODE_RESTORE; + plci->adjust_b_state = ADJUST_B_START; + dbug(1, dprintf("[%06lx] %s,%d: Adjust B1 resource %d %04x...", + UnMapId(Id), (char *)(FILE_), __LINE__, + plci->B1_resource, b1_facilities)); +} + + +static void adjust_b_restore(dword Id, PLCI *plci, byte Rc) +{ + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: adjust_b_restore %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + if (plci->req_in != 0) + { + plci->internal_command = ADJUST_B_RESTORE_1; + break; + } + Rc = OK; + case ADJUST_B_RESTORE_1: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B enqueued failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + } + plci->adjust_b_parms_msg = NULL; + plci->adjust_b_facilities = plci->B1_facilities; + plci->adjust_b_command = ADJUST_B_RESTORE_2; + plci->adjust_b_ncci = (word)(Id >> 16); + plci->adjust_b_mode = ADJUST_B_MODE_RESTORE; + plci->adjust_b_state = ADJUST_B_START; + dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore...", + UnMapId(Id), (char *)(FILE_), __LINE__)); + case ADJUST_B_RESTORE_2: + if (adjust_b_process(Id, plci, Rc) != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + } + if (plci->internal_command) + break; + break; + } +} + + +static void reset_b3_command(dword Id, PLCI *plci, byte Rc) +{ + word Info; + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: reset_b3_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + Info = GOOD; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + plci->adjust_b_parms_msg = NULL; + plci->adjust_b_facilities = plci->B1_facilities; + plci->adjust_b_command = RESET_B3_COMMAND_1; + plci->adjust_b_ncci = (word)(Id >> 16); + plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_CONNECT; + plci->adjust_b_state = ADJUST_B_START; + dbug(1, dprintf("[%06lx] %s,%d: Reset B3...", + UnMapId(Id), (char *)(FILE_), __LINE__)); + case RESET_B3_COMMAND_1: + Info = adjust_b_process(Id, plci, Rc); + if (Info != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Reset failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + break; + } + if (plci->internal_command) + return; + break; + } /* sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/ - sendf(plci->appl,_RESET_B3_I,Id,0,"s",""); + sendf(plci->appl, _RESET_B3_I, Id, 0, "s", ""); +} + + +static void select_b_command(dword Id, PLCI *plci, byte Rc) +{ + word Info; + word internal_command; + byte esc_chi[3]; + + dbug(1, dprintf("[%06lx] %s,%d: select_b_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + Info = GOOD; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + plci->adjust_b_parms_msg = &plci->saved_msg; + if ((plci->tel == ADV_VOICE) && (plci == plci->adapter->AdvSignalPLCI)) + plci->adjust_b_facilities = plci->B1_facilities | B1_FACILITY_VOICE; + else + plci->adjust_b_facilities = plci->B1_facilities & ~B1_FACILITY_VOICE; + plci->adjust_b_command = SELECT_B_COMMAND_1; + plci->adjust_b_ncci = (word)(Id >> 16); + if (plci->saved_msg.parms[0].length == 0) + { + plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 | + ADJUST_B_MODE_NO_RESOURCE; + } + else + { + plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 | + ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE; + } + plci->adjust_b_state = ADJUST_B_START; + dbug(1, dprintf("[%06lx] %s,%d: Select B protocol...", + UnMapId(Id), (char *)(FILE_), __LINE__)); + case SELECT_B_COMMAND_1: + Info = adjust_b_process(Id, plci, Rc); + if (Info != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: Select B protocol failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + break; + } + if (plci->internal_command) + return; + if (plci->tel == ADV_VOICE) + { + esc_chi[0] = 0x02; + esc_chi[1] = 0x18; + esc_chi[2] = plci->b_channel; + SetVoiceChannel(plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter); + } + break; + } + sendf(plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info); +} + + +static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc) +{ + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: fax_connect_ack_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + case FAX_CONNECT_ACK_COMMAND_1: + if (plci_nl_busy(plci)) + { + plci->internal_command = FAX_CONNECT_ACK_COMMAND_1; + return; + } + plci->internal_command = FAX_CONNECT_ACK_COMMAND_2; + plci->NData[0].P = plci->fax_connect_info_buffer; + plci->NData[0].PLength = plci->fax_connect_info_length; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_CONNECT_ACK; + plci->adapter->request(&plci->NL); + return; + case FAX_CONNECT_ACK_COMMAND_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + break; + } + } + if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) + && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) + { + if (plci->B3_prot == 4) + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + else + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer); + plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; + } +} + + +static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc) +{ + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: fax_edata_ack_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + case FAX_EDATA_ACK_COMMAND_1: + if (plci_nl_busy(plci)) + { + plci->internal_command = FAX_EDATA_ACK_COMMAND_1; + return; + } + plci->internal_command = FAX_EDATA_ACK_COMMAND_2; + plci->NData[0].P = plci->fax_connect_info_buffer; + plci->NData[0].PLength = plci->fax_edata_ack_length; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_EDATA; + plci->adapter->request(&plci->NL); + return; + case FAX_EDATA_ACK_COMMAND_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + break; + } + } +} + + +static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc) +{ + word Info; + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: fax_connect_info_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + Info = GOOD; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + case FAX_CONNECT_INFO_COMMAND_1: + if (plci_nl_busy(plci)) + { + plci->internal_command = FAX_CONNECT_INFO_COMMAND_1; + return; + } + plci->internal_command = FAX_CONNECT_INFO_COMMAND_2; + plci->NData[0].P = plci->fax_connect_info_buffer; + plci->NData[0].PLength = plci->fax_connect_info_length; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_EDATA; + plci->adapter->request(&plci->NL); + return; + case FAX_CONNECT_INFO_COMMAND_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: FAX setting connect info failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + if (plci_nl_busy(plci)) + { + plci->internal_command = FAX_CONNECT_INFO_COMMAND_2; + return; + } + plci->command = _CONNECT_B3_R; + nl_req_ncci(plci, N_CONNECT, 0); + send_req(plci); + return; + } + sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); +} + + +static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc) +{ + word Info; + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + Info = GOOD; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + plci->adjust_b_parms_msg = NULL; + plci->adjust_b_facilities = plci->B1_facilities; + plci->adjust_b_command = FAX_ADJUST_B23_COMMAND_1; + plci->adjust_b_ncci = (word)(Id >> 16); + plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23; + plci->adjust_b_state = ADJUST_B_START; + dbug(1, dprintf("[%06lx] %s,%d: FAX adjust B23...", + UnMapId(Id), (char *)(FILE_), __LINE__)); + case FAX_ADJUST_B23_COMMAND_1: + Info = adjust_b_process(Id, plci, Rc); + if (Info != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: FAX adjust failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + break; + } + if (plci->internal_command) + return; + case FAX_ADJUST_B23_COMMAND_2: + if (plci_nl_busy(plci)) + { + plci->internal_command = FAX_ADJUST_B23_COMMAND_2; + return; + } + plci->command = _CONNECT_B3_R; + nl_req_ncci(plci, N_CONNECT, 0); + send_req(plci); + return; + } + sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); +} + + +static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc) +{ + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: fax_disconnect_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + plci->internal_command = FAX_DISCONNECT_COMMAND_1; + return; + case FAX_DISCONNECT_COMMAND_1: + case FAX_DISCONNECT_COMMAND_2: + case FAX_DISCONNECT_COMMAND_3: + if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) + { + dbug(1, dprintf("[%06lx] %s,%d: FAX disconnect EDATA failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + break; + } + if (Rc == OK) + { + if ((internal_command == FAX_DISCONNECT_COMMAND_1) + || (internal_command == FAX_DISCONNECT_COMMAND_2)) + { + plci->internal_command = FAX_DISCONNECT_COMMAND_2; + } + } + else if (Rc == 0) + { + if (internal_command == FAX_DISCONNECT_COMMAND_1) + plci->internal_command = FAX_DISCONNECT_COMMAND_3; + } + return; + } +} + + + +static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc) +{ + word Info; + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + Info = GOOD; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + case RTP_CONNECT_B3_REQ_COMMAND_1: + if (plci_nl_busy(plci)) + { + plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1; + return; + } + plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2; + nl_req_ncci(plci, N_CONNECT, 0); + send_req(plci); + return; + case RTP_CONNECT_B3_REQ_COMMAND_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect info failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + Info = _WRONG_STATE; + break; + } + if (plci_nl_busy(plci)) + { + plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2; + return; + } + plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_3; + plci->NData[0].PLength = plci->internal_req_buffer[0]; + plci->NData[0].P = plci->internal_req_buffer + 1; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_UDATA; + plci->adapter->request(&plci->NL); + break; + case RTP_CONNECT_B3_REQ_COMMAND_3: + return; + } + sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); +} + + +static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc) +{ + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + case RTP_CONNECT_B3_RES_COMMAND_1: + if (plci_nl_busy(plci)) + { + plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1; + return; + } + plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2; + nl_req_ncci(plci, N_CONNECT_ACK, (byte)(Id >> 16)); + send_req(plci); + return; + case RTP_CONNECT_B3_RES_COMMAND_2: + if ((Rc != OK) && (Rc != OK_FC)) + { + dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect resp info failed %02x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc)); + break; + } + if (plci_nl_busy(plci)) + { + plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2; + return; + } + sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); + plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_3; + plci->NData[0].PLength = plci->internal_req_buffer[0]; + plci->NData[0].P = plci->internal_req_buffer + 1; + plci->NL.X = plci->NData; + plci->NL.ReqCh = 0; + plci->NL.Req = plci->nl_req = (byte) N_UDATA; + plci->adapter->request(&plci->NL); + return; + case RTP_CONNECT_B3_RES_COMMAND_3: + return; + } +} + + + +static void hold_save_command(dword Id, PLCI *plci, byte Rc) +{ + byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ + word Info; + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: hold_save_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + Info = GOOD; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + if (!plci->NL.Id) + break; + plci->command = 0; + plci->adjust_b_parms_msg = NULL; + plci->adjust_b_facilities = plci->B1_facilities; + plci->adjust_b_command = HOLD_SAVE_COMMAND_1; + plci->adjust_b_ncci = (word)(Id >> 16); + plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23; + plci->adjust_b_state = ADJUST_B_START; + dbug(1, dprintf("[%06lx] %s,%d: HOLD save...", + UnMapId(Id), (char *)(FILE_), __LINE__)); + case HOLD_SAVE_COMMAND_1: + Info = adjust_b_process(Id, plci, Rc); + if (Info != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: HOLD save failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + break; + } + if (plci->internal_command) + return; + } + sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind); +} + + +static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc) +{ + byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/ + word Info; + word internal_command; + + dbug(1, dprintf("[%06lx] %s,%d: retrieve_restore_command %02x %04x", + UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + + Info = GOOD; + internal_command = plci->internal_command; + plci->internal_command = 0; + switch (internal_command) + { + default: + plci->command = 0; + plci->adjust_b_parms_msg = NULL; + plci->adjust_b_facilities = plci->B1_facilities; + plci->adjust_b_command = RETRIEVE_RESTORE_COMMAND_1; + plci->adjust_b_ncci = (word)(Id >> 16); + plci->adjust_b_mode = ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE; + plci->adjust_b_state = ADJUST_B_START; + dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore...", + UnMapId(Id), (char *)(FILE_), __LINE__)); + case RETRIEVE_RESTORE_COMMAND_1: + Info = adjust_b_process(Id, plci, Rc); + if (Info != GOOD) + { + dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore failed", + UnMapId(Id), (char *)(FILE_), __LINE__)); + break; + } + if (plci->internal_command) + return; + } + sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind); } -static void select_b_command (dword Id, PLCI *plci, byte Rc) +static void init_b1_config(PLCI *plci) { - word Info; - word internal_command; - byte esc_chi[3]; - - dbug (1, dprintf ("[%06lx] %s,%d: select_b_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - plci->adjust_b_parms_msg = &plci->saved_msg; - if ((plci->tel == ADV_VOICE) && (plci == plci->adapter->AdvSignalPLCI)) - plci->adjust_b_facilities = plci->B1_facilities | B1_FACILITY_VOICE; - else - plci->adjust_b_facilities = plci->B1_facilities & ~B1_FACILITY_VOICE; - plci->adjust_b_command = SELECT_B_COMMAND_1; - plci->adjust_b_ncci = (word)(Id >> 16); - if (plci->saved_msg.parms[0].length == 0) - { - plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 | - ADJUST_B_MODE_NO_RESOURCE; - } - else - { - plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 | - ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE; - } - plci->adjust_b_state = ADJUST_B_START; - dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol...", - UnMapId (Id), (char *)(FILE_), __LINE__)); - case SELECT_B_COMMAND_1: - Info = adjust_b_process (Id, plci, Rc); - if (Info != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - break; - } - if (plci->internal_command) - return; - if (plci->tel == ADV_VOICE) - { - esc_chi[0] = 0x02; - esc_chi[1] = 0x18; - esc_chi[2] = plci->b_channel; - SetVoiceChannel (plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter); - } - break; - } - sendf (plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info); -} + dbug(1, dprintf("[%06lx] %s,%d: init_b1_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); -static void fax_connect_ack_command (dword Id, PLCI *plci, byte Rc) -{ - word Info; - word internal_command; + plci->B1_resource = 0; + plci->B1_facilities = 0; - dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + plci->li_bchannel_id = 0; + mixer_clear_config(plci); - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - case FAX_CONNECT_ACK_COMMAND_1: - if (plci_nl_busy (plci)) - { - plci->internal_command = FAX_CONNECT_ACK_COMMAND_1; - return; - } - plci->internal_command = FAX_CONNECT_ACK_COMMAND_2; - plci->NData[0].P = plci->fax_connect_info_buffer; - plci->NData[0].PLength = plci->fax_connect_info_length; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_CONNECT_ACK; - plci->adapter->request (&plci->NL); - return; - case FAX_CONNECT_ACK_COMMAND_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - break; - } - } - if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT) - && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT)) - { - if (plci->B3_prot == 4) - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s",""); - else - sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer); - plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT; - } -} + ec_clear_config(plci); -static void fax_edata_ack_command (dword Id, PLCI *plci, byte Rc) -{ - word Info; - word internal_command; - dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + dtmf_rec_clear_config(plci); + dtmf_send_clear_config(plci); + dtmf_parameter_clear_config(plci); - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - case FAX_EDATA_ACK_COMMAND_1: - if (plci_nl_busy (plci)) - { - plci->internal_command = FAX_EDATA_ACK_COMMAND_1; - return; - } - plci->internal_command = FAX_EDATA_ACK_COMMAND_2; - plci->NData[0].P = plci->fax_connect_info_buffer; - plci->NData[0].PLength = plci->fax_edata_ack_length; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_EDATA; - plci->adapter->request (&plci->NL); - return; - case FAX_EDATA_ACK_COMMAND_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - break; - } - } + adv_voice_clear_config(plci); + adjust_b_clear(plci); } -static void fax_connect_info_command (dword Id, PLCI *plci, byte Rc) +static void clear_b1_config(PLCI *plci) { - word Info; - word internal_command; - dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_info_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - case FAX_CONNECT_INFO_COMMAND_1: - if (plci_nl_busy (plci)) - { - plci->internal_command = FAX_CONNECT_INFO_COMMAND_1; - return; - } - plci->internal_command = FAX_CONNECT_INFO_COMMAND_2; - plci->NData[0].P = plci->fax_connect_info_buffer; - plci->NData[0].PLength = plci->fax_connect_info_length; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_EDATA; - plci->adapter->request (&plci->NL); - return; - case FAX_CONNECT_INFO_COMMAND_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: FAX setting connect info failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - if (plci_nl_busy (plci)) - { - plci->internal_command = FAX_CONNECT_INFO_COMMAND_2; - return; - } - plci->command = _CONNECT_B3_R; - nl_req_ncci (plci, N_CONNECT, 0); - send_req (plci); - return; - } - sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); -} - - -static void fax_adjust_b23_command (dword Id, PLCI *plci, byte Rc) -{ - word Info; - word internal_command; - - dbug (1, dprintf ("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - plci->adjust_b_parms_msg = NULL; - plci->adjust_b_facilities = plci->B1_facilities; - plci->adjust_b_command = FAX_ADJUST_B23_COMMAND_1; - plci->adjust_b_ncci = (word)(Id >> 16); - plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23; - plci->adjust_b_state = ADJUST_B_START; - dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust B23...", - UnMapId (Id), (char *)(FILE_), __LINE__)); - case FAX_ADJUST_B23_COMMAND_1: - Info = adjust_b_process (Id, plci, Rc); - if (Info != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - break; - } - if (plci->internal_command) - return; - case FAX_ADJUST_B23_COMMAND_2: - if (plci_nl_busy (plci)) - { - plci->internal_command = FAX_ADJUST_B23_COMMAND_2; - return; - } - plci->command = _CONNECT_B3_R; - nl_req_ncci (plci, N_CONNECT, 0); - send_req (plci); - return; - } - sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); -} - - -static void fax_disconnect_command (dword Id, PLCI *plci, byte Rc) -{ - word internal_command; - - dbug (1, dprintf ("[%06lx] %s,%d: fax_disconnect_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - plci->internal_command = FAX_DISCONNECT_COMMAND_1; - return; - case FAX_DISCONNECT_COMMAND_1: - case FAX_DISCONNECT_COMMAND_2: - case FAX_DISCONNECT_COMMAND_3: - if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0)) - { - dbug (1, dprintf ("[%06lx] %s,%d: FAX disconnect EDATA failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - break; - } - if (Rc == OK) - { - if ((internal_command == FAX_DISCONNECT_COMMAND_1) - || (internal_command == FAX_DISCONNECT_COMMAND_2)) - { - plci->internal_command = FAX_DISCONNECT_COMMAND_2; - } - } - else if (Rc == 0) - { - if (internal_command == FAX_DISCONNECT_COMMAND_1) - plci->internal_command = FAX_DISCONNECT_COMMAND_3; - } - return; - } -} - - - -static void rtp_connect_b3_req_command (dword Id, PLCI *plci, byte Rc) -{ - word Info; - word internal_command; - - dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - case RTP_CONNECT_B3_REQ_COMMAND_1: - if (plci_nl_busy (plci)) - { - plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1; - return; - } - plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2; - nl_req_ncci (plci, N_CONNECT, 0); - send_req (plci); - return; - case RTP_CONNECT_B3_REQ_COMMAND_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect info failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - if (plci_nl_busy (plci)) - { - plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2; - return; - } - plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_3; - plci->NData[0].PLength = plci->internal_req_buffer[0]; - plci->NData[0].P = plci->internal_req_buffer + 1; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_UDATA; - plci->adapter->request (&plci->NL); - break; - case RTP_CONNECT_B3_REQ_COMMAND_3: - return; - } - sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info); -} - - -static void rtp_connect_b3_res_command (dword Id, PLCI *plci, byte Rc) -{ - word Info; - word internal_command; - - dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - case RTP_CONNECT_B3_RES_COMMAND_1: - if (plci_nl_busy (plci)) - { - plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1; - return; - } - plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2; - nl_req_ncci (plci, N_CONNECT_ACK, (byte)(Id >> 16)); - send_req (plci); - return; - case RTP_CONNECT_B3_RES_COMMAND_2: - if ((Rc != OK) && (Rc != OK_FC)) - { - dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc)); - Info = _WRONG_STATE; - break; - } - if (plci_nl_busy (plci)) - { - plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2; - return; - } - sendf (plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", ""); - plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_3; - plci->NData[0].PLength = plci->internal_req_buffer[0]; - plci->NData[0].P = plci->internal_req_buffer + 1; - plci->NL.X = plci->NData; - plci->NL.ReqCh = 0; - plci->NL.Req = plci->nl_req = (byte) N_UDATA; - plci->adapter->request (&plci->NL); - return; - case RTP_CONNECT_B3_RES_COMMAND_3: - return; - } -} + dbug(1, dprintf("[%06lx] %s,%d: clear_b1_config", + (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)), + (char *)(FILE_), __LINE__)); + adv_voice_clear_config(plci); + adjust_b_clear(plci); + ec_clear_config(plci); -static void hold_save_command (dword Id, PLCI *plci, byte Rc) -{ - byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ - word Info; - word internal_command; - - dbug (1, dprintf ("[%06lx] %s,%d: hold_save_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); - - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - if (!plci->NL.Id) - break; - plci->command = 0; - plci->adjust_b_parms_msg = NULL; - plci->adjust_b_facilities = plci->B1_facilities; - plci->adjust_b_command = HOLD_SAVE_COMMAND_1; - plci->adjust_b_ncci = (word)(Id >> 16); - plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23; - plci->adjust_b_state = ADJUST_B_START; - dbug (1, dprintf ("[%06lx] %s,%d: HOLD save...", - UnMapId (Id), (char *)(FILE_), __LINE__)); - case HOLD_SAVE_COMMAND_1: - Info = adjust_b_process (Id, plci, Rc); - if (Info != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: HOLD save failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - break; - } - if (plci->internal_command) - return; - } - sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind); -} + dtmf_rec_clear_config(plci); + dtmf_send_clear_config(plci); + dtmf_parameter_clear_config(plci); -static void retrieve_restore_command (dword Id, PLCI *plci, byte Rc) -{ - byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/ - word Info; - word internal_command; - dbug (1, dprintf ("[%06lx] %s,%d: retrieve_restore_command %02x %04x", - UnMapId (Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command)); + if ((plci->li_bchannel_id != 0) + && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci)) + { + mixer_clear_config(plci); + li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = NULL; + plci->li_bchannel_id = 0; + } - Info = GOOD; - internal_command = plci->internal_command; - plci->internal_command = 0; - switch (internal_command) - { - default: - plci->command = 0; - plci->adjust_b_parms_msg = NULL; - plci->adjust_b_facilities = plci->B1_facilities; - plci->adjust_b_command = RETRIEVE_RESTORE_COMMAND_1; - plci->adjust_b_ncci = (word)(Id >> 16); - plci->adjust_b_mode = ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE; - plci->adjust_b_state = ADJUST_B_START; - dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore...", - UnMapId (Id), (char *)(FILE_), __LINE__)); - case RETRIEVE_RESTORE_COMMAND_1: - Info = adjust_b_process (Id, plci, Rc); - if (Info != GOOD) - { - dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore failed", - UnMapId (Id), (char *)(FILE_), __LINE__)); - break; - } - if (plci->internal_command) - return; - } - sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind); -} - - -static void init_b1_config (PLCI *plci) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: init_b1_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - plci->B1_resource = 0; - plci->B1_facilities = 0; - - plci->li_bchannel_id = 0; - mixer_clear_config (plci); - - - ec_clear_config (plci); - - - dtmf_rec_clear_config (plci); - dtmf_send_clear_config (plci); - dtmf_parameter_clear_config (plci); - - adv_voice_clear_config (plci); - adjust_b_clear (plci); -} - - -static void clear_b1_config (PLCI *plci) -{ - - dbug (1, dprintf ("[%06lx] %s,%d: clear_b1_config", - (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)), - (char *)(FILE_), __LINE__)); - - adv_voice_clear_config (plci); - adjust_b_clear (plci); - - ec_clear_config (plci); - - - dtmf_rec_clear_config (plci); - dtmf_send_clear_config (plci); - dtmf_parameter_clear_config (plci); - - - if ((plci->li_bchannel_id != 0) - && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci)) - { - mixer_clear_config (plci); - li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = NULL; - plci->li_bchannel_id = 0; - } - - plci->B1_resource = 0; - plci->B1_facilities = 0; + plci->B1_resource = 0; + plci->B1_facilities = 0; } /* ----------------------------------------------------------------- - XON protocol local helpers + XON protocol local helpers ----------------------------------------------------------------- */ -static void channel_flow_control_remove (PLCI * plci) { - DIVA_CAPI_ADAPTER * a = plci->adapter; - word i; - for(i=1;i<MAX_NL_CHANNEL+1;i++) { - if (a->ch_flow_plci[i] == plci->Id) { - a->ch_flow_plci[i] = 0; - a->ch_flow_control[i] = 0; - } - } -} - -static void channel_x_on (PLCI * plci, byte ch) { - DIVA_CAPI_ADAPTER * a = plci->adapter; - if (a->ch_flow_control[ch] & N_XON_SENT) { - a->ch_flow_control[ch] &= ~N_XON_SENT; - } -} - -static void channel_x_off (PLCI * plci, byte ch, byte flag) { - DIVA_CAPI_ADAPTER * a = plci->adapter; - if ((a->ch_flow_control[ch] & N_RX_FLOW_CONTROL_MASK) == 0) { - a->ch_flow_control[ch] |= (N_CH_XOFF | flag); - a->ch_flow_plci[ch] = plci->Id; - a->ch_flow_control_pending++; - } -} - -static void channel_request_xon (PLCI * plci, byte ch) { - DIVA_CAPI_ADAPTER * a = plci->adapter; - - if (a->ch_flow_control[ch] & N_CH_XOFF) { - a->ch_flow_control[ch] |= N_XON_REQ; - a->ch_flow_control[ch] &= ~N_CH_XOFF; - a->ch_flow_control[ch] &= ~N_XON_CONNECT_IND; - } -} - -static void channel_xmit_extended_xon (PLCI * plci) { - DIVA_CAPI_ADAPTER * a; - int max_ch = sizeof(a->ch_flow_control)/sizeof(a->ch_flow_control[0]); - int i, one_requested = 0; - - if ((!plci) || (!plci->Id) || ((a = plci->adapter) == 0)) { - return; - } - - for (i = 0; i < max_ch; i++) { - if ((a->ch_flow_control[i] & N_CH_XOFF) && - (a->ch_flow_control[i] & N_XON_CONNECT_IND) && - (plci->Id == a->ch_flow_plci[i])) { - channel_request_xon (plci, (byte)i); - one_requested = 1; - } - } - - if (one_requested) { - channel_xmit_xon (plci); - } +static void channel_flow_control_remove(PLCI *plci) { + DIVA_CAPI_ADAPTER *a = plci->adapter; + word i; + for (i = 1; i < MAX_NL_CHANNEL + 1; i++) { + if (a->ch_flow_plci[i] == plci->Id) { + a->ch_flow_plci[i] = 0; + a->ch_flow_control[i] = 0; + } + } +} + +static void channel_x_on(PLCI *plci, byte ch) { + DIVA_CAPI_ADAPTER *a = plci->adapter; + if (a->ch_flow_control[ch] & N_XON_SENT) { + a->ch_flow_control[ch] &= ~N_XON_SENT; + } +} + +static void channel_x_off(PLCI *plci, byte ch, byte flag) { + DIVA_CAPI_ADAPTER *a = plci->adapter; + if ((a->ch_flow_control[ch] & N_RX_FLOW_CONTROL_MASK) == 0) { + a->ch_flow_control[ch] |= (N_CH_XOFF | flag); + a->ch_flow_plci[ch] = plci->Id; + a->ch_flow_control_pending++; + } +} + +static void channel_request_xon(PLCI *plci, byte ch) { + DIVA_CAPI_ADAPTER *a = plci->adapter; + + if (a->ch_flow_control[ch] & N_CH_XOFF) { + a->ch_flow_control[ch] |= N_XON_REQ; + a->ch_flow_control[ch] &= ~N_CH_XOFF; + a->ch_flow_control[ch] &= ~N_XON_CONNECT_IND; + } +} + +static void channel_xmit_extended_xon(PLCI *plci) { + DIVA_CAPI_ADAPTER *a; + int max_ch = ARRAY_SIZE(a->ch_flow_control); + int i, one_requested = 0; + + if ((!plci) || (!plci->Id) || ((a = plci->adapter) == NULL)) { + return; + } + + for (i = 0; i < max_ch; i++) { + if ((a->ch_flow_control[i] & N_CH_XOFF) && + (a->ch_flow_control[i] & N_XON_CONNECT_IND) && + (plci->Id == a->ch_flow_plci[i])) { + channel_request_xon(plci, (byte)i); + one_requested = 1; + } + } + + if (one_requested) { + channel_xmit_xon(plci); + } } /* Try to xmit next X_ON - */ -static int find_channel_with_pending_x_on (DIVA_CAPI_ADAPTER * a, PLCI * plci) { - int max_ch = sizeof(a->ch_flow_control)/sizeof(a->ch_flow_control[0]); - int i; - - if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) { - return (0); - } - - if (a->last_flow_control_ch >= max_ch) { - a->last_flow_control_ch = 1; - } - for (i=a->last_flow_control_ch; i < max_ch; i++) { - if ((a->ch_flow_control[i] & N_XON_REQ) && - (plci->Id == a->ch_flow_plci[i])) { - a->last_flow_control_ch = i+1; - return (i); - } - } - - for (i = 1; i < a->last_flow_control_ch; i++) { - if ((a->ch_flow_control[i] & N_XON_REQ) && - (plci->Id == a->ch_flow_plci[i])) { - a->last_flow_control_ch = i+1; - return (i); - } - } - - return (0); -} - -static void channel_xmit_xon (PLCI * plci) { - DIVA_CAPI_ADAPTER * a = plci->adapter; - byte ch; - - if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) { - return; - } - if ((ch = (byte)find_channel_with_pending_x_on (a, plci)) == 0) { - return; - } - a->ch_flow_control[ch] &= ~N_XON_REQ; - a->ch_flow_control[ch] |= N_XON_SENT; - - plci->NL.Req = plci->nl_req = (byte)N_XON; - plci->NL.ReqCh = ch; - plci->NL.X = plci->NData; - plci->NL.XNum = 1; - plci->NData[0].P = &plci->RBuffer[0]; - plci->NData[0].PLength = 0; - - plci->adapter->request(&plci->NL); -} - -static int channel_can_xon (PLCI * plci, byte ch) { - APPL * APPLptr; - DIVA_CAPI_ADAPTER * a; - word NCCIcode; - dword count; - word Num; - word i; - - APPLptr = plci->appl; - a = plci->adapter; - - if (!APPLptr) - return (0); - - NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8); - - /* count all buffers within the Application pool */ - /* belonging to the same NCCI. XON if a first is */ - /* used. */ - count = 0; - Num = 0xffff; - for(i=0; i<APPLptr->MaxBuffer; i++) { - if(NCCIcode==APPLptr->DataNCCI[i]) count++; - if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i; - } - if ((count > 2) || (Num == 0xffff)) { - return (0); - } - return (1); +*/ +static int find_channel_with_pending_x_on(DIVA_CAPI_ADAPTER *a, PLCI *plci) { + int max_ch = ARRAY_SIZE(a->ch_flow_control); + int i; + + if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) { + return (0); + } + + if (a->last_flow_control_ch >= max_ch) { + a->last_flow_control_ch = 1; + } + for (i = a->last_flow_control_ch; i < max_ch; i++) { + if ((a->ch_flow_control[i] & N_XON_REQ) && + (plci->Id == a->ch_flow_plci[i])) { + a->last_flow_control_ch = i + 1; + return (i); + } + } + + for (i = 1; i < a->last_flow_control_ch; i++) { + if ((a->ch_flow_control[i] & N_XON_REQ) && + (plci->Id == a->ch_flow_plci[i])) { + a->last_flow_control_ch = i + 1; + return (i); + } + } + + return (0); +} + +static void channel_xmit_xon(PLCI *plci) { + DIVA_CAPI_ADAPTER *a = plci->adapter; + byte ch; + + if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) { + return; + } + if ((ch = (byte)find_channel_with_pending_x_on(a, plci)) == 0) { + return; + } + a->ch_flow_control[ch] &= ~N_XON_REQ; + a->ch_flow_control[ch] |= N_XON_SENT; + + plci->NL.Req = plci->nl_req = (byte)N_XON; + plci->NL.ReqCh = ch; + plci->NL.X = plci->NData; + plci->NL.XNum = 1; + plci->NData[0].P = &plci->RBuffer[0]; + plci->NData[0].PLength = 0; + + plci->adapter->request(&plci->NL); +} + +static int channel_can_xon(PLCI *plci, byte ch) { + APPL *APPLptr; + DIVA_CAPI_ADAPTER *a; + word NCCIcode; + dword count; + word Num; + word i; + + APPLptr = plci->appl; + a = plci->adapter; + + if (!APPLptr) + return (0); + + NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8); + + /* count all buffers within the Application pool */ + /* belonging to the same NCCI. XON if a first is */ + /* used. */ + count = 0; + Num = 0xffff; + for (i = 0; i < APPLptr->MaxBuffer; i++) { + if (NCCIcode == APPLptr->DataNCCI[i]) count++; + if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i; + } + if ((count > 2) || (Num == 0xffff)) { + return (0); + } + return (1); } /*------------------------------------------------------------------*/ -static word CPN_filter_ok(byte *cpn,DIVA_CAPI_ADAPTER * a,word offset) +static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *a, word offset) { - return 1; + return 1; } @@ -14729,116 +14733,116 @@ static word CPN_filter_ok(byte *cpn,DIVA_CAPI_ADAPTER * a,word offset) /* function must be enabled by setting "a->group_optimization_enabled" from the */ /* OS specific part (per adapter). */ /**********************************************************************************/ -static void group_optimization(DIVA_CAPI_ADAPTER * a, PLCI * plci) -{ - word i,j,k,busy,group_found; - dword info_mask_group[MAX_CIP_TYPES]; - dword cip_mask_group[MAX_CIP_TYPES]; - word appl_number_group_type[MAX_APPL]; - PLCI *auxplci; - - set_group_ind_mask (plci); /* all APPLs within this inc. call are allowed to dial in */ - - if(!a->group_optimization_enabled) - { - dbug(1,dprintf("No group optimization")); - return; - } - - dbug(1,dprintf("Group optimization = 0x%x...", a->group_optimization_enabled)); - - for(i=0;i<MAX_CIP_TYPES;i++) - { - info_mask_group[i] = 0; - cip_mask_group [i] = 0; - } - for(i=0;i<MAX_APPL;i++) - { - appl_number_group_type[i] = 0; - } - for(i=0; i<max_appl; i++) /* check if any multi instance capable application is present */ - { /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */ - if(application[i].Id && (application[i].MaxNCCI) > 1 && (a->CIP_Mask[i]) && (a->group_optimization_enabled ==1) ) - { - dbug(1,dprintf("Multi-Instance capable, no optimization required")); - return; /* allow good application unfiltered access */ - } - } - for(i=0; i<max_appl; i++) /* Build CIP Groups */ - { - if(application[i].Id && a->CIP_Mask[i] ) - { - for(k=0,busy=FALSE; k<a->max_plci; k++) - { - if(a->plci[k].Id) - { - auxplci = &a->plci[k]; - if(auxplci->appl == &application[i]) /* application has a busy PLCI */ - { - busy = TRUE; - dbug(1,dprintf("Appl 0x%x is busy",i+1)); - } - else if(test_c_ind_mask_bit (auxplci, i)) /* application has an incoming call pending */ - { - busy = TRUE; - dbug(1,dprintf("Appl 0x%x has inc. call pending",i+1)); - } - } - } - - for(j=0,group_found=0; j<=(MAX_CIP_TYPES) && !busy &&!group_found; j++) /* build groups with free applications only */ - { - if(j==MAX_CIP_TYPES) /* all groups are in use but group still not found */ - { /* the MAX_CIP_TYPES group enables all calls because of field overflow */ - appl_number_group_type[i] = MAX_CIP_TYPES; - group_found=TRUE; - dbug(1,dprintf("Field overflow appl 0x%x",i+1)); - } - else if( (info_mask_group[j]==a->CIP_Mask[i]) && (cip_mask_group[j]==a->Info_Mask[i]) ) - { /* is group already present ? */ - appl_number_group_type[i] = j|0x80; /* store the group number for each application */ - group_found=TRUE; - dbug(1,dprintf("Group 0x%x found with appl 0x%x, CIP=0x%lx",appl_number_group_type[i],i+1,info_mask_group[j])); - } - else if(!info_mask_group[j]) - { /* establish a new group */ - appl_number_group_type[i] = j|0x80; /* store the group number for each application */ - info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group */ - cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group */ - group_found=TRUE; - dbug(1,dprintf("New Group 0x%x established with appl 0x%x, CIP=0x%lx",appl_number_group_type[i],i+1,info_mask_group[j])); - } - } - } - } - - for(i=0; i<max_appl; i++) /* Build group_optimization_mask_table */ - { - if(appl_number_group_type[i]) /* application is free, has listens and is member of a group */ - { - if(appl_number_group_type[i] == MAX_CIP_TYPES) - { - dbug(1,dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled",appl_number_group_type[i],i+1)); - } - else - { - dbug(1,dprintf("Group 0x%x, valid appl = 0x%x",appl_number_group_type[i],i+1)); - for(j=i+1; j<max_appl; j++) /* search other group members and mark them as busy */ - { - if(appl_number_group_type[i] == appl_number_group_type[j]) - { - dbug(1,dprintf("Appl 0x%x is member of group 0x%x, no call",j+1,appl_number_group_type[j])); - clear_group_ind_mask_bit (plci, j); /* disable call on other group members */ - appl_number_group_type[j] = 0; /* remove disabled group member from group list */ - } - } - } - } - else /* application should not get a call */ - { - clear_group_ind_mask_bit (plci, i); - } - } +static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci) +{ + word i, j, k, busy, group_found; + dword info_mask_group[MAX_CIP_TYPES]; + dword cip_mask_group[MAX_CIP_TYPES]; + word appl_number_group_type[MAX_APPL]; + PLCI *auxplci; + + set_group_ind_mask(plci); /* all APPLs within this inc. call are allowed to dial in */ + + if (!a->group_optimization_enabled) + { + dbug(1, dprintf("No group optimization")); + return; + } + + dbug(1, dprintf("Group optimization = 0x%x...", a->group_optimization_enabled)); + + for (i = 0; i < MAX_CIP_TYPES; i++) + { + info_mask_group[i] = 0; + cip_mask_group[i] = 0; + } + for (i = 0; i < MAX_APPL; i++) + { + appl_number_group_type[i] = 0; + } + for (i = 0; i < max_appl; i++) /* check if any multi instance capable application is present */ + { /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */ + if (application[i].Id && (application[i].MaxNCCI) > 1 && (a->CIP_Mask[i]) && (a->group_optimization_enabled == 1)) + { + dbug(1, dprintf("Multi-Instance capable, no optimization required")); + return; /* allow good application unfiltered access */ + } + } + for (i = 0; i < max_appl; i++) /* Build CIP Groups */ + { + if (application[i].Id && a->CIP_Mask[i]) + { + for (k = 0, busy = false; k < a->max_plci; k++) + { + if (a->plci[k].Id) + { + auxplci = &a->plci[k]; + if (auxplci->appl == &application[i]) /* application has a busy PLCI */ + { + busy = true; + dbug(1, dprintf("Appl 0x%x is busy", i + 1)); + } + else if (test_c_ind_mask_bit(auxplci, i)) /* application has an incoming call pending */ + { + busy = true; + dbug(1, dprintf("Appl 0x%x has inc. call pending", i + 1)); + } + } + } + + for (j = 0, group_found = 0; j <= (MAX_CIP_TYPES) && !busy && !group_found; j++) /* build groups with free applications only */ + { + if (j == MAX_CIP_TYPES) /* all groups are in use but group still not found */ + { /* the MAX_CIP_TYPES group enables all calls because of field overflow */ + appl_number_group_type[i] = MAX_CIP_TYPES; + group_found = true; + dbug(1, dprintf("Field overflow appl 0x%x", i + 1)); + } + else if ((info_mask_group[j] == a->CIP_Mask[i]) && (cip_mask_group[j] == a->Info_Mask[i])) + { /* is group already present ? */ + appl_number_group_type[i] = j | 0x80; /* store the group number for each application */ + group_found = true; + dbug(1, dprintf("Group 0x%x found with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j])); + } + else if (!info_mask_group[j]) + { /* establish a new group */ + appl_number_group_type[i] = j | 0x80; /* store the group number for each application */ + info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group */ + cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group */ + group_found = true; + dbug(1, dprintf("New Group 0x%x established with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j])); + } + } + } + } + + for (i = 0; i < max_appl; i++) /* Build group_optimization_mask_table */ + { + if (appl_number_group_type[i]) /* application is free, has listens and is member of a group */ + { + if (appl_number_group_type[i] == MAX_CIP_TYPES) + { + dbug(1, dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled", appl_number_group_type[i], i + 1)); + } + else + { + dbug(1, dprintf("Group 0x%x, valid appl = 0x%x", appl_number_group_type[i], i + 1)); + for (j = i + 1; j < max_appl; j++) /* search other group members and mark them as busy */ + { + if (appl_number_group_type[i] == appl_number_group_type[j]) + { + dbug(1, dprintf("Appl 0x%x is member of group 0x%x, no call", j + 1, appl_number_group_type[j])); + clear_group_ind_mask_bit(plci, j); /* disable call on other group members */ + appl_number_group_type[j] = 0; /* remove disabled group member from group list */ + } + } + } + } + else /* application should not get a call */ + { + clear_group_ind_mask_bit(plci, i); + } + } } @@ -14847,201 +14851,201 @@ static void group_optimization(DIVA_CAPI_ADAPTER * a, PLCI * plci) /* OS notifies the driver about a application Capi_Register */ word CapiRegister(word id) { - word i,j,appls_found; - - PLCI *plci; - DIVA_CAPI_ADAPTER *a; - - for(i=0,appls_found=0; i<max_appl; i++) - { - if( application[i].Id && (application[i].Id!=id) ) - { - appls_found++; /* an application has been found */ - } - } - - if(appls_found) return TRUE; - for(i=0; i<max_adapter; i++) /* scan all adapters... */ - { - a = &adapter[i]; - if(a->request) - { - if(a->flag_dynamic_l1_down) /* remove adapter from L1 tristate (Huntgroup) */ - { - if(!appls_found) /* first application does a capi register */ - { - if((j=get_plci(a))) /* activate L1 of all adapters */ - { - plci = &a->plci[j-1]; - plci->command = 0; - add_p(plci,OAD,"\x01\xfd"); - add_p(plci,CAI,"\x01\x80"); - add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30"); - add_p(plci,SHIFT|6,NULL); - add_p(plci,SIN,"\x02\x00\x00"); - plci->internal_command = START_L1_SIG_ASSIGN_PEND; - sig_req(plci,ASSIGN,DSIG_ID); - add_p(plci,FTY,"\x02\xff\x07"); /* l1 start */ - sig_req(plci,SIG_CTRL,0); - send_req(plci); - } - } - } - } - } - return FALSE; + word i, j, appls_found; + + PLCI *plci; + DIVA_CAPI_ADAPTER *a; + + for (i = 0, appls_found = 0; i < max_appl; i++) + { + if (application[i].Id && (application[i].Id != id)) + { + appls_found++; /* an application has been found */ + } + } + + if (appls_found) return true; + for (i = 0; i < max_adapter; i++) /* scan all adapters... */ + { + a = &adapter[i]; + if (a->request) + { + if (a->flag_dynamic_l1_down) /* remove adapter from L1 tristate (Huntgroup) */ + { + if (!appls_found) /* first application does a capi register */ + { + if ((j = get_plci(a))) /* activate L1 of all adapters */ + { + plci = &a->plci[j - 1]; + plci->command = 0; + add_p(plci, OAD, "\x01\xfd"); + add_p(plci, CAI, "\x01\x80"); + add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30"); + add_p(plci, SHIFT | 6, NULL); + add_p(plci, SIN, "\x02\x00\x00"); + plci->internal_command = START_L1_SIG_ASSIGN_PEND; + sig_req(plci, ASSIGN, DSIG_ID); + add_p(plci, FTY, "\x02\xff\x07"); /* l1 start */ + sig_req(plci, SIG_CTRL, 0); + send_req(plci); + } + } + } + } + } + return false; } /*------------------------------------------------------------------*/ /* Functions for virtual Switching e.g. Transfer by join, Conference */ -static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms) -{ - word i; - /* Format of vswitch_t: - 0 byte length - 1 byte VSWITCHIE - 2 byte VSWITCH_REQ/VSWITCH_IND - 3 byte reserved - 4 word VSwitchcommand - 6 word returnerror - 8... Params - */ - if(!plci || - !plci->appl || - !plci->State || - plci->Sig.Ind==NCR_FACILITY - ) - return; - - for(i=0;i<MAX_MULTI_IE;i++) - { - if(!parms[i][0]) continue; - if(parms[i][0]<7) - { - parms[i][0]=0; /* kill it */ - continue; - } - dbug(1,dprintf("VSwitchReqInd(%d)",parms[i][4])); - switch(parms[i][4]) - { - case VSJOIN: - if(!plci->relatedPTYPLCI || - (plci->ptyState!=S_ECT && plci->relatedPTYPLCI->ptyState!=S_ECT)) - { /* Error */ - break; - } - /* remember all necessary informations */ - if(parms[i][0]!=11 || parms[i][8]!=3) /* Length Test */ - { - break; - } - if(parms[i][2]==VSWITCH_IND && parms[i][9]==1) - { /* first indication after ECT-Request on Consultation Call */ - plci->vswitchstate=parms[i][9]; - parms[i][9]=2; /* State */ - /* now ask first Call to join */ - } - else if(parms[i][2]==VSWITCH_REQ && parms[i][9]==3) - { /* Answer of VSWITCH_REQ from first Call */ - plci->vswitchstate=parms[i][9]; - /* tell consultation call to join - and the protocol capabilities of the first call */ - } - else - { /* Error */ - break; - } - plci->vsprot=parms[i][10]; /* protocol */ - plci->vsprotdialect=parms[i][11]; /* protocoldialect */ - /* send join request to related PLCI */ - parms[i][1]=VSWITCHIE; - parms[i][2]=VSWITCH_REQ; - - plci->relatedPTYPLCI->command = 0; - plci->relatedPTYPLCI->internal_command = VSWITCH_REQ_PEND; - add_p(plci->relatedPTYPLCI,ESC,&parms[i][0]); - sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0); - send_req(plci->relatedPTYPLCI); - break; - case VSTRANSPORT: - default: - if(plci->relatedPTYPLCI && - plci->vswitchstate==3 && - plci->relatedPTYPLCI->vswitchstate==3) - { - add_p(plci->relatedPTYPLCI,ESC,&parms[i][0]); - sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0); - send_req(plci->relatedPTYPLCI); - } - break; - } - parms[i][0]=0; /* kill it */ - } +static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms) +{ + word i; + /* Format of vswitch_t: + 0 byte length + 1 byte VSWITCHIE + 2 byte VSWITCH_REQ/VSWITCH_IND + 3 byte reserved + 4 word VSwitchcommand + 6 word returnerror + 8... Params + */ + if (!plci || + !plci->appl || + !plci->State || + plci->Sig.Ind == NCR_FACILITY + ) + return; + + for (i = 0; i < MAX_MULTI_IE; i++) + { + if (!parms[i][0]) continue; + if (parms[i][0] < 7) + { + parms[i][0] = 0; /* kill it */ + continue; + } + dbug(1, dprintf("VSwitchReqInd(%d)", parms[i][4])); + switch (parms[i][4]) + { + case VSJOIN: + if (!plci->relatedPTYPLCI || + (plci->ptyState != S_ECT && plci->relatedPTYPLCI->ptyState != S_ECT)) + { /* Error */ + break; + } + /* remember all necessary informations */ + if (parms[i][0] != 11 || parms[i][8] != 3) /* Length Test */ + { + break; + } + if (parms[i][2] == VSWITCH_IND && parms[i][9] == 1) + { /* first indication after ECT-Request on Consultation Call */ + plci->vswitchstate = parms[i][9]; + parms[i][9] = 2; /* State */ + /* now ask first Call to join */ + } + else if (parms[i][2] == VSWITCH_REQ && parms[i][9] == 3) + { /* Answer of VSWITCH_REQ from first Call */ + plci->vswitchstate = parms[i][9]; + /* tell consultation call to join + and the protocol capabilities of the first call */ + } + else + { /* Error */ + break; + } + plci->vsprot = parms[i][10]; /* protocol */ + plci->vsprotdialect = parms[i][11]; /* protocoldialect */ + /* send join request to related PLCI */ + parms[i][1] = VSWITCHIE; + parms[i][2] = VSWITCH_REQ; + + plci->relatedPTYPLCI->command = 0; + plci->relatedPTYPLCI->internal_command = VSWITCH_REQ_PEND; + add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]); + sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0); + send_req(plci->relatedPTYPLCI); + break; + case VSTRANSPORT: + default: + if (plci->relatedPTYPLCI && + plci->vswitchstate == 3 && + plci->relatedPTYPLCI->vswitchstate == 3) + { + add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]); + sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0); + send_req(plci->relatedPTYPLCI); + } + break; + } + parms[i][0] = 0; /* kill it */ + } } /*------------------------------------------------------------------*/ -static int diva_get_dma_descriptor (PLCI *plci, dword *dma_magic) { - ENTITY e; - IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e; - - if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) { - return (-1); - } - - pReq->xdi_dma_descriptor_operation.Req = 0; - pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; - - pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC; - pReq->xdi_dma_descriptor_operation.info.descriptor_number = -1; - pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; - pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; - - e.user[0] = plci->adapter->Id - 1; - plci->adapter->request((ENTITY*)pReq); - - if (!pReq->xdi_dma_descriptor_operation.info.operation && - (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) && - pReq->xdi_dma_descriptor_operation.info.descriptor_magic) { - *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic; - dbug(3,dprintf("dma_alloc, a:%d (%d-%08x)", - plci->adapter->Id, - pReq->xdi_dma_descriptor_operation.info.descriptor_number, - *dma_magic)); - return (pReq->xdi_dma_descriptor_operation.info.descriptor_number); - } else { - dbug(1,dprintf("dma_alloc failed")); - return (-1); - } -} - -static void diva_free_dma_descriptor (PLCI *plci, int nr) { - ENTITY e; - IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e; - - if (nr < 0) { - return; - } - - pReq->xdi_dma_descriptor_operation.Req = 0; - pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; - - pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE; - pReq->xdi_dma_descriptor_operation.info.descriptor_number = nr; - pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; - pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; - - e.user[0] = plci->adapter->Id - 1; - plci->adapter->request((ENTITY*)pReq); - - if (!pReq->xdi_dma_descriptor_operation.info.operation) { - dbug(1,dprintf("dma_free(%d)", nr)); - } else { - dbug(1,dprintf("dma_free failed (%d)", nr)); - } +static int diva_get_dma_descriptor(PLCI *plci, dword *dma_magic) { + ENTITY e; + IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e; + + if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) { + return (-1); + } + + pReq->xdi_dma_descriptor_operation.Req = 0; + pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; + + pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC; + pReq->xdi_dma_descriptor_operation.info.descriptor_number = -1; + pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; + pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; + + e.user[0] = plci->adapter->Id - 1; + plci->adapter->request((ENTITY *)pReq); + + if (!pReq->xdi_dma_descriptor_operation.info.operation && + (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) && + pReq->xdi_dma_descriptor_operation.info.descriptor_magic) { + *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic; + dbug(3, dprintf("dma_alloc, a:%d (%d-%08x)", + plci->adapter->Id, + pReq->xdi_dma_descriptor_operation.info.descriptor_number, + *dma_magic)); + return (pReq->xdi_dma_descriptor_operation.info.descriptor_number); + } else { + dbug(1, dprintf("dma_alloc failed")); + return (-1); + } +} + +static void diva_free_dma_descriptor(PLCI *plci, int nr) { + ENTITY e; + IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e; + + if (nr < 0) { + return; + } + + pReq->xdi_dma_descriptor_operation.Req = 0; + pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION; + + pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE; + pReq->xdi_dma_descriptor_operation.info.descriptor_number = nr; + pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL; + pReq->xdi_dma_descriptor_operation.info.descriptor_magic = 0; + + e.user[0] = plci->adapter->Id - 1; + plci->adapter->request((ENTITY *)pReq); + + if (!pReq->xdi_dma_descriptor_operation.info.operation) { + dbug(1, dprintf("dma_free(%d)", nr)); + } else { + dbug(1, dprintf("dma_free failed (%d)", nr)); + } } /*------------------------------------------------------------------*/ diff --git a/drivers/isdn/hardware/eicon/mi_pc.h b/drivers/isdn/hardware/eicon/mi_pc.h index a861dac1f78..83e9ed8c1bf 100644 --- a/drivers/isdn/hardware/eicon/mi_pc.h +++ b/drivers/isdn/hardware/eicon/mi_pc.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /*---------------------------------------------------------------------------- @@ -68,30 +68,30 @@ /* CPU exception context structure in MP shared ram after trap */ typedef struct mp_xcptcontext_s MP_XCPTC; struct mp_xcptcontext_s { - dword sr; - dword cr; - dword epc; - dword vaddr; - dword regs[32]; - dword mdlo; - dword mdhi; - dword reseverd; - dword xclass; + dword sr; + dword cr; + dword epc; + dword vaddr; + dword regs[32]; + dword mdlo; + dword mdhi; + dword reseverd; + dword xclass; }; /* boot interface structure for PRI */ struct mp_load { - dword volatile cmd; - dword volatile addr; - dword volatile len; - dword volatile err; - dword volatile live; - dword volatile res1[0x1b]; - dword volatile TrapId; /* has value 0x999999XX on a CPU trap */ - dword volatile res2[0x03]; - MP_XCPTC volatile xcpt; /* contains register dump */ - dword volatile rest[((0x1020>>2)-6) - 0x1b - 1 - 0x03 - (sizeof(MP_XCPTC)>>2)]; - dword volatile signature; - dword data[60000]; /* real interface description */ + dword volatile cmd; + dword volatile addr; + dword volatile len; + dword volatile err; + dword volatile live; + dword volatile res1[0x1b]; + dword volatile TrapId; /* has value 0x999999XX on a CPU trap */ + dword volatile res2[0x03]; + MP_XCPTC volatile xcpt; /* contains register dump */ + dword volatile rest[((0x1020 >> 2) - 6) - 0x1b - 1 - 0x03 - (sizeof(MP_XCPTC) >> 2)]; + dword volatile signature; + dword data[60000]; /* real interface description */ }; /*----------------------------------------------------------------------------*/ /* SERVER 4BRI (Quattro PCI) */ @@ -150,11 +150,11 @@ struct mp_load { #define CS_BASEREG 0x0018 #define BOOT_BASEREG 0x001c #define GTREGS_BASEREG 0x0024 /*GTRegsBase reg-contain the base addr where*/ - /*the GT64010 internal regs where mapped */ + /*the GT64010 internal regs where mapped */ /* * GT64010 internal registers */ - /* DRAM device coding */ +/* DRAM device coding */ #define LOW_RAS0_DREG 0x0400 /*Ras0 low decode address*/ #define HI_RAS0_DREG 0x0404 /*Ras0 high decode address*/ #define LOW_RAS1_DREG 0x0408 /*Ras1 low decode address*/ @@ -163,7 +163,7 @@ struct mp_load { #define HI_RAS2_DREG 0x0414 /*Ras2 high decode address*/ #define LOW_RAS3_DREG 0x0418 /*Ras3 low decode address*/ #define HI_RAS3_DREG 0x041c /*Ras3 high decode address*/ - /* I/O CS device coding */ +/* I/O CS device coding */ #define LOW_CS0_DREG 0x0420 /* CS0* low decode register */ #define HI_CS0_DREG 0x0424 /* CS0* high decode register */ #define LOW_CS1_DREG 0x0428 /* CS1* low decode register */ @@ -172,20 +172,20 @@ struct mp_load { #define HI_CS2_DREG 0x0434 /* CS2* high decode register */ #define LOW_CS3_DREG 0x0438 /* CS3* low decode register */ #define HI_CS3_DREG 0x043c /* CS3* high decode register */ - /* Boot PROM device coding */ +/* Boot PROM device coding */ #define LOW_BOOTCS_DREG 0x0440 /* Boot CS low decode register */ #define HI_BOOTCS_DREG 0x0444 /* Boot CS High decode register */ - /* DRAM group coding (for CPU) */ +/* DRAM group coding (for CPU) */ #define LO_RAS10_GREG 0x0008 /*Ras1..0 group low decode address*/ #define HI_RAS10_GREG 0x0010 /*Ras1..0 group high decode address*/ #define LO_RAS32_GREG 0x0018 /*Ras3..2 group low decode address */ #define HI_RAS32_GREG 0x0020 /*Ras3..2 group high decode address */ - /* I/O CS group coding for (CPU) */ +/* I/O CS group coding for (CPU) */ #define LO_CS20_GREG 0x0028 /* CS2..0 group low decode register */ #define HI_CS20_GREG 0x0030 /* CS2..0 group high decode register */ #define LO_CS3B_GREG 0x0038 /* CS3 & PROM group low decode register */ #define HI_CS3B_GREG 0x0040 /* CS3 & PROM group high decode register */ - /* Galileo specific PCI config. */ +/* Galileo specific PCI config. */ #define PCI_TIMEOUT_RET 0x0c04 /* Time Out and retry register */ #define RAS10_BANKSIZE 0x0c08 /* RAS 1..0 group PCI bank size */ #define RAS32_BANKSIZE 0x0c0c /* RAS 3..2 group PCI bank size */ diff --git a/drivers/isdn/hardware/eicon/mntfunc.c b/drivers/isdn/hardware/eicon/mntfunc.c index a564b756003..1cd9affb605 100644 --- a/drivers/isdn/hardware/eicon/mntfunc.c +++ b/drivers/isdn/hardware/eicon/mntfunc.c @@ -27,7 +27,7 @@ static dword notify_handle; static DESCRIPTOR DAdapter; static DESCRIPTOR MAdapter; static DESCRIPTOR MaintDescriptor = - { IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp }; +{ IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp }; extern int diva_os_copy_to_user(void *os_handle, void __user *dst, const void *src, int length); @@ -44,7 +44,7 @@ static void no_printf(unsigned char *x, ...) /* * DIDD callback function */ -static void *didd_callback(void *context, DESCRIPTOR * adapter, +static void *didd_callback(void *context, DESCRIPTOR *adapter, int removal) { if (adapter->type == IDI_DADAPTER) { @@ -72,7 +72,7 @@ static void *didd_callback(void *context, DESCRIPTOR * adapter, /* * connect to didd */ -static int DIVA_INIT_FUNCTION connect_didd(void) +static int __init connect_didd(void) { int x = 0; int dadapter = 0; @@ -87,20 +87,20 @@ static int DIVA_INIT_FUNCTION connect_didd(void) 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; + 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); + DAdapter.request((ENTITY *)&req); if (req.didd_notify.e.Rc != 0xff) return (0); notify_handle = req.didd_notify.info.handle; /* Register MAINT (me) */ req.didd_add_adapter.e.Req = 0; req.didd_add_adapter.e.Rc = - IDI_SYNC_REQ_DIDD_ADD_ADAPTER; + IDI_SYNC_REQ_DIDD_ADD_ADAPTER; req.didd_add_adapter.info.descriptor = - (void *) &MaintDescriptor; - DAdapter.request((ENTITY *) & req); + (void *) &MaintDescriptor; + DAdapter.request((ENTITY *)&req); if (req.didd_add_adapter.e.Rc != 0xff) return (0); } else if ((DIDD_Table[x].type > 0) @@ -114,20 +114,20 @@ static int DIVA_INIT_FUNCTION connect_didd(void) /* * disconnect from didd */ -static void DIVA_EXIT_FUNCTION disconnect_didd(void) +static void __exit disconnect_didd(void) { IDI_SYNC_REQ req; 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); + DAdapter.request((ENTITY *)&req); req.didd_remove_adapter.e.Req = 0; req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER; req.didd_remove_adapter.info.p_request = - (IDI_CALL) MaintDescriptor.request; - DAdapter.request((ENTITY *) & req); + (IDI_CALL) MaintDescriptor.request; + DAdapter.request((ENTITY *)&req); } /* @@ -147,9 +147,9 @@ int maint_read_write(void __user *buf, int count) return (-EFAULT); } - cmd = *(dword *) & data[0]; /* command */ - id = *(dword *) & data[4]; /* driver id */ - mask = *(dword *) & data[8]; /* mask or size */ + cmd = *(dword *)&data[0]; /* command */ + id = *(dword *)&data[4]; /* driver id */ + mask = *(dword *)&data[8]; /* mask or size */ switch (cmd) { case DITRACE_CMD_GET_DRIVER_INFO: @@ -178,19 +178,19 @@ int maint_read_write(void __user *buf, int count) } break; - /* - Filter commands will ignore the ID due to fact that filtering affects - the B- channel and Audio Tap trace levels only. Also MAINT driver will - select the right trace ID by itself - */ + /* + Filter commands will ignore the ID due to fact that filtering affects + the B- channel and Audio Tap trace levels only. Also MAINT driver will + select the right trace ID by itself + */ case DITRACE_WRITE_SELECTIVE_TRACE_FILTER: if (!mask) { - ret = diva_set_trace_filter (1, "*"); + ret = diva_set_trace_filter(1, "*"); } else if (mask < sizeof(data)) { - if (diva_os_copy_from_user(NULL, data, (char __user *)buf+12, mask)) { + if (diva_os_copy_from_user(NULL, data, (char __user *)buf + 12, mask)) { ret = -EFAULT; } else { - ret = diva_set_trace_filter ((int)mask, data); + ret = diva_set_trace_filter((int)mask, data); } } else { ret = -EINVAL; @@ -198,8 +198,8 @@ int maint_read_write(void __user *buf, int count) break; case DITRACE_READ_SELECTIVE_TRACE_FILTER: - if ((ret = diva_get_trace_filter (sizeof(data), data)) > 0) { - if (diva_os_copy_to_user (NULL, buf, data, ret)) + if ((ret = diva_get_trace_filter(sizeof(data), data)) > 0) { + if (diva_os_copy_to_user(NULL, buf, data, ret)) ret = -EFAULT; } else { ret = -ENODEV; @@ -207,88 +207,88 @@ int maint_read_write(void __user *buf, int count) break; case DITRACE_READ_TRACE_ENTRY:{ - diva_os_spin_lock_magic_t old_irql; - word size; - diva_dbg_entry_head_t *pmsg; - byte *pbuf; + diva_os_spin_lock_magic_t old_irql; + word size; + diva_dbg_entry_head_t *pmsg; + byte *pbuf; - if (!(pbuf = diva_os_malloc(0, mask))) { - return (-ENOMEM); - } + if (!(pbuf = diva_os_malloc(0, mask))) { + return (-ENOMEM); + } - for(;;) { - if (!(pmsg = - diva_maint_get_message(&size, &old_irql))) { - break; - } - if (size > mask) { - diva_maint_ack_message(0, &old_irql); - ret = -EINVAL; - break; - } - ret = size; - memcpy(pbuf, pmsg, size); - diva_maint_ack_message(1, &old_irql); - if ((count < size) || - diva_os_copy_to_user (NULL, buf, (void *) pbuf, size)) - ret = -EFAULT; + for (;;) { + if (!(pmsg = + diva_maint_get_message(&size, &old_irql))) { + break; + } + if (size > mask) { + diva_maint_ack_message(0, &old_irql); + ret = -EINVAL; break; } - diva_os_free(0, pbuf); + ret = size; + memcpy(pbuf, pmsg, size); + diva_maint_ack_message(1, &old_irql); + if ((count < size) || + diva_os_copy_to_user(NULL, buf, (void *) pbuf, size)) + ret = -EFAULT; + break; } + diva_os_free(0, pbuf); + } break; case DITRACE_READ_TRACE_ENTRYS:{ - diva_os_spin_lock_magic_t old_irql; - word size; - diva_dbg_entry_head_t *pmsg; - byte *pbuf = NULL; - int written = 0; + diva_os_spin_lock_magic_t old_irql; + word size; + diva_dbg_entry_head_t *pmsg; + byte *pbuf = NULL; + int written = 0; - if (mask < 4096) { - ret = -EINVAL; + if (mask < 4096) { + ret = -EINVAL; + break; + } + if (!(pbuf = diva_os_malloc(0, mask))) { + return (-ENOMEM); + } + + for (;;) { + if (!(pmsg = + diva_maint_get_message(&size, &old_irql))) { break; } - if (!(pbuf = diva_os_malloc(0, mask))) { - return (-ENOMEM); - } - - for (;;) { - if (!(pmsg = - diva_maint_get_message(&size, &old_irql))) { - break; - } - if ((size + 8) > mask) { - diva_maint_ack_message(0, &old_irql); - break; - } - /* - Write entry length - */ - pbuf[written++] = (byte) size; - pbuf[written++] = (byte) (size >> 8); - pbuf[written++] = 0; - pbuf[written++] = 0; - /* - Write message - */ - memcpy(&pbuf[written], pmsg, size); - diva_maint_ack_message(1, &old_irql); - written += size; - mask -= (size + 4); + if ((size + 8) > mask) { + diva_maint_ack_message(0, &old_irql); + break; } + /* + Write entry length + */ + pbuf[written++] = (byte) size; + pbuf[written++] = (byte) (size >> 8); pbuf[written++] = 0; pbuf[written++] = 0; - pbuf[written++] = 0; - pbuf[written++] = 0; + /* + Write message + */ + memcpy(&pbuf[written], pmsg, size); + diva_maint_ack_message(1, &old_irql); + written += size; + mask -= (size + 4); + } + pbuf[written++] = 0; + pbuf[written++] = 0; + pbuf[written++] = 0; + pbuf[written++] = 0; - if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) { - ret = -EFAULT; - } else { - ret = written; - } - diva_os_free(0, pbuf); + if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) { + ret = -EFAULT; + } else { + ret = written; } + diva_os_free(0, pbuf); + } break; default: @@ -300,7 +300,7 @@ int maint_read_write(void __user *buf, int count) /* * init */ -int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer, +int __init mntfunc_init(int *buffer_length, void **buffer, unsigned long diva_dbg_mem) { if (*buffer_length < 64) { @@ -316,7 +316,7 @@ int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer, } else { while ((*buffer_length >= (64 * 1024)) && - (!(*buffer = diva_os_malloc (0, *buffer_length)))) { + (!(*buffer = diva_os_malloc(0, *buffer_length)))) { *buffer_length -= 1024; } @@ -328,7 +328,7 @@ int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer, if (diva_maint_init(*buffer, *buffer_length, (diva_dbg_mem == 0))) { if (!diva_dbg_mem) { - diva_os_free (0, *buffer); + diva_os_free(0, *buffer); } DBG_ERR(("init: maint init failed")); return (0); @@ -338,7 +338,7 @@ int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer, DBG_ERR(("init: failed to connect to DIDD.")); diva_maint_finit(); if (!diva_dbg_mem) { - diva_os_free (0, *buffer); + diva_os_free(0, *buffer); } return (0); } @@ -348,7 +348,7 @@ int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer, /* * exit */ -void DIVA_EXIT_FUNCTION mntfunc_finit(void) +void __exit mntfunc_finit(void) { void *buffer; int i = 100; @@ -362,7 +362,7 @@ void DIVA_EXIT_FUNCTION mntfunc_finit(void) disconnect_didd(); if ((buffer = diva_maint_finit())) { - diva_os_free (0, buffer); + diva_os_free(0, buffer); } memset(&MAdapter, 0, sizeof(MAdapter)); diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c index 11e6f937c1e..1891246807e 100644 --- a/drivers/isdn/hardware/eicon/os_4bri.c +++ b/drivers/isdn/hardware/eicon/os_4bri.c @@ -27,12 +27,12 @@ static dword diva_xdiLoadFileLength = 0; extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter); extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter); extern void diva_xdi_display_adapter_features(int card); -extern void diva_add_slave_adapter(diva_os_xdi_adapter_t * a); +extern void diva_add_slave_adapter(diva_os_xdi_adapter_t *a); extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter); extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter); -extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a); +extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a); /* ** LOCALS @@ -57,23 +57,23 @@ static unsigned long _4bri_v2_bri_bar_length[4] = { }; -static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a); -static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a); +static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a); +static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a); static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, - diva_xdi_um_cfg_cmd_t * cmd, + diva_xdi_um_cfg_cmd_t *cmd, int length); -static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a); -static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a, - byte * data, dword length); +static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a); +static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a, + byte *data, dword length); static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter); static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter, dword address, - const byte * data, + const byte *data, dword length, dword limit); static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter, dword start_address, dword features); static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter); -static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a); +static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a); static int _4bri_is_rev_2_card(int card_ordinal) { @@ -112,8 +112,8 @@ static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a) a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0; /* - Set up hardware related pointers - */ + Set up hardware related pointers + */ a->xdi_adapter.Address = a->resources.pci.addr[2]; /* BAR2 SDRAM */ a->xdi_adapter.Address += c_offset; @@ -121,15 +121,15 @@ static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a) a->xdi_adapter.ram = a->resources.pci.addr[2]; /* BAR2 SDRAM */ a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE); - + a->xdi_adapter.reset = a->resources.pci.addr[0]; /* BAR0 CONFIG */ /* - ctlReg contains the register address for the MIPS CPU reset control - */ + ctlReg contains the register address for the MIPS CPU reset control + */ a->xdi_adapter.ctlReg = a->resources.pci.addr[3]; /* BAR3 CNTRL */ /* - prom contains the register address for FPGA and EEPROM programming - */ + prom contains the register address for FPGA and EEPROM programming + */ a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E]; } @@ -141,7 +141,7 @@ static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a) ** ** Called by master adapter, that will initialize and add slave adapters */ -int diva_4bri_init_card(diva_os_xdi_adapter_t * a) +int diva_4bri_init_card(diva_os_xdi_adapter_t *a) { int bar, i; byte __iomem *p; @@ -149,8 +149,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) diva_os_xdi_adapter_t *diva_current; diva_os_xdi_adapter_t *adapter_list[4]; PISDN_ADAPTER Slave; - unsigned long bar_length[sizeof(_4bri_bar_length) / - sizeof(_4bri_bar_length[0])]; + unsigned long bar_length[ARRAY_SIZE(_4bri_bar_length)]; int v2 = _4bri_is_rev_2_card(a->CardOrdinal); int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT; int factor = (tasks == 1) ? 1 : 2; @@ -169,48 +168,48 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d", bar_length[2], tasks, factor)) - /* - Get Serial Number - The serial number of 4BRI is accessible in accordance with PCI spec - via command register located in configuration space, also we do not - have to map any BAR before we can access it - */ - if (!_4bri_get_serial_number(a)) { - DBG_ERR(("A: 4BRI can't get Serial Number")) - diva_4bri_cleanup_adapter(a); - return (-1); - } + /* + Get Serial Number + The serial number of 4BRI is accessible in accordance with PCI spec + via command register located in configuration space, also we do not + have to map any BAR before we can access it + */ + if (!_4bri_get_serial_number(a)) { + DBG_ERR(("A: 4BRI can't get Serial Number")) + diva_4bri_cleanup_adapter(a); + return (-1); + } /* - Set properties - */ + Set properties + */ a->xdi_adapter.Properties = CardProperties[a->CardOrdinal]; DBG_LOG(("Load %s, SN:%ld, bus:%02x, func:%02x", a->xdi_adapter.Properties.Name, a->xdi_adapter.serialNo, a->resources.pci.bus, a->resources.pci.func)) - /* - First initialization step: get and check hardware resoures. - Do not map resources and do not access card at this step - */ - for (bar = 0; bar < 4; bar++) { - a->resources.pci.bar[bar] = - divasa_get_pci_bar(a->resources.pci.bus, - a->resources.pci.func, bar, - a->resources.pci.hdev); - if (!a->resources.pci.bar[bar] - || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) { - DBG_ERR( - ("A: invalid bar[%d]=%08x", bar, - a->resources.pci.bar[bar])) - return (-1); + /* + First initialization step: get and check hardware resoures. + Do not map resources and do not access card at this step + */ + for (bar = 0; bar < 4; bar++) { + a->resources.pci.bar[bar] = + divasa_get_pci_bar(a->resources.pci.bus, + a->resources.pci.func, bar, + a->resources.pci.hdev); + if (!a->resources.pci.bar[bar] + || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) { + DBG_ERR( + ("A: invalid bar[%d]=%08x", bar, + a->resources.pci.bar[bar])) + return (-1); + } } - } a->resources.pci.irq = - (byte) divasa_get_pci_irq(a->resources.pci.bus, - a->resources.pci.func, - a->resources.pci.hdev); + (byte) divasa_get_pci_irq(a->resources.pci.bus, + a->resources.pci.func, + a->resources.pci.hdev); if (!a->resources.pci.irq) { DBG_ERR(("A: invalid irq")); return (-1); @@ -219,30 +218,30 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) a->xdi_adapter.sdram_bar = a->resources.pci.bar[2]; /* - Map all MEMORY BAR's - */ + Map all MEMORY BAR's + */ for (bar = 0; bar < 4; bar++) { if (bar != 1) { /* ignore I/O */ a->resources.pci.addr[bar] = - divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar], - bar_length[bar]); + divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar], + bar_length[bar]); if (!a->resources.pci.addr[bar]) { DBG_ERR(("A: 4BRI: can't map bar[%d]", bar)) - diva_4bri_cleanup_adapter(a); + diva_4bri_cleanup_adapter(a); return (-1); } } } /* - Register I/O port - */ + Register I/O port + */ sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo); if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1], bar_length[1], &a->port_name[0], 1)) { DBG_ERR(("A: 4BRI: can't register bar[1]")) - diva_4bri_cleanup_adapter(a); + diva_4bri_cleanup_adapter(a); return (-1); } @@ -250,23 +249,23 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) (void *) (unsigned long) a->resources.pci.bar[1]; /* - Set cleanup pointer for base adapter only, so slave adapter - will be unable to get cleanup - */ + Set cleanup pointer for base adapter only, so slave adapter + will be unable to get cleanup + */ a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter; /* - Create slave adapters - */ + Create slave adapters + */ if (tasks > 1) { if (!(a->slave_adapters[0] = - (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) + (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) { diva_4bri_cleanup_adapter(a); return (-1); } if (!(a->slave_adapters[1] = - (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) + (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) { diva_os_free(0, a->slave_adapters[0]); a->slave_adapters[0] = NULL; @@ -274,7 +273,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) return (-1); } if (!(a->slave_adapters[2] = - (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) + (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) { diva_os_free(0, a->slave_adapters[0]); diva_os_free(0, a->slave_adapters[1]); @@ -294,10 +293,10 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) adapter_list[3] = a->slave_adapters[2]; /* - Allocate slave list - */ + Allocate slave list + */ quadro_list = - (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list)); + (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list)); if (!(a->slave_list = quadro_list)) { for (i = 0; i < (tasks - 1); i++) { diva_os_free(0, a->slave_adapters[i]); @@ -309,14 +308,14 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) memset(quadro_list, 0x00, sizeof(*quadro_list)); /* - Set interfaces - */ + Set interfaces + */ a->xdi_adapter.QuadroList = quadro_list; for (i = 0; i < tasks; i++) { adapter_list[i]->xdi_adapter.ControllerNumber = i; adapter_list[i]->xdi_adapter.tasks = tasks; quadro_list->QuadroAdapter[i] = - &adapter_list[i]->xdi_adapter; + &adapter_list[i]->xdi_adapter; } for (i = 0; i < tasks; i++) { @@ -325,21 +324,21 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) diva_current->dsp_mask = 0x00000003; diva_current->xdi_adapter.a.io = - &diva_current->xdi_adapter; + &diva_current->xdi_adapter; diva_current->xdi_adapter.DIRequest = request; diva_current->interface.cmd_proc = diva_4bri_cmd_card_proc; diva_current->xdi_adapter.Properties = - CardProperties[a->CardOrdinal]; + CardProperties[a->CardOrdinal]; diva_current->CardOrdinal = a->CardOrdinal; diva_current->xdi_adapter.Channels = - CardProperties[a->CardOrdinal].Channels; + CardProperties[a->CardOrdinal].Channels; diva_current->xdi_adapter.e_max = - CardProperties[a->CardOrdinal].E_info; + CardProperties[a->CardOrdinal].E_info; diva_current->xdi_adapter.e_tbl = - diva_os_malloc(0, - diva_current->xdi_adapter.e_max * - sizeof(E_INFO)); + diva_os_malloc(0, + diva_current->xdi_adapter.e_max * + sizeof(E_INFO)); if (!diva_current->xdi_adapter.e_tbl) { diva_4bri_cleanup_slave_adapters(a); @@ -371,8 +370,8 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) strcpy(diva_current->xdi_adapter.req_soft_isr. dpc_thread_name, "kdivas4brid"); - if (diva_os_initialize_soft_isr (&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine, - &diva_current->xdi_adapter)) { + if (diva_os_initialize_soft_isr(&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine, + &diva_current->xdi_adapter)) { diva_4bri_cleanup_slave_adapters(a); diva_4bri_cleanup_adapter(a); for (i = 1; i < (tasks - 1); i++) { @@ -382,10 +381,10 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) } /* - Do not initialize second DPC - only one thread will be created - */ + Do not initialize second DPC - only one thread will be created + */ diva_current->xdi_adapter.isr_soft_isr.object = - diva_current->xdi_adapter.req_soft_isr.object; + diva_current->xdi_adapter.req_soft_isr.object; } if (v2) { @@ -398,12 +397,12 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) diva_current = adapter_list[i]; if (i) memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t)); - diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor); + diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor); } /* - Set up hardware related pointers - */ + Set up hardware related pointers + */ a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0]; /* BAR0 CONFIG */ a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1]; /* BAR1 */ a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3]; /* BAR3 CNTRL */ @@ -416,21 +415,21 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) Slave->sdram_bar = a->xdi_adapter.sdram_bar; if (i) { Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) | - a->xdi_adapter.serialNo; + a->xdi_adapter.serialNo; Slave->cardType = a->xdi_adapter.cardType; } } /* - reset contains the base address for the PLX 9054 register set - */ + reset contains the base address for the PLX 9054 register set + */ p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter); WRITE_BYTE(&p[PLX9054_INTCSR], 0x00); /* disable PCI interrupts */ DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p); /* - Set IRQ handler - */ + Set IRQ handler + */ a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq; sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo); @@ -448,8 +447,8 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) a->xdi_adapter.irq_info.registered = 1; /* - Add three slave adapters - */ + Add three slave adapters + */ if (tasks > 1) { diva_add_slave_adapter(adapter_list[1]); diva_add_slave_adapter(adapter_list[2]); @@ -464,36 +463,36 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a) /* ** Cleanup function will be called for master adapter only -** this is garanteed by design: cleanup callback is set +** this is guaranteed by design: cleanup callback is set ** by master adapter only */ -static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a) +static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a) { int bar; /* - Stop adapter if running - */ + Stop adapter if running + */ if (a->xdi_adapter.Initialized) { diva_4bri_stop_adapter(a); } /* - Remove IRQ handler - */ + Remove IRQ handler + */ if (a->xdi_adapter.irq_info.registered) { diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr); } a->xdi_adapter.irq_info.registered = 0; /* - Free DPC's and spin locks on all adapters - */ + Free DPC's and spin locks on all adapters + */ diva_4bri_cleanup_slave_adapters(a); /* - Unmap all BARS - */ + Unmap all BARS + */ for (bar = 0; bar < 4; bar++) { if (bar != 1) { if (a->resources.pci.bar[bar] @@ -506,8 +505,8 @@ static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a) } /* - Unregister I/O - */ + Unregister I/O + */ if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) { diva_os_register_io_port(a, 0, a->resources.pci.bar[1], _4bri_is_rev_2_card(a-> @@ -527,7 +526,7 @@ static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a) return (0); } -static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a) +static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a) { dword data[64]; dword serNo; @@ -552,13 +551,13 @@ static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a) } if (j >= 5) { DBG_ERR(("EEPROM[%d] read failed (0x%x)", i * 4, addr)) - return (0); + return (0); } PCIread(Bus, Slot, 0x50, &data[i], sizeof(data[i]), hdev); } DBG_BLK(((char *) &data[0], sizeof(data))) - serNo = data[32]; + serNo = data[32]; if (serNo == 0 || serNo == 0xffffffff) serNo = data[63]; @@ -573,13 +572,13 @@ static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a) DBG_REG(("Serial No. : %ld", a->xdi_adapter.serialNo)) - return (serNo); + return (serNo); } /* ** Release resources of slave adapters */ -static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a) +static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a) { diva_os_xdi_adapter_t *adapter_list[4]; diva_os_xdi_adapter_t *diva_current; @@ -626,24 +625,24 @@ static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a) static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, - diva_xdi_um_cfg_cmd_t * cmd, int length) + diva_xdi_um_cfg_cmd_t *cmd, int length) { int ret = -1; if (cmd->adapter != a->controller) { DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d", cmd->adapter, a->controller)) - return (-1); + return (-1); } switch (cmd->command) { case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = - (dword) a->CardOrdinal; + (dword) a->CardOrdinal; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } @@ -652,10 +651,10 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_GET_SERIAL_NR: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = - (dword) a->xdi_adapter.serialNo; + (dword) a->xdi_adapter.serialNo; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } @@ -664,11 +663,11 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG: if (!a->xdi_adapter.ControllerNumber) { /* - Only master adapter can access hardware config - */ + Only master adapter can access hardware config + */ a->xdi_mbox.data_length = sizeof(dword) * 9; a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { int i; dword *data = (dword *) a->xdi_mbox.data; @@ -687,7 +686,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, if (!a->xdi_adapter.ControllerNumber) { a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { dword *data = (dword *) a->xdi_mbox.data; if (!a->xdi_adapter.ram @@ -710,11 +709,11 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_WRITE_FPGA: if (!a->xdi_adapter.ControllerNumber) { ret = - diva_4bri_write_fpga_image(a, - (byte *) & cmd[1], - cmd->command_data. - write_fpga. - image_length); + diva_4bri_write_fpga_image(a, + (byte *)&cmd[1], + cmd->command_data. + write_fpga. + image_length); } break; @@ -755,12 +754,12 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES: if (!a->xdi_adapter.ControllerNumber) { a->xdi_adapter.features = - cmd->command_data.features.features; + cmd->command_data.features.features; a->xdi_adapter.a.protocol_capabilities = - a->xdi_adapter.features; + a->xdi_adapter.features; DBG_TRC(("Set raw protocol features (%08x)", a->xdi_adapter.features)) - ret = 0; + ret = 0; } break; @@ -778,16 +777,16 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, if (!a->xdi_adapter.ControllerNumber && a->xdi_adapter.Address) { if ( - (a->xdi_mbox.data_length = - cmd->command_data.read_sdram.length)) { + (a->xdi_mbox.data_length = + cmd->command_data.read_sdram.length)) { if ( - (a->xdi_mbox.data_length + - cmd->command_data.read_sdram.offset) < - a->xdi_adapter.MemorySize) { + (a->xdi_mbox.data_length + + cmd->command_data.read_sdram.offset) < + a->xdi_adapter.MemorySize) { a->xdi_mbox.data = - diva_os_malloc(0, - a->xdi_mbox. - data_length); + diva_os_malloc(0, + a->xdi_mbox. + data_length); if (a->xdi_mbox.data) { byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter); byte __iomem *src = p; @@ -811,7 +810,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, default: DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller, cmd->command)) - } + } return (ret); } @@ -839,7 +838,7 @@ void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter) } static int -diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a, byte * data, +diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a, byte *data, dword length) { int ret; @@ -866,12 +865,12 @@ static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter) if (IoAdapter->Initialized) { DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first", IoAdapter->ANum)) - return (-1); + return (-1); } /* - Forget all entities on all adapters - */ + Forget all entities on all adapters + */ for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) { Slave = IoAdapter->QuadroList->QuadroAdapter[i]; Slave->e_count = 0; @@ -909,7 +908,7 @@ static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter) static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter, dword address, - const byte * data, dword length, dword limit) + const byte *data, dword length, dword limit) { byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); byte __iomem *mem = p; @@ -918,7 +917,7 @@ diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter, DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p); DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx", IoAdapter->ANum, address + length)) - return (-1); + return (-1); } mem += address; @@ -940,14 +939,14 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter, byte __iomem *p; /* - start adapter - */ + start adapter + */ start_qBri_hardware(IoAdapter); p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter); /* - wait for signature in shared memory (max. 3 seconds) - */ + wait for signature in shared memory (max. 3 seconds) + */ signature = (volatile word __iomem *) (&p[0x1E]); for (i = 0; i < 300; ++i) { @@ -955,23 +954,23 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter, if (READ_WORD(&signature[0]) == 0x4447) { DBG_TRC(("Protocol startup time %d.%02d seconds", (i / 100), (i % 100))) - started = 1; + started = 1; break; } } for (i = 1; i < IoAdapter->tasks; i++) { IoAdapter->QuadroList->QuadroAdapter[i]->features = - IoAdapter->features; + IoAdapter->features; IoAdapter->QuadroList->QuadroAdapter[i]->a. - protocol_capabilities = IoAdapter->features; + protocol_capabilities = IoAdapter->features; } if (!started) { DBG_FTL(("%s: Adapter selftest failed, signature=%04x", IoAdapter->Properties.Name, READ_WORD(&signature[0]))) - DIVA_OS_MEM_DETACH_RAM(IoAdapter, p); + DIVA_OS_MEM_DETACH_RAM(IoAdapter, p); (*(IoAdapter->trapFnc)) (IoAdapter); IoAdapter->stop(IoAdapter); return (-1); @@ -986,9 +985,9 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter, if (check_qBri_interrupt(IoAdapter)) { DBG_ERR(("A: A(%d) interrupt test failed", IoAdapter->ANum)) - for (i = 0; i < IoAdapter->tasks; i++) { - IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0; - } + for (i = 0; i < IoAdapter->tasks; i++) { + IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0; + } IoAdapter->stop(IoAdapter); return (-1); } @@ -997,10 +996,10 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter, diva_xdi_display_adapter_features(IoAdapter->ANum); for (i = 0; i < IoAdapter->tasks; i++) { - DBG_LOG(("A(%d) %s adapter successfull started", + DBG_LOG(("A(%d) %s adapter successfully started", IoAdapter->QuadroList->QuadroAdapter[i]->ANum, (IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI")) - diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum); + diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum); IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features; } @@ -1023,8 +1022,8 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter) WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE); DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); /* - interrupt test - */ + interrupt test + */ a->ReadyInt = 1; a->ram_out(a, &PR_RAM->ReadyInt, 1); @@ -1035,14 +1034,14 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter) dword volatile __iomem *qBriIrq; byte __iomem *p; /* - Reset on-board interrupt register - */ + Reset on-board interrupt register + */ IoAdapter->IrqCount = 0; p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card - (IoAdapter-> - cardType) ? (MQ2_BREG_IRQ_TEST) - : (MQ_BREG_IRQ_TEST)]); + (IoAdapter-> + cardType) ? (MQ2_BREG_IRQ_TEST) + : (MQ_BREG_IRQ_TEST)]); WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); @@ -1057,13 +1056,13 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter) #endif /* SUPPORT_INTERRUPT_TEST_ON_4BRI */ } -static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a) +static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t *a) { PISDN_ADAPTER IoAdapter = &a->xdi_adapter; /* - clear any pending interrupt - */ + clear any pending interrupt + */ IoAdapter->disIrq(IoAdapter); IoAdapter->tst_irq(&IoAdapter->a); @@ -1071,13 +1070,13 @@ static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a) IoAdapter->tst_irq(&IoAdapter->a); /* - kill pending dpcs - */ + kill pending dpcs + */ diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr); diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr); } -static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a) +static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a) { PISDN_ADAPTER IoAdapter = &a->xdi_adapter; int i; @@ -1089,7 +1088,7 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a) if (!IoAdapter->Initialized) { DBG_ERR(("A: A(%d) can't stop PRI adapter - not running", IoAdapter->ANum)) - return (-1); /* nothing to stop */ + return (-1); /* nothing to stop */ } for (i = 0; i < IoAdapter->tasks; i++) { @@ -1097,8 +1096,8 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a) } /* - Disconnect Adapters from DIDD - */ + Disconnect Adapters from DIDD + */ for (i = 0; i < IoAdapter->tasks; i++) { diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum); } @@ -1106,8 +1105,8 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a) i = 100; /* - Stop interrupts - */ + Stop interrupts + */ a->clear_interrupts_proc = diva_4bri_clear_interrupts; IoAdapter->a.ReadyInt = 1; IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt); @@ -1120,12 +1119,12 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a) a->clear_interrupts_proc = NULL; DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter", IoAdapter->ANum)) - } + } IoAdapter->a.ReadyInt = 0; /* - Stop and reset adapter - */ + Stop and reset adapter + */ IoAdapter->stop(IoAdapter); return (0); diff --git a/drivers/isdn/hardware/eicon/os_4bri.h b/drivers/isdn/hardware/eicon/os_4bri.h index 665f0af27ce..72253278d4f 100644 --- a/drivers/isdn/hardware/eicon/os_4bri.h +++ b/drivers/isdn/hardware/eicon/os_4bri.h @@ -3,6 +3,6 @@ #ifndef __DIVA_OS_4_BRI_H__ #define __DIVA_OS_4_BRI_H__ -int diva_4bri_init_card(diva_os_xdi_adapter_t * a); +int diva_4bri_init_card(diva_os_xdi_adapter_t *a); #endif diff --git a/drivers/isdn/hardware/eicon/os_bri.c b/drivers/isdn/hardware/eicon/os_bri.c index f31bba5b16f..20f2653c58f 100644 --- a/drivers/isdn/hardware/eicon/os_bri.c +++ b/drivers/isdn/hardware/eicon/os_bri.c @@ -23,7 +23,7 @@ */ extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter); extern void diva_xdi_display_adapter_features(int card); -extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a); +extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a); /* ** LOCALS @@ -33,20 +33,20 @@ static int bri_bar_length[3] = { 0x80, 0x20 }; -static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a); -static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a); +static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a); +static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a); static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, - diva_xdi_um_cfg_cmd_t * cmd, int length); -static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a); + diva_xdi_um_cfg_cmd_t *cmd, int length); +static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a); static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter); static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter, dword address, - const byte * data, dword length); + const byte *data, dword length); static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter, dword start_address, dword features); -static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a); +static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a); -static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a) +static void diva_bri_set_addresses(diva_os_xdi_adapter_t *a) { a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0; a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1; @@ -54,7 +54,7 @@ static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a) a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1; a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2; a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2; - + a->xdi_adapter.ram = a->resources.pci.addr[0]; a->xdi_adapter.cfg = a->resources.pci.addr[1]; a->xdi_adapter.Address = a->resources.pci.addr[2]; @@ -72,7 +72,7 @@ static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a) ** BAR1 - I/O Addr - 0x80 ** BAR2 - I/O Addr - 0x20 */ -int diva_bri_init_card(diva_os_xdi_adapter_t * a) +int diva_bri_init_card(diva_os_xdi_adapter_t *a) { int bar; dword bar2 = 0, bar2_length = 0xffffffff; @@ -82,75 +82,75 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a) byte __iomem *p; /* - Set properties - */ + Set properties + */ a->xdi_adapter.Properties = CardProperties[a->CardOrdinal]; DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name)) - /* - Get resources - */ - for (bar = 0; bar < 3; bar++) { - a->resources.pci.bar[bar] = - divasa_get_pci_bar(a->resources.pci.bus, - a->resources.pci.func, bar, - a->resources.pci.hdev); - if (!a->resources.pci.bar[bar]) { - DBG_ERR(("A: can't get BAR[%d]", bar)) - return (-1); + /* + Get resources + */ + for (bar = 0; bar < 3; bar++) { + a->resources.pci.bar[bar] = + divasa_get_pci_bar(a->resources.pci.bus, + a->resources.pci.func, bar, + a->resources.pci.hdev); + if (!a->resources.pci.bar[bar]) { + DBG_ERR(("A: can't get BAR[%d]", bar)) + return (-1); + } } - } a->resources.pci.irq = - (byte) divasa_get_pci_irq(a->resources.pci.bus, - a->resources.pci.func, - a->resources.pci.hdev); + (byte) divasa_get_pci_irq(a->resources.pci.bus, + a->resources.pci.func, + a->resources.pci.hdev); if (!a->resources.pci.irq) { DBG_ERR(("A: invalid irq")); return (-1); } /* - Get length of I/O bar 2 - it is different by older - EEPROM version - */ + Get length of I/O bar 2 - it is different by older + EEPROM version + */ Bus = a->resources.pci.bus; Slot = a->resources.pci.func; hdev = a->resources.pci.hdev; /* - Get plain original values of the BAR2 CDM registers - */ + Get plain original values of the BAR2 CDM registers + */ PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev); PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev); /* - Disable device and get BAR2 length - */ + Disable device and get BAR2 length + */ PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev); PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev); PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev); /* - Restore BAR2 and CMD registers - */ + Restore BAR2 and CMD registers + */ PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev); PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev); /* - Calculate BAR2 length - */ + Calculate BAR2 length + */ bar2_length = (~(bar2_length & ~7)) + 1; DBG_LOG(("BAR[2] length=%lx", bar2_length)) - /* - Map and register resources - */ - if (!(a->resources.pci.addr[0] = - divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0], - bri_bar_length[0]))) { - DBG_ERR(("A: BRI, can't map BAR[0]")) - diva_bri_cleanup_adapter(a); - return (-1); - } + /* + Map and register resources + */ + if (!(a->resources.pci.addr[0] = + divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0], + bri_bar_length[0]))) { + DBG_ERR(("A: BRI, can't map BAR[0]")) + diva_bri_cleanup_adapter(a); + return (-1); + } sprintf(&a->port_name[0], "BRI %02x:%02x", a->resources.pci.bus, a->resources.pci.func); @@ -158,7 +158,7 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a) if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1], bri_bar_length[1], &a->port_name[0], 1)) { DBG_ERR(("A: BRI, can't register BAR[1]")) - diva_bri_cleanup_adapter(a); + diva_bri_cleanup_adapter(a); return (-1); } a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1]; @@ -167,33 +167,33 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a) if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2], bar2_length, &a->port_name[0], 2)) { DBG_ERR(("A: BRI, can't register BAR[2]")) - diva_bri_cleanup_adapter(a); + diva_bri_cleanup_adapter(a); return (-1); } a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2]; a->resources.pci.length[2] = bar2_length; /* - Set all memory areas - */ + Set all memory areas + */ diva_bri_set_addresses(a); /* - Get Serial Number - */ + Get Serial Number + */ a->xdi_adapter.serialNo = diva_bri_get_serial_number(a); /* - Register I/O ports with correct name now - */ + Register I/O ports with correct name now + */ if (diva_bri_reregister_io(a)) { diva_bri_cleanup_adapter(a); return (-1); } /* - Initialize OS dependent objects - */ + Initialize OS dependent objects + */ if (diva_os_initialize_spin_lock (&a->xdi_adapter.isr_spin_lock, "isr")) { diva_bri_cleanup_adapter(a); @@ -213,13 +213,13 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a) return (-1); } /* - Do not initialize second DPC - only one thread will be created - */ + Do not initialize second DPC - only one thread will be created + */ a->xdi_adapter.isr_soft_isr.object = a->xdi_adapter.req_soft_isr.object; /* - Create entity table - */ + Create entity table + */ a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels; a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info; a->xdi_adapter.e_tbl = diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO)); @@ -230,8 +230,8 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a) memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO)); /* - Set up interface - */ + Set up interface + */ a->xdi_adapter.a.io = &a->xdi_adapter; a->xdi_adapter.DIRequest = request; a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter; @@ -246,8 +246,8 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a) a->dsp_mask = 0x00000003; /* - Set IRQ handler - */ + Set IRQ handler + */ a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq; sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %ld", (long) a->xdi_adapter.serialNo); @@ -265,7 +265,7 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a) } -static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a) +static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a) { int i; @@ -274,8 +274,8 @@ static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a) } /* - Remove ISR Handler - */ + Remove ISR Handler + */ if (a->xdi_adapter.irq_info.registered) { diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr); } @@ -300,8 +300,8 @@ static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a) } /* - Free OS objects - */ + Free OS objects + */ diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr); diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr); @@ -312,8 +312,8 @@ static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a) diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm"); /* - Free memory - */ + Free memory + */ if (a->xdi_adapter.e_tbl) { diva_os_free(0, a->xdi_adapter.e_tbl); a->xdi_adapter.e_tbl = NULL; @@ -329,7 +329,7 @@ void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter) /* ** Get serial number */ -static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a) +static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a) { dword serNo = 0; byte __iomem *confIO; @@ -345,7 +345,7 @@ static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a) if ((serNo == 0) || (serNo == 0xFFFFFFFF)) { DBG_FTL(("W: BRI use BAR[0] to get card serial number")) - confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter); + confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter); serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF); serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF); serNo = (((dword) serHi) << 16) | ((dword) serLo); @@ -354,14 +354,14 @@ static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a) DBG_LOG(("Serial Number=%ld", serNo)) - return (serNo); + return (serNo); } /* ** Unregister I/O and register it with new name, ** based on Serial Number */ -static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a) +static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a) { int i; @@ -380,10 +380,10 @@ static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a) a->resources.pci.length[i], &a->port_name[0], i)) { DBG_ERR(("A: failed to reregister BAR[%d]", i)) - return (-1); + return (-1); } a->resources.pci.addr[i] = - (void *) (unsigned long) a->resources.pci.bar[i]; + (void *) (unsigned long) a->resources.pci.bar[i]; } return (0); @@ -394,24 +394,24 @@ static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a) */ static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, - diva_xdi_um_cfg_cmd_t * cmd, int length) + diva_xdi_um_cfg_cmd_t *cmd, int length) { int ret = -1; if (cmd->adapter != a->controller) { DBG_ERR(("A: pri_cmd, invalid controller=%d != %d", cmd->adapter, a->controller)) - return (-1); + return (-1); } switch (cmd->command) { case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = - (dword) a->CardOrdinal; + (dword) a->CardOrdinal; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } @@ -420,10 +420,10 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_GET_SERIAL_NR: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = - (dword) a->xdi_adapter.serialNo; + (dword) a->xdi_adapter.serialNo; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } @@ -432,7 +432,7 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG: a->xdi_mbox.data_length = sizeof(dword) * 9; a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { int i; dword *data = (dword *) a->xdi_mbox.data; @@ -449,7 +449,7 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_GET_CARD_STATE: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { dword *data = (dword *) a->xdi_mbox.data; if (!a->xdi_adapter.port) { @@ -474,7 +474,7 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, ret = diva_bri_write_sdram_block(&a->xdi_adapter, cmd->command_data. write_sdram.offset, - (byte *) & cmd[1], + (byte *)&cmd[1], cmd->command_data. write_sdram.length); break; @@ -489,9 +489,9 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES: a->xdi_adapter.features = - cmd->command_data.features.features; + cmd->command_data.features.features; a->xdi_adapter.a.protocol_capabilities = - a->xdi_adapter.features; + a->xdi_adapter.features; DBG_TRC( ("Set raw protocol features (%08x)", a->xdi_adapter.features)) ret = 0; @@ -530,18 +530,18 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter) diva_os_wait(100); Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter); addrHi = Port + - ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); addrLo = Port + ADDR; ioaddr = Port + DATA; /* - recover - */ + recover + */ outpp(addrHi, (byte) 0); outppw(addrLo, (word) 0); outppw(ioaddr, (word) 0); /* - clear shared memory - */ + clear shared memory + */ outpp(addrHi, (byte) ( (IoAdapter->MemoryBase + IoAdapter->MemorySize - @@ -551,8 +551,8 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter) diva_os_wait(100); /* - clear signature - */ + clear signature + */ outpp(addrHi, (byte) ( (IoAdapter->MemoryBase + IoAdapter->MemorySize - @@ -568,8 +568,8 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter) DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port); /* - Forget all outstanding entities - */ + Forget all outstanding entities + */ IoAdapter->e_count = 0; if (IoAdapter->e_tbl) { memset(IoAdapter->e_tbl, 0x00, @@ -602,7 +602,7 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter) static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter, - dword address, const byte * data, dword length) + dword address, const byte *data, dword length) { byte __iomem *addrHi, *addrLo, *ioaddr; byte __iomem *Port; @@ -613,7 +613,7 @@ diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter, Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter); addrHi = Port + - ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); addrLo = Port + ADDR; ioaddr = Port + DATA; @@ -651,9 +651,9 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter, sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum); DBG_LOG(("A(%d) start BRI", IoAdapter->ANum)) - Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter); + Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter); addrHi = Port + - ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); addrLo = Port + ADDR; ioaddr = Port + DATA; @@ -666,20 +666,20 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter, DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port); /* - start the protocol code - */ + start the protocol code + */ Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); outpp(Port, 0x08); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port); Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter); addrHi = Port + - ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); addrLo = Port + ADDR; ioaddr = Port + DATA; /* - wait for signature (max. 3 seconds) - */ + wait for signature (max. 3 seconds) + */ for (i = 0; i < 300; ++i) { diva_os_wait(10); outpp(addrHi, @@ -693,7 +693,7 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter, DBG_LOG( ("Protocol startup time %d.%02d seconds", (i / 100), (i % 100))) - started = 1; + started = 1; break; } } @@ -703,15 +703,15 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter, DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X", IoAdapter->ANum, IoAdapter->Properties.Name, test)) - (*(IoAdapter->trapFnc)) (IoAdapter); + (*(IoAdapter->trapFnc)) (IoAdapter); return (-1); } IoAdapter->Initialized = 1; /* - Check Interrupt - */ + Check Interrupt + */ IoAdapter->IrqCount = 0; a->ReadyInt = 1; @@ -729,29 +729,29 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter, DBG_ERR( ("A: A(%d) interrupt test failed", IoAdapter->ANum)) - IoAdapter->Initialized = 0; + IoAdapter->Initialized = 0; IoAdapter->stop(IoAdapter); return (-1); } IoAdapter->Properties.Features = (word) features; diva_xdi_display_adapter_features(IoAdapter->ANum); - DBG_LOG(("A(%d) BRI adapter successfull started", IoAdapter->ANum)) - /* - Register with DIDD - */ - diva_xdi_didd_register_adapter(IoAdapter->ANum); + DBG_LOG(("A(%d) BRI adapter successfully started", IoAdapter->ANum)) + /* + Register with DIDD + */ + diva_xdi_didd_register_adapter(IoAdapter->ANum); return (0); } -static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t * a) +static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t *a) { PISDN_ADAPTER IoAdapter = &a->xdi_adapter; /* - clear any pending interrupt - */ + clear any pending interrupt + */ IoAdapter->disIrq(IoAdapter); IoAdapter->tst_irq(&IoAdapter->a); @@ -759,8 +759,8 @@ static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t * a) IoAdapter->tst_irq(&IoAdapter->a); /* - kill pending dpcs - */ + kill pending dpcs + */ diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr); diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr); } @@ -768,7 +768,7 @@ static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t * a) /* ** Stop card */ -static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a) +static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a) { PISDN_ADAPTER IoAdapter = &a->xdi_adapter; int i = 100; @@ -779,18 +779,18 @@ static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a) if (!IoAdapter->Initialized) { DBG_ERR(("A: A(%d) can't stop BRI adapter - not running", IoAdapter->ANum)) - return (-1); /* nothing to stop */ + return (-1); /* nothing to stop */ } IoAdapter->Initialized = 0; /* - Disconnect Adapter from DIDD - */ + Disconnect Adapter from DIDD + */ diva_xdi_didd_remove_adapter(IoAdapter->ANum); /* - Stop interrupts - */ + Stop interrupts + */ a->clear_interrupts_proc = diva_bri_clear_interrupts; IoAdapter->a.ReadyInt = 1; IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt); @@ -802,12 +802,12 @@ static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a) a->clear_interrupts_proc = NULL; DBG_ERR(("A: A(%d) no final interrupt from BRI adapter", IoAdapter->ANum)) - } + } IoAdapter->a.ReadyInt = 0; /* - Stop and reset adapter - */ + Stop and reset adapter + */ IoAdapter->stop(IoAdapter); return (0); diff --git a/drivers/isdn/hardware/eicon/os_bri.h b/drivers/isdn/hardware/eicon/os_bri.h index a54f0ce58e1..02e7456f896 100644 --- a/drivers/isdn/hardware/eicon/os_bri.h +++ b/drivers/isdn/hardware/eicon/os_bri.h @@ -3,6 +3,6 @@ #ifndef __DIVA_OS_BRI_REV_1_H__ #define __DIVA_OS_BRI_REV_1_H__ -int diva_bri_init_card(diva_os_xdi_adapter_t * a); +int diva_bri_init_card(diva_os_xdi_adapter_t *a); #endif diff --git a/drivers/isdn/hardware/eicon/os_capi.h b/drivers/isdn/hardware/eicon/os_capi.h index 726f915a09e..e72394b95d5 100644 --- a/drivers/isdn/hardware/eicon/os_capi.h +++ b/drivers/isdn/hardware/eicon/os_capi.h @@ -1,16 +1,16 @@ /* $Id: os_capi.h,v 1.7 2003/04/12 21:40:49 schindler Exp $ * * ISDN interface module for Eicon active cards DIVA. - * CAPI Interface OS include files - * - * Copyright 2000-2003 by Armin Schindler (mac@melware.de) + * CAPI Interface OS include files + * + * Copyright 2000-2003 by Armin Schindler (mac@melware.de) * Copyright 2000-2003 Cytronics & Melware (info@melware.de) - * + * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. */ -#ifndef __OS_CAPI_H__ +#ifndef __OS_CAPI_H__ #define __OS_CAPI_H__ #include <linux/capi.h> diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c index a296a846f29..da4957abb42 100644 --- a/drivers/isdn/hardware/eicon/os_pri.c +++ b/drivers/isdn/hardware/eicon/os_pri.c @@ -24,11 +24,11 @@ OS Dependent part of XDI driver for DIVA PRI Adapter DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com) --------------------------------------------------------------------------- */ + -------------------------------------------------------------------------- */ #define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1 -extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a); +extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a); /* ** IMPORTS @@ -37,12 +37,12 @@ extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter); extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter); extern void diva_xdi_display_adapter_features(int card); -static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a); +static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a); static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, - diva_xdi_um_cfg_cmd_t * cmd, int length); -static int pri_get_serial_number(diva_os_xdi_adapter_t * a); -static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a); -static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a); + diva_xdi_um_cfg_cmd_t *cmd, int length); +static int pri_get_serial_number(diva_os_xdi_adapter_t *a); +static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a); +static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a); /* ** Check card revision @@ -57,7 +57,7 @@ static int pri_is_rev_2_card(int card_ordinal) return (0); } -static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a) +static void diva_pri_set_addresses(diva_os_xdi_adapter_t *a) { a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0; a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2; @@ -66,7 +66,7 @@ static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a) a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2; a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4; a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3; - + a->xdi_adapter.Address = a->resources.pci.addr[0]; a->xdi_adapter.Control = a->resources.pci.addr[2]; a->xdi_adapter.Config = a->resources.pci.addr[4]; @@ -92,7 +92,7 @@ static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a) ** BAR3 - FLASH (REG), 0x8000 ** BAR4 - CONFIG (CFG), 0x1000 */ -int diva_pri_init_card(diva_os_xdi_adapter_t * a) +int diva_pri_init_card(diva_os_xdi_adapter_t *a) { int bar = 0; int pri_rev_2; @@ -110,59 +110,59 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a) bar_length[0] = MP2_MEMORY_SIZE; } /* - Set properties - */ + Set properties + */ a->xdi_adapter.Properties = CardProperties[a->CardOrdinal]; DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name)) - /* - First initialization step: get and check hardware resoures. - Do not map resources and do not acecess card at this step - */ - for (bar = 0; bar < 5; bar++) { - a->resources.pci.bar[bar] = - divasa_get_pci_bar(a->resources.pci.bus, - a->resources.pci.func, bar, - a->resources.pci.hdev); - if (!a->resources.pci.bar[bar] - || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) { - DBG_ERR(("A: invalid bar[%d]=%08x", bar, - a->resources.pci.bar[bar])) - return (-1); + /* + First initialization step: get and check hardware resoures. + Do not map resources and do not acecess card at this step + */ + for (bar = 0; bar < 5; bar++) { + a->resources.pci.bar[bar] = + divasa_get_pci_bar(a->resources.pci.bus, + a->resources.pci.func, bar, + a->resources.pci.hdev); + if (!a->resources.pci.bar[bar] + || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) { + DBG_ERR(("A: invalid bar[%d]=%08x", bar, + a->resources.pci.bar[bar])) + return (-1); + } } - } a->resources.pci.irq = - (byte) divasa_get_pci_irq(a->resources.pci.bus, - a->resources.pci.func, - a->resources.pci.hdev); + (byte) divasa_get_pci_irq(a->resources.pci.bus, + a->resources.pci.func, + a->resources.pci.hdev); if (!a->resources.pci.irq) { DBG_ERR(("A: invalid irq")); return (-1); } /* - Map all BAR's - */ + Map all BAR's + */ for (bar = 0; bar < 5; bar++) { a->resources.pci.addr[bar] = - divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar], - bar_length[bar]); + divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar], + bar_length[bar]); if (!a->resources.pci.addr[bar]) { DBG_ERR(("A: A(%d), can't map bar[%d]", a->controller, bar)) - diva_pri_cleanup_adapter(a); + diva_pri_cleanup_adapter(a); return (-1); } } /* - Set all memory areas - */ + Set all memory areas + */ diva_pri_set_addresses(a); /* - Get Serial Number of this adapter - */ + Get Serial Number of this adapter + */ if (pri_get_serial_number(a)) { dword serNo; serNo = a->resources.pci.bar[1] & 0xffff0000; @@ -171,12 +171,12 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a) a->xdi_adapter.serialNo = serNo & ~0xFF000000; DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld", a->controller, a->xdi_adapter.serialNo)) - } + } /* - Initialize os objects - */ + Initialize os objects + */ if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) { diva_pri_cleanup_adapter(a); return (-1); @@ -196,20 +196,20 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a) } /* - Do not initialize second DPC - only one thread will be created - */ + Do not initialize second DPC - only one thread will be created + */ a->xdi_adapter.isr_soft_isr.object = - a->xdi_adapter.req_soft_isr.object; + a->xdi_adapter.req_soft_isr.object; /* - Next step of card initialization: - set up all interface pointers - */ + Next step of card initialization: + set up all interface pointers + */ a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels; a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info; a->xdi_adapter.e_tbl = - diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO)); + diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO)); if (!a->xdi_adapter.e_tbl) { diva_pri_cleanup_adapter(a); return (-1); @@ -230,16 +230,16 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a) a->dsp_mask = diva_pri_detect_dsps(a); /* - Allocate DMA map - */ + Allocate DMA map + */ if (pri_rev_2) { diva_init_dma_map(a->resources.pci.hdev, (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32); } /* - Set IRQ handler - */ + Set IRQ handler + */ a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq; sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA PRI %ld", (long) a->xdi_adapter.serialNo); @@ -257,28 +257,28 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a) return (0); } -static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a) +static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a) { int bar = 0; /* - Stop Adapter if adapter is running - */ + Stop Adapter if adapter is running + */ if (a->xdi_adapter.Initialized) { diva_pri_stop_adapter(a); } /* - Remove ISR Handler - */ + Remove ISR Handler + */ if (a->xdi_adapter.irq_info.registered) { diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr); } a->xdi_adapter.irq_info.registered = 0; /* - Step 1: unmap all BAR's, if any was mapped - */ + Step 1: unmap all BAR's, if any was mapped + */ for (bar = 0; bar < 5; bar++) { if (a->resources.pci.bar[bar] && a->resources.pci.addr[bar]) { @@ -289,8 +289,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a) } /* - Free OS objects - */ + Free OS objects + */ diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr); diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr); @@ -301,8 +301,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a) diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm"); /* - Free memory accupied by XDI adapter - */ + Free memory accupied by XDI adapter + */ if (a->xdi_adapter.e_tbl) { diva_os_free(0, a->xdi_adapter.e_tbl); a->xdi_adapter.e_tbl = NULL; @@ -312,8 +312,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a) /* - Free adapter DMA map - */ + Free adapter DMA map + */ diva_free_dma_map(a->resources.pci.hdev, (struct _diva_dma_map_entry *) a->xdi_adapter. dma_map); @@ -321,8 +321,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a) /* - Detach this adapter from debug driver - */ + Detach this adapter from debug driver + */ return (0); } @@ -341,7 +341,7 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter) if (IoAdapter->Initialized) { DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first", IoAdapter->ANum)) - return (-1); + return (-1); } boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); @@ -360,20 +360,20 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter) DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!", IoAdapter->ANum, IoAdapter->serialNo)) - return (-1); + return (-1); } if (READ_DWORD(&boot->err)) { DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx", IoAdapter->ANum, IoAdapter->serialNo, READ_DWORD(&boot->err))) - DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); + DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); return (-1); } DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); /* - Forget all outstanding entities - */ + Forget all outstanding entities + */ IoAdapter->e_count = 0; if (IoAdapter->e_tbl) { memset(IoAdapter->e_tbl, 0x00, @@ -407,7 +407,7 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter) static int diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter, dword address, - const byte * data, dword length, dword limit) + const byte *data, dword length, dword limit) { byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); byte __iomem *mem = p; @@ -416,7 +416,7 @@ diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter, DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p); DBG_ERR(("A: A(%d) write PRI address=0x%08lx", IoAdapter->ANum, address + length)) - return (-1); + return (-1); } mem += address; @@ -443,20 +443,20 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter, DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running", IoAdapter->ANum)) - return (-1); + return (-1); } if (!boot) { DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); DBG_ERR(("A: PRI %ld can't start, adapter not mapped", IoAdapter->serialNo)) - return (-1); + return (-1); } sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum); DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum, start_address)) - WRITE_DWORD(&boot->addr, start_address); + WRITE_DWORD(&boot->addr, start_address); WRITE_DWORD(&boot->cmd, 3); for (i = 0; i < 300; ++i) { @@ -464,7 +464,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter, if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) { DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds", IoAdapter->ANum, (i / 100), (i % 100))) - started = 1; + started = 1; break; } } @@ -478,7 +478,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter, DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx", IoAdapter->ANum, READ_DWORD(&boot->signature), TrapId, debug)) - DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); + DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); if (IoAdapter->trapFnc) { (*(IoAdapter->trapFnc)) (IoAdapter); } @@ -487,14 +487,14 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter, } DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot); - IoAdapter->Initialized = TRUE; + IoAdapter->Initialized = true; /* - Check Interrupt - */ + Check Interrupt + */ IoAdapter->IrqCount = 0; p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter); - WRITE_DWORD(p, (dword) ~ 0x03E00000); + WRITE_DWORD(p, (dword)~0x03E00000); DIVA_OS_MEM_DETACH_CFG(IoAdapter, p); a->ReadyInt = 1; a->ram_out(a, &PR_RAM->ReadyInt, 1); @@ -504,7 +504,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter, if (!IoAdapter->IrqCount) { DBG_ERR(("A: A(%d) interrupt test failed", IoAdapter->ANum)) - IoAdapter->Initialized = FALSE; + IoAdapter->Initialized = false; IoAdapter->stop(IoAdapter); return (-1); } @@ -513,22 +513,22 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter, diva_xdi_display_adapter_features(IoAdapter->ANum); - DBG_LOG(("A(%d) PRI adapter successfull started", IoAdapter->ANum)) - /* - Register with DIDD - */ - diva_xdi_didd_register_adapter(IoAdapter->ANum); + DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum)) + /* + Register with DIDD + */ + diva_xdi_didd_register_adapter(IoAdapter->ANum); return (0); } -static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a) +static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t *a) { PISDN_ADAPTER IoAdapter = &a->xdi_adapter; /* - clear any pending interrupt - */ + clear any pending interrupt + */ IoAdapter->disIrq(IoAdapter); IoAdapter->tst_irq(&IoAdapter->a); @@ -536,8 +536,8 @@ static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a) IoAdapter->tst_irq(&IoAdapter->a); /* - kill pending dpcs - */ + kill pending dpcs + */ diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr); diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr); } @@ -546,7 +546,7 @@ static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a) ** Stop Adapter, but do not unmap/unregister - adapter ** will be restarted later */ -static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a) +static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a) { PISDN_ADAPTER IoAdapter = &a->xdi_adapter; int i = 100; @@ -557,18 +557,18 @@ static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a) if (!IoAdapter->Initialized) { DBG_ERR(("A: A(%d) can't stop PRI adapter - not running", IoAdapter->ANum)) - return (-1); /* nothing to stop */ + return (-1); /* nothing to stop */ } IoAdapter->Initialized = 0; /* - Disconnect Adapter from DIDD - */ + Disconnect Adapter from DIDD + */ diva_xdi_didd_remove_adapter(IoAdapter->ANum); /* - Stop interrupts - */ + Stop interrupts + */ a->clear_interrupts_proc = diva_pri_clear_interrupts; IoAdapter->a.ReadyInt = 1; IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt); @@ -581,12 +581,12 @@ static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a) a->clear_interrupts_proc = NULL; DBG_ERR(("A: A(%d) no final interrupt from PRI adapter", IoAdapter->ANum)) - } + } IoAdapter->a.ReadyInt = 0; /* - Stop and reset adapter - */ + Stop and reset adapter + */ IoAdapter->stop(IoAdapter); return (0); @@ -600,24 +600,24 @@ static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a) */ static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, - diva_xdi_um_cfg_cmd_t * cmd, int length) + diva_xdi_um_cfg_cmd_t *cmd, int length) { int ret = -1; if (cmd->adapter != a->controller) { DBG_ERR(("A: pri_cmd, invalid controller=%d != %d", cmd->adapter, a->controller)) - return (-1); + return (-1); } switch (cmd->command) { case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = - (dword) a->CardOrdinal; + (dword) a->CardOrdinal; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } @@ -626,10 +626,10 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_GET_SERIAL_NR: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = - (dword) a->xdi_adapter.serialNo; + (dword) a->xdi_adapter.serialNo; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } @@ -638,7 +638,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG: a->xdi_mbox.data_length = sizeof(dword) * 9; a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { int i; dword *data = (dword *) a->xdi_mbox.data; @@ -660,7 +660,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, ret = diva_pri_write_sdram_block(&a->xdi_adapter, cmd->command_data. write_sdram.offset, - (byte *) & cmd[1], + (byte *)&cmd[1], cmd->command_data. write_sdram.length, pri_is_rev_2_card(a-> @@ -683,22 +683,22 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES: a->xdi_adapter.features = - cmd->command_data.features.features; + cmd->command_data.features.features; a->xdi_adapter.a.protocol_capabilities = - a->xdi_adapter.features; + a->xdi_adapter.features; DBG_TRC(("Set raw protocol features (%08x)", a->xdi_adapter.features)) - ret = 0; + ret = 0; break; case DIVA_XDI_UM_CMD_GET_CARD_STATE: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = - diva_os_malloc(0, a->xdi_mbox.data_length); + diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { dword *data = (dword *) a->xdi_mbox.data; if (!a->xdi_adapter.ram || - !a->xdi_adapter.reset || + !a->xdi_adapter.reset || !a->xdi_adapter.cfg) { *data = 3; } else if (a->xdi_adapter.trapped) { @@ -720,16 +720,16 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, case DIVA_XDI_UM_CMD_READ_SDRAM: if (a->xdi_adapter.Address) { if ( - (a->xdi_mbox.data_length = - cmd->command_data.read_sdram.length)) { + (a->xdi_mbox.data_length = + cmd->command_data.read_sdram.length)) { if ( - (a->xdi_mbox.data_length + - cmd->command_data.read_sdram.offset) < - a->xdi_adapter.MemorySize) { + (a->xdi_mbox.data_length + + cmd->command_data.read_sdram.offset) < + a->xdi_adapter.MemorySize) { a->xdi_mbox.data = - diva_os_malloc(0, - a->xdi_mbox. - data_length); + diva_os_malloc(0, + a->xdi_mbox. + data_length); if (a->xdi_mbox.data) { byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter); byte __iomem *src = p; @@ -753,7 +753,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, default: DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller, cmd->command)) - } + } return (ret); } @@ -761,7 +761,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a, /* ** Get Serial Number */ -static int pri_get_serial_number(diva_os_xdi_adapter_t * a) +static int pri_get_serial_number(diva_os_xdi_adapter_t *a) { byte data[64]; int i; @@ -773,28 +773,28 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a) /* * First set some GT6401x config registers before accessing the BOOT-ROM */ - config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); + config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); c = READ_BYTE(&config[0xc3c]); if (!(c & 0x08)) { WRITE_BYTE(&config[0xc3c], c); /* Base Address enable register */ } WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00); WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF); - DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); + DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); /* * Read only the last 64 bytes of manufacturing data */ memset(data, '\0', len); - flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter); + flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter); for (i = 0; i < len; i++) { data[i] = READ_BYTE(&flash[0x8000 - len + i]); } - DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash); + DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash); - config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); + config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC); /* Disable FLASH EPROM access */ WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF); - DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); + DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); if (memcmp(&data[48], "DIVAserverPR", 12)) { #if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND) /* { */ @@ -808,11 +808,11 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a) addr1 = a->resources.pci.bar[1]; /* unused */ DBG_ERR(("A: apply Compaq BIOS workaround")) - DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7])) + DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7])) - Bus = a->resources.pci.bus; + Bus = a->resources.pci.bus; Slot = a->resources.pci.func; hdev = a->resources.pci.hdev; PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev); @@ -832,69 +832,69 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a) a->resources.pci.bar[4] = addr1; /* - Try to read Flash again - */ + Try to read Flash again + */ len = sizeof(data); - config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); + config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); if (!(config[0xc3c] & 0x08)) { config[0xc3c] |= 0x08; /* Base Address enable register */ } config[LOW_BOOTCS_DREG] = 0x00; config[HI_BOOTCS_DREG] = 0xFF; - DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); + DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); memset(data, '\0', len); - flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter); + flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter); for (i = 0; i < len; i++) { data[i] = flash[0x8000 - len + i]; } - DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash); - config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); + DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash); + config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter); config[LOW_BOOTCS_DREG] = 0xFC; config[HI_BOOTCS_DREG] = 0xFF; - DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); + DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config); if (memcmp(&data[48], "DIVAserverPR", 12)) { DBG_ERR(("A: failed to read serial number")) - DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7])) - return (-1); + DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7])) + return (-1); } #else /* } { */ DBG_ERR(("A: failed to read DIVA signature word")) - DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7])) - DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46], - data[45], data[44])) + DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7])) + DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46], + data[45], data[44])) #endif /* } */ - } + } a->xdi_adapter.serialNo = - (data[47] << 24) | (data[46] << 16) | (data[45] << 8) | - data[44]; + (data[47] << 24) | (data[46] << 16) | (data[45] << 8) | + data[44]; if (!a->xdi_adapter.serialNo || (a->xdi_adapter.serialNo == 0xffffffff)) { a->xdi_adapter.serialNo = 0; DBG_ERR(("A: failed to read serial number")) - return (-1); + return (-1); } DBG_LOG(("Serial No. : %ld", a->xdi_adapter.serialNo)) - DBG_TRC(("Board Revision : %d.%02d", (int) data[41], - (int) data[40])) - DBG_TRC(("PLD revision : %d.%02d", (int) data[33], - (int) data[32])) - DBG_TRC(("Boot loader version : %d.%02d", (int) data[37], - (int) data[36])) + DBG_TRC(("Board Revision : %d.%02d", (int) data[41], + (int) data[40])) + DBG_TRC(("PLD revision : %d.%02d", (int) data[33], + (int) data[32])) + DBG_TRC(("Boot loader version : %d.%02d", (int) data[37], + (int) data[36])) - DBG_TRC(("Manufacturing Date : %d/%02d/%02d (yyyy/mm/dd)", - (int) ((data[28] > 90) ? 1900 : 2000) + - (int) data[28], (int) data[29], (int) data[30])) + DBG_TRC(("Manufacturing Date : %d/%02d/%02d (yyyy/mm/dd)", + (int) ((data[28] > 90) ? 1900 : 2000) + + (int) data[28], (int) data[29], (int) data[30])) - return (0); + return (0); } void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter) @@ -909,7 +909,7 @@ void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter) ** Checks presence of DSP on board */ static int -dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, int dsp) +dsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp) { word pattern; @@ -922,7 +922,7 @@ dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, i if (pattern != DSP_SIGNATURE_PROBE_WORD) { DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)", dsp, pattern, DSP_SIGNATURE_PROBE_WORD)) - return (-1); + return (-1); } WRITE_WORD(addr, 0x4000); @@ -931,15 +931,15 @@ dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, i WRITE_WORD(addr, 0x4000); pattern = READ_WORD(data); - if (pattern != (word) ~ DSP_SIGNATURE_PROBE_WORD) { + if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) { DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)", - dsp, pattern, (word) ~ DSP_SIGNATURE_PROBE_WORD)) - return (-2); + dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD)) + return (-2); } DBG_TRC(("DSP[%d] present", dsp)) - return (0); + return (0); } @@ -952,7 +952,7 @@ dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, i ** ... ** Bit 29 - DSP30 */ -static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a) +static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a) { byte __iomem *base; byte __iomem *p; @@ -1008,8 +1008,8 @@ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a) diva_os_wait(5); /* - Verify modules - */ + Verify modules + */ for (dsp_row = 0; dsp_row < 4; dsp_row++) { row_state = ((ret >> (dsp_row * 7)) & 0x7F); if (row_state && (row_state != 0x7F)) { @@ -1018,35 +1018,35 @@ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a) DBG_ERR(("A: MODULE[%d]-DSP[%d] failed", dsp_row + 1, dsp_index + 1)) - } + } } } } if (!(ret & 0x10000000)) { DBG_ERR(("A: ON BOARD-DSP[1] failed")) - } + } if (!(ret & 0x20000000)) { DBG_ERR(("A: ON BOARD-DSP[2] failed")) - } + } /* - Print module population now - */ - DBG_LOG(("+-----------------------+")) - DBG_LOG(("| DSP MODULE POPULATION |")) - DBG_LOG(("+-----------------------+")) - DBG_LOG(("| 1 | 2 | 3 | 4 |")) - DBG_LOG(("+-----------------------+")) - DBG_LOG(("| %s | %s | %s | %s |", - ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N", - ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N", - ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N", - ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N")) + Print module population now + */ DBG_LOG(("+-----------------------+")) - - DBG_LOG(("DSP's(present-absent):%08x-%08x", ret, - ~ret & 0x3fffffff)) - - return (ret); + DBG_LOG(("| DSP MODULE POPULATION |")) + DBG_LOG(("+-----------------------+")) + DBG_LOG(("| 1 | 2 | 3 | 4 |")) + DBG_LOG(("+-----------------------+")) + DBG_LOG(("| %s | %s | %s | %s |", + ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N", + ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N", + ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N", + ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N")) + DBG_LOG(("+-----------------------+")) + + DBG_LOG(("DSP's(present-absent):%08x-%08x", ret, + ~ret & 0x3fffffff)) + + return (ret); } diff --git a/drivers/isdn/hardware/eicon/os_pri.h b/drivers/isdn/hardware/eicon/os_pri.h index a7c42f94d78..537c74d042e 100644 --- a/drivers/isdn/hardware/eicon/os_pri.h +++ b/drivers/isdn/hardware/eicon/os_pri.h @@ -3,6 +3,6 @@ #ifndef __DIVA_OS_PRI_REV_1_H__ #define __DIVA_OS_PRI_REV_1_H__ -int diva_pri_init_card(diva_os_xdi_adapter_t * a); +int diva_pri_init_card(diva_os_xdi_adapter_t *a); #endif diff --git a/drivers/isdn/hardware/eicon/pc.h b/drivers/isdn/hardware/eicon/pc.h index 1c6945768a3..329c0c26abf 100644 --- a/drivers/isdn/hardware/eicon/pc.h +++ b/drivers/isdn/hardware/eicon/pc.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PC_H_INCLUDED /* { */ @@ -29,42 +29,42 @@ /* buffer definition */ /*------------------------------------------------------------------*/ typedef struct { - word length; /* length of data/parameter field */ - byte P[270]; /* data/parameter field */ + word length; /* length of data/parameter field */ + byte P[270]; /* data/parameter field */ } PBUFFER; /*------------------------------------------------------------------*/ /* dual port ram structure */ /*------------------------------------------------------------------*/ struct dual { - byte Req; /* request register */ - byte ReqId; /* request task/entity identification */ - byte Rc; /* return code register */ - byte RcId; /* return code task/entity identification */ - byte Ind; /* Indication register */ - byte IndId; /* Indication task/entity identification */ - byte IMask; /* Interrupt Mask Flag */ - byte RNR; /* Receiver Not Ready (set by PC) */ - byte XLock; /* XBuffer locked Flag */ - byte Int; /* ISDN-S interrupt */ - byte ReqCh; /* Channel field for layer-3 Requests */ - byte RcCh; /* Channel field for layer-3 Returncodes */ - byte IndCh; /* Channel field for layer-3 Indications */ - byte MInd; /* more data indication field */ - word MLength; /* more data total packet length */ - byte ReadyInt; /* request field for ready interrupt */ - byte SWReg; /* Software register for special purposes */ - byte Reserved[11]; /* reserved space */ - byte InterfaceType; /* interface type 1=16K interface */ - word Signature; /* ISDN-S adapter Signature (GD) */ - PBUFFER XBuffer; /* Transmit Buffer */ - PBUFFER RBuffer; /* Receive Buffer */ + byte Req; /* request register */ + byte ReqId; /* request task/entity identification */ + byte Rc; /* return code register */ + byte RcId; /* return code task/entity identification */ + byte Ind; /* Indication register */ + byte IndId; /* Indication task/entity identification */ + byte IMask; /* Interrupt Mask Flag */ + byte RNR; /* Receiver Not Ready (set by PC) */ + byte XLock; /* XBuffer locked Flag */ + byte Int; /* ISDN-S interrupt */ + byte ReqCh; /* Channel field for layer-3 Requests */ + byte RcCh; /* Channel field for layer-3 Returncodes */ + byte IndCh; /* Channel field for layer-3 Indications */ + byte MInd; /* more data indication field */ + word MLength; /* more data total packet length */ + byte ReadyInt; /* request field for ready interrupt */ + byte SWReg; /* Software register for special purposes */ + byte Reserved[11]; /* reserved space */ + byte InterfaceType; /* interface type 1=16K interface */ + word Signature; /* ISDN-S adapter Signature (GD) */ + PBUFFER XBuffer; /* Transmit Buffer */ + PBUFFER RBuffer; /* Receive Buffer */ }; /*------------------------------------------------------------------*/ /* SWReg Values (0 means no command) */ /*------------------------------------------------------------------*/ #define SWREG_DIE_WITH_LEDON 0x01 -#define SWREG_HALT_CPU 0x02 /* Push CPU into a while(1) loop */ +#define SWREG_HALT_CPU 0x02 /* Push CPU into a while (1) loop */ /*------------------------------------------------------------------*/ /* Id Fields Coding */ /*------------------------------------------------------------------*/ @@ -273,7 +273,7 @@ struct dual #define MORE 0xa0 /* more data */ #define SDNCMPL 0xa1 /* sending complete */ #define CL 0xb0 /* congestion level */ - /* codeset 0 */ +/* codeset 0 */ #define SMSG 0x00 /* segmented message */ #define BC 0x04 /* Bearer Capability */ #define CAU 0x08 /* cause */ @@ -307,7 +307,7 @@ struct dual #define NLC 0x21 /* network layer configuration */ #define REDIRECT_IE 0x22 /* redirection request/indication data */ #define REDIRECT_NET_IE 0x23 /* redirection network override data */ - /* codeset 6 */ +/* codeset 6 */ #define SIN 0x01 /* service indicator */ #define CIF 0x02 /* charging information */ #define DATE 0x03 /* date */ @@ -387,13 +387,13 @@ struct dual #define SMASK_CCNR 0x00000200 #define SMASK_CONF 0x00000400 /* ---------------------------------------------- - Types of transfers used to transfer the - information in the 'struct RC->Reserved2[8]' - The information is transferred as 2 dwords - (2 4Byte unsigned values) - First of them is the transfer type. - 2^32-1 possible messages are possible in this way. - The context of the second one had no meaning + Types of transfers used to transfer the + information in the 'struct RC->Reserved2[8]' + The information is transferred as 2 dwords + (2 4Byte unsigned values) + First of them is the transfer type. + 2^32-1 possible messages are possible in this way. + The context of the second one had no meaning ---------------------------------------------- */ #define DIVA_RC_TYPE_NONE 0x00000000 #define DIVA_RC_TYPE_REMOVE_COMPLETE 0x00000008 @@ -402,14 +402,14 @@ struct dual #define DIVA_RC_TYPE_OK_FC 0x0000000b #define DIVA_RC_TYPE_RX_DMA 0x0000000c /* ------------------------------------------------------ - IO Control codes for IN BAND SIGNALING + IO Control codes for IN BAND SIGNALING ------------------------------------------------------ */ #define CTRL_L1_SET_SIG_ID 5 #define CTRL_L1_SET_DAD 6 #define CTRL_L1_RESOURCES 7 /* ------------------------------------------------------ */ /* ------------------------------------------------------ - Layer 2 types + Layer 2 types ------------------------------------------------------ */ #define X75T 1 /* x.75 for ttx */ #define TRF 2 /* transparent with hdlc framing */ @@ -419,11 +419,11 @@ struct dual #define LAPD 6 /* lapd (Q.921) */ #define X25_L2 7 /* x.25 layer-2 */ #define V120_L2 8 /* V.120 layer-2 protocol */ -#define V42_IN 9 /* V.42 layer-2 protocol, incomming */ +#define V42_IN 9 /* V.42 layer-2 protocol, incoming */ #define V42 10 /* V.42 layer-2 protocol */ #define MDM_ATP 11 /* AT Parser built in the L2 */ #define X75_V42BIS 12 /* x.75 with V.42bis */ -#define RTPL2_IN 13 /* RTP layer-2 protocol, incomming */ +#define RTPL2_IN 13 /* RTP layer-2 protocol, incoming */ #define RTPL2 14 /* RTP layer-2 protocol */ #define V120_V42BIS 15 /* V.120 asynchronous mode supporting V.42bis compression */ #define LISTENER 27 /* Layer 2 to listen line */ @@ -439,31 +439,31 @@ struct dual #define PIAFS_UDATA_ABILITY_DCDON 0x01 #define PIAFS_UDATA_ABILITY_DDI 0x80 /* -DLC of PIAFS : -Byte | 8 7 6 5 4 3 2 1 ------+-------------------------------------------------------- - 0 | 0 0 1 0 0 0 0 0 Data Link Configuration - 1 | X X X X X X X X Length of IE (at least 15 Bytes) - 2 | 0 0 0 0 0 0 0 0 max. information field, LOW byte (not used, fix 73 Bytes) - 3 | 0 0 0 0 0 0 0 0 max. information field, HIGH byte (not used, fix 73 Bytes) - 4 | 0 0 0 0 0 0 0 0 address A (not used) - 5 | 0 0 0 0 0 0 0 0 address B (not used) - 6 | 0 0 0 0 0 0 0 0 Mode (not used, fix 128) - 7 | 0 0 0 0 0 0 0 0 Window Size (not used, fix 127) - 8 | X X X X X X X X XID Length, Low Byte (at least 7 Bytes) - 9 | X X X X X X X X XID Length, High Byte + DLC of PIAFS : + Byte | 8 7 6 5 4 3 2 1 + -----+-------------------------------------------------------- + 0 | 0 0 1 0 0 0 0 0 Data Link Configuration + 1 | X X X X X X X X Length of IE (at least 15 Bytes) + 2 | 0 0 0 0 0 0 0 0 max. information field, LOW byte (not used, fix 73 Bytes) + 3 | 0 0 0 0 0 0 0 0 max. information field, HIGH byte (not used, fix 73 Bytes) + 4 | 0 0 0 0 0 0 0 0 address A (not used) + 5 | 0 0 0 0 0 0 0 0 address B (not used) + 6 | 0 0 0 0 0 0 0 0 Mode (not used, fix 128) + 7 | 0 0 0 0 0 0 0 0 Window Size (not used, fix 127) + 8 | X X X X X X X X XID Length, Low Byte (at least 7 Bytes) + 9 | X X X X X X X X XID Length, High Byte 10 | 0 0 0 0 0 C V S PIAFS Protocol Speed configuration -> Note(1) - | S = 0 -> Protocol Speed is 32K - | S = 1 -> Protocol Speed is 64K - | V = 0 -> Protocol Speed is fixed - | V = 1 -> Protocol Speed is variable - | C = 0 -> speed setting according to standard - | C = 1 -> speed setting for chinese implementation + | S = 0 -> Protocol Speed is 32K + | S = 1 -> Protocol Speed is 64K + | V = 0 -> Protocol Speed is fixed + | V = 1 -> Protocol Speed is variable + | C = 0 -> speed setting according to standard + | C = 1 -> speed setting for chinese implementation 11 | 0 0 0 0 0 0 R T P0 - V42bis Compression enable/disable, Low Byte - | T = 0 -> Transmit Direction enable - | T = 1 -> Transmit Direction disable - | R = 0 -> Receive Direction enable - | R = 1 -> Receive Direction disable + | T = 0 -> Transmit Direction enable + | T = 1 -> Transmit Direction disable + | R = 0 -> Receive Direction enable + | R = 1 -> Receive Direction disable 13 | 0 0 0 0 0 0 0 0 P0 - V42bis Compression enable/disable, High Byte 14 | X X X X X X X X P1 - V42bis Dictionary Size, Low Byte 15 | X X X X X X X X P1 - V42bis Dictionary Size, High Byte @@ -472,61 +472,61 @@ Byte | 8 7 6 5 4 3 2 1 18 | X X X X X X X X PIAFS extension length 19 | 1 0 0 0 0 0 0 0 PIAFS extension Id (0x80) - UDATA abilities 20 | U 0 0 0 0 0 0 D UDATA abilities -> Note (2) - | up to now the following Bits are defined: - | D - signal DCD ON - | U - use extensive UDATA control communication - | for DDI test application -+ Note (1): ----------+------+-----------------------------------------+ -| PIAFS Protocol | Bit | | -| Speed configuration | S | Bit 1 - Protocol Speed | -| | | 0 - 32K | -| | | 1 - 64K (default) | -| | V | Bit 2 - Variable Protocol Speed | -| | | 0 - Speed is fix | -| | | 1 - Speed is variable (default) | -| | | OVERWRITES 32k Bit 1 | -| | C | Bit 3 0 - Speed Settings according to | -| | | PIAFS specification | -| | | 1 - Speed setting for chinese | -| | | PIAFS implementation | -| | | Explanation for chinese speed settings: | -| | | if Bit 3 is set the following | -| | | rules apply: | -| | | Bit1=0 Bit2=0: 32k fix | -| | | Bit1=1 Bit2=0: 64k fix | -| | | Bit1=0 Bit2=1: PIAFS is trying | -| | | to negotiate 32k is that is | -| | | not possible it tries to | -| | | negotiate 64k | -| | | Bit1=1 Bit2=1: PIAFS is trying | -| | | to negotiate 64k is that is | -| | | not possible it tries to | -| | | negotiate 32k | -+ Note (2): ----------+------+-----------------------------------------+ -| PIAFS | Bit | this byte defines the usage of UDATA | -| Implementation | | control communication | -| UDATA usage | D | Bit 1 - DCD-ON signalling | -| | | 0 - no DCD-ON is signalled | -| | | (default) | -| | | 1 - DCD-ON will be signalled | -| | U | Bit 8 - DDI test application UDATA | -| | | control communication | -| | | 0 - no UDATA control | -| | | communication (default) | -| | | sets as well the DCD-ON | -| | | signalling | -| | | 1 - UDATA control communication | -| | | ATTENTION: Do not use these | -| | | setting if you | -| | | are not really | -| | | that you need it | -| | | and you know | -| | | exactly what you | -| | | are doing. | -| | | You can easily | -| | | disable any | -| | | data transfer. | -+---------------------+------+-----------------------------------------+ + | up to now the following Bits are defined: + | D - signal DCD ON + | U - use extensive UDATA control communication + | for DDI test application + + Note (1): ----------+------+-----------------------------------------+ + | PIAFS Protocol | Bit | | + | Speed configuration | S | Bit 1 - Protocol Speed | + | | | 0 - 32K | + | | | 1 - 64K (default) | + | | V | Bit 2 - Variable Protocol Speed | + | | | 0 - Speed is fix | + | | | 1 - Speed is variable (default) | + | | | OVERWRITES 32k Bit 1 | + | | C | Bit 3 0 - Speed Settings according to | + | | | PIAFS specification | + | | | 1 - Speed setting for chinese | + | | | PIAFS implementation | + | | | Explanation for chinese speed settings: | + | | | if Bit 3 is set the following | + | | | rules apply: | + | | | Bit1=0 Bit2=0: 32k fix | + | | | Bit1=1 Bit2=0: 64k fix | + | | | Bit1=0 Bit2=1: PIAFS is trying | + | | | to negotiate 32k is that is | + | | | not possible it tries to | + | | | negotiate 64k | + | | | Bit1=1 Bit2=1: PIAFS is trying | + | | | to negotiate 64k is that is | + | | | not possible it tries to | + | | | negotiate 32k | + + Note (2): ----------+------+-----------------------------------------+ + | PIAFS | Bit | this byte defines the usage of UDATA | + | Implementation | | control communication | + | UDATA usage | D | Bit 1 - DCD-ON signalling | + | | | 0 - no DCD-ON is signalled | + | | | (default) | + | | | 1 - DCD-ON will be signalled | + | | U | Bit 8 - DDI test application UDATA | + | | | control communication | + | | | 0 - no UDATA control | + | | | communication (default) | + | | | sets as well the DCD-ON | + | | | signalling | + | | | 1 - UDATA control communication | + | | | ATTENTION: Do not use these | + | | | setting if you | + | | | are not really | + | | | that you need it | + | | | and you know | + | | | exactly what you | + | | | are doing. | + | | | You can easily | + | | | disable any | + | | | data transfer. | + +---------------------+------+-----------------------------------------+ */ /* ------------------------------------------------------ LISTENER DLC DEFINITIONS @@ -701,7 +701,7 @@ Byte | 8 7 6 5 4 3 2 1 #define PROTCAP_FREE12 0x1000 /* not used */ #define PROTCAP_FREE13 0x2000 /* not used */ #define PROTCAP_FREE14 0x4000 /* not used */ -#define PROTCAP_EXTENSION 0x8000 /* used for future extentions */ +#define PROTCAP_EXTENSION 0x8000 /* used for future extensions */ /* -----------------------------------------------------------* */ /* Onhook data transmission ETS30065901 */ /* Message Type */ @@ -712,11 +712,11 @@ Byte | 8 7 6 5 4 3 2 1 /*#define RESERVED85 0x85*/ #define ADVICE_OF_CHARGE 0x86 /*1111 0001 -to -1111 1111 -F1H - Reserved for network operator use -to -FFH*/ + to + 1111 1111 + F1H - Reserved for network operator use + to + FFH*/ /* Parameter Types */ #define DATE_AND_TIME 1 #define CLI_PARAMETER_TYPE 2 diff --git a/drivers/isdn/hardware/eicon/pc_init.h b/drivers/isdn/hardware/eicon/pc_init.h index a616fc9d32e..d1d00866e8d 100644 --- a/drivers/isdn/hardware/eicon/pc_init.h +++ b/drivers/isdn/hardware/eicon/pc_init.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef PC_INIT_H_ @@ -57,15 +57,15 @@ 0x0060 length (8) 0x0061 RBS Answer Delay 0x0062 RBS Config Bit 3, 4: - 0 0 -> Wink Start - 1 0 -> Loop Start - 0 1 -> Ground Start - 1 1 -> reserved - Bit 5, 6: - 0 0 -> Pulse Dial -> Rotary - 1 0 -> DTMF - 0 1 -> MF - 1 1 -> reserved + 0 0 -> Wink Start + 1 0 -> Loop Start + 0 1 -> Ground Start + 1 1 -> reserved + Bit 5, 6: + 0 0 -> Pulse Dial -> Rotary + 1 0 -> DTMF + 0 1 -> MF + 1 1 -> reserved 0x0063 RBS RX Digit Timeout 0x0064 RBS Bearer Capability 0x0065-0x0069 RBS Debug Mask diff --git a/drivers/isdn/hardware/eicon/pc_maint.h b/drivers/isdn/hardware/eicon/pc_maint.h index 352ab8dafb2..496f018fb5a 100644 --- a/drivers/isdn/hardware/eicon/pc_maint.h +++ b/drivers/isdn/hardware/eicon/pc_maint.h @@ -1,31 +1,31 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef PLATFORM_GT_32BIT /* #define POINTER_32BIT byte * __ptr32 */ -#define POINTER_32BIT dword +#define POINTER_32BIT dword #else #define POINTER_32BIT byte * #endif @@ -70,91 +70,91 @@ #define NO_EVENT 1 struct DSigStruc { - byte Id; - byte u; - byte listen; - byte active; - byte sin[3]; - byte bc[6]; - byte llc[6]; - byte hlc[6]; - byte oad[20]; + byte Id; + byte u; + byte listen; + byte active; + byte sin[3]; + byte bc[6]; + byte llc[6]; + byte hlc[6]; + byte oad[20]; }; struct BL1Struc { - dword cx_b1; - dword cx_b2; - dword cr_b1; - dword cr_b2; - dword px_b1; - dword px_b2; - dword pr_b1; - dword pr_b2; - word er_b1; - word er_b2; + dword cx_b1; + dword cx_b2; + dword cr_b1; + dword cr_b2; + dword px_b1; + dword px_b2; + dword pr_b1; + dword pr_b2; + word er_b1; + word er_b2; }; struct L2Struc { - dword XTotal; - dword RTotal; - word XError; - word RError; + dword XTotal; + dword RTotal; + word XError; + word RError; }; struct OSStruc { - dword free_n; + dword free_n; }; typedef union { - struct DSigStruc DSigStats; - struct BL1Struc BL1Stats; - struct L2Struc L2Stats; - struct OSStruc OSStats; - byte b[BUFFER_SZ]; - word w[BUFFER_SZ>>1]; - word l[BUFFER_SZ>>2]; /* word is wrong, do not use! Use 'd' instead. */ - dword d[BUFFER_SZ>>2]; + struct DSigStruc DSigStats; + struct BL1Struc BL1Stats; + struct L2Struc L2Stats; + struct OSStruc OSStats; + byte b[BUFFER_SZ]; + word w[BUFFER_SZ >> 1]; + word l[BUFFER_SZ >> 2]; /* word is wrong, do not use! Use 'd' instead. */ + dword d[BUFFER_SZ >> 2]; } BUFFER; typedef union { - struct DSigStruc DSigStats; - struct BL1Struc BL1Stats; - struct L2Struc L2Stats; - struct OSStruc OSStats; - byte b[MIPS_BUFFER_SZ]; - word w[MIPS_BUFFER_SZ>>1]; - word l[BUFFER_SZ>>2]; /* word is wrong, do not use! Use 'd' instead. */ - dword d[MIPS_BUFFER_SZ>>2]; + struct DSigStruc DSigStats; + struct BL1Struc BL1Stats; + struct L2Struc L2Stats; + struct OSStruc OSStats; + byte b[MIPS_BUFFER_SZ]; + word w[MIPS_BUFFER_SZ >> 1]; + word l[BUFFER_SZ >> 2]; /* word is wrong, do not use! Use 'd' instead. */ + dword d[MIPS_BUFFER_SZ >> 2]; } MIPS_BUFFER; #if !defined(MIPS_SCOM) struct pc_maint { - byte req; - byte rc; - POINTER_32BIT mem; - short length; - word port; - byte fill[6]; - BUFFER data; + byte req; + byte rc; + POINTER_32BIT mem; + short length; + word port; + byte fill[6]; + BUFFER data; }; #else struct pc_maint { - byte req; - byte rc; - byte reserved[2]; /* R3000 alignment ... */ - POINTER_32BIT mem; - short length; - word port; - byte fill[4]; /* data at offset 16 */ - BUFFER data; + byte req; + byte rc; + byte reserved[2]; /* R3000 alignment ... */ + POINTER_32BIT mem; + short length; + word port; + byte fill[4]; /* data at offset 16 */ + BUFFER data; }; #endif struct mi_pc_maint { - byte req; - byte rc; - byte reserved[2]; /* R3000 alignment ... */ - POINTER_32BIT mem; - short length; - word port; - byte fill[4]; /* data at offset 16 */ - MIPS_BUFFER data; + byte req; + byte rc; + byte reserved[2]; /* R3000 alignment ... */ + POINTER_32BIT mem; + short length; + word port; + byte fill[4]; /* data at offset 16 */ + MIPS_BUFFER data; }; diff --git a/drivers/isdn/hardware/eicon/pkmaint.h b/drivers/isdn/hardware/eicon/pkmaint.h index 722f85fe42f..cf3fb14a8e6 100644 --- a/drivers/isdn/hardware/eicon/pkmaint.h +++ b/drivers/isdn/hardware/eicon/pkmaint.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_XDI_OS_DEPENDENT_PACK_MAIN_ON_BYTE_INC__ @@ -28,17 +28,16 @@ /* - Only one purpose of this compiler dependent file to pack - structures, described in pc_maint.h so that no padding - will be included. + Only one purpose of this compiler dependent file to pack + structures, described in pc_maint.h so that no padding + will be included. - With microsoft compile it is done by "pshpack1.h" and - after is restored by "poppack.h" - */ + With microsoft compile it is done by "pshpack1.h" and + after is restored by "poppack.h" +*/ #include "pc_maint.h" #endif - diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h index 12b8ff29e97..b2edb7590dd 100644 --- a/drivers/isdn/hardware/eicon/platform.h +++ b/drivers/isdn/hardware/eicon/platform.h @@ -1,10 +1,10 @@ /* $Id: platform.h,v 1.37.4.6 2005/01/31 12:22:20 armin Exp $ * * platform.h - * + * * * Copyright 2000-2003 by Armin Schindler (mac@melware.de) - * Copyright 2000 Eicon Networks + * Copyright 2000 Eicon Networks * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. @@ -18,7 +18,6 @@ #define DIVA_BUILD "local" #endif -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> @@ -27,7 +26,6 @@ #include <linux/vmalloc.h> #include <linux/proc_fs.h> #include <linux/interrupt.h> -#include <linux/smp_lock.h> #include <linux/delay.h> #include <linux/list.h> #include <asm/types.h> @@ -40,9 +38,6 @@ #define DIVA_NO_DEBUGLIB #endif -#define DIVA_INIT_FUNCTION __init -#define DIVA_EXIT_FUNCTION __exit - #define DIVA_USER_MODE_CARD_CONFIG 1 #define USE_EXTENDED_DEBUGS 1 @@ -72,26 +67,10 @@ #define qword u64 #endif -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - #ifndef NULL #define NULL ((void *) 0) #endif -#ifndef MIN -#define MIN(a,b) ((a)>(b) ? (b) : (a)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a)>(b) ? (a) : (b)) -#endif - #ifndef far #define far #endif @@ -130,44 +109,40 @@ #define DIVA_OS_MEM_ATTACH_CONFIG(a) ((a)->Config) #define DIVA_OS_MEM_ATTACH_CONTROL(a) ((a)->Control) -#define DIVA_OS_MEM_DETACH_RAM(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_PORT(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_PROM(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_CTLREG(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_RESET(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_CFG(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_ADDRESS(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_CONFIG(a, x) do { } while(0) -#define DIVA_OS_MEM_DETACH_CONTROL(a, x) do { } while(0) - -#if !defined(DIM) -#define DIM(array) (sizeof (array)/sizeof ((array)[0])) -#endif +#define DIVA_OS_MEM_DETACH_RAM(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_PORT(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_PROM(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_CTLREG(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_RESET(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_CFG(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_ADDRESS(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_CONFIG(a, x) do { } while (0) +#define DIVA_OS_MEM_DETACH_CONTROL(a, x) do { } while (0) #define DIVA_INVALID_FILE_HANDLE ((dword)(-1)) -#define DIVAS_CONTAINING_RECORD(address, type, field) \ - ((type *)((char*)(address) - (char*)(&((type *)0)->field))) +#define DIVAS_CONTAINING_RECORD(address, type, field) \ + ((type *)((char *)(address) - (char *)(&((type *)0)->field))) -extern int sprintf(char *, const char*, ...); +extern int sprintf(char *, const char *, ...); -typedef void* LIST_ENTRY; +typedef void *LIST_ENTRY; -typedef char DEVICE_NAME[64]; -typedef struct _ISDN_ADAPTER ISDN_ADAPTER; -typedef struct _ISDN_ADAPTER* PISDN_ADAPTER; +typedef char DEVICE_NAME[64]; +typedef struct _ISDN_ADAPTER ISDN_ADAPTER; +typedef struct _ISDN_ADAPTER *PISDN_ADAPTER; -typedef void (* DIVA_DI_PRINTF) (unsigned char *, ...); +typedef void (*DIVA_DI_PRINTF)(unsigned char *, ...); #include "debuglib.h" #define dtrc(p) DBG_PRV0(p) -#define dbug(a,p) DBG_PRV1(p) +#define dbug(a, p) DBG_PRV1(p) -typedef struct e_info_s E_INFO ; +typedef struct e_info_s E_INFO; typedef char diva_os_dependent_devica_name_t[64]; -typedef void* PDEVICE_OBJECT; +typedef void *PDEVICE_OBJECT; struct _diva_os_soft_isr; struct _diva_os_timer; @@ -178,13 +153,13 @@ void diva_log_info(unsigned char *, ...); /* ** XDI DIDD Interface */ -void diva_xdi_didd_register_adapter (int card); -void diva_xdi_didd_remove_adapter (int card); +void diva_xdi_didd_register_adapter(int card); +void diva_xdi_didd_remove_adapter(int card); /* ** memory allocation */ -static __inline__ void* diva_os_malloc (unsigned long flags, unsigned long size) +static __inline__ void *diva_os_malloc(unsigned long flags, unsigned long size) { void *ret = NULL; @@ -193,7 +168,7 @@ static __inline__ void* diva_os_malloc (unsigned long flags, unsigned long size) } return (ret); } -static __inline__ void diva_os_free (unsigned long flags, void* ptr) +static __inline__ void diva_os_free(unsigned long flags, void *ptr) { vfree(ptr); } @@ -222,34 +197,34 @@ static __inline__ void diva_os_wait(dword mSec) /* ** PCI Configuration space access */ -void PCIwrite (byte bus, byte func, int offset, void* data, int length, void* pci_dev_handle); -void PCIread (byte bus, byte func, int offset, void* data, int length, void* pci_dev_handle); +void PCIwrite(byte bus, byte func, int offset, void *data, int length, void *pci_dev_handle); +void PCIread(byte bus, byte func, int offset, void *data, int length, void *pci_dev_handle); /* ** I/O Port utilities */ -int diva_os_register_io_port (void *adapter, int register, unsigned long port, - unsigned long length, const char* name, int id); +int diva_os_register_io_port(void *adapter, int register, unsigned long port, + unsigned long length, const char *name, int id); /* ** I/O port access abstraction */ -byte inpp (void __iomem *); -word inppw (void __iomem *); -void inppw_buffer (void __iomem *, void*, int); -void outppw (void __iomem *, word); -void outppw_buffer (void __iomem * , void*, int); -void outpp (void __iomem *, word); +byte inpp(void __iomem *); +word inppw(void __iomem *); +void inppw_buffer(void __iomem *, void *, int); +void outppw(void __iomem *, word); +void outppw_buffer(void __iomem * , void*, int); +void outpp(void __iomem *, word); /* -** IRQ +** IRQ */ typedef struct _diva_os_adapter_irq_info { - byte irq_nr; - int registered; - char irq_name[24]; + byte irq_nr; + int registered; + char irq_name[24]; } diva_os_adapter_irq_info_t; -int diva_os_register_irq (void* context, byte irq, const char* name); -void diva_os_remove_irq (void* context, byte irq); +int diva_os_register_irq(void *context, byte irq, const char *name); +void diva_os_remove_irq(void *context, byte irq); #define diva_os_in_irq() in_irq() @@ -258,58 +233,58 @@ void diva_os_remove_irq (void* context, byte irq); */ typedef long diva_os_spin_lock_magic_t; typedef spinlock_t diva_os_spin_lock_t; -static __inline__ int diva_os_initialize_spin_lock (spinlock_t *lock, void * unused) { \ - spin_lock_init (lock); return(0); } -static __inline__ void diva_os_enter_spin_lock (diva_os_spin_lock_t* a, \ - diva_os_spin_lock_magic_t* old_irql, \ - void* dbg) { spin_lock_bh(a); } -static __inline__ void diva_os_leave_spin_lock (diva_os_spin_lock_t* a, \ - diva_os_spin_lock_magic_t* old_irql, \ - void* dbg) { spin_unlock_bh(a); } +static __inline__ int diva_os_initialize_spin_lock(spinlock_t *lock, void *unused) { \ + spin_lock_init(lock); return (0); } +static __inline__ void diva_os_enter_spin_lock(diva_os_spin_lock_t *a, \ + diva_os_spin_lock_magic_t *old_irql, \ + void *dbg) { spin_lock_bh(a); } +static __inline__ void diva_os_leave_spin_lock(diva_os_spin_lock_t *a, \ + diva_os_spin_lock_magic_t *old_irql, \ + void *dbg) { spin_unlock_bh(a); } -#define diva_os_destroy_spin_lock(a,b) do { } while(0) +#define diva_os_destroy_spin_lock(a, b) do { } while (0) /* ** Deffered processing framework */ -typedef int (*diva_os_isr_callback_t)(struct _ISDN_ADAPTER*); -typedef void (*diva_os_soft_isr_callback_t)(struct _diva_os_soft_isr* psoft_isr, void* context); +typedef int (*diva_os_isr_callback_t)(struct _ISDN_ADAPTER *); +typedef void (*diva_os_soft_isr_callback_t)(struct _diva_os_soft_isr *psoft_isr, void *context); typedef struct _diva_os_soft_isr { - void* object; - diva_os_soft_isr_callback_t callback; - void* callback_context; - char dpc_thread_name[24]; + void *object; + diva_os_soft_isr_callback_t callback; + void *callback_context; + char dpc_thread_name[24]; } diva_os_soft_isr_t; -int diva_os_initialize_soft_isr (diva_os_soft_isr_t* psoft_isr, diva_os_soft_isr_callback_t callback, void* callback_context); -int diva_os_schedule_soft_isr (diva_os_soft_isr_t* psoft_isr); -int diva_os_cancel_soft_isr (diva_os_soft_isr_t* psoft_isr); -void diva_os_remove_soft_isr (diva_os_soft_isr_t* psoft_isr); +int diva_os_initialize_soft_isr(diva_os_soft_isr_t *psoft_isr, diva_os_soft_isr_callback_t callback, void *callback_context); +int diva_os_schedule_soft_isr(diva_os_soft_isr_t *psoft_isr); +int diva_os_cancel_soft_isr(diva_os_soft_isr_t *psoft_isr); +void diva_os_remove_soft_isr(diva_os_soft_isr_t *psoft_isr); /* Get time service - */ -void diva_os_get_time (dword* sec, dword* usec); +*/ +void diva_os_get_time(dword *sec, dword *usec); /* ** atomic operation, fake because we use threads */ typedef int diva_os_atomic_t; static diva_os_atomic_t __inline__ -diva_os_atomic_increment(diva_os_atomic_t* pv) +diva_os_atomic_increment(diva_os_atomic_t *pv) { - *pv += 1; - return (*pv); + *pv += 1; + return (*pv); } static diva_os_atomic_t __inline__ -diva_os_atomic_decrement(diva_os_atomic_t* pv) +diva_os_atomic_decrement(diva_os_atomic_t *pv) { - *pv -= 1; - return (*pv); + *pv -= 1; + return (*pv); } -/* +/* ** CAPI SECTION */ #define NO_CORNETN @@ -341,9 +316,9 @@ diva_os_atomic_decrement(diva_os_atomic_t* pv) #define READ_WORD(addr) readw(addr) #define READ_DWORD(addr) readl(addr) -#define WRITE_BYTE(addr,v) writeb(v,addr) -#define WRITE_WORD(addr,v) writew(v,addr) -#define WRITE_DWORD(addr,v) writel(v,addr) +#define WRITE_BYTE(addr, v) writeb(v, addr) +#define WRITE_WORD(addr, v) writew(v, addr) +#define WRITE_DWORD(addr, v) writel(v, addr) static inline __u16 GET_WORD(void *addr) { @@ -366,10 +341,10 @@ static inline void PUT_DWORD(void *addr, __u32 v) ** 32/64 bit macors */ #ifdef BITS_PER_LONG - #if BITS_PER_LONG > 32 - #define PLATFORM_GT_32BIT - #define ULongToPtr(x) (void *)(unsigned long)(x) - #endif +#if BITS_PER_LONG > 32 +#define PLATFORM_GT_32BIT +#define ULongToPtr(x) (void *)(unsigned long)(x) +#endif #endif /* @@ -384,7 +359,7 @@ static inline void PUT_DWORD(void *addr, __u32 v) */ #define diva_os_dump_file_t char #define diva_os_board_trace_t char -#define diva_os_dump_file(__x__) do { } while(0) +#define diva_os_dump_file(__x__) do { } while (0) /* ** size of internal arrays diff --git a/drivers/isdn/hardware/eicon/pr_pc.h b/drivers/isdn/hardware/eicon/pr_pc.h index bf49a5af567..a08d6d57a48 100644 --- a/drivers/isdn/hardware/eicon/pr_pc.h +++ b/drivers/isdn/hardware/eicon/pr_pc.h @@ -1,76 +1,76 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ struct pr_ram { - word NextReq; /* pointer to next Req Buffer */ - word NextRc; /* pointer to next Rc Buffer */ - word NextInd; /* pointer to next Ind Buffer */ - byte ReqInput; /* number of Req Buffers sent */ - byte ReqOutput; /* number of Req Buffers returned */ - byte ReqReserved; /* number of Req Buffers reserved */ - byte Int; /* ISDN-P interrupt */ - byte XLock; /* Lock field for arbitration */ - byte RcOutput; /* number of Rc buffers received */ - byte IndOutput; /* number of Ind buffers received */ - byte IMask; /* Interrupt Mask Flag */ - byte Reserved1[2]; /* reserved field, do not use */ - byte ReadyInt; /* request field for ready interrupt */ - byte Reserved2[12]; /* reserved field, do not use */ - byte InterfaceType; /* interface type 1=16K interface */ - word Signature; /* ISDN-P initialized indication */ - byte B[1]; /* buffer space for Req,Ind and Rc */ + word NextReq; /* pointer to next Req Buffer */ + word NextRc; /* pointer to next Rc Buffer */ + word NextInd; /* pointer to next Ind Buffer */ + byte ReqInput; /* number of Req Buffers sent */ + byte ReqOutput; /* number of Req Buffers returned */ + byte ReqReserved; /* number of Req Buffers reserved */ + byte Int; /* ISDN-P interrupt */ + byte XLock; /* Lock field for arbitration */ + byte RcOutput; /* number of Rc buffers received */ + byte IndOutput; /* number of Ind buffers received */ + byte IMask; /* Interrupt Mask Flag */ + byte Reserved1[2]; /* reserved field, do not use */ + byte ReadyInt; /* request field for ready interrupt */ + byte Reserved2[12]; /* reserved field, do not use */ + byte InterfaceType; /* interface type 1=16K interface */ + word Signature; /* ISDN-P initialized indication */ + byte B[1]; /* buffer space for Req,Ind and Rc */ }; typedef struct { - word next; - byte Req; - byte ReqId; - byte ReqCh; - byte Reserved1; - word Reference; - byte Reserved[8]; - PBUFFER XBuffer; + word next; + byte Req; + byte ReqId; + byte ReqCh; + byte Reserved1; + word Reference; + byte Reserved[8]; + PBUFFER XBuffer; } REQ; typedef struct { - word next; - byte Rc; - byte RcId; - byte RcCh; - byte Reserved1; - word Reference; - byte Reserved2[8]; + word next; + byte Rc; + byte RcId; + byte RcCh; + byte Reserved1; + word Reference; + byte Reserved2[8]; } RC; typedef struct { - word next; - byte Ind; - byte IndId; - byte IndCh; - byte MInd; - word MLength; - word Reference; - byte RNR; - byte Reserved; - dword Ack; - PBUFFER RBuffer; + word next; + byte Ind; + byte IndId; + byte IndCh; + byte MInd; + word MLength; + word Reference; + byte RNR; + byte Reserved; + dword Ack; + PBUFFER RBuffer; } IND; diff --git a/drivers/isdn/hardware/eicon/s_4bri.c b/drivers/isdn/hardware/eicon/s_4bri.c index 25c5d7feb83..ec12165fbf6 100644 --- a/drivers/isdn/hardware/eicon/s_4bri.c +++ b/drivers/isdn/hardware/eicon/s_4bri.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -42,13 +42,13 @@ #define MAX_XLOG_SIZE (64 * 1024) /* -------------------------------------------------------------------------- - Recovery XLOG from QBRI Card - -------------------------------------------------------------------------- */ -static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) { - byte __iomem *base ; - word *Xlog ; - dword regs[4], TrapID, offset, size ; - Xdesc xlogDesc ; + Recovery XLOG from QBRI Card + -------------------------------------------------------------------------- */ +static void qBri_cpu_trapped(PISDN_ADAPTER IoAdapter) { + byte __iomem *base; + word *Xlog; + dword regs[4], TrapID, offset, size; + Xdesc xlogDesc; int factor = (IoAdapter->tasks == 1) ? 1 : 2; /* @@ -56,211 +56,211 @@ static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) { */ base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter); - offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor) ; + offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor); - TrapID = READ_DWORD(&base[0x80]) ; + TrapID = READ_DWORD(&base[0x80]); - if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) ) + if ((TrapID == 0x99999999) || (TrapID == 0x99999901)) { - dump_trap_frame (IoAdapter, &base[0x90]) ; - IoAdapter->trapped = 1 ; + dump_trap_frame(IoAdapter, &base[0x90]); + IoAdapter->trapped = 1; } regs[0] = READ_DWORD((base + offset) + 0x70); regs[1] = READ_DWORD((base + offset) + 0x74); regs[2] = READ_DWORD((base + offset) + 0x78); regs[3] = READ_DWORD((base + offset) + 0x7c); - regs[0] &= IoAdapter->MemorySize - 1 ; + regs[0] &= IoAdapter->MemorySize - 1; - if ( (regs[0] >= offset) - && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1) ) + if ((regs[0] >= offset) + && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1)) { - if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) { + if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) { DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base); - return ; + return; } - size = offset + (IoAdapter->MemorySize >> factor) - regs[0] ; - if ( size > MAX_XLOG_SIZE ) - size = MAX_XLOG_SIZE ; - memcpy_fromio (Xlog, &base[regs[0]], size) ; - xlogDesc.buf = Xlog ; - xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]) ; - xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]) ; - dump_xlog_buffer (IoAdapter, &xlogDesc) ; - diva_os_free (0, Xlog) ; - IoAdapter->trapped = 2 ; + size = offset + (IoAdapter->MemorySize >> factor) - regs[0]; + if (size > MAX_XLOG_SIZE) + size = MAX_XLOG_SIZE; + memcpy_fromio(Xlog, &base[regs[0]], size); + xlogDesc.buf = Xlog; + xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]); + xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]); + dump_xlog_buffer(IoAdapter, &xlogDesc); + diva_os_free(0, Xlog); + IoAdapter->trapped = 2; } DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base); } /* -------------------------------------------------------------------------- - Reset QBRI Hardware - -------------------------------------------------------------------------- */ -static void reset_qBri_hardware (PISDN_ADAPTER IoAdapter) { - word volatile __iomem *qBriReset ; - byte volatile __iomem *qBriCntrl ; - byte volatile __iomem *p ; + Reset QBRI Hardware + -------------------------------------------------------------------------- */ +static void reset_qBri_hardware(PISDN_ADAPTER IoAdapter) { + word volatile __iomem *qBriReset; + byte volatile __iomem *qBriCntrl; + byte volatile __iomem *p; qBriReset = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter); - WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET) ; - diva_os_wait (1) ; - WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET) ; - diva_os_wait (1); - WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_RELOAD_EEPROM) ; - diva_os_wait (1) ; - WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM) ; - diva_os_wait (1); + WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET); + diva_os_wait(1); + WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET); + diva_os_wait(1); + WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_RELOAD_EEPROM); + diva_os_wait(1); + WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM); + diva_os_wait(1); DIVA_OS_MEM_DETACH_PROM(IoAdapter, qBriReset); qBriCntrl = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); p = &qBriCntrl[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]; - WRITE_DWORD(p, 0) ; + WRITE_DWORD(p, 0); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, qBriCntrl); DBG_TRC(("resetted board @ reset addr 0x%08lx", qBriReset)) - DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p)) -} + DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p)) + } /* -------------------------------------------------------------------------- - Start Card CPU - -------------------------------------------------------------------------- */ -void start_qBri_hardware (PISDN_ADAPTER IoAdapter) { - byte volatile __iomem *qBriReset ; - byte volatile __iomem *p ; + Start Card CPU + -------------------------------------------------------------------------- */ +void start_qBri_hardware(PISDN_ADAPTER IoAdapter) { + byte volatile __iomem *qBriReset; + byte volatile __iomem *p; p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); qBriReset = &p[(DIVA_4BRI_REVISION(IoAdapter)) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)]; - WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK) ; - diva_os_wait (2) ; - WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK) ; - diva_os_wait (10) ; + WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK); + diva_os_wait(2); + WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK); + diva_os_wait(10); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); DBG_TRC(("started processor @ addr 0x%08lx", qBriReset)) -} + } /* -------------------------------------------------------------------------- - Stop Card CPU - -------------------------------------------------------------------------- */ -static void stop_qBri_hardware (PISDN_ADAPTER IoAdapter) { - byte volatile __iomem *p ; - dword volatile __iomem *qBriReset ; - dword volatile __iomem *qBriIrq ; - dword volatile __iomem *qBriIsacDspReset ; + Stop Card CPU + -------------------------------------------------------------------------- */ +static void stop_qBri_hardware(PISDN_ADAPTER IoAdapter) { + byte volatile __iomem *p; + dword volatile __iomem *qBriReset; + dword volatile __iomem *qBriIrq; + dword volatile __iomem *qBriIsacDspReset; int rev2 = DIVA_4BRI_REVISION(IoAdapter); int reset_offset = rev2 ? (MQ2_BREG_RISC) : (MQ_BREG_RISC); int irq_offset = rev2 ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST); int hw_offset = rev2 ? (MQ2_ISAC_DSP_RESET) : (MQ_ISAC_DSP_RESET); - if ( IoAdapter->ControllerNumber > 0 ) - return ; + if (IoAdapter->ControllerNumber > 0) + return; p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); qBriReset = (dword volatile __iomem *)&p[reset_offset]; qBriIsacDspReset = (dword volatile __iomem *)&p[hw_offset]; /* * clear interrupt line (reset Local Interrupt Test Register) */ - WRITE_DWORD(qBriReset, 0) ; - WRITE_DWORD(qBriIsacDspReset, 0) ; + WRITE_DWORD(qBriReset, 0); + WRITE_DWORD(qBriIsacDspReset, 0); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); - + p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); WRITE_BYTE(&p[PLX9054_INTCSR], 0x00); /* disable PCI interrupts */ DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); - + p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); qBriIrq = (dword volatile __iomem *)&p[irq_offset]; - WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ; + WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); DBG_TRC(("stopped processor @ addr 0x%08lx", qBriReset)) -} + } /* -------------------------------------------------------------------------- - FPGA download - -------------------------------------------------------------------------- */ + FPGA download + -------------------------------------------------------------------------- */ #define FPGA_NAME_OFFSET 0x10 -static byte * qBri_check_FPGAsrc (PISDN_ADAPTER IoAdapter, char *FileName, - dword *Length, dword *code) { - byte *File ; - char *fpgaFile, *fpgaType, *fpgaDate, *fpgaTime ; - dword fpgaFlen, fpgaTlen, fpgaDlen, cnt, year, i ; +static byte *qBri_check_FPGAsrc(PISDN_ADAPTER IoAdapter, char *FileName, + dword *Length, dword *code) { + byte *File; + char *fpgaFile, *fpgaType, *fpgaDate, *fpgaTime; + dword fpgaFlen, fpgaTlen, fpgaDlen, cnt, year, i; - if (!(File = (byte *)xdiLoadFile (FileName, Length, 0))) { - return (NULL) ; + if (!(File = (byte *)xdiLoadFile(FileName, Length, 0))) { + return (NULL); } /* * scan file until FF and put id string into buffer */ - for ( i = 0 ; File[i] != 0xff ; ) + for (i = 0; File[i] != 0xff;) { - if ( ++i >= *Length ) + if (++i >= *Length) { DBG_FTL(("FPGA download: start of data header not found")) - xdiFreeFile (File) ; - return (NULL) ; + xdiFreeFile(File); + return (NULL); } } - *code = i++ ; + *code = i++; - if ( (File[i] & 0xF0) != 0x20 ) + if ((File[i] & 0xF0) != 0x20) { DBG_FTL(("FPGA download: data header corrupted")) - xdiFreeFile (File) ; - return (NULL) ; + xdiFreeFile(File); + return (NULL); } - fpgaFlen = (dword) File[FPGA_NAME_OFFSET - 1] ; - if ( fpgaFlen == 0 ) - fpgaFlen = 12 ; - fpgaFile = (char *)&File[FPGA_NAME_OFFSET] ; - fpgaTlen = (dword) fpgaFile[fpgaFlen + 2] ; - if ( fpgaTlen == 0 ) - fpgaTlen = 10 ; - fpgaType = (char *)&fpgaFile[fpgaFlen + 3] ; - fpgaDlen = (dword) fpgaType[fpgaTlen + 2] ; - if ( fpgaDlen == 0 ) - fpgaDlen = 11 ; - fpgaDate = (char *)&fpgaType[fpgaTlen + 3] ; - fpgaTime = (char *)&fpgaDate[fpgaDlen + 3] ; - cnt = (dword)(((File[ i ] & 0x0F) << 20) + (File[i + 1] << 12) - + (File[i + 2] << 4) + (File[i + 3] >> 4)) ; - - if ( (dword)(i + (cnt / 8)) > *Length ) + fpgaFlen = (dword)File[FPGA_NAME_OFFSET - 1]; + if (fpgaFlen == 0) + fpgaFlen = 12; + fpgaFile = (char *)&File[FPGA_NAME_OFFSET]; + fpgaTlen = (dword)fpgaFile[fpgaFlen + 2]; + if (fpgaTlen == 0) + fpgaTlen = 10; + fpgaType = (char *)&fpgaFile[fpgaFlen + 3]; + fpgaDlen = (dword) fpgaType[fpgaTlen + 2]; + if (fpgaDlen == 0) + fpgaDlen = 11; + fpgaDate = (char *)&fpgaType[fpgaTlen + 3]; + fpgaTime = (char *)&fpgaDate[fpgaDlen + 3]; + cnt = (dword)(((File[i] & 0x0F) << 20) + (File[i + 1] << 12) + + (File[i + 2] << 4) + (File[i + 3] >> 4)); + + if ((dword)(i + (cnt / 8)) > *Length) { DBG_FTL(("FPGA download: '%s' file too small (%ld < %ld)", - FileName, *Length, code + ((cnt + 7) / 8) )) - xdiFreeFile (File) ; - return (NULL) ; + FileName, *Length, code + ((cnt + 7) / 8))) + xdiFreeFile(File); + return (NULL); } - i = 0 ; + i = 0; do { - while ( (fpgaDate[i] != '\0') - && ((fpgaDate[i] < '0') || (fpgaDate[i] > '9')) ) + while ((fpgaDate[i] != '\0') + && ((fpgaDate[i] < '0') || (fpgaDate[i] > '9'))) { i++; } - year = 0 ; - while ( (fpgaDate[i] >= '0') && (fpgaDate[i] <= '9') ) - year = year * 10 + (fpgaDate[i++] - '0') ; - } while ( (year < 2000) && (fpgaDate[i] != '\0') ); + year = 0; + while ((fpgaDate[i] >= '0') && (fpgaDate[i] <= '9')) + year = year * 10 + (fpgaDate[i++] - '0'); + } while ((year < 2000) && (fpgaDate[i] != '\0')); switch (IoAdapter->cardType) { - case CARDTYPE_DIVASRV_B_2F_PCI: - break; + case CARDTYPE_DIVASRV_B_2F_PCI: + break; - default: - if ( year >= 2001 ) { - IoAdapter->fpga_features |= PCINIT_FPGA_PLX_ACCESS_SUPPORTED ; - } + default: + if (year >= 2001) { + IoAdapter->fpga_features |= PCINIT_FPGA_PLX_ACCESS_SUPPORTED; + } } DBG_LOG(("FPGA[%s] file %s (%s %s) len %d", - fpgaType, fpgaFile, fpgaDate, fpgaTime, cnt)) - return (File) ; + fpgaType, fpgaFile, fpgaDate, fpgaTime, cnt)) + return (File); } /******************************************************************************/ @@ -272,114 +272,114 @@ static byte * qBri_check_FPGAsrc (PISDN_ADAPTER IoAdapter, char *FileName, #define FPGA_DOUT 0x0400 #define FPGA_DIN FPGA_DOUT /* bidirectional I/O */ -int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) { - int bit ; - byte *File ; - dword code, FileLength ; +int qBri_FPGA_download(PISDN_ADAPTER IoAdapter) { + int bit; + byte *File; + dword code, FileLength; word volatile __iomem *addr = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter); - word val, baseval = FPGA_CS | FPGA_PROG ; + word val, baseval = FPGA_CS | FPGA_PROG; if (DIVA_4BRI_REVISION(IoAdapter)) { - char* name; + char *name; switch (IoAdapter->cardType) { - case CARDTYPE_DIVASRV_B_2F_PCI: - name = "dsbri2f.bit"; - break; + case CARDTYPE_DIVASRV_B_2F_PCI: + name = "dsbri2f.bit"; + break; - case CARDTYPE_DIVASRV_B_2M_V2_PCI: - case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI: - name = "dsbri2m.bit"; - break; + case CARDTYPE_DIVASRV_B_2M_V2_PCI: + case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI: + name = "dsbri2m.bit"; + break; - default: - name = "ds4bri2.bit"; + default: + name = "ds4bri2.bit"; } - File = qBri_check_FPGAsrc (IoAdapter, name, - &FileLength, &code); + File = qBri_check_FPGAsrc(IoAdapter, name, + &FileLength, &code); } else { - File = qBri_check_FPGAsrc (IoAdapter, "ds4bri.bit", - &FileLength, &code) ; + File = qBri_check_FPGAsrc(IoAdapter, "ds4bri.bit", + &FileLength, &code); } - if ( !File ) { + if (!File) { DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr); - return (0) ; + return (0); } /* * prepare download, pulse PROGRAM pin down. */ - WRITE_WORD(addr, baseval & ~FPGA_PROG) ; /* PROGRAM low pulse */ - WRITE_WORD(addr, baseval) ; /* release */ - diva_os_wait (50) ; /* wait until FPGA finished internal memory clear */ + WRITE_WORD(addr, baseval & ~FPGA_PROG); /* PROGRAM low pulse */ + WRITE_WORD(addr, baseval); /* release */ + diva_os_wait(50); /* wait until FPGA finished internal memory clear */ /* * check done pin, must be low */ - if ( READ_WORD(addr) & FPGA_BUSY ) + if (READ_WORD(addr) & FPGA_BUSY) { DBG_FTL(("FPGA download: acknowledge for FPGA memory clear missing")) - xdiFreeFile (File) ; + xdiFreeFile(File); DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr); - return (0) ; + return (0); } /* * put data onto the FPGA */ - while ( code < FileLength ) + while (code < FileLength) { - val = ((word)File[code++]) << 3 ; + val = ((word)File[code++]) << 3; - for ( bit = 8 ; bit-- > 0 ; val <<= 1 ) /* put byte onto FPGA */ + for (bit = 8; bit-- > 0; val <<= 1) /* put byte onto FPGA */ { - baseval &= ~FPGA_DOUT ; /* clr data bit */ - baseval |= (val & FPGA_DOUT) ; /* copy data bit */ - WRITE_WORD(addr, baseval) ; - WRITE_WORD(addr, baseval | FPGA_CCLK) ; /* set CCLK hi */ - WRITE_WORD(addr, baseval | FPGA_CCLK) ; /* set CCLK hi */ - WRITE_WORD(addr, baseval) ; /* set CCLK lo */ + baseval &= ~FPGA_DOUT; /* clr data bit */ + baseval |= (val & FPGA_DOUT); /* copy data bit */ + WRITE_WORD(addr, baseval); + WRITE_WORD(addr, baseval | FPGA_CCLK); /* set CCLK hi */ + WRITE_WORD(addr, baseval | FPGA_CCLK); /* set CCLK hi */ + WRITE_WORD(addr, baseval); /* set CCLK lo */ } } - xdiFreeFile (File) ; - diva_os_wait (100) ; - val = READ_WORD(addr) ; + xdiFreeFile(File); + diva_os_wait(100); + val = READ_WORD(addr); DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr); - if ( !(val & FPGA_BUSY) ) + if (!(val & FPGA_BUSY)) { DBG_FTL(("FPGA download: chip remains in busy state (0x%04x)", val)) - return (0) ; + return (0); } - return (1) ; + return (1); } -static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) { +static int load_qBri_hardware(PISDN_ADAPTER IoAdapter) { return (0); } /* -------------------------------------------------------------------------- - Card ISR - -------------------------------------------------------------------------- */ -static int qBri_ISR (struct _ISDN_ADAPTER* IoAdapter) { - dword volatile __iomem *qBriIrq ; + Card ISR + -------------------------------------------------------------------------- */ +static int qBri_ISR(struct _ISDN_ADAPTER *IoAdapter) { + dword volatile __iomem *qBriIrq; - PADAPTER_LIST_ENTRY QuadroList = IoAdapter->QuadroList ; + PADAPTER_LIST_ENTRY QuadroList = IoAdapter->QuadroList; - word i ; - int serviced = 0 ; + word i; + int serviced = 0; byte __iomem *p; p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); - if ( !(READ_BYTE(&p[PLX9054_INTCSR]) & 0x80) ) { + if (!(READ_BYTE(&p[PLX9054_INTCSR]) & 0x80)) { DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); - return (0) ; + return (0); } DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); @@ -388,34 +388,34 @@ static int qBri_ISR (struct _ISDN_ADAPTER* IoAdapter) { */ p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]); - WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ; + WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); - for ( i = 0 ; i < IoAdapter->tasks; ++i ) + for (i = 0; i < IoAdapter->tasks; ++i) { - IoAdapter = QuadroList->QuadroAdapter[i] ; + IoAdapter = QuadroList->QuadroAdapter[i]; - if ( IoAdapter && IoAdapter->Initialized - && IoAdapter->tst_irq (&IoAdapter->a) ) + if (IoAdapter && IoAdapter->Initialized + && IoAdapter->tst_irq(&IoAdapter->a)) { - IoAdapter->IrqCount++ ; - serviced = 1 ; - diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr); + IoAdapter->IrqCount++; + serviced = 1; + diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr); } } - return (serviced) ; + return (serviced); } /* -------------------------------------------------------------------------- - Does disable the interrupt on the card - -------------------------------------------------------------------------- */ -static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) { - dword volatile __iomem *qBriIrq ; + Does disable the interrupt on the card + -------------------------------------------------------------------------- */ +static void disable_qBri_interrupt(PISDN_ADAPTER IoAdapter) { + dword volatile __iomem *qBriIrq; byte __iomem *p; - if ( IoAdapter->ControllerNumber > 0 ) - return ; + if (IoAdapter->ControllerNumber > 0) + return; /* * clear interrupt line (reset Local Interrupt Test Register) */ @@ -425,84 +425,84 @@ static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) { p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]); - WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ; + WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); } /* -------------------------------------------------------------------------- - Install Adapter Entry Points - -------------------------------------------------------------------------- */ -static void set_common_qBri_functions (PISDN_ADAPTER IoAdapter) { + Install Adapter Entry Points + -------------------------------------------------------------------------- */ +static void set_common_qBri_functions(PISDN_ADAPTER IoAdapter) { ADAPTER *a; - a = &IoAdapter->a ; + a = &IoAdapter->a; - a->ram_in = mem_in ; - a->ram_inw = mem_inw ; - a->ram_in_buffer = mem_in_buffer ; - a->ram_look_ahead = mem_look_ahead ; - a->ram_out = mem_out ; - a->ram_outw = mem_outw ; - a->ram_out_buffer = mem_out_buffer ; - a->ram_inc = mem_inc ; + a->ram_in = mem_in; + a->ram_inw = mem_inw; + a->ram_in_buffer = mem_in_buffer; + a->ram_look_ahead = mem_look_ahead; + a->ram_out = mem_out; + a->ram_outw = mem_outw; + a->ram_out_buffer = mem_out_buffer; + a->ram_inc = mem_inc; - IoAdapter->out = pr_out ; - IoAdapter->dpc = pr_dpc ; - IoAdapter->tst_irq = scom_test_int ; - IoAdapter->clr_irq = scom_clear_int ; - IoAdapter->pcm = (struct pc_maint *)MIPS_MAINT_OFFS ; + IoAdapter->out = pr_out; + IoAdapter->dpc = pr_dpc; + IoAdapter->tst_irq = scom_test_int; + IoAdapter->clr_irq = scom_clear_int; + IoAdapter->pcm = (struct pc_maint *)MIPS_MAINT_OFFS; - IoAdapter->load = load_qBri_hardware ; + IoAdapter->load = load_qBri_hardware; - IoAdapter->disIrq = disable_qBri_interrupt ; - IoAdapter->rstFnc = reset_qBri_hardware ; - IoAdapter->stop = stop_qBri_hardware ; - IoAdapter->trapFnc = qBri_cpu_trapped ; + IoAdapter->disIrq = disable_qBri_interrupt; + IoAdapter->rstFnc = reset_qBri_hardware; + IoAdapter->stop = stop_qBri_hardware; + IoAdapter->trapFnc = qBri_cpu_trapped; IoAdapter->diva_isr_handler = qBri_ISR; - IoAdapter->a.io = (void*)IoAdapter ; + IoAdapter->a.io = (void *)IoAdapter; } -static void set_qBri_functions (PISDN_ADAPTER IoAdapter) { +static void set_qBri_functions(PISDN_ADAPTER IoAdapter) { if (!IoAdapter->tasks) { IoAdapter->tasks = MQ_INSTANCE_COUNT; } - IoAdapter->MemorySize = MQ_MEMORY_SIZE ; - set_common_qBri_functions (IoAdapter) ; - diva_os_set_qBri_functions (IoAdapter) ; + IoAdapter->MemorySize = MQ_MEMORY_SIZE; + set_common_qBri_functions(IoAdapter); + diva_os_set_qBri_functions(IoAdapter); } -static void set_qBri2_functions (PISDN_ADAPTER IoAdapter) { +static void set_qBri2_functions(PISDN_ADAPTER IoAdapter) { if (!IoAdapter->tasks) { IoAdapter->tasks = MQ_INSTANCE_COUNT; } IoAdapter->MemorySize = (IoAdapter->tasks == 1) ? BRI2_MEMORY_SIZE : MQ2_MEMORY_SIZE; - set_common_qBri_functions (IoAdapter) ; - diva_os_set_qBri2_functions (IoAdapter) ; + set_common_qBri_functions(IoAdapter); + diva_os_set_qBri2_functions(IoAdapter); } /******************************************************************************/ -void prepare_qBri_functions (PISDN_ADAPTER IoAdapter) { +void prepare_qBri_functions(PISDN_ADAPTER IoAdapter) { - set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[0]) ; - set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[1]) ; - set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[2]) ; - set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[3]) ; + set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[0]); + set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[1]); + set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[2]); + set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[3]); } -void prepare_qBri2_functions (PISDN_ADAPTER IoAdapter) { +void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter) { if (!IoAdapter->tasks) { IoAdapter->tasks = MQ_INSTANCE_COUNT; } - set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[0]) ; + set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[0]); if (IoAdapter->tasks > 1) { - set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[1]) ; - set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[2]) ; - set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[3]) ; + set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[1]); + set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[2]); + set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[3]); } } diff --git a/drivers/isdn/hardware/eicon/s_bri.c b/drivers/isdn/hardware/eicon/s_bri.c index 5c87552e8c0..6a5bb746233 100644 --- a/drivers/isdn/hardware/eicon/s_bri.c +++ b/drivers/isdn/hardware/eicon/s_bri.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -38,154 +38,154 @@ /*****************************************************************************/ #define MAX_XLOG_SIZE (64 * 1024) /* -------------------------------------------------------------------------- - Investigate card state, recovery trace buffer - -------------------------------------------------------------------------- */ -static void bri_cpu_trapped (PISDN_ADAPTER IoAdapter) { - byte __iomem *addrHi, *addrLo, *ioaddr ; - word *Xlog ; - dword regs[4], i, size ; - Xdesc xlogDesc ; - byte __iomem *Port; + Investigate card state, recovery trace buffer + -------------------------------------------------------------------------- */ +static void bri_cpu_trapped(PISDN_ADAPTER IoAdapter) { + byte __iomem *addrHi, *addrLo, *ioaddr; + word *Xlog; + dword regs[4], i, size; + Xdesc xlogDesc; + byte __iomem *Port; /* * first read pointers and trap frame */ - if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) - return ; - Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter); - addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ; - addrLo = Port + ADDR ; - ioaddr = Port + DATA ; - outpp (addrHi, 0) ; - outppw (addrLo, 0) ; - for ( i = 0 ; i < 0x100 ; Xlog[i++] = inppw(ioaddr) ) ; + if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) + return; + Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter); + addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH); + addrLo = Port + ADDR; + ioaddr = Port + DATA; + outpp(addrHi, 0); + outppw(addrLo, 0); + for (i = 0; i < 0x100; Xlog[i++] = inppw(ioaddr)); /* * check for trapped MIPS 3xxx CPU, dump only exception frame */ - if ( GET_DWORD(&Xlog[0x80 / sizeof(Xlog[0])]) == 0x99999999 ) - { - dump_trap_frame (IoAdapter, &((byte *)Xlog)[0x90]) ; - IoAdapter->trapped = 1 ; - } - regs[0] = GET_DWORD(&((byte *)Xlog)[0x70]); - regs[1] = GET_DWORD(&((byte *)Xlog)[0x74]); - regs[2] = GET_DWORD(&((byte *)Xlog)[0x78]); - regs[3] = GET_DWORD(&((byte *)Xlog)[0x7c]); - outpp (addrHi, (regs[1] >> 16) & 0x7F) ; - outppw (addrLo, regs[1] & 0xFFFF) ; - xlogDesc.cnt = inppw(ioaddr) ; - outpp (addrHi, (regs[2] >> 16) & 0x7F) ; - outppw (addrLo, regs[2] & 0xFFFF) ; - xlogDesc.out = inppw(ioaddr) ; - xlogDesc.buf = Xlog ; - regs[0] &= IoAdapter->MemorySize - 1 ; - if ( (regs[0] < IoAdapter->MemorySize - 1) ) - { - size = IoAdapter->MemorySize - regs[0] ; - if ( size > MAX_XLOG_SIZE ) - size = MAX_XLOG_SIZE ; - for ( i = 0 ; i < (size / sizeof(*Xlog)) ; regs[0] += 2 ) - { - outpp (addrHi, (regs[0] >> 16) & 0x7F) ; - outppw (addrLo, regs[0] & 0xFFFF) ; - Xlog[i++] = inppw(ioaddr) ; - } - dump_xlog_buffer (IoAdapter, &xlogDesc) ; - diva_os_free (0, Xlog) ; - IoAdapter->trapped = 2 ; - } - outpp (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + IoAdapter->MemorySize - - BRI_SHARED_RAM_SIZE)) >> 16)) ; - outppw (addrLo, 0x00) ; - DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port); + if (GET_DWORD(&Xlog[0x80 / sizeof(Xlog[0])]) == 0x99999999) + { + dump_trap_frame(IoAdapter, &((byte *)Xlog)[0x90]); + IoAdapter->trapped = 1; + } + regs[0] = GET_DWORD(&((byte *)Xlog)[0x70]); + regs[1] = GET_DWORD(&((byte *)Xlog)[0x74]); + regs[2] = GET_DWORD(&((byte *)Xlog)[0x78]); + regs[3] = GET_DWORD(&((byte *)Xlog)[0x7c]); + outpp(addrHi, (regs[1] >> 16) & 0x7F); + outppw(addrLo, regs[1] & 0xFFFF); + xlogDesc.cnt = inppw(ioaddr); + outpp(addrHi, (regs[2] >> 16) & 0x7F); + outppw(addrLo, regs[2] & 0xFFFF); + xlogDesc.out = inppw(ioaddr); + xlogDesc.buf = Xlog; + regs[0] &= IoAdapter->MemorySize - 1; + if ((regs[0] < IoAdapter->MemorySize - 1)) + { + size = IoAdapter->MemorySize - regs[0]; + if (size > MAX_XLOG_SIZE) + size = MAX_XLOG_SIZE; + for (i = 0; i < (size / sizeof(*Xlog)); regs[0] += 2) + { + outpp(addrHi, (regs[0] >> 16) & 0x7F); + outppw(addrLo, regs[0] & 0xFFFF); + Xlog[i++] = inppw(ioaddr); + } + dump_xlog_buffer(IoAdapter, &xlogDesc); + diva_os_free(0, Xlog); + IoAdapter->trapped = 2; + } + outpp(addrHi, (byte)((BRI_UNCACHED_ADDR(IoAdapter->MemoryBase + IoAdapter->MemorySize - + BRI_SHARED_RAM_SIZE)) >> 16)); + outppw(addrLo, 0x00); + DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port); } /* --------------------------------------------------------------------- Reset hardware - --------------------------------------------------------------------- */ -static void reset_bri_hardware (PISDN_ADAPTER IoAdapter) { - byte __iomem *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); - outpp (p, 0x00) ; - DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); + --------------------------------------------------------------------- */ +static void reset_bri_hardware(PISDN_ADAPTER IoAdapter) { + byte __iomem *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); + outpp(p, 0x00); + DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); } /* --------------------------------------------------------------------- Halt system - --------------------------------------------------------------------- */ -static void stop_bri_hardware (PISDN_ADAPTER IoAdapter) { - byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); - if (p) { - outpp (p, 0x00) ; /* disable interrupts ! */ - } - DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); - p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); - outpp (p, 0x00) ; /* clear int, halt cpu */ - DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); + --------------------------------------------------------------------- */ +static void stop_bri_hardware(PISDN_ADAPTER IoAdapter) { + byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); + if (p) { + outpp(p, 0x00); /* disable interrupts ! */ + } + DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); + p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); + outpp(p, 0x00); /* clear int, halt cpu */ + DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); } -static int load_bri_hardware (PISDN_ADAPTER IoAdapter) { - return (0); +static int load_bri_hardware(PISDN_ADAPTER IoAdapter) { + return (0); } /******************************************************************************/ -static int bri_ISR (struct _ISDN_ADAPTER* IoAdapter) { - byte __iomem *p; +static int bri_ISR(struct _ISDN_ADAPTER *IoAdapter) { + byte __iomem *p; - p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); - if ( !(inpp (p) & 0x01) ) { - DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); - return (0) ; - } - /* - clear interrupt line - */ - outpp (p, 0x08) ; - DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); - IoAdapter->IrqCount++ ; - if ( IoAdapter->Initialized ) { - diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr); - } - return (1) ; + p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); + if (!(inpp(p) & 0x01)) { + DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); + return (0); + } + /* + clear interrupt line + */ + outpp(p, 0x08); + DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); + IoAdapter->IrqCount++; + if (IoAdapter->Initialized) { + diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr); + } + return (1); } /* -------------------------------------------------------------------------- - Disable IRQ in the card hardware - -------------------------------------------------------------------------- */ -static void disable_bri_interrupt (PISDN_ADAPTER IoAdapter) { - byte __iomem *p; - p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); - if ( p ) - { - outpp (p, 0x00) ; /* disable interrupts ! */ - } - DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); - p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); - outpp (p, 0x00) ; /* clear int, halt cpu */ - DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); + Disable IRQ in the card hardware + -------------------------------------------------------------------------- */ +static void disable_bri_interrupt(PISDN_ADAPTER IoAdapter) { + byte __iomem *p; + p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); + if (p) + { + outpp(p, 0x00); /* disable interrupts ! */ + } + DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); + p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); + outpp(p, 0x00); /* clear int, halt cpu */ + DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); } /* ------------------------------------------------------------------------- - Fill card entry points - ------------------------------------------------------------------------- */ -void prepare_maestra_functions (PISDN_ADAPTER IoAdapter) { - ADAPTER *a = &IoAdapter->a ; - a->ram_in = io_in ; - a->ram_inw = io_inw ; - a->ram_in_buffer = io_in_buffer ; - a->ram_look_ahead = io_look_ahead ; - a->ram_out = io_out ; - a->ram_outw = io_outw ; - a->ram_out_buffer = io_out_buffer ; - a->ram_inc = io_inc ; - IoAdapter->MemoryBase = BRI_MEMORY_BASE ; - IoAdapter->MemorySize = BRI_MEMORY_SIZE ; - IoAdapter->out = pr_out ; - IoAdapter->dpc = pr_dpc ; - IoAdapter->tst_irq = scom_test_int ; - IoAdapter->clr_irq = scom_clear_int ; - IoAdapter->pcm = (struct pc_maint *)MIPS_MAINT_OFFS ; - IoAdapter->load = load_bri_hardware ; - IoAdapter->disIrq = disable_bri_interrupt ; - IoAdapter->rstFnc = reset_bri_hardware ; - IoAdapter->stop = stop_bri_hardware ; - IoAdapter->trapFnc = bri_cpu_trapped ; - IoAdapter->diva_isr_handler = bri_ISR; - /* - Prepare OS dependent functions - */ - diva_os_prepare_maestra_functions (IoAdapter); + Fill card entry points + ------------------------------------------------------------------------- */ +void prepare_maestra_functions(PISDN_ADAPTER IoAdapter) { + ADAPTER *a = &IoAdapter->a; + a->ram_in = io_in; + a->ram_inw = io_inw; + a->ram_in_buffer = io_in_buffer; + a->ram_look_ahead = io_look_ahead; + a->ram_out = io_out; + a->ram_outw = io_outw; + a->ram_out_buffer = io_out_buffer; + a->ram_inc = io_inc; + IoAdapter->MemoryBase = BRI_MEMORY_BASE; + IoAdapter->MemorySize = BRI_MEMORY_SIZE; + IoAdapter->out = pr_out; + IoAdapter->dpc = pr_dpc; + IoAdapter->tst_irq = scom_test_int; + IoAdapter->clr_irq = scom_clear_int; + IoAdapter->pcm = (struct pc_maint *)MIPS_MAINT_OFFS; + IoAdapter->load = load_bri_hardware; + IoAdapter->disIrq = disable_bri_interrupt; + IoAdapter->rstFnc = reset_bri_hardware; + IoAdapter->stop = stop_bri_hardware; + IoAdapter->trapFnc = bri_cpu_trapped; + IoAdapter->diva_isr_handler = bri_ISR; + /* + Prepare OS dependent functions + */ + diva_os_prepare_maestra_functions(IoAdapter); } /* -------------------------------------------------------------------------- */ diff --git a/drivers/isdn/hardware/eicon/s_pri.c b/drivers/isdn/hardware/eicon/s_pri.c index 18f28788857..ddd0e0ef8ed 100644 --- a/drivers/isdn/hardware/eicon/s_pri.c +++ b/drivers/isdn/hardware/eicon/s_pri.c @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "platform.h" @@ -38,168 +38,168 @@ /*****************************************************************************/ #define MAX_XLOG_SIZE (64 * 1024) /* ------------------------------------------------------------------------- - Does return offset between ADAPTER->ram and real begin of memory - ------------------------------------------------------------------------- */ -static dword pri_ram_offset (ADAPTER* a) { - return ((dword)MP_SHARED_RAM_OFFSET); + Does return offset between ADAPTER->ram and real begin of memory + ------------------------------------------------------------------------- */ +static dword pri_ram_offset(ADAPTER *a) { + return ((dword)MP_SHARED_RAM_OFFSET); } /* ------------------------------------------------------------------------- - Recovery XLOG buffer from the card - ------------------------------------------------------------------------- */ -static void pri_cpu_trapped (PISDN_ADAPTER IoAdapter) { - byte __iomem *base ; - word *Xlog ; - dword regs[4], TrapID, size ; - Xdesc xlogDesc ; + Recovery XLOG buffer from the card + ------------------------------------------------------------------------- */ +static void pri_cpu_trapped(PISDN_ADAPTER IoAdapter) { + byte __iomem *base; + word *Xlog; + dword regs[4], TrapID, size; + Xdesc xlogDesc; /* * check for trapped MIPS 46xx CPU, dump exception frame */ - base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); - TrapID = READ_DWORD(&base[0x80]) ; - if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) ) - { - dump_trap_frame (IoAdapter, &base[0x90]) ; - IoAdapter->trapped = 1 ; - } - regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]); - regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]); - regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]); - regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]); - regs[0] &= IoAdapter->MemorySize - 1 ; - if ( (regs[0] < IoAdapter->MemorySize - 1) ) - { - if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) { - DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); - return ; - } - size = IoAdapter->MemorySize - regs[0] ; - if ( size > MAX_XLOG_SIZE ) - size = MAX_XLOG_SIZE ; - memcpy_fromio(Xlog, &base[regs[0]], size) ; - xlogDesc.buf = Xlog ; - xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]) ; - xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]) ; - dump_xlog_buffer (IoAdapter, &xlogDesc) ; - diva_os_free (0, Xlog) ; - IoAdapter->trapped = 2 ; - } - DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); + base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); + TrapID = READ_DWORD(&base[0x80]); + if ((TrapID == 0x99999999) || (TrapID == 0x99999901)) + { + dump_trap_frame(IoAdapter, &base[0x90]); + IoAdapter->trapped = 1; + } + regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]); + regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]); + regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]); + regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]); + regs[0] &= IoAdapter->MemorySize - 1; + if ((regs[0] < IoAdapter->MemorySize - 1)) + { + if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) { + DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); + return; + } + size = IoAdapter->MemorySize - regs[0]; + if (size > MAX_XLOG_SIZE) + size = MAX_XLOG_SIZE; + memcpy_fromio(Xlog, &base[regs[0]], size); + xlogDesc.buf = Xlog; + xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]); + xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]); + dump_xlog_buffer(IoAdapter, &xlogDesc); + diva_os_free(0, Xlog); + IoAdapter->trapped = 2; + } + DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); } /* ------------------------------------------------------------------------- - Hardware reset of PRI card - ------------------------------------------------------------------------- */ -static void reset_pri_hardware (PISDN_ADAPTER IoAdapter) { - byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); - WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); - diva_os_wait (50) ; - WRITE_BYTE(p, 0x00); - diva_os_wait (50) ; - DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); + Hardware reset of PRI card + ------------------------------------------------------------------------- */ +static void reset_pri_hardware(PISDN_ADAPTER IoAdapter) { + byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); + WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); + diva_os_wait(50); + WRITE_BYTE(p, 0x00); + diva_os_wait(50); + DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); } /* ------------------------------------------------------------------------- - Stop Card Hardware - ------------------------------------------------------------------------- */ -static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) { - dword i; - byte __iomem *p; - dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); - WRITE_DWORD(&cfgReg[3], 0); - WRITE_DWORD(&cfgReg[1], 0); - DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); - IoAdapter->a.ram_out (&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU) ; - i = 0 ; - while ( (i < 100) && (IoAdapter->a.ram_in (&IoAdapter->a, &RAM->SWReg) != 0) ) - { - diva_os_wait (1) ; - i++ ; - } - DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i)) - cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); - WRITE_DWORD(&cfgReg[0],((dword)(~0x03E00000))); - DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); - diva_os_wait (1) ; - p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); - WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); - DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); + Stop Card Hardware + ------------------------------------------------------------------------- */ +static void stop_pri_hardware(PISDN_ADAPTER IoAdapter) { + dword i; + byte __iomem *p; + dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); + WRITE_DWORD(&cfgReg[3], 0); + WRITE_DWORD(&cfgReg[1], 0); + DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); + IoAdapter->a.ram_out(&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU); + i = 0; + while ((i < 100) && (IoAdapter->a.ram_in(&IoAdapter->a, &RAM->SWReg) != 0)) + { + diva_os_wait(1); + i++; + } + DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i)) + cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); + WRITE_DWORD(&cfgReg[0], ((dword)(~0x03E00000))); + DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); + diva_os_wait(1); + p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); + WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); + DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); } -static int load_pri_hardware (PISDN_ADAPTER IoAdapter) { - return (0); +static int load_pri_hardware(PISDN_ADAPTER IoAdapter) { + return (0); } /* -------------------------------------------------------------------------- - PRI Adapter interrupt Service Routine + PRI Adapter interrupt Service Routine -------------------------------------------------------------------------- */ -static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) { - byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter); - if ( !(READ_DWORD(cfg) & 0x80000000) ) { - DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); - return (0) ; - } - /* - clear interrupt line - */ - WRITE_DWORD(cfg, (dword)~0x03E00000) ; - DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); - IoAdapter->IrqCount++ ; - if ( IoAdapter->Initialized ) - { - diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr); - } - return (1) ; +static int pri_ISR(struct _ISDN_ADAPTER *IoAdapter) { + byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter); + if (!(READ_DWORD(cfg) & 0x80000000)) { + DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); + return (0); + } + /* + clear interrupt line + */ + WRITE_DWORD(cfg, (dword)~0x03E00000); + DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); + IoAdapter->IrqCount++; + if (IoAdapter->Initialized) + { + diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr); + } + return (1); } /* ------------------------------------------------------------------------- - Disable interrupt in the card hardware - ------------------------------------------------------------------------- */ -static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) { - dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ; - WRITE_DWORD(&cfgReg[3], 0); - WRITE_DWORD(&cfgReg[1], 0); - WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ; - DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); + Disable interrupt in the card hardware + ------------------------------------------------------------------------- */ +static void disable_pri_interrupt(PISDN_ADAPTER IoAdapter) { + dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); + WRITE_DWORD(&cfgReg[3], 0); + WRITE_DWORD(&cfgReg[1], 0); + WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)); + DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); } /* ------------------------------------------------------------------------- - Install entry points for PRI Adapter - ------------------------------------------------------------------------- */ -static void prepare_common_pri_functions (PISDN_ADAPTER IoAdapter) { - ADAPTER *a = &IoAdapter->a ; - a->ram_in = mem_in ; - a->ram_inw = mem_inw ; - a->ram_in_buffer = mem_in_buffer ; - a->ram_look_ahead = mem_look_ahead ; - a->ram_out = mem_out ; - a->ram_outw = mem_outw ; - a->ram_out_buffer = mem_out_buffer ; - a->ram_inc = mem_inc ; - a->ram_offset = pri_ram_offset ; - a->ram_out_dw = mem_out_dw; - a->ram_in_dw = mem_in_dw; - a->istream_wakeup = pr_stream; - IoAdapter->out = pr_out ; - IoAdapter->dpc = pr_dpc ; - IoAdapter->tst_irq = scom_test_int ; - IoAdapter->clr_irq = scom_clear_int ; - IoAdapter->pcm = (struct pc_maint *)(MIPS_MAINT_OFFS - - MP_SHARED_RAM_OFFSET) ; - IoAdapter->load = load_pri_hardware ; - IoAdapter->disIrq = disable_pri_interrupt ; - IoAdapter->rstFnc = reset_pri_hardware ; - IoAdapter->stop = stop_pri_hardware ; - IoAdapter->trapFnc = pri_cpu_trapped ; - IoAdapter->diva_isr_handler = pri_ISR; + Install entry points for PRI Adapter + ------------------------------------------------------------------------- */ +static void prepare_common_pri_functions(PISDN_ADAPTER IoAdapter) { + ADAPTER *a = &IoAdapter->a; + a->ram_in = mem_in; + a->ram_inw = mem_inw; + a->ram_in_buffer = mem_in_buffer; + a->ram_look_ahead = mem_look_ahead; + a->ram_out = mem_out; + a->ram_outw = mem_outw; + a->ram_out_buffer = mem_out_buffer; + a->ram_inc = mem_inc; + a->ram_offset = pri_ram_offset; + a->ram_out_dw = mem_out_dw; + a->ram_in_dw = mem_in_dw; + a->istream_wakeup = pr_stream; + IoAdapter->out = pr_out; + IoAdapter->dpc = pr_dpc; + IoAdapter->tst_irq = scom_test_int; + IoAdapter->clr_irq = scom_clear_int; + IoAdapter->pcm = (struct pc_maint *)(MIPS_MAINT_OFFS + - MP_SHARED_RAM_OFFSET); + IoAdapter->load = load_pri_hardware; + IoAdapter->disIrq = disable_pri_interrupt; + IoAdapter->rstFnc = reset_pri_hardware; + IoAdapter->stop = stop_pri_hardware; + IoAdapter->trapFnc = pri_cpu_trapped; + IoAdapter->diva_isr_handler = pri_ISR; } /* ------------------------------------------------------------------------- - Install entry points for PRI Adapter - ------------------------------------------------------------------------- */ -void prepare_pri_functions (PISDN_ADAPTER IoAdapter) { - IoAdapter->MemorySize = MP_MEMORY_SIZE ; - prepare_common_pri_functions (IoAdapter) ; - diva_os_prepare_pri_functions (IoAdapter); + Install entry points for PRI Adapter + ------------------------------------------------------------------------- */ +void prepare_pri_functions(PISDN_ADAPTER IoAdapter) { + IoAdapter->MemorySize = MP_MEMORY_SIZE; + prepare_common_pri_functions(IoAdapter); + diva_os_prepare_pri_functions(IoAdapter); } /* ------------------------------------------------------------------------- - Install entry points for PRI Rev.2 Adapter - ------------------------------------------------------------------------- */ -void prepare_pri2_functions (PISDN_ADAPTER IoAdapter) { - IoAdapter->MemorySize = MP2_MEMORY_SIZE ; - prepare_common_pri_functions (IoAdapter) ; - diva_os_prepare_pri2_functions (IoAdapter); + Install entry points for PRI Rev.2 Adapter + ------------------------------------------------------------------------- */ +void prepare_pri2_functions(PISDN_ADAPTER IoAdapter) { + IoAdapter->MemorySize = MP2_MEMORY_SIZE; + prepare_common_pri_functions(IoAdapter); + diva_os_prepare_pri2_functions(IoAdapter); } /* ------------------------------------------------------------------------- */ diff --git a/drivers/isdn/hardware/eicon/sdp_hdr.h b/drivers/isdn/hardware/eicon/sdp_hdr.h index 8f61c696b9a..5e20f8d6867 100644 --- a/drivers/isdn/hardware/eicon/sdp_hdr.h +++ b/drivers/isdn/hardware/eicon/sdp_hdr.h @@ -1,48 +1,48 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef __DIVA_SOFT_DSP_TASK_ENTRY_H__ #define __DIVA_SOFT_DSP_TASK_ENTRY_H__ /* - The soft DSP image is described by binary header contained on begin of this - image: -OFFSET FROM IMAGE START | VARIABLE ------------------------------------------------------------------------- - DIVA_MIPS_TASK_IMAGE_LINK_OFFS | link to the next image + The soft DSP image is described by binary header contained on begin of this + image: + OFFSET FROM IMAGE START | VARIABLE + ------------------------------------------------------------------------ + DIVA_MIPS_TASK_IMAGE_LINK_OFFS | link to the next image ---------------------------------------------------------------------- - DIVA_MIPS_TASK_IMAGE_GP_OFFS | image gp register value, void* + DIVA_MIPS_TASK_IMAGE_GP_OFFS | image gp register value, void* ---------------------------------------------------------------------- - DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS | diva_mips_sdp_task_entry_t* + DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS | diva_mips_sdp_task_entry_t* ---------------------------------------------------------------------- - DIVA_MIPS_TASK_IMAGE_LOAD_ADDR_OFFS | image image start address (void*) + DIVA_MIPS_TASK_IMAGE_LOAD_ADDR_OFFS | image image start address (void*) ---------------------------------------------------------------------- - DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS | image image end address (void*) + DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS | image image end address (void*) ---------------------------------------------------------------------- - DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS | image id string char[...]; + DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS | image id string char[...]; ---------------------------------------------------------------------- - */ +*/ #define DIVA_MIPS_TASK_IMAGE_LINK_OFFS 0x6C #define DIVA_MIPS_TASK_IMAGE_GP_OFFS 0x70 #define DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS 0x74 @@ -50,63 +50,63 @@ OFFSET FROM IMAGE START | VARIABLE #define DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS 0x7c #define DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS 0x80 /* - This function is called in order to set GP register of this task - This function should be always called before any function of the - task is called - */ -typedef void (*diva_task_set_prog_gp_proc_t)(void* new_gp); + This function is called in order to set GP register of this task + This function should be always called before any function of the + task is called +*/ +typedef void (*diva_task_set_prog_gp_proc_t)(void *new_gp); /* - This function is called to clear .bss at task initialization step - */ -typedef void (*diva_task_sys_reset_proc_t)(void); + This function is called to clear .bss at task initialization step +*/ +typedef void (*diva_task_sys_reset_proc_t)(void); /* - This function is called in order to provide GP of master call to - task, that will be used by calls from the task to the master - */ -typedef void (*diva_task_set_main_gp_proc_t)(void* main_gp); + This function is called in order to provide GP of master call to + task, that will be used by calls from the task to the master +*/ +typedef void (*diva_task_set_main_gp_proc_t)(void *main_gp); /* - This function is called to provide address of 'dprintf' function - to the task - */ + This function is called to provide address of 'dprintf' function + to the task +*/ typedef word (*diva_prt_proc_t)(char *, ...); typedef void (*diva_task_set_prt_proc_t)(diva_prt_proc_t fn); /* - This function is called to set task PID - */ + This function is called to set task PID +*/ typedef void (*diva_task_set_pid_proc_t)(dword id); /* - This function is called for run-time task init - */ + This function is called for run-time task init +*/ typedef int (*diva_task_run_time_init_proc_t)(void*, dword); /* - This function is called from system scheduler or from timer - */ + This function is called from system scheduler or from timer +*/ typedef void (*diva_task_callback_proc_t)(void); /* - This callback is used by task to get current time im mS - */ + This callback is used by task to get current time im mS +*/ typedef dword (*diva_task_get_tick_count_proc_t)(void); typedef void (*diva_task_set_get_time_proc_t)(\ - diva_task_get_tick_count_proc_t fn); + diva_task_get_tick_count_proc_t fn); typedef struct _diva_mips_sdp_task_entry { - diva_task_set_prog_gp_proc_t set_gp_proc; - diva_task_sys_reset_proc_t sys_reset_proc; - diva_task_set_main_gp_proc_t set_main_gp_proc; - diva_task_set_prt_proc_t set_dprintf_proc; - diva_task_set_pid_proc_t set_pid_proc; - diva_task_run_time_init_proc_t run_time_init_proc; - diva_task_callback_proc_t task_callback_proc; - diva_task_callback_proc_t timer_callback_proc; - diva_task_set_get_time_proc_t set_get_time_proc; - void* last_entry_proc; + diva_task_set_prog_gp_proc_t set_gp_proc; + diva_task_sys_reset_proc_t sys_reset_proc; + diva_task_set_main_gp_proc_t set_main_gp_proc; + diva_task_set_prt_proc_t set_dprintf_proc; + diva_task_set_pid_proc_t set_pid_proc; + diva_task_run_time_init_proc_t run_time_init_proc; + diva_task_callback_proc_t task_callback_proc; + diva_task_callback_proc_t timer_callback_proc; + diva_task_set_get_time_proc_t set_get_time_proc; + void *last_entry_proc; } diva_mips_sdp_task_entry_t; /* - 'last_entry_proc' should be set to zero and is used for future extensuios - */ + 'last_entry_proc' should be set to zero and is used for future extensuios +*/ typedef struct _diva_mips_sw_task { - diva_mips_sdp_task_entry_t sdp_entry; - void* sdp_gp_reg; - void* own_gp_reg; + diva_mips_sdp_task_entry_t sdp_entry; + void *sdp_gp_reg; + void *own_gp_reg; } diva_mips_sw_task_t; #if !defined(DIVA_BRI2F_SDP_1_NAME) #define DIVA_BRI2F_SDP_1_NAME "sdp0.2q0" diff --git a/drivers/isdn/hardware/eicon/um_idi.c b/drivers/isdn/hardware/eicon/um_idi.c index 6563db998d0..e1519718ce6 100644 --- a/drivers/isdn/hardware/eicon/um_idi.c +++ b/drivers/isdn/hardware/eicon/um_idi.c @@ -14,30 +14,30 @@ #define DIVAS_MAX_XDI_ADAPTERS 64 /* -------------------------------------------------------------------------- - IMPORTS + IMPORTS -------------------------------------------------------------------------- */ extern void diva_os_wakeup_read(void *os_context); extern void diva_os_wakeup_close(void *os_context); /* -------------------------------------------------------------------------- - LOCALS + LOCALS -------------------------------------------------------------------------- */ static LIST_HEAD(adapter_q); static diva_os_spin_lock_t adapter_lock; static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr); -static void cleanup_adapter(diva_um_idi_adapter_t * a); -static void cleanup_entity(divas_um_idi_entity_t * e); -static int diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a, +static void cleanup_adapter(diva_um_idi_adapter_t *a); +static void cleanup_entity(divas_um_idi_entity_t *e); +static int diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t *a, diva_um_idi_adapter_features_t - * features); -static int process_idi_request(divas_um_idi_entity_t * e, - const diva_um_idi_req_hdr_t * req); -static int process_idi_rc(divas_um_idi_entity_t * e, byte rc); -static int process_idi_ind(divas_um_idi_entity_t * e, byte ind); -static int write_return_code(divas_um_idi_entity_t * e, byte rc); + *features); +static int process_idi_request(divas_um_idi_entity_t *e, + const diva_um_idi_req_hdr_t *req); +static int process_idi_rc(divas_um_idi_entity_t *e, byte rc); +static int process_idi_ind(divas_um_idi_entity_t *e, byte ind); +static int write_return_code(divas_um_idi_entity_t *e, byte rc); /* -------------------------------------------------------------------------- - MAIN + MAIN -------------------------------------------------------------------------- */ int diva_user_mode_idi_init(void) { @@ -46,10 +46,10 @@ int diva_user_mode_idi_init(void) } /* -------------------------------------------------------------------------- - Copy adapter features to user supplied buffer + Copy adapter features to user supplied buffer -------------------------------------------------------------------------- */ static int -diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a, +diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t *a, diva_um_idi_adapter_features_t * features) { @@ -63,14 +63,14 @@ diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a, sync_req.GetName.Req = 0; sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME; - (*(a->d.request)) ((ENTITY *) & sync_req); + (*(a->d.request)) ((ENTITY *)&sync_req); strlcpy(features->name, sync_req.GetName.name, sizeof(features->name)); sync_req.GetSerial.Req = 0; sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL; sync_req.GetSerial.serial = 0; - (*(a->d.request)) ((ENTITY *) & sync_req); + (*(a->d.request))((ENTITY *)&sync_req); features->serial_number = sync_req.GetSerial.serial; } @@ -78,7 +78,7 @@ diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a, } /* -------------------------------------------------------------------------- - REMOVE ADAPTER + REMOVE ADAPTER -------------------------------------------------------------------------- */ void diva_user_mode_idi_remove_adapter(int adapter_nr) { @@ -98,7 +98,7 @@ void diva_user_mode_idi_remove_adapter(int adapter_nr) } /* -------------------------------------------------------------------------- - CALLED ON DRIVER EXIT (UNLOAD) + CALLED ON DRIVER EXIT (UNLOAD) -------------------------------------------------------------------------- */ void diva_user_mode_idi_finit(void) { @@ -116,15 +116,15 @@ void diva_user_mode_idi_finit(void) } /* ------------------------------------------------------------------------- - CREATE AND INIT IDI ADAPTER - ------------------------------------------------------------------------- */ -int diva_user_mode_idi_create_adapter(const DESCRIPTOR * d, int adapter_nr) + CREATE AND INIT IDI ADAPTER + ------------------------------------------------------------------------- */ +int diva_user_mode_idi_create_adapter(const DESCRIPTOR *d, int adapter_nr) { diva_os_spin_lock_magic_t old_irql; diva_um_idi_adapter_t *a = - (diva_um_idi_adapter_t *) diva_os_malloc(0, - sizeof - (diva_um_idi_adapter_t)); + (diva_um_idi_adapter_t *) diva_os_malloc(0, + sizeof + (diva_um_idi_adapter_t)); if (!a) { return (-1); @@ -145,7 +145,7 @@ int diva_user_mode_idi_create_adapter(const DESCRIPTOR * d, int adapter_nr) } /* ------------------------------------------------------------------------ - Find adapter by Adapter number + Find adapter by Adapter number ------------------------------------------------------------------------ */ static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr) { @@ -159,14 +159,14 @@ static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr) break; a = NULL; } - return(a); + return (a); } /* ------------------------------------------------------------------------ - Cleanup this adapter and cleanup/delete all entities assigned - to this adapter + Cleanup this adapter and cleanup/delete all entities assigned + to this adapter ------------------------------------------------------------------------ */ -static void cleanup_adapter(diva_um_idi_adapter_t * a) +static void cleanup_adapter(diva_um_idi_adapter_t *a) { struct list_head *tmp, *safe; divas_um_idi_entity_t *e; @@ -184,9 +184,9 @@ static void cleanup_adapter(diva_um_idi_adapter_t * a) } /* ------------------------------------------------------------------------ - Cleanup, but NOT delete this entity + Cleanup, but NOT delete this entity ------------------------------------------------------------------------ */ -static void cleanup_entity(divas_um_idi_entity_t * e) +static void cleanup_entity(divas_um_idi_entity_t *e) { e->os_ref = NULL; e->status = 0; @@ -203,7 +203,7 @@ static void cleanup_entity(divas_um_idi_entity_t * e) /* ------------------------------------------------------------------------ - Create ENTITY, link it to the adapter and remove pointer to entity + Create ENTITY, link it to the adapter and remove pointer to entity ------------------------------------------------------------------------ */ void *divas_um_idi_create_entity(dword adapter_nr, void *file) { @@ -236,12 +236,12 @@ void *divas_um_idi_create_entity(dword adapter_nr, void *file) diva_os_enter_spin_lock(&adapter_lock, &old_irql, "create_entity"); /* - Look for Adapter requested - */ + Look for Adapter requested + */ if (!(a = diva_um_idi_find_adapter(adapter_nr))) { /* - No adapter was found, or this adapter was removed - */ + No adapter was found, or this adapter was removed + */ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "create_entity"); DBG_LOG(("A: no adapter(%ld)", adapter_nr)); @@ -267,7 +267,7 @@ void *divas_um_idi_create_entity(dword adapter_nr, void *file) } /* ------------------------------------------------------------------------ - Unlink entity and free memory + Unlink entity and free memory ------------------------------------------------------------------------ */ int divas_um_idi_delete_entity(int adapter_nr, void *entity) { @@ -288,16 +288,16 @@ int divas_um_idi_delete_entity(int adapter_nr, void *entity) cleanup_entity(e); diva_os_free(0, e->os_context); memset(e, 0x00, sizeof(*e)); - diva_os_free(0, e); DBG_LOG(("A(%d) remove E:%08x", adapter_nr, e)); + diva_os_free(0, e); return (0); } /* -------------------------------------------------------------------------- - Called by application to read data from IDI - -------------------------------------------------------------------------- */ + Called by application to read data from IDI + -------------------------------------------------------------------------- */ int diva_um_idi_read(void *entity, void *os_handle, void *dst, @@ -319,20 +319,20 @@ int diva_um_idi_read(void *entity, (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) { diva_os_leave_spin_lock(&adapter_lock, &old_irql, "read"); DBG_ERR(("E(%08x) read failed - adapter removed", e)) - return (-1); + return (-1); } DBG_TRC(("A(%d) E(%08x) read(%d)", a->adapter_nr, e, max_length)); /* - Try to read return code first - */ + Try to read return code first + */ data = diva_data_q_get_segment4read(&e->rc); q = &e->rc; /* - No return codes available, read indications now - */ + No return codes available, read indications now + */ if (!data) { if (!(e->status & DIVA_UM_IDI_RC_PENDING)) { DBG_TRC(("A(%d) E(%08x) read data", a->adapter_nr, e)); @@ -348,8 +348,8 @@ int diva_um_idi_read(void *entity, if ((length = diva_data_q_get_segment_length(q)) > max_length) { /* - Not enough space to read message - */ + Not enough space to read message + */ DBG_ERR(("A: A(%d) E(%08x) read small buffer", a->adapter_nr, e, ret)); diva_os_leave_spin_lock(&adapter_lock, &old_irql, @@ -357,14 +357,14 @@ int diva_um_idi_read(void *entity, return (-2); } /* - Copy it to user, this function does access ONLY locked an verified - memory, also we can access it witch spin lock held - */ + Copy it to user, this function does access ONLY locked an verified + memory, also we can access it witch spin lock held + */ if ((ret = (*cp_fn) (os_handle, dst, data, length)) >= 0) { /* - Acknowledge only if read was successfull - */ + Acknowledge only if read was successful + */ diva_data_q_ack_segment4read(q); } } @@ -399,7 +399,7 @@ int diva_um_idi_write(void *entity, (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) { diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write"); DBG_ERR(("E(%08x) write failed - adapter removed", e)) - return (-1); + return (-1); } DBG_TRC(("A(%d) E(%08x) write(%d)", a->adapter_nr, e, length)); @@ -416,9 +416,9 @@ int diva_um_idi_write(void *entity, } /* - Copy function does access only locked verified memory, - also it can be called with spin lock held - */ + Copy function does access only locked verified memory, + also it can be called with spin lock held + */ if ((ret = (*cp_fn) (os_handle, e->buffer, src, length)) < 0) { DBG_TRC(("A: A(%d) E(%08x) write error=%d", a->adapter_nr, e, ret)); @@ -426,32 +426,32 @@ int diva_um_idi_write(void *entity, return (ret); } - req = (diva_um_idi_req_hdr_t *) & e->buffer[0]; + req = (diva_um_idi_req_hdr_t *)&e->buffer[0]; switch (req->type) { case DIVA_UM_IDI_GET_FEATURES:{ - DBG_LOG(("A(%d) get_features", a->adapter_nr)); - if (!(data = - diva_data_q_get_segment4write(&e->data))) { - DBG_ERR(("A(%d) get_features, no free buffer", - a->adapter_nr)); - diva_os_leave_spin_lock(&adapter_lock, - &old_irql, - "write"); - return (0); - } - diva_user_mode_idi_adapter_features(a, &(((diva_um_idi_ind_hdr_t - *) data)->hdr.features)); - ((diva_um_idi_ind_hdr_t *) data)->type = - DIVA_UM_IDI_IND_FEATURES; - ((diva_um_idi_ind_hdr_t *) data)->data_length = 0; - diva_data_q_ack_segment4write(&e->data, - sizeof(diva_um_idi_ind_hdr_t)); + DBG_LOG(("A(%d) get_features", a->adapter_nr)); + if (!(data = + diva_data_q_get_segment4write(&e->data))) { + DBG_ERR(("A(%d) get_features, no free buffer", + a->adapter_nr)); + diva_os_leave_spin_lock(&adapter_lock, + &old_irql, + "write"); + return (0); + } + diva_user_mode_idi_adapter_features(a, &(((diva_um_idi_ind_hdr_t + *) data)->hdr.features)); + ((diva_um_idi_ind_hdr_t *) data)->type = + DIVA_UM_IDI_IND_FEATURES; + ((diva_um_idi_ind_hdr_t *) data)->data_length = 0; + diva_data_q_ack_segment4write(&e->data, + sizeof(diva_um_idi_ind_hdr_t)); - diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write"); + diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write"); - diva_os_wakeup_read(e->os_context); - } + diva_os_wakeup_read(e->os_context); + } break; case DIVA_UM_IDI_REQ: @@ -486,9 +486,9 @@ int diva_um_idi_write(void *entity, } /* -------------------------------------------------------------------------- - CALLBACK FROM XDI - -------------------------------------------------------------------------- */ -static void diva_um_idi_xdi_callback(ENTITY * entity) + CALLBACK FROM XDI + -------------------------------------------------------------------------- */ +static void diva_um_idi_xdi_callback(ENTITY *entity) { divas_um_idi_entity_t *e = DIVAS_CONTAINING_RECORD(entity, divas_um_idi_entity_t, @@ -529,8 +529,8 @@ static void diva_um_idi_xdi_callback(ENTITY * entity) } } -static int process_idi_request(divas_um_idi_entity_t * e, - const diva_um_idi_req_hdr_t * req) +static int process_idi_request(divas_um_idi_entity_t *e, + const diva_um_idi_req_hdr_t *req) { int assign = 0; byte Req = (byte) req->Req; @@ -579,7 +579,7 @@ static int process_idi_request(divas_um_idi_entity_t * e, e->e.Req = Req; e->e.ReqCh = (byte) req->ReqCh; e->e.X->PLength = (word) req->data_length; - e->e.X->P = (byte *) & req[1]; /* Our buffer is safe */ + e->e.X->P = (byte *)&req[1]; /* Our buffer is safe */ DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))", e->adapter->adapter_nr, e, e->e.Id, e->e.Req, @@ -595,9 +595,9 @@ static int process_idi_request(divas_um_idi_entity_t * e, if (assign) { if (e->e.Rc == OUT_OF_RESOURCES) { /* - XDI has no entities more, call was not forwarded to the card, - no callback will be scheduled - */ + XDI has no entities more, call was not forwarded to the card, + no callback will be scheduled + */ DBG_ERR(("A: A(%d) E(%08x) XDI out of entities", e->adapter->adapter_nr, e)); @@ -621,7 +621,7 @@ static int process_idi_request(divas_um_idi_entity_t * e, return (0); } -static int process_idi_rc(divas_um_idi_entity_t * e, byte rc) +static int process_idi_rc(divas_um_idi_entity_t *e, byte rc) { DBG_TRC(("A(%d) E(%08x) rc(%02x-%02x-%02x)", e->adapter->adapter_nr, e, e->e.Id, rc, e->e.RcCh)); @@ -674,20 +674,20 @@ static int process_idi_rc(divas_um_idi_entity_t * e, byte rc) return (1); } -static int process_idi_ind(divas_um_idi_entity_t * e, byte ind) +static int process_idi_ind(divas_um_idi_entity_t *e, byte ind) { int do_wakeup = 0; if (e->e.complete != 0x02) { diva_um_idi_ind_hdr_t *pind = - (diva_um_idi_ind_hdr_t *) - diva_data_q_get_segment4write(&e->data); + (diva_um_idi_ind_hdr_t *) + diva_data_q_get_segment4write(&e->data); if (pind) { e->e.RNum = 1; - e->e.R->P = (byte *) & pind[1]; + e->e.R->P = (byte *)&pind[1]; e->e.R->PLength = - (word) (diva_data_q_get_max_length(&e->data) - - sizeof(*pind)); + (word) (diva_data_q_get_max_length(&e->data) - + sizeof(*pind)); DBG_TRC(("A(%d) E(%08x) ind_1(%02x-%02x-%02x)-[%d-%d]", e->adapter->adapter_nr, e, e->e.Id, ind, e->e.IndCh, e->e.RLength, @@ -703,7 +703,7 @@ static int process_idi_ind(divas_um_idi_entity_t * e, byte ind) } } else { diva_um_idi_ind_hdr_t *pind = - (diva_um_idi_ind_hdr_t *) (e->e.R->P); + (diva_um_idi_ind_hdr_t *) (e->e.R->P); DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-[%d]", e->adapter->adapter_nr, e, e->e.Id, ind, @@ -728,14 +728,14 @@ static int process_idi_ind(divas_um_idi_entity_t * e, byte ind) } /* -------------------------------------------------------------------------- - Write return code to the return code queue of entity - -------------------------------------------------------------------------- */ -static int write_return_code(divas_um_idi_entity_t * e, byte rc) + Write return code to the return code queue of entity + -------------------------------------------------------------------------- */ +static int write_return_code(divas_um_idi_entity_t *e, byte rc) { diva_um_idi_ind_hdr_t *prc; if (!(prc = - (diva_um_idi_ind_hdr_t *) diva_data_q_get_segment4write(&e->rc))) + (diva_um_idi_ind_hdr_t *) diva_data_q_get_segment4write(&e->rc))) { DBG_ERR(("A: A(%d) E(%08x) rc(%02x) lost", e->adapter->adapter_nr, e, rc)); @@ -753,9 +753,9 @@ static int write_return_code(divas_um_idi_entity_t * e, byte rc) } /* -------------------------------------------------------------------------- - Return amount of entries that can be bead from this entity or - -1 if adapter was removed - -------------------------------------------------------------------------- */ + Return amount of entries that can be bead from this entity or + -1 if adapter was removed + -------------------------------------------------------------------------- */ int diva_user_mode_idi_ind_ready(void *entity, void *os_handle) { divas_um_idi_entity_t *e; @@ -771,16 +771,16 @@ int diva_user_mode_idi_ind_ready(void *entity, void *os_handle) if ((!a) || (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) { /* - Adapter was unloaded - */ + Adapter was unloaded + */ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready"); return (-1); /* adapter was removed */ } if (e->status & DIVA_UM_IDI_REMOVED) { /* - entity was removed as result of adapter removal - user should assign this entity again - */ + entity was removed as result of adapter removal + user should assign this entity again + */ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready"); return (-1); } @@ -827,7 +827,7 @@ int divas_um_idi_entity_assigned(void *entity) DBG_TRC(("Id:%02x, rc_count:%d, status:%08x", e->e.Id, e->rc_count, e->status)) - diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?"); + diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?"); return (ret); } @@ -850,23 +850,23 @@ int divas_um_idi_entity_start_remove(void *entity) if (e->rc_count) { /* - Entity BUSY - */ + Entity BUSY + */ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove"); return (1); } if (!e->e.Id) { /* - Remove request was already pending, and arrived now - */ + Remove request was already pending, and arrived now + */ diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove"); return (0); /* REMOVE was pending */ } /* - Now send remove request - */ + Now send remove request + */ e->e.Req = REMOVE; e->e.ReqCh = 0; diff --git a/drivers/isdn/hardware/eicon/um_idi.h b/drivers/isdn/hardware/eicon/um_idi.h index 141072f8881..ffb88f7b42f 100644 --- a/drivers/isdn/hardware/eicon/um_idi.h +++ b/drivers/isdn/hardware/eicon/um_idi.h @@ -6,7 +6,7 @@ /* interface between UM IDI core and OS dependent part - */ +*/ int diva_user_mode_idi_init(void); void diva_user_mode_idi_finit(void); void *divas_um_idi_create_entity(dword adapter_nr, void *file); diff --git a/drivers/isdn/hardware/eicon/xdi_adapter.h b/drivers/isdn/hardware/eicon/xdi_adapter.h index a3bd163afb8..d303e65dbe6 100644 --- a/drivers/isdn/hardware/eicon/xdi_adapter.h +++ b/drivers/isdn/hardware/eicon/xdi_adapter.h @@ -24,12 +24,12 @@ typedef union _divas_card_resources { } divas_card_resources_t; struct _diva_os_xdi_adapter; -typedef int (*diva_init_card_proc_t) (struct _diva_os_xdi_adapter * a); -typedef int (*diva_cmd_card_proc_t) (struct _diva_os_xdi_adapter * a, - diva_xdi_um_cfg_cmd_t * data, - int length); -typedef void (*diva_xdi_clear_interrupts_proc_t) (struct - _diva_os_xdi_adapter *); +typedef int (*diva_init_card_proc_t)(struct _diva_os_xdi_adapter *a); +typedef int (*diva_cmd_card_proc_t)(struct _diva_os_xdi_adapter *a, + diva_xdi_um_cfg_cmd_t *data, + int length); +typedef void (*diva_xdi_clear_interrupts_proc_t)(struct + _diva_os_xdi_adapter *); #define DIVA_XDI_MBOX_BUSY 1 #define DIVA_XDI_MBOX_WAIT_XLOG 2 diff --git a/drivers/isdn/hardware/eicon/xdi_msg.h b/drivers/isdn/hardware/eicon/xdi_msg.h index 3ade28f6669..58368f7b5cb 100644 --- a/drivers/isdn/hardware/eicon/xdi_msg.h +++ b/drivers/isdn/hardware/eicon/xdi_msg.h @@ -80,7 +80,7 @@ /* Set untranslated protocol code features - */ +*/ #define DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES 11 typedef struct _diva_xdi_um_cfg_cmd_data_set_features { diff --git a/drivers/isdn/hardware/eicon/xdi_vers.h b/drivers/isdn/hardware/eicon/xdi_vers.h index cf3494185b9..b3479e59c7c 100644 --- a/drivers/isdn/hardware/eicon/xdi_vers.h +++ b/drivers/isdn/hardware/eicon/xdi_vers.h @@ -1,26 +1,26 @@ /* * - Copyright (c) Eicon Networks, 2002. + Copyright (c) Eicon Networks, 2002. * - This source file is supplied for the use with - Eicon Networks range of DIVA Server Adapters. + This source file is supplied for the use with + Eicon Networks range of DIVA Server Adapters. * - Eicon File Revision : 2.1 + Eicon File Revision : 2.1 * - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. * - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. * - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ -static char diva_xdi_common_code_build[] = "102-52"; +static char diva_xdi_common_code_build[] = "102-52"; diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig new file mode 100644 index 00000000000..b8611e3e5e7 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/Kconfig @@ -0,0 +1,94 @@ +# +# Hardware for mISDN +# +comment "mISDN hardware drivers" + +config MISDN_HFCPCI + tristate "Support for HFC PCI cards" + depends on MISDN + depends on PCI + help + Enable support for cards with Cologne Chip AG's + HFC PCI chip. + +config MISDN_HFCMULTI + tristate "Support for HFC multiport cards (HFC-4S/8S/E1)" + depends on PCI || 8xx + depends on MISDN + help + Enable support for cards with Cologne Chip AG's HFC multiport + chip. There are three types of chips that are quite similar, + but the interface is different: + * HFC-4S (4 S/T interfaces on one chip) + * HFC-8S (8 S/T interfaces on one chip) + * HFC-E1 (E1 interface for 2Mbit ISDN) + +config MISDN_HFCMULTI_8xx + boolean "Support for XHFC embedded board in HFC multiport driver" + depends on MISDN + depends on MISDN_HFCMULTI + depends on 8xx + default 8xx + help + Enable support for the XHFC embedded solution from Speech Design. + +config MISDN_HFCUSB + tristate "Support for HFC-S USB based TAs" + depends on USB + help + Enable support for USB ISDN TAs with Cologne Chip AG's + HFC-S USB ISDN Controller + +config MISDN_AVMFRITZ + tristate "Support for AVM FRITZ!CARD PCI" + depends on MISDN + depends on PCI + select MISDN_IPAC + help + Enable support for AVMs FRITZ!CARD PCI cards + +config MISDN_SPEEDFAX + tristate "Support for Sedlbauer Speedfax+" + depends on MISDN + depends on PCI + select MISDN_IPAC + select MISDN_ISAR + help + Enable support for Sedlbauer Speedfax+. + +config MISDN_INFINEON + tristate "Support for cards with Infineon chipset" + depends on MISDN + depends on PCI + select MISDN_IPAC + help + Enable support for cards with ISAC + HSCX, IPAC or IPAC-SX + chip from Infineon (former manufacturer Siemens). + +config MISDN_W6692 + tristate "Support for cards with Winbond 6692" + depends on MISDN + depends on PCI + help + Enable support for Winbond 6692 PCI chip based cards. + +config MISDN_NETJET + tristate "Support for NETJet cards" + depends on MISDN + depends on PCI + depends on TTY + select MISDN_IPAC + select ISDN_HDLC + select ISDN_I4L + help + Enable support for Traverse Technologies NETJet PCI cards. + + +config MISDN_IPAC + tristate + depends on MISDN + +config MISDN_ISAR + tristate + depends on MISDN + diff --git a/drivers/isdn/hardware/mISDN/Makefile b/drivers/isdn/hardware/mISDN/Makefile new file mode 100644 index 00000000000..2987d990993 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/Makefile @@ -0,0 +1,16 @@ +# +# Makefile for the modular ISDN hardware drivers +# +# + +obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o +obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o +obj-$(CONFIG_MISDN_HFCUSB) += hfcsusb.o +obj-$(CONFIG_MISDN_AVMFRITZ) += avmfritz.o +obj-$(CONFIG_MISDN_SPEEDFAX) += speedfax.o +obj-$(CONFIG_MISDN_INFINEON) += mISDNinfineon.o +obj-$(CONFIG_MISDN_W6692) += w6692.o +obj-$(CONFIG_MISDN_NETJET) += netjet.o +# chip modules +obj-$(CONFIG_MISDN_IPAC) += mISDNipac.o +obj-$(CONFIG_MISDN_ISAR) += mISDNisar.o diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c new file mode 100644 index 00000000000..292991c90c0 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/avmfritz.c @@ -0,0 +1,1176 @@ +/* + * avm_fritz.c low level stuff for AVM FRITZ!CARD PCI ISDN cards + * Thanks to AVM, Berlin for informations + * + * Author Karsten Keil <keil@isdn4linux.de> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/mISDNhw.h> +#include <linux/slab.h> +#include <asm/unaligned.h> +#include "ipac.h" + + +#define AVMFRITZ_REV "2.3" + +static int AVM_cnt; +static int debug; + +enum { + AVM_FRITZ_PCI, + AVM_FRITZ_PCIV2, +}; + +#define HDLC_FIFO 0x0 +#define HDLC_STATUS 0x4 +#define CHIP_WINDOW 0x10 + +#define CHIP_INDEX 0x4 +#define AVM_HDLC_1 0x00 +#define AVM_HDLC_2 0x01 +#define AVM_ISAC_FIFO 0x02 +#define AVM_ISAC_REG_LOW 0x04 +#define AVM_ISAC_REG_HIGH 0x06 + +#define AVM_STATUS0_IRQ_ISAC 0x01 +#define AVM_STATUS0_IRQ_HDLC 0x02 +#define AVM_STATUS0_IRQ_TIMER 0x04 +#define AVM_STATUS0_IRQ_MASK 0x07 + +#define AVM_STATUS0_RESET 0x01 +#define AVM_STATUS0_DIS_TIMER 0x02 +#define AVM_STATUS0_RES_TIMER 0x04 +#define AVM_STATUS0_ENA_IRQ 0x08 +#define AVM_STATUS0_TESTBIT 0x10 + +#define AVM_STATUS1_INT_SEL 0x0f +#define AVM_STATUS1_ENA_IOM 0x80 + +#define HDLC_MODE_ITF_FLG 0x01 +#define HDLC_MODE_TRANS 0x02 +#define HDLC_MODE_CCR_7 0x04 +#define HDLC_MODE_CCR_16 0x08 +#define HDLC_FIFO_SIZE_128 0x20 +#define HDLC_MODE_TESTLOOP 0x80 + +#define HDLC_INT_XPR 0x80 +#define HDLC_INT_XDU 0x40 +#define HDLC_INT_RPR 0x20 +#define HDLC_INT_MASK 0xE0 + +#define HDLC_STAT_RME 0x01 +#define HDLC_STAT_RDO 0x10 +#define HDLC_STAT_CRCVFRRAB 0x0E +#define HDLC_STAT_CRCVFR 0x06 +#define HDLC_STAT_RML_MASK_V1 0x3f00 +#define HDLC_STAT_RML_MASK_V2 0x7f00 + +#define HDLC_CMD_XRS 0x80 +#define HDLC_CMD_XME 0x01 +#define HDLC_CMD_RRS 0x20 +#define HDLC_CMD_XML_MASK 0x3f00 + +#define HDLC_FIFO_SIZE_V1 32 +#define HDLC_FIFO_SIZE_V2 128 + +/* Fritz PCI v2.0 */ + +#define AVM_HDLC_FIFO_1 0x10 +#define AVM_HDLC_FIFO_2 0x18 + +#define AVM_HDLC_STATUS_1 0x14 +#define AVM_HDLC_STATUS_2 0x1c + +#define AVM_ISACX_INDEX 0x04 +#define AVM_ISACX_DATA 0x08 + +/* data struct */ +#define LOG_SIZE 63 + +struct hdlc_stat_reg { +#ifdef __BIG_ENDIAN + u8 fill; + u8 mode; + u8 xml; + u8 cmd; +#else + u8 cmd; + u8 xml; + u8 mode; + u8 fill; +#endif +} __attribute__((packed)); + +struct hdlc_hw { + union { + u32 ctrl; + struct hdlc_stat_reg sr; + } ctrl; + u32 stat; +}; + +struct fritzcard { + struct list_head list; + struct pci_dev *pdev; + char name[MISDN_MAX_IDLEN]; + u8 type; + u8 ctrlreg; + u16 irq; + u32 irqcnt; + u32 addr; + spinlock_t lock; /* hw lock */ + struct isac_hw isac; + struct hdlc_hw hdlc[2]; + struct bchannel bch[2]; + char log[LOG_SIZE + 1]; +}; + +static LIST_HEAD(Cards); +static DEFINE_RWLOCK(card_lock); /* protect Cards */ + +static void +_set_debug(struct fritzcard *card) +{ + card->isac.dch.debug = debug; + card->bch[0].debug = debug; + card->bch[1].debug = debug; +} + +static int +set_debug(const char *val, struct kernel_param *kp) +{ + int ret; + struct fritzcard *card; + + ret = param_set_uint(val, kp); + if (!ret) { + read_lock(&card_lock); + list_for_each_entry(card, &Cards, list) + _set_debug(card); + read_unlock(&card_lock); + } + return ret; +} + +MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(AVMFRITZ_REV); +module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "avmfritz debug mask"); + +/* Interface functions */ + +static u8 +ReadISAC_V1(void *p, u8 offset) +{ + struct fritzcard *fc = p; + u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; + + outb(idx, fc->addr + CHIP_INDEX); + return inb(fc->addr + CHIP_WINDOW + (offset & 0xf)); +} + +static void +WriteISAC_V1(void *p, u8 offset, u8 value) +{ + struct fritzcard *fc = p; + u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW; + + outb(idx, fc->addr + CHIP_INDEX); + outb(value, fc->addr + CHIP_WINDOW + (offset & 0xf)); +} + +static void +ReadFiFoISAC_V1(void *p, u8 off, u8 *data, int size) +{ + struct fritzcard *fc = p; + + outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX); + insb(fc->addr + CHIP_WINDOW, data, size); +} + +static void +WriteFiFoISAC_V1(void *p, u8 off, u8 *data, int size) +{ + struct fritzcard *fc = p; + + outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX); + outsb(fc->addr + CHIP_WINDOW, data, size); +} + +static u8 +ReadISAC_V2(void *p, u8 offset) +{ + struct fritzcard *fc = p; + + outl(offset, fc->addr + AVM_ISACX_INDEX); + return 0xff & inl(fc->addr + AVM_ISACX_DATA); +} + +static void +WriteISAC_V2(void *p, u8 offset, u8 value) +{ + struct fritzcard *fc = p; + + outl(offset, fc->addr + AVM_ISACX_INDEX); + outl(value, fc->addr + AVM_ISACX_DATA); +} + +static void +ReadFiFoISAC_V2(void *p, u8 off, u8 *data, int size) +{ + struct fritzcard *fc = p; + int i; + + outl(off, fc->addr + AVM_ISACX_INDEX); + for (i = 0; i < size; i++) + data[i] = 0xff & inl(fc->addr + AVM_ISACX_DATA); +} + +static void +WriteFiFoISAC_V2(void *p, u8 off, u8 *data, int size) +{ + struct fritzcard *fc = p; + int i; + + outl(off, fc->addr + AVM_ISACX_INDEX); + for (i = 0; i < size; i++) + outl(data[i], fc->addr + AVM_ISACX_DATA); +} + +static struct bchannel * +Sel_BCS(struct fritzcard *fc, u32 channel) +{ + if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) && + (fc->bch[0].nr & channel)) + return &fc->bch[0]; + else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) && + (fc->bch[1].nr & channel)) + return &fc->bch[1]; + else + return NULL; +} + +static inline void +__write_ctrl_pci(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) { + u32 idx = channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1; + + outl(idx, fc->addr + CHIP_INDEX); + outl(hdlc->ctrl.ctrl, fc->addr + CHIP_WINDOW + HDLC_STATUS); +} + +static inline void +__write_ctrl_pciv2(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) { + outl(hdlc->ctrl.ctrl, fc->addr + (channel == 2 ? AVM_HDLC_STATUS_2 : + AVM_HDLC_STATUS_1)); +} + +void +write_ctrl(struct bchannel *bch, int which) { + struct fritzcard *fc = bch->hw; + struct hdlc_hw *hdlc; + + hdlc = &fc->hdlc[(bch->nr - 1) & 1]; + pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc->name, '@' + bch->nr, + which, hdlc->ctrl.ctrl); + switch (fc->type) { + case AVM_FRITZ_PCIV2: + __write_ctrl_pciv2(fc, hdlc, bch->nr); + break; + case AVM_FRITZ_PCI: + __write_ctrl_pci(fc, hdlc, bch->nr); + break; + } +} + + +static inline u32 +__read_status_pci(u_long addr, u32 channel) +{ + outl(channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1, addr + CHIP_INDEX); + return inl(addr + CHIP_WINDOW + HDLC_STATUS); +} + +static inline u32 +__read_status_pciv2(u_long addr, u32 channel) +{ + return inl(addr + (channel == 2 ? AVM_HDLC_STATUS_2 : + AVM_HDLC_STATUS_1)); +} + + +static u32 +read_status(struct fritzcard *fc, u32 channel) +{ + switch (fc->type) { + case AVM_FRITZ_PCIV2: + return __read_status_pciv2(fc->addr, channel); + case AVM_FRITZ_PCI: + return __read_status_pci(fc->addr, channel); + } + /* dummy */ + return 0; +} + +static void +enable_hwirq(struct fritzcard *fc) +{ + fc->ctrlreg |= AVM_STATUS0_ENA_IRQ; + outb(fc->ctrlreg, fc->addr + 2); +} + +static void +disable_hwirq(struct fritzcard *fc) +{ + fc->ctrlreg &= ~AVM_STATUS0_ENA_IRQ; + outb(fc->ctrlreg, fc->addr + 2); +} + +static int +modehdlc(struct bchannel *bch, int protocol) +{ + struct fritzcard *fc = bch->hw; + struct hdlc_hw *hdlc; + u8 mode; + + hdlc = &fc->hdlc[(bch->nr - 1) & 1]; + pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name, + '@' + bch->nr, bch->state, protocol, bch->nr); + hdlc->ctrl.ctrl = 0; + mode = (fc->type == AVM_FRITZ_PCIV2) ? HDLC_FIFO_SIZE_128 : 0; + + switch (protocol) { + case -1: /* used for init */ + bch->state = -1; + case ISDN_P_NONE: + if (bch->state == ISDN_P_NONE) + break; + hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; + hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS; + write_ctrl(bch, 5); + bch->state = ISDN_P_NONE; + test_and_clear_bit(FLG_HDLC, &bch->Flags); + test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags); + break; + case ISDN_P_B_RAW: + bch->state = protocol; + hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; + hdlc->ctrl.sr.mode = mode | HDLC_MODE_TRANS; + write_ctrl(bch, 5); + hdlc->ctrl.sr.cmd = HDLC_CMD_XRS; + write_ctrl(bch, 1); + hdlc->ctrl.sr.cmd = 0; + test_and_set_bit(FLG_TRANSPARENT, &bch->Flags); + break; + case ISDN_P_B_HDLC: + bch->state = protocol; + hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS; + hdlc->ctrl.sr.mode = mode | HDLC_MODE_ITF_FLG; + write_ctrl(bch, 5); + hdlc->ctrl.sr.cmd = HDLC_CMD_XRS; + write_ctrl(bch, 1); + hdlc->ctrl.sr.cmd = 0; + test_and_set_bit(FLG_HDLC, &bch->Flags); + break; + default: + pr_info("%s: protocol not known %x\n", fc->name, protocol); + return -ENOPROTOOPT; + } + return 0; +} + +static void +hdlc_empty_fifo(struct bchannel *bch, int count) +{ + u32 *ptr; + u8 *p; + u32 val, addr; + int cnt; + struct fritzcard *fc = bch->hw; + + pr_debug("%s: %s %d\n", fc->name, __func__, count); + if (test_bit(FLG_RX_OFF, &bch->Flags)) { + p = NULL; + bch->dropcnt += count; + } else { + cnt = bchannel_get_rxbuf(bch, count); + if (cnt < 0) { + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + fc->name, bch->nr, count); + return; + } + p = skb_put(bch->rx_skb, count); + } + ptr = (u32 *)p; + if (fc->type == AVM_FRITZ_PCIV2) + addr = fc->addr + (bch->nr == 2 ? + AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1); + else { + addr = fc->addr + CHIP_WINDOW; + outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr); + } + cnt = 0; + while (cnt < count) { + val = le32_to_cpu(inl(addr)); + if (p) { + put_unaligned(val, ptr); + ptr++; + } + cnt += 4; + } + if (p && (debug & DEBUG_HW_BFIFO)) { + snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ", + bch->nr, fc->name, count); + print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count); + } +} + +static void +hdlc_fill_fifo(struct bchannel *bch) +{ + struct fritzcard *fc = bch->hw; + struct hdlc_hw *hdlc; + int count, fs, cnt = 0, idx; + bool fillempty = false; + u8 *p; + u32 *ptr, val, addr; + + idx = (bch->nr - 1) & 1; + hdlc = &fc->hdlc[idx]; + fs = (fc->type == AVM_FRITZ_PCIV2) ? + HDLC_FIFO_SIZE_V2 : HDLC_FIFO_SIZE_V1; + if (!bch->tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &bch->Flags)) + return; + count = fs; + p = bch->fill; + fillempty = true; + } else { + count = bch->tx_skb->len - bch->tx_idx; + if (count <= 0) + return; + p = bch->tx_skb->data + bch->tx_idx; + } + hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME; + if (count > fs) { + count = fs; + } else { + if (test_bit(FLG_HDLC, &bch->Flags)) + hdlc->ctrl.sr.cmd |= HDLC_CMD_XME; + } + ptr = (u32 *)p; + if (!fillempty) { + pr_debug("%s.B%d: %d/%d/%d", fc->name, bch->nr, count, + bch->tx_idx, bch->tx_skb->len); + bch->tx_idx += count; + } else { + pr_debug("%s.B%d: fillempty %d\n", fc->name, bch->nr, count); + } + hdlc->ctrl.sr.xml = ((count == fs) ? 0 : count); + if (fc->type == AVM_FRITZ_PCIV2) { + __write_ctrl_pciv2(fc, hdlc, bch->nr); + addr = fc->addr + (bch->nr == 2 ? + AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1); + } else { + __write_ctrl_pci(fc, hdlc, bch->nr); + addr = fc->addr + CHIP_WINDOW; + } + if (fillempty) { + while (cnt < count) { + /* all bytes the same - no worry about endian */ + outl(*ptr, addr); + cnt += 4; + } + } else { + while (cnt < count) { + val = get_unaligned(ptr); + outl(cpu_to_le32(val), addr); + ptr++; + cnt += 4; + } + } + if ((debug & DEBUG_HW_BFIFO) && !fillempty) { + snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ", + bch->nr, fc->name, count); + print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count); + } +} + +static void +HDLC_irq_xpr(struct bchannel *bch) +{ + if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) { + hdlc_fill_fifo(bch); + } else { + if (bch->tx_skb) + dev_kfree_skb(bch->tx_skb); + if (get_next_bframe(bch)) { + hdlc_fill_fifo(bch); + test_and_clear_bit(FLG_TX_EMPTY, &bch->Flags); + } else if (test_bit(FLG_TX_EMPTY, &bch->Flags)) { + hdlc_fill_fifo(bch); + } + } +} + +static void +HDLC_irq(struct bchannel *bch, u32 stat) +{ + struct fritzcard *fc = bch->hw; + int len, fs; + u32 rmlMask; + struct hdlc_hw *hdlc; + + hdlc = &fc->hdlc[(bch->nr - 1) & 1]; + pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat); + if (fc->type == AVM_FRITZ_PCIV2) { + rmlMask = HDLC_STAT_RML_MASK_V2; + fs = HDLC_FIFO_SIZE_V2; + } else { + rmlMask = HDLC_STAT_RML_MASK_V1; + fs = HDLC_FIFO_SIZE_V1; + } + if (stat & HDLC_INT_RPR) { + if (stat & HDLC_STAT_RDO) { + pr_warning("%s: ch%d stat %x RDO\n", + fc->name, bch->nr, stat); + hdlc->ctrl.sr.xml = 0; + hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS; + write_ctrl(bch, 1); + hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS; + write_ctrl(bch, 1); + if (bch->rx_skb) + skb_trim(bch->rx_skb, 0); + } else { + len = (stat & rmlMask) >> 8; + if (!len) + len = fs; + hdlc_empty_fifo(bch, len); + if (!bch->rx_skb) + goto handle_tx; + if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { + recv_Bchannel(bch, 0, false); + } else if (stat & HDLC_STAT_RME) { + if ((stat & HDLC_STAT_CRCVFRRAB) == + HDLC_STAT_CRCVFR) { + recv_Bchannel(bch, 0, false); + } else { + pr_warning("%s: got invalid frame\n", + fc->name); + skb_trim(bch->rx_skb, 0); + } + } + } + } +handle_tx: + if (stat & HDLC_INT_XDU) { + /* Here we lost an TX interrupt, so + * restart transmitting the whole frame on HDLC + * in transparent mode we send the next data + */ + pr_warning("%s: ch%d stat %x XDU %s\n", fc->name, bch->nr, + stat, bch->tx_skb ? "tx_skb" : "no tx_skb"); + if (bch->tx_skb && bch->tx_skb->len) { + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + bch->tx_idx = 0; + } else if (test_bit(FLG_FILLEMPTY, &bch->Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &bch->Flags); + } + hdlc->ctrl.sr.xml = 0; + hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS; + write_ctrl(bch, 1); + hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XRS; + HDLC_irq_xpr(bch); + return; + } else if (stat & HDLC_INT_XPR) + HDLC_irq_xpr(bch); +} + +static inline void +HDLC_irq_main(struct fritzcard *fc) +{ + u32 stat; + struct bchannel *bch; + + stat = read_status(fc, 1); + if (stat & HDLC_INT_MASK) { + bch = Sel_BCS(fc, 1); + if (bch) + HDLC_irq(bch, stat); + else + pr_debug("%s: spurious ch1 IRQ\n", fc->name); + } + stat = read_status(fc, 2); + if (stat & HDLC_INT_MASK) { + bch = Sel_BCS(fc, 2); + if (bch) + HDLC_irq(bch, stat); + else + pr_debug("%s: spurious ch2 IRQ\n", fc->name); + } +} + +static irqreturn_t +avm_fritz_interrupt(int intno, void *dev_id) +{ + struct fritzcard *fc = dev_id; + u8 val; + u8 sval; + + spin_lock(&fc->lock); + sval = inb(fc->addr + 2); + pr_debug("%s: irq stat0 %x\n", fc->name, sval); + if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) { + /* shared IRQ from other HW */ + spin_unlock(&fc->lock); + return IRQ_NONE; + } + fc->irqcnt++; + + if (!(sval & AVM_STATUS0_IRQ_ISAC)) { + val = ReadISAC_V1(fc, ISAC_ISTA); + mISDNisac_irq(&fc->isac, val); + } + if (!(sval & AVM_STATUS0_IRQ_HDLC)) + HDLC_irq_main(fc); + spin_unlock(&fc->lock); + return IRQ_HANDLED; +} + +static irqreturn_t +avm_fritzv2_interrupt(int intno, void *dev_id) +{ + struct fritzcard *fc = dev_id; + u8 val; + u8 sval; + + spin_lock(&fc->lock); + sval = inb(fc->addr + 2); + pr_debug("%s: irq stat0 %x\n", fc->name, sval); + if (!(sval & AVM_STATUS0_IRQ_MASK)) { + /* shared IRQ from other HW */ + spin_unlock(&fc->lock); + return IRQ_NONE; + } + fc->irqcnt++; + + if (sval & AVM_STATUS0_IRQ_HDLC) + HDLC_irq_main(fc); + if (sval & AVM_STATUS0_IRQ_ISAC) { + val = ReadISAC_V2(fc, ISACX_ISTA); + mISDNisac_irq(&fc->isac, val); + } + if (sval & AVM_STATUS0_IRQ_TIMER) { + pr_debug("%s: timer irq\n", fc->name); + outb(fc->ctrlreg | AVM_STATUS0_RES_TIMER, fc->addr + 2); + udelay(1); + outb(fc->ctrlreg, fc->addr + 2); + } + spin_unlock(&fc->lock); + return IRQ_HANDLED; +} + +static int +avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct fritzcard *fc = bch->hw; + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + unsigned long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(&fc->lock, flags); + ret = bchannel_senddata(bch, skb); + if (ret > 0) { /* direct TX */ + hdlc_fill_fifo(bch); + ret = 0; + } + spin_unlock_irqrestore(&fc->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + spin_lock_irqsave(&fc->lock, flags); + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) + ret = modehdlc(bch, ch->protocol); + else + ret = 0; + spin_unlock_irqrestore(&fc->lock, flags); + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + break; + case PH_DEACTIVATE_REQ: + spin_lock_irqsave(&fc->lock, flags); + mISDN_clear_bchannel(bch); + modehdlc(bch, ISDN_P_NONE); + spin_unlock_irqrestore(&fc->lock, flags); + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + ret = 0; + break; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static void +inithdlc(struct fritzcard *fc) +{ + modehdlc(&fc->bch[0], -1); + modehdlc(&fc->bch[1], -1); +} + +void +clear_pending_hdlc_ints(struct fritzcard *fc) +{ + u32 val; + + val = read_status(fc, 1); + pr_debug("%s: HDLC 1 STA %x\n", fc->name, val); + val = read_status(fc, 2); + pr_debug("%s: HDLC 2 STA %x\n", fc->name, val); +} + +static void +reset_avm(struct fritzcard *fc) +{ + switch (fc->type) { + case AVM_FRITZ_PCI: + fc->ctrlreg = AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER; + break; + case AVM_FRITZ_PCIV2: + fc->ctrlreg = AVM_STATUS0_RESET; + break; + } + if (debug & DEBUG_HW) + pr_notice("%s: reset\n", fc->name); + disable_hwirq(fc); + mdelay(5); + switch (fc->type) { + case AVM_FRITZ_PCI: + fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER; + disable_hwirq(fc); + outb(AVM_STATUS1_ENA_IOM, fc->addr + 3); + break; + case AVM_FRITZ_PCIV2: + fc->ctrlreg = 0; + disable_hwirq(fc); + break; + } + mdelay(1); + if (debug & DEBUG_HW) + pr_notice("%s: S0/S1 %x/%x\n", fc->name, + inb(fc->addr + 2), inb(fc->addr + 3)); +} + +static int +init_card(struct fritzcard *fc) +{ + int ret, cnt = 3; + u_long flags; + + reset_avm(fc); /* disable IRQ */ + if (fc->type == AVM_FRITZ_PCIV2) + ret = request_irq(fc->irq, avm_fritzv2_interrupt, + IRQF_SHARED, fc->name, fc); + else + ret = request_irq(fc->irq, avm_fritz_interrupt, + IRQF_SHARED, fc->name, fc); + if (ret) { + pr_info("%s: couldn't get interrupt %d\n", + fc->name, fc->irq); + return ret; + } + while (cnt--) { + spin_lock_irqsave(&fc->lock, flags); + ret = fc->isac.init(&fc->isac); + if (ret) { + spin_unlock_irqrestore(&fc->lock, flags); + pr_info("%s: ISAC init failed with %d\n", + fc->name, ret); + break; + } + clear_pending_hdlc_ints(fc); + inithdlc(fc); + enable_hwirq(fc); + /* RESET Receiver and Transmitter */ + if (fc->type == AVM_FRITZ_PCIV2) { + WriteISAC_V2(fc, ISACX_MASK, 0); + WriteISAC_V2(fc, ISACX_CMDRD, 0x41); + } else { + WriteISAC_V1(fc, ISAC_MASK, 0); + WriteISAC_V1(fc, ISAC_CMDR, 0x41); + } + spin_unlock_irqrestore(&fc->lock, flags); + /* Timeout 10ms */ + msleep_interruptible(10); + if (debug & DEBUG_HW) + pr_notice("%s: IRQ %d count %d\n", fc->name, + fc->irq, fc->irqcnt); + if (!fc->irqcnt) { + pr_info("%s: IRQ(%d) getting no IRQs during init %d\n", + fc->name, fc->irq, 3 - cnt); + reset_avm(fc); + } else + return 0; + } + free_irq(fc->irq, fc); + return -EIO; +} + +static int +channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + return mISDN_ctrl_bchannel(bch, cq); +} + +static int +avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct fritzcard *fc = bch->hw; + int ret = -EINVAL; + u_long flags; + + pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg); + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + cancel_work_sync(&bch->workq); + spin_lock_irqsave(&fc->lock, flags); + mISDN_clear_bchannel(bch); + modehdlc(bch, ISDN_P_NONE); + spin_unlock_irqrestore(&fc->lock, flags); + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(THIS_MODULE); + ret = 0; + break; + case CONTROL_CHANNEL: + ret = channel_bctrl(bch, arg); + break; + default: + pr_info("%s: %s unknown prim(%x)\n", fc->name, __func__, cmd); + } + return ret; +} + +static int +channel_ctrl(struct fritzcard *fc, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3; + break; + case MISDN_CTRL_LOOP: + /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */ + if (cq->channel < 0 || cq->channel > 3) { + ret = -EINVAL; + break; + } + ret = fc->isac.ctrl(&fc->isac, HW_TESTLOOP, cq->channel); + break; + case MISDN_CTRL_L1_TIMER3: + ret = fc->isac.ctrl(&fc->isac, HW_TIMER3_VALUE, cq->p1); + break; + default: + pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +static int +open_bchannel(struct fritzcard *fc, struct channel_req *rq) +{ + struct bchannel *bch; + + if (rq->adr.channel == 0 || rq->adr.channel > 2) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + bch = &fc->bch[rq->adr.channel - 1]; + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + bch->ch.protocol = rq->protocol; + rq->ch = &bch->ch; + return 0; +} + +/* + * device control function + */ +static int +avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct fritzcard *fc = dch->hw; + struct channel_req *rq; + int err = 0; + + pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + if (rq->protocol == ISDN_P_TE_S0) + err = fc->isac.open(&fc->isac, rq); + else + err = open_bchannel(fc, rq); + if (err) + break; + if (!try_module_get(THIS_MODULE)) + pr_info("%s: cannot get module\n", fc->name); + break; + case CLOSE_CHANNEL: + pr_debug("%s: dev(%d) close from %p\n", fc->name, dch->dev.id, + __builtin_return_address(0)); + module_put(THIS_MODULE); + break; + case CONTROL_CHANNEL: + err = channel_ctrl(fc, arg); + break; + default: + pr_debug("%s: %s unknown command %x\n", + fc->name, __func__, cmd); + return -EINVAL; + } + return err; +} + +int +setup_fritz(struct fritzcard *fc) +{ + u32 val, ver; + + if (!request_region(fc->addr, 32, fc->name)) { + pr_info("%s: AVM config port %x-%x already in use\n", + fc->name, fc->addr, fc->addr + 31); + return -EIO; + } + switch (fc->type) { + case AVM_FRITZ_PCI: + val = inl(fc->addr); + outl(AVM_HDLC_1, fc->addr + CHIP_INDEX); + ver = inl(fc->addr + CHIP_WINDOW + HDLC_STATUS) >> 24; + if (debug & DEBUG_HW) { + pr_notice("%s: PCI stat %#x\n", fc->name, val); + pr_notice("%s: PCI Class %X Rev %d\n", fc->name, + val & 0xff, (val >> 8) & 0xff); + pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf); + } + ASSIGN_FUNC(V1, ISAC, fc->isac); + fc->isac.type = IPAC_TYPE_ISAC; + break; + case AVM_FRITZ_PCIV2: + val = inl(fc->addr); + ver = inl(fc->addr + AVM_HDLC_STATUS_1) >> 24; + if (debug & DEBUG_HW) { + pr_notice("%s: PCI V2 stat %#x\n", fc->name, val); + pr_notice("%s: PCI V2 Class %X Rev %d\n", fc->name, + val & 0xff, (val >> 8) & 0xff); + pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf); + } + ASSIGN_FUNC(V2, ISAC, fc->isac); + fc->isac.type = IPAC_TYPE_ISACX; + break; + default: + release_region(fc->addr, 32); + pr_info("%s: AVM unknown type %d\n", fc->name, fc->type); + return -ENODEV; + } + pr_notice("%s: %s config irq:%d base:0x%X\n", fc->name, + (fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" : + "AVM Fritz!CARD PCIv2", fc->irq, fc->addr); + return 0; +} + +static void +release_card(struct fritzcard *card) +{ + u_long flags; + + disable_hwirq(card); + spin_lock_irqsave(&card->lock, flags); + modehdlc(&card->bch[0], ISDN_P_NONE); + modehdlc(&card->bch[1], ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + card->isac.release(&card->isac); + free_irq(card->irq, card); + mISDN_freebchannel(&card->bch[1]); + mISDN_freebchannel(&card->bch[0]); + mISDN_unregister_device(&card->isac.dch.dev); + release_region(card->addr, 32); + pci_disable_device(card->pdev); + pci_set_drvdata(card->pdev, NULL); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + kfree(card); + AVM_cnt--; +} + +static int +setup_instance(struct fritzcard *card) +{ + int i, err; + unsigned short minsize; + u_long flags; + + snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1); + write_lock_irqsave(&card_lock, flags); + list_add_tail(&card->list, &Cards); + write_unlock_irqrestore(&card_lock, flags); + + _set_debug(card); + card->isac.name = card->name; + spin_lock_init(&card->lock); + card->isac.hwlock = &card->lock; + mISDNisac_init(&card->isac, card); + + card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + card->isac.dch.dev.D.ctrl = avm_dctrl; + for (i = 0; i < 2; i++) { + card->bch[i].nr = i + 1; + set_channelmap(i + 1, card->isac.dch.dev.channelmap); + if (AVM_FRITZ_PCIV2 == card->type) + minsize = HDLC_FIFO_SIZE_V2; + else + minsize = HDLC_FIFO_SIZE_V1; + mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize); + card->bch[i].hw = card; + card->bch[i].ch.send = avm_l2l1B; + card->bch[i].ch.ctrl = avm_bctrl; + card->bch[i].ch.nr = i + 1; + list_add(&card->bch[i].ch.list, &card->isac.dch.dev.bchannels); + } + err = setup_fritz(card); + if (err) + goto error; + err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev, + card->name); + if (err) + goto error_reg; + err = init_card(card); + if (!err) { + AVM_cnt++; + pr_notice("AVM %d cards installed DEBUG\n", AVM_cnt); + return 0; + } + mISDN_unregister_device(&card->isac.dch.dev); +error_reg: + release_region(card->addr, 32); +error: + card->isac.release(&card->isac); + mISDN_freebchannel(&card->bch[1]); + mISDN_freebchannel(&card->bch[0]); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + kfree(card); + return err; +} + +static int +fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = -ENOMEM; + struct fritzcard *card; + + card = kzalloc(sizeof(struct fritzcard), GFP_KERNEL); + if (!card) { + pr_info("No kmem for fritzcard\n"); + return err; + } + if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) + card->type = AVM_FRITZ_PCIV2; + else + card->type = AVM_FRITZ_PCI; + card->pdev = pdev; + err = pci_enable_device(pdev); + if (err) { + kfree(card); + return err; + } + + pr_notice("mISDN: found adapter %s at %s\n", + (char *) ent->driver_data, pci_name(pdev)); + + card->addr = pci_resource_start(pdev, 1); + card->irq = pdev->irq; + pci_set_drvdata(pdev, card); + err = setup_instance(card); + if (err) + pci_set_drvdata(pdev, NULL); + return err; +} + +static void +fritz_remove_pci(struct pci_dev *pdev) +{ + struct fritzcard *card = pci_get_drvdata(pdev); + + if (card) + release_card(card); + else + if (debug) + pr_info("%s: drvdata already removed\n", __func__); +} + +static struct pci_device_id fcpci_ids[] = { + { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID, + 0, 0, (unsigned long) "Fritz!Card PCI"}, + { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID, + 0, 0, (unsigned long) "Fritz!Card PCI v2" }, + { } +}; +MODULE_DEVICE_TABLE(pci, fcpci_ids); + +static struct pci_driver fcpci_driver = { + .name = "fcpci", + .probe = fritzpci_probe, + .remove = fritz_remove_pci, + .id_table = fcpci_ids, +}; + +static int __init AVM_init(void) +{ + int err; + + pr_notice("AVM Fritz PCI driver Rev. %s\n", AVMFRITZ_REV); + err = pci_register_driver(&fcpci_driver); + return err; +} + +static void __exit AVM_cleanup(void) +{ + pci_unregister_driver(&fcpci_driver); +} + +module_init(AVM_init); +module_exit(AVM_cleanup); diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h new file mode 100644 index 00000000000..c601f880141 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfc_multi.h @@ -0,0 +1,1235 @@ +/* + * see notice in hfc_multi.c + */ + +#define DEBUG_HFCMULTI_FIFO 0x00010000 +#define DEBUG_HFCMULTI_CRC 0x00020000 +#define DEBUG_HFCMULTI_INIT 0x00040000 +#define DEBUG_HFCMULTI_PLXSD 0x00080000 +#define DEBUG_HFCMULTI_MODE 0x00100000 +#define DEBUG_HFCMULTI_MSG 0x00200000 +#define DEBUG_HFCMULTI_STATE 0x00400000 +#define DEBUG_HFCMULTI_FILL 0x00800000 +#define DEBUG_HFCMULTI_SYNC 0x01000000 +#define DEBUG_HFCMULTI_DTMF 0x02000000 +#define DEBUG_HFCMULTI_LOCK 0x80000000 + +#define PCI_ENA_REGIO 0x01 +#define PCI_ENA_MEMIO 0x02 + +#define XHFC_IRQ 4 /* SIU_IRQ2 */ +#define XHFC_MEMBASE 0xFE000000 +#define XHFC_MEMSIZE 0x00001000 +#define XHFC_OFFSET 0x00001000 +#define PA_XHFC_A0 0x0020 /* PA10 */ +#define PB_XHFC_IRQ1 0x00000100 /* PB23 */ +#define PB_XHFC_IRQ2 0x00000200 /* PB22 */ +#define PB_XHFC_IRQ3 0x00000400 /* PB21 */ +#define PB_XHFC_IRQ4 0x00000800 /* PB20 */ + +/* + * NOTE: some registers are assigned multiple times due to different modes + * also registers are assigned differen for HFC-4s/8s and HFC-E1 + */ + +/* + #define MAX_FRAME_SIZE 2048 +*/ + +struct hfc_chan { + struct dchannel *dch; /* link if channel is a D-channel */ + struct bchannel *bch; /* link if channel is a B-channel */ + int port; /* the interface port this */ + /* channel is associated with */ + int nt_timer; /* -1 if off, 0 if elapsed, >0 if running */ + int los, ais, slip_tx, slip_rx, rdi; /* current alarms */ + int jitter; + u_long cfg; /* port configuration */ + int sync; /* sync state (used by E1) */ + u_int protocol; /* current protocol */ + int slot_tx; /* current pcm slot */ + int bank_tx; /* current pcm bank */ + int slot_rx; + int bank_rx; + int conf; /* conference setting of TX slot */ + int txpending; /* if there is currently data in */ + /* the FIFO 0=no, 1=yes, 2=splloop */ + int Zfill; /* rx-fifo level on last hfcmulti_tx */ + int rx_off; /* set to turn fifo receive off */ + int coeff_count; /* curren coeff block */ + s32 *coeff; /* memory pointer to 8 coeff blocks */ +}; + + +struct hfcm_hw { + u_char r_ctrl; + u_char r_irq_ctrl; + u_char r_cirm; + u_char r_ram_sz; + u_char r_pcm_md0; + u_char r_irqmsk_misc; + u_char r_dtmf; + u_char r_st_sync; + u_char r_sci_msk; + u_char r_tx0, r_tx1; + u_char a_st_ctrl0[8]; + u_char r_bert_wd_md; + timer_t timer; +}; + + +/* for each stack these flags are used (cfg) */ +#define HFC_CFG_NONCAP_TX 1 /* S/T TX interface has less capacity */ +#define HFC_CFG_DIS_ECHANNEL 2 /* disable E-channel processing */ +#define HFC_CFG_REG_ECHANNEL 3 /* register E-channel */ +#define HFC_CFG_OPTICAL 4 /* the E1 interface is optical */ +#define HFC_CFG_REPORT_LOS 5 /* the card should report loss of signal */ +#define HFC_CFG_REPORT_AIS 6 /* the card should report alarm ind. sign. */ +#define HFC_CFG_REPORT_SLIP 7 /* the card should report bit slips */ +#define HFC_CFG_REPORT_RDI 8 /* the card should report remote alarm */ +#define HFC_CFG_DTMF 9 /* enable DTMF-detection */ +#define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */ +/* use double frame instead. */ + +#define HFC_TYPE_E1 1 /* controller is HFC-E1 */ +#define HFC_TYPE_4S 4 /* controller is HFC-4S */ +#define HFC_TYPE_8S 8 /* controller is HFC-8S */ +#define HFC_TYPE_XHFC 5 /* controller is XHFC */ + +#define HFC_CHIP_EXRAM_128 0 /* external ram 128k */ +#define HFC_CHIP_EXRAM_512 1 /* external ram 256k */ +#define HFC_CHIP_REVISION0 2 /* old fifo handling */ +#define HFC_CHIP_PCM_SLAVE 3 /* PCM is slave */ +#define HFC_CHIP_PCM_MASTER 4 /* PCM is master */ +#define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */ +#define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */ +#define HFC_CHIP_CONF 7 /* conference handling is enabled */ +#define HFC_CHIP_ULAW 8 /* ULAW mode */ +#define HFC_CHIP_CLOCK2 9 /* double clock mode */ +#define HFC_CHIP_E1CLOCK_GET 10 /* always get clock from E1 interface */ +#define HFC_CHIP_E1CLOCK_PUT 11 /* always put clock from E1 interface */ +#define HFC_CHIP_WATCHDOG 12 /* whether we should send signals */ +/* to the watchdog */ +#define HFC_CHIP_B410P 13 /* whether we have a b410p with echocan in */ +/* hw */ +#define HFC_CHIP_PLXSD 14 /* whether we have a Speech-Design PLX */ +#define HFC_CHIP_EMBSD 15 /* whether we have a SD Embedded board */ + +#define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */ +#define HFC_IO_MODE_REGIO 0x01 /* PCI io access */ +#define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */ +#define HFC_IO_MODE_EMBSD 0x03 /* direct access */ + +/* table entry in the PCI devices list */ +struct hm_map { + char *vendor_name; + char *card_name; + int type; + int ports; + int clock2; + int leds; + int opticalsupport; + int dip_type; + int io_mode; + int irq; +}; + +struct hfc_multi { + struct list_head list; + struct hm_map *mtyp; + int id; + int pcm; /* id of pcm bus */ + int ctype; /* controller type */ + int ports; + + u_int irq; /* irq used by card */ + u_int irqcnt; + struct pci_dev *pci_dev; + int io_mode; /* selects mode */ +#ifdef HFC_REGISTER_DEBUG + void (*HFC_outb)(struct hfc_multi *hc, u_char reg, + u_char val, const char *function, int line); + void (*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg, + u_char val, const char *function, int line); + u_char (*HFC_inb)(struct hfc_multi *hc, u_char reg, + const char *function, int line); + u_char (*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg, + const char *function, int line); + u_short (*HFC_inw)(struct hfc_multi *hc, u_char reg, + const char *function, int line); + u_short (*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg, + const char *function, int line); + void (*HFC_wait)(struct hfc_multi *hc, + const char *function, int line); + void (*HFC_wait_nodebug)(struct hfc_multi *hc, + const char *function, int line); +#else + void (*HFC_outb)(struct hfc_multi *hc, u_char reg, + u_char val); + void (*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg, + u_char val); + u_char (*HFC_inb)(struct hfc_multi *hc, u_char reg); + u_char (*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg); + u_short (*HFC_inw)(struct hfc_multi *hc, u_char reg); + u_short (*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg); + void (*HFC_wait)(struct hfc_multi *hc); + void (*HFC_wait_nodebug)(struct hfc_multi *hc); +#endif + void (*read_fifo)(struct hfc_multi *hc, u_char *data, + int len); + void (*write_fifo)(struct hfc_multi *hc, u_char *data, + int len); + u_long pci_origmembase, plx_origmembase; + void __iomem *pci_membase; /* PCI memory */ + void __iomem *plx_membase; /* PLX memory */ + u_long xhfc_origmembase; + u_char *xhfc_membase; + u_long *xhfc_memaddr, *xhfc_memdata; +#ifdef CONFIG_MISDN_HFCMULTI_8xx + struct immap *immap; +#endif + u_long pb_irqmsk; /* Portbit mask to check the IRQ line */ + u_long pci_iobase; /* PCI IO */ + struct hfcm_hw hw; /* remember data of write-only-registers */ + + u_long chip; /* chip configuration */ + int masterclk; /* port that provides master clock -1=off */ + unsigned char silence;/* silence byte */ + unsigned char silence_data[128];/* silence block */ + int dtmf; /* flag that dtmf is currently in process */ + int Flen; /* F-buffer size */ + int Zlen; /* Z-buffer size (must be int for calculation)*/ + int max_trans; /* maximum transparent fifo fill */ + int Zmin; /* Z-buffer offset */ + int DTMFbase; /* base address of DTMF coefficients */ + + u_int slots; /* number of PCM slots */ + u_int leds; /* type of leds */ + u_long ledstate; /* save last state of leds */ + int opticalsupport; /* has the e1 board */ + /* an optical Interface */ + + u_int bmask[32]; /* bitmask of bchannels for port */ + u_char dnum[32]; /* array of used dchannel numbers for port */ + u_char created[32]; /* what port is created */ + u_int activity_tx; /* if there is data TX / RX */ + u_int activity_rx; /* bitmask according to port number */ + /* (will be cleared after */ + /* showing led-states) */ + u_int flash[8]; /* counter for flashing 8 leds on activity */ + + u_long wdcount; /* every 500 ms we need to */ + /* send the watchdog a signal */ + u_char wdbyte; /* watchdog toggle byte */ + int e1_state; /* keep track of last state */ + int e1_getclock; /* if sync is retrieved from interface */ + int syncronized; /* keep track of existing sync interface */ + int e1_resync; /* resync jobs */ + + spinlock_t lock; /* the lock */ + + struct mISDNclock *iclock; /* isdn clock support */ + int iclock_on; + + /* + * the channel index is counted from 0, regardless where the channel + * is located on the hfc-channel. + * the bch->channel is equvalent to the hfc-channel + */ + struct hfc_chan chan[32]; + signed char slot_owner[256]; /* owner channel of slot */ +}; + +/* PLX GPIOs */ +#define PLX_GPIO4_DIR_BIT 13 +#define PLX_GPIO4_BIT 14 +#define PLX_GPIO5_DIR_BIT 16 +#define PLX_GPIO5_BIT 17 +#define PLX_GPIO6_DIR_BIT 19 +#define PLX_GPIO6_BIT 20 +#define PLX_GPIO7_DIR_BIT 22 +#define PLX_GPIO7_BIT 23 +#define PLX_GPIO8_DIR_BIT 25 +#define PLX_GPIO8_BIT 26 + +#define PLX_GPIO4 (1 << PLX_GPIO4_BIT) +#define PLX_GPIO5 (1 << PLX_GPIO5_BIT) +#define PLX_GPIO6 (1 << PLX_GPIO6_BIT) +#define PLX_GPIO7 (1 << PLX_GPIO7_BIT) +#define PLX_GPIO8 (1 << PLX_GPIO8_BIT) + +#define PLX_GPIO4_DIR (1 << PLX_GPIO4_DIR_BIT) +#define PLX_GPIO5_DIR (1 << PLX_GPIO5_DIR_BIT) +#define PLX_GPIO6_DIR (1 << PLX_GPIO6_DIR_BIT) +#define PLX_GPIO7_DIR (1 << PLX_GPIO7_DIR_BIT) +#define PLX_GPIO8_DIR (1 << PLX_GPIO8_DIR_BIT) + +#define PLX_TERM_ON PLX_GPIO7 +#define PLX_SLAVE_EN_N PLX_GPIO5 +#define PLX_MASTER_EN PLX_GPIO6 +#define PLX_SYNC_O_EN PLX_GPIO4 +#define PLX_DSP_RES_N PLX_GPIO8 +/* GPIO4..8 Enable & Set to OUT, SLAVE_EN_N = 1 */ +#define PLX_GPIOC_INIT (PLX_GPIO4_DIR | PLX_GPIO5_DIR | PLX_GPIO6_DIR \ + | PLX_GPIO7_DIR | PLX_GPIO8_DIR | PLX_SLAVE_EN_N) + +/* PLX Interrupt Control/STATUS */ +#define PLX_INTCSR_LINTI1_ENABLE 0x01 +#define PLX_INTCSR_LINTI1_STATUS 0x04 +#define PLX_INTCSR_LINTI2_ENABLE 0x08 +#define PLX_INTCSR_LINTI2_STATUS 0x20 +#define PLX_INTCSR_PCIINT_ENABLE 0x40 + +/* PLX Registers */ +#define PLX_INTCSR 0x4c +#define PLX_CNTRL 0x50 +#define PLX_GPIOC 0x54 + + +/* + * REGISTER SETTING FOR HFC-4S/8S AND HFC-E1 + */ + +/* write only registers */ +#define R_CIRM 0x00 +#define R_CTRL 0x01 +#define R_BRG_PCM_CFG 0x02 +#define R_RAM_ADDR0 0x08 +#define R_RAM_ADDR1 0x09 +#define R_RAM_ADDR2 0x0A +#define R_FIRST_FIFO 0x0B +#define R_RAM_SZ 0x0C +#define R_FIFO_MD 0x0D +#define R_INC_RES_FIFO 0x0E +#define R_FSM_IDX 0x0F +#define R_FIFO 0x0F +#define R_SLOT 0x10 +#define R_IRQMSK_MISC 0x11 +#define R_SCI_MSK 0x12 +#define R_IRQ_CTRL 0x13 +#define R_PCM_MD0 0x14 +#define R_PCM_MD1 0x15 +#define R_PCM_MD2 0x15 +#define R_SH0H 0x15 +#define R_SH1H 0x15 +#define R_SH0L 0x15 +#define R_SH1L 0x15 +#define R_SL_SEL0 0x15 +#define R_SL_SEL1 0x15 +#define R_SL_SEL2 0x15 +#define R_SL_SEL3 0x15 +#define R_SL_SEL4 0x15 +#define R_SL_SEL5 0x15 +#define R_SL_SEL6 0x15 +#define R_SL_SEL7 0x15 +#define R_ST_SEL 0x16 +#define R_ST_SYNC 0x17 +#define R_CONF_EN 0x18 +#define R_TI_WD 0x1A +#define R_BERT_WD_MD 0x1B +#define R_DTMF 0x1C +#define R_DTMF_N 0x1D +#define R_E1_WR_STA 0x20 +#define R_E1_RD_STA 0x20 +#define R_LOS0 0x22 +#define R_LOS1 0x23 +#define R_RX0 0x24 +#define R_RX_FR0 0x25 +#define R_RX_FR1 0x26 +#define R_TX0 0x28 +#define R_TX1 0x29 +#define R_TX_FR0 0x2C + +#define R_TX_FR1 0x2D +#define R_TX_FR2 0x2E +#define R_JATT_ATT 0x2F /* undocumented */ +#define A_ST_RD_STATE 0x30 +#define A_ST_WR_STATE 0x30 +#define R_RX_OFF 0x30 +#define A_ST_CTRL0 0x31 +#define R_SYNC_OUT 0x31 +#define A_ST_CTRL1 0x32 +#define A_ST_CTRL2 0x33 +#define A_ST_SQ_WR 0x34 +#define R_TX_OFF 0x34 +#define R_SYNC_CTRL 0x35 +#define A_ST_CLK_DLY 0x37 +#define R_PWM0 0x38 +#define R_PWM1 0x39 +#define A_ST_B1_TX 0x3C +#define A_ST_B2_TX 0x3D +#define A_ST_D_TX 0x3E +#define R_GPIO_OUT0 0x40 +#define R_GPIO_OUT1 0x41 +#define R_GPIO_EN0 0x42 +#define R_GPIO_EN1 0x43 +#define R_GPIO_SEL 0x44 +#define R_BRG_CTRL 0x45 +#define R_PWM_MD 0x46 +#define R_BRG_MD 0x47 +#define R_BRG_TIM0 0x48 +#define R_BRG_TIM1 0x49 +#define R_BRG_TIM2 0x4A +#define R_BRG_TIM3 0x4B +#define R_BRG_TIM_SEL01 0x4C +#define R_BRG_TIM_SEL23 0x4D +#define R_BRG_TIM_SEL45 0x4E +#define R_BRG_TIM_SEL67 0x4F +#define A_SL_CFG 0xD0 +#define A_CONF 0xD1 +#define A_CH_MSK 0xF4 +#define A_CON_HDLC 0xFA +#define A_SUBCH_CFG 0xFB +#define A_CHANNEL 0xFC +#define A_FIFO_SEQ 0xFD +#define A_IRQ_MSK 0xFF + +/* read only registers */ +#define A_Z12 0x04 +#define A_Z1L 0x04 +#define A_Z1 0x04 +#define A_Z1H 0x05 +#define A_Z2L 0x06 +#define A_Z2 0x06 +#define A_Z2H 0x07 +#define A_F1 0x0C +#define A_F12 0x0C +#define A_F2 0x0D +#define R_IRQ_OVIEW 0x10 +#define R_IRQ_MISC 0x11 +#define R_IRQ_STATECH 0x12 +#define R_CONF_OFLOW 0x14 +#define R_RAM_USE 0x15 +#define R_CHIP_ID 0x16 +#define R_BERT_STA 0x17 +#define R_F0_CNTL 0x18 +#define R_F0_CNTH 0x19 +#define R_BERT_EC 0x1A +#define R_BERT_ECL 0x1A +#define R_BERT_ECH 0x1B +#define R_STATUS 0x1C +#define R_CHIP_RV 0x1F +#define R_STATE 0x20 +#define R_SYNC_STA 0x24 +#define R_RX_SL0_0 0x25 +#define R_RX_SL0_1 0x26 +#define R_RX_SL0_2 0x27 +#define R_JATT_DIR 0x2b /* undocumented */ +#define R_SLIP 0x2c +#define A_ST_RD_STA 0x30 +#define R_FAS_EC 0x30 +#define R_FAS_ECL 0x30 +#define R_FAS_ECH 0x31 +#define R_VIO_EC 0x32 +#define R_VIO_ECL 0x32 +#define R_VIO_ECH 0x33 +#define A_ST_SQ_RD 0x34 +#define R_CRC_EC 0x34 +#define R_CRC_ECL 0x34 +#define R_CRC_ECH 0x35 +#define R_E_EC 0x36 +#define R_E_ECL 0x36 +#define R_E_ECH 0x37 +#define R_SA6_SA13_EC 0x38 +#define R_SA6_SA13_ECL 0x38 +#define R_SA6_SA13_ECH 0x39 +#define R_SA6_SA23_EC 0x3A +#define R_SA6_SA23_ECL 0x3A +#define R_SA6_SA23_ECH 0x3B +#define A_ST_B1_RX 0x3C +#define A_ST_B2_RX 0x3D +#define A_ST_D_RX 0x3E +#define A_ST_E_RX 0x3F +#define R_GPIO_IN0 0x40 +#define R_GPIO_IN1 0x41 +#define R_GPI_IN0 0x44 +#define R_GPI_IN1 0x45 +#define R_GPI_IN2 0x46 +#define R_GPI_IN3 0x47 +#define R_INT_DATA 0x88 +#define R_IRQ_FIFO_BL0 0xC8 +#define R_IRQ_FIFO_BL1 0xC9 +#define R_IRQ_FIFO_BL2 0xCA +#define R_IRQ_FIFO_BL3 0xCB +#define R_IRQ_FIFO_BL4 0xCC +#define R_IRQ_FIFO_BL5 0xCD +#define R_IRQ_FIFO_BL6 0xCE +#define R_IRQ_FIFO_BL7 0xCF + +/* read and write registers */ +#define A_FIFO_DATA0 0x80 +#define A_FIFO_DATA1 0x80 +#define A_FIFO_DATA2 0x80 +#define A_FIFO_DATA0_NOINC 0x84 +#define A_FIFO_DATA1_NOINC 0x84 +#define A_FIFO_DATA2_NOINC 0x84 +#define R_RAM_DATA 0xC0 + + +/* + * BIT SETTING FOR HFC-4S/8S AND HFC-E1 + */ + +/* chapter 2: universal bus interface */ +/* R_CIRM */ +#define V_IRQ_SEL 0x01 +#define V_SRES 0x08 +#define V_HFCRES 0x10 +#define V_PCMRES 0x20 +#define V_STRES 0x40 +#define V_ETRES 0x40 +#define V_RLD_EPR 0x80 +/* R_CTRL */ +#define V_FIFO_LPRIO 0x02 +#define V_SLOW_RD 0x04 +#define V_EXT_RAM 0x08 +#define V_CLK_OFF 0x20 +#define V_ST_CLK 0x40 +/* R_RAM_ADDR0 */ +#define V_RAM_ADDR2 0x01 +#define V_ADDR_RES 0x40 +#define V_ADDR_INC 0x80 +/* R_RAM_SZ */ +#define V_RAM_SZ 0x01 +#define V_PWM0_16KHZ 0x10 +#define V_PWM1_16KHZ 0x20 +#define V_FZ_MD 0x80 +/* R_CHIP_ID */ +#define V_PNP_IRQ 0x01 +#define V_CHIP_ID 0x10 + +/* chapter 3: data flow */ +/* R_FIRST_FIFO */ +#define V_FIRST_FIRO_DIR 0x01 +#define V_FIRST_FIFO_NUM 0x02 +/* R_FIFO_MD */ +#define V_FIFO_MD 0x01 +#define V_CSM_MD 0x04 +#define V_FSM_MD 0x08 +#define V_FIFO_SZ 0x10 +/* R_FIFO */ +#define V_FIFO_DIR 0x01 +#define V_FIFO_NUM 0x02 +#define V_REV 0x80 +/* R_SLOT */ +#define V_SL_DIR 0x01 +#define V_SL_NUM 0x02 +/* A_SL_CFG */ +#define V_CH_DIR 0x01 +#define V_CH_SEL 0x02 +#define V_ROUTING 0x40 +/* A_CON_HDLC */ +#define V_IFF 0x01 +#define V_HDLC_TRP 0x02 +#define V_TRP_IRQ 0x04 +#define V_DATA_FLOW 0x20 +/* A_SUBCH_CFG */ +#define V_BIT_CNT 0x01 +#define V_START_BIT 0x08 +#define V_LOOP_FIFO 0x40 +#define V_INV_DATA 0x80 +/* A_CHANNEL */ +#define V_CH_DIR0 0x01 +#define V_CH_NUM0 0x02 +/* A_FIFO_SEQ */ +#define V_NEXT_FIFO_DIR 0x01 +#define V_NEXT_FIFO_NUM 0x02 +#define V_SEQ_END 0x40 + +/* chapter 4: FIFO handling and HDLC controller */ +/* R_INC_RES_FIFO */ +#define V_INC_F 0x01 +#define V_RES_F 0x02 +#define V_RES_LOST 0x04 + +/* chapter 5: S/T interface */ +/* R_SCI_MSK */ +#define V_SCI_MSK_ST0 0x01 +#define V_SCI_MSK_ST1 0x02 +#define V_SCI_MSK_ST2 0x04 +#define V_SCI_MSK_ST3 0x08 +#define V_SCI_MSK_ST4 0x10 +#define V_SCI_MSK_ST5 0x20 +#define V_SCI_MSK_ST6 0x40 +#define V_SCI_MSK_ST7 0x80 +/* R_ST_SEL */ +#define V_ST_SEL 0x01 +#define V_MULT_ST 0x08 +/* R_ST_SYNC */ +#define V_SYNC_SEL 0x01 +#define V_AUTO_SYNC 0x08 +/* A_ST_WR_STA */ +#define V_ST_SET_STA 0x01 +#define V_ST_LD_STA 0x10 +#define V_ST_ACT 0x20 +#define V_SET_G2_G3 0x80 +/* A_ST_CTRL0 */ +#define V_B1_EN 0x01 +#define V_B2_EN 0x02 +#define V_ST_MD 0x04 +#define V_D_PRIO 0x08 +#define V_SQ_EN 0x10 +#define V_96KHZ 0x20 +#define V_TX_LI 0x40 +#define V_ST_STOP 0x80 +/* A_ST_CTRL1 */ +#define V_G2_G3_EN 0x01 +#define V_D_HI 0x04 +#define V_E_IGNO 0x08 +#define V_E_LO 0x10 +#define V_B12_SWAP 0x80 +/* A_ST_CTRL2 */ +#define V_B1_RX_EN 0x01 +#define V_B2_RX_EN 0x02 +#define V_ST_TRIS 0x40 +/* A_ST_CLK_DLY */ +#define V_ST_CK_DLY 0x01 +#define V_ST_SMPL 0x10 +/* A_ST_D_TX */ +#define V_ST_D_TX 0x40 +/* R_IRQ_STATECH */ +#define V_SCI_ST0 0x01 +#define V_SCI_ST1 0x02 +#define V_SCI_ST2 0x04 +#define V_SCI_ST3 0x08 +#define V_SCI_ST4 0x10 +#define V_SCI_ST5 0x20 +#define V_SCI_ST6 0x40 +#define V_SCI_ST7 0x80 +/* A_ST_RD_STA */ +#define V_ST_STA 0x01 +#define V_FR_SYNC_ST 0x10 +#define V_TI2_EXP 0x20 +#define V_INFO0 0x40 +#define V_G2_G3 0x80 +/* A_ST_SQ_RD */ +#define V_ST_SQ 0x01 +#define V_MF_RX_RDY 0x10 +#define V_MF_TX_RDY 0x80 +/* A_ST_D_RX */ +#define V_ST_D_RX 0x40 +/* A_ST_E_RX */ +#define V_ST_E_RX 0x40 + +/* chapter 5: E1 interface */ +/* R_E1_WR_STA */ +/* R_E1_RD_STA */ +#define V_E1_SET_STA 0x01 +#define V_E1_LD_STA 0x10 +/* R_RX0 */ +#define V_RX_CODE 0x01 +#define V_RX_FBAUD 0x04 +#define V_RX_CMI 0x08 +#define V_RX_INV_CMI 0x10 +#define V_RX_INV_CLK 0x20 +#define V_RX_INV_DATA 0x40 +#define V_AIS_ITU 0x80 +/* R_RX_FR0 */ +#define V_NO_INSYNC 0x01 +#define V_AUTO_RESYNC 0x02 +#define V_AUTO_RECO 0x04 +#define V_SWORD_COND 0x08 +#define V_SYNC_LOSS 0x10 +#define V_XCRC_SYNC 0x20 +#define V_MF_RESYNC 0x40 +#define V_RESYNC 0x80 +/* R_RX_FR1 */ +#define V_RX_MF 0x01 +#define V_RX_MF_SYNC 0x02 +#define V_RX_SL0_RAM 0x04 +#define V_ERR_SIM 0x20 +#define V_RES_NMF 0x40 +/* R_TX0 */ +#define V_TX_CODE 0x01 +#define V_TX_FBAUD 0x04 +#define V_TX_CMI_CODE 0x08 +#define V_TX_INV_CMI_CODE 0x10 +#define V_TX_INV_CLK 0x20 +#define V_TX_INV_DATA 0x40 +#define V_OUT_EN 0x80 +/* R_TX1 */ +#define V_INV_CLK 0x01 +#define V_EXCHG_DATA_LI 0x02 +#define V_AIS_OUT 0x04 +#define V_ATX 0x20 +#define V_NTRI 0x40 +#define V_AUTO_ERR_RES 0x80 +/* R_TX_FR0 */ +#define V_TRP_FAS 0x01 +#define V_TRP_NFAS 0x02 +#define V_TRP_RAL 0x04 +#define V_TRP_SA 0x08 +/* R_TX_FR1 */ +#define V_TX_FAS 0x01 +#define V_TX_NFAS 0x02 +#define V_TX_RAL 0x04 +#define V_TX_SA 0x08 +/* R_TX_FR2 */ +#define V_TX_MF 0x01 +#define V_TRP_SL0 0x02 +#define V_TX_SL0_RAM 0x04 +#define V_TX_E 0x10 +#define V_NEG_E 0x20 +#define V_XS12_ON 0x40 +#define V_XS15_ON 0x80 +/* R_RX_OFF */ +#define V_RX_SZ 0x01 +#define V_RX_INIT 0x04 +/* R_SYNC_OUT */ +#define V_SYNC_E1_RX 0x01 +#define V_IPATS0 0x20 +#define V_IPATS1 0x40 +#define V_IPATS2 0x80 +/* R_TX_OFF */ +#define V_TX_SZ 0x01 +#define V_TX_INIT 0x04 +/* R_SYNC_CTRL */ +#define V_EXT_CLK_SYNC 0x01 +#define V_SYNC_OFFS 0x02 +#define V_PCM_SYNC 0x04 +#define V_NEG_CLK 0x08 +#define V_HCLK 0x10 +/* + #define V_JATT_AUTO_DEL 0x20 + #define V_JATT_AUTO 0x40 +*/ +#define V_JATT_OFF 0x80 +/* R_STATE */ +#define V_E1_STA 0x01 +#define V_ALT_FR_RX 0x40 +#define V_ALT_FR_TX 0x80 +/* R_SYNC_STA */ +#define V_RX_STA 0x01 +#define V_FR_SYNC_E1 0x04 +#define V_SIG_LOS 0x08 +#define V_MFA_STA 0x10 +#define V_AIS 0x40 +#define V_NO_MF_SYNC 0x80 +/* R_RX_SL0_0 */ +#define V_SI_FAS 0x01 +#define V_SI_NFAS 0x02 +#define V_A 0x04 +#define V_CRC_OK 0x08 +#define V_TX_E1 0x10 +#define V_TX_E2 0x20 +#define V_RX_E1 0x40 +#define V_RX_E2 0x80 +/* R_SLIP */ +#define V_SLIP_RX 0x01 +#define V_FOSLIP_RX 0x08 +#define V_SLIP_TX 0x10 +#define V_FOSLIP_TX 0x80 + +/* chapter 6: PCM interface */ +/* R_PCM_MD0 */ +#define V_PCM_MD 0x01 +#define V_C4_POL 0x02 +#define V_F0_NEG 0x04 +#define V_F0_LEN 0x08 +#define V_PCM_ADDR 0x10 +/* R_SL_SEL0 */ +#define V_SL_SEL0 0x01 +#define V_SH_SEL0 0x80 +/* R_SL_SEL1 */ +#define V_SL_SEL1 0x01 +#define V_SH_SEL1 0x80 +/* R_SL_SEL2 */ +#define V_SL_SEL2 0x01 +#define V_SH_SEL2 0x80 +/* R_SL_SEL3 */ +#define V_SL_SEL3 0x01 +#define V_SH_SEL3 0x80 +/* R_SL_SEL4 */ +#define V_SL_SEL4 0x01 +#define V_SH_SEL4 0x80 +/* R_SL_SEL5 */ +#define V_SL_SEL5 0x01 +#define V_SH_SEL5 0x80 +/* R_SL_SEL6 */ +#define V_SL_SEL6 0x01 +#define V_SH_SEL6 0x80 +/* R_SL_SEL7 */ +#define V_SL_SEL7 0x01 +#define V_SH_SEL7 0x80 +/* R_PCM_MD1 */ +#define V_ODEC_CON 0x01 +#define V_PLL_ADJ 0x04 +#define V_PCM_DR 0x10 +#define V_PCM_LOOP 0x40 +/* R_PCM_MD2 */ +#define V_SYNC_PLL 0x02 +#define V_SYNC_SRC 0x04 +#define V_SYNC_OUT 0x08 +#define V_ICR_FR_TIME 0x40 +#define V_EN_PLL 0x80 + +/* chapter 7: pulse width modulation */ +/* R_PWM_MD */ +#define V_EXT_IRQ_EN 0x08 +#define V_PWM0_MD 0x10 +#define V_PWM1_MD 0x40 + +/* chapter 8: multiparty audio conferences */ +/* R_CONF_EN */ +#define V_CONF_EN 0x01 +#define V_ULAW 0x80 +/* A_CONF */ +#define V_CONF_NUM 0x01 +#define V_NOISE_SUPPR 0x08 +#define V_ATT_LEV 0x20 +#define V_CONF_SL 0x80 +/* R_CONF_OFLOW */ +#define V_CONF_OFLOW0 0x01 +#define V_CONF_OFLOW1 0x02 +#define V_CONF_OFLOW2 0x04 +#define V_CONF_OFLOW3 0x08 +#define V_CONF_OFLOW4 0x10 +#define V_CONF_OFLOW5 0x20 +#define V_CONF_OFLOW6 0x40 +#define V_CONF_OFLOW7 0x80 + +/* chapter 9: DTMF contoller */ +/* R_DTMF0 */ +#define V_DTMF_EN 0x01 +#define V_HARM_SEL 0x02 +#define V_DTMF_RX_CH 0x04 +#define V_DTMF_STOP 0x08 +#define V_CHBL_SEL 0x10 +#define V_RST_DTMF 0x40 +#define V_ULAW_SEL 0x80 + +/* chapter 10: BERT */ +/* R_BERT_WD_MD */ +#define V_PAT_SEQ 0x01 +#define V_BERT_ERR 0x08 +#define V_AUTO_WD_RES 0x20 +#define V_WD_RES 0x80 +/* R_BERT_STA */ +#define V_BERT_SYNC_SRC 0x01 +#define V_BERT_SYNC 0x10 +#define V_BERT_INV_DATA 0x20 + +/* chapter 11: auxiliary interface */ +/* R_BRG_PCM_CFG */ +#define V_BRG_EN 0x01 +#define V_BRG_MD 0x02 +#define V_PCM_CLK 0x20 +#define V_ADDR_WRDLY 0x40 +/* R_BRG_CTRL */ +#define V_BRG_CS 0x01 +#define V_BRG_ADDR 0x08 +#define V_BRG_CS_SRC 0x80 +/* R_BRG_MD */ +#define V_BRG_MD0 0x01 +#define V_BRG_MD1 0x02 +#define V_BRG_MD2 0x04 +#define V_BRG_MD3 0x08 +#define V_BRG_MD4 0x10 +#define V_BRG_MD5 0x20 +#define V_BRG_MD6 0x40 +#define V_BRG_MD7 0x80 +/* R_BRG_TIM0 */ +#define V_BRG_TIM0_IDLE 0x01 +#define V_BRG_TIM0_CLK 0x10 +/* R_BRG_TIM1 */ +#define V_BRG_TIM1_IDLE 0x01 +#define V_BRG_TIM1_CLK 0x10 +/* R_BRG_TIM2 */ +#define V_BRG_TIM2_IDLE 0x01 +#define V_BRG_TIM2_CLK 0x10 +/* R_BRG_TIM3 */ +#define V_BRG_TIM3_IDLE 0x01 +#define V_BRG_TIM3_CLK 0x10 +/* R_BRG_TIM_SEL01 */ +#define V_BRG_WR_SEL0 0x01 +#define V_BRG_RD_SEL0 0x04 +#define V_BRG_WR_SEL1 0x10 +#define V_BRG_RD_SEL1 0x40 +/* R_BRG_TIM_SEL23 */ +#define V_BRG_WR_SEL2 0x01 +#define V_BRG_RD_SEL2 0x04 +#define V_BRG_WR_SEL3 0x10 +#define V_BRG_RD_SEL3 0x40 +/* R_BRG_TIM_SEL45 */ +#define V_BRG_WR_SEL4 0x01 +#define V_BRG_RD_SEL4 0x04 +#define V_BRG_WR_SEL5 0x10 +#define V_BRG_RD_SEL5 0x40 +/* R_BRG_TIM_SEL67 */ +#define V_BRG_WR_SEL6 0x01 +#define V_BRG_RD_SEL6 0x04 +#define V_BRG_WR_SEL7 0x10 +#define V_BRG_RD_SEL7 0x40 + +/* chapter 12: clock, reset, interrupt, timer and watchdog */ +/* R_IRQMSK_MISC */ +#define V_STA_IRQMSK 0x01 +#define V_TI_IRQMSK 0x02 +#define V_PROC_IRQMSK 0x04 +#define V_DTMF_IRQMSK 0x08 +#define V_IRQ1S_MSK 0x10 +#define V_SA6_IRQMSK 0x20 +#define V_RX_EOMF_MSK 0x40 +#define V_TX_EOMF_MSK 0x80 +/* R_IRQ_CTRL */ +#define V_FIFO_IRQ 0x01 +#define V_GLOB_IRQ_EN 0x08 +#define V_IRQ_POL 0x10 +/* R_TI_WD */ +#define V_EV_TS 0x01 +#define V_WD_TS 0x10 +/* A_IRQ_MSK */ +#define V_IRQ 0x01 +#define V_BERT_EN 0x02 +#define V_MIX_IRQ 0x04 +/* R_IRQ_OVIEW */ +#define V_IRQ_FIFO_BL0 0x01 +#define V_IRQ_FIFO_BL1 0x02 +#define V_IRQ_FIFO_BL2 0x04 +#define V_IRQ_FIFO_BL3 0x08 +#define V_IRQ_FIFO_BL4 0x10 +#define V_IRQ_FIFO_BL5 0x20 +#define V_IRQ_FIFO_BL6 0x40 +#define V_IRQ_FIFO_BL7 0x80 +/* R_IRQ_MISC */ +#define V_STA_IRQ 0x01 +#define V_TI_IRQ 0x02 +#define V_IRQ_PROC 0x04 +#define V_DTMF_IRQ 0x08 +#define V_IRQ1S 0x10 +#define V_SA6_IRQ 0x20 +#define V_RX_EOMF 0x40 +#define V_TX_EOMF 0x80 +/* R_STATUS */ +#define V_BUSY 0x01 +#define V_PROC 0x02 +#define V_DTMF_STA 0x04 +#define V_LOST_STA 0x08 +#define V_SYNC_IN 0x10 +#define V_EXT_IRQSTA 0x20 +#define V_MISC_IRQSTA 0x40 +#define V_FR_IRQSTA 0x80 +/* R_IRQ_FIFO_BL0 */ +#define V_IRQ_FIFO0_TX 0x01 +#define V_IRQ_FIFO0_RX 0x02 +#define V_IRQ_FIFO1_TX 0x04 +#define V_IRQ_FIFO1_RX 0x08 +#define V_IRQ_FIFO2_TX 0x10 +#define V_IRQ_FIFO2_RX 0x20 +#define V_IRQ_FIFO3_TX 0x40 +#define V_IRQ_FIFO3_RX 0x80 +/* R_IRQ_FIFO_BL1 */ +#define V_IRQ_FIFO4_TX 0x01 +#define V_IRQ_FIFO4_RX 0x02 +#define V_IRQ_FIFO5_TX 0x04 +#define V_IRQ_FIFO5_RX 0x08 +#define V_IRQ_FIFO6_TX 0x10 +#define V_IRQ_FIFO6_RX 0x20 +#define V_IRQ_FIFO7_TX 0x40 +#define V_IRQ_FIFO7_RX 0x80 +/* R_IRQ_FIFO_BL2 */ +#define V_IRQ_FIFO8_TX 0x01 +#define V_IRQ_FIFO8_RX 0x02 +#define V_IRQ_FIFO9_TX 0x04 +#define V_IRQ_FIFO9_RX 0x08 +#define V_IRQ_FIFO10_TX 0x10 +#define V_IRQ_FIFO10_RX 0x20 +#define V_IRQ_FIFO11_TX 0x40 +#define V_IRQ_FIFO11_RX 0x80 +/* R_IRQ_FIFO_BL3 */ +#define V_IRQ_FIFO12_TX 0x01 +#define V_IRQ_FIFO12_RX 0x02 +#define V_IRQ_FIFO13_TX 0x04 +#define V_IRQ_FIFO13_RX 0x08 +#define V_IRQ_FIFO14_TX 0x10 +#define V_IRQ_FIFO14_RX 0x20 +#define V_IRQ_FIFO15_TX 0x40 +#define V_IRQ_FIFO15_RX 0x80 +/* R_IRQ_FIFO_BL4 */ +#define V_IRQ_FIFO16_TX 0x01 +#define V_IRQ_FIFO16_RX 0x02 +#define V_IRQ_FIFO17_TX 0x04 +#define V_IRQ_FIFO17_RX 0x08 +#define V_IRQ_FIFO18_TX 0x10 +#define V_IRQ_FIFO18_RX 0x20 +#define V_IRQ_FIFO19_TX 0x40 +#define V_IRQ_FIFO19_RX 0x80 +/* R_IRQ_FIFO_BL5 */ +#define V_IRQ_FIFO20_TX 0x01 +#define V_IRQ_FIFO20_RX 0x02 +#define V_IRQ_FIFO21_TX 0x04 +#define V_IRQ_FIFO21_RX 0x08 +#define V_IRQ_FIFO22_TX 0x10 +#define V_IRQ_FIFO22_RX 0x20 +#define V_IRQ_FIFO23_TX 0x40 +#define V_IRQ_FIFO23_RX 0x80 +/* R_IRQ_FIFO_BL6 */ +#define V_IRQ_FIFO24_TX 0x01 +#define V_IRQ_FIFO24_RX 0x02 +#define V_IRQ_FIFO25_TX 0x04 +#define V_IRQ_FIFO25_RX 0x08 +#define V_IRQ_FIFO26_TX 0x10 +#define V_IRQ_FIFO26_RX 0x20 +#define V_IRQ_FIFO27_TX 0x40 +#define V_IRQ_FIFO27_RX 0x80 +/* R_IRQ_FIFO_BL7 */ +#define V_IRQ_FIFO28_TX 0x01 +#define V_IRQ_FIFO28_RX 0x02 +#define V_IRQ_FIFO29_TX 0x04 +#define V_IRQ_FIFO29_RX 0x08 +#define V_IRQ_FIFO30_TX 0x10 +#define V_IRQ_FIFO30_RX 0x20 +#define V_IRQ_FIFO31_TX 0x40 +#define V_IRQ_FIFO31_RX 0x80 + +/* chapter 13: general purpose I/O pins (GPIO) and input pins (GPI) */ +/* R_GPIO_OUT0 */ +#define V_GPIO_OUT0 0x01 +#define V_GPIO_OUT1 0x02 +#define V_GPIO_OUT2 0x04 +#define V_GPIO_OUT3 0x08 +#define V_GPIO_OUT4 0x10 +#define V_GPIO_OUT5 0x20 +#define V_GPIO_OUT6 0x40 +#define V_GPIO_OUT7 0x80 +/* R_GPIO_OUT1 */ +#define V_GPIO_OUT8 0x01 +#define V_GPIO_OUT9 0x02 +#define V_GPIO_OUT10 0x04 +#define V_GPIO_OUT11 0x08 +#define V_GPIO_OUT12 0x10 +#define V_GPIO_OUT13 0x20 +#define V_GPIO_OUT14 0x40 +#define V_GPIO_OUT15 0x80 +/* R_GPIO_EN0 */ +#define V_GPIO_EN0 0x01 +#define V_GPIO_EN1 0x02 +#define V_GPIO_EN2 0x04 +#define V_GPIO_EN3 0x08 +#define V_GPIO_EN4 0x10 +#define V_GPIO_EN5 0x20 +#define V_GPIO_EN6 0x40 +#define V_GPIO_EN7 0x80 +/* R_GPIO_EN1 */ +#define V_GPIO_EN8 0x01 +#define V_GPIO_EN9 0x02 +#define V_GPIO_EN10 0x04 +#define V_GPIO_EN11 0x08 +#define V_GPIO_EN12 0x10 +#define V_GPIO_EN13 0x20 +#define V_GPIO_EN14 0x40 +#define V_GPIO_EN15 0x80 +/* R_GPIO_SEL */ +#define V_GPIO_SEL0 0x01 +#define V_GPIO_SEL1 0x02 +#define V_GPIO_SEL2 0x04 +#define V_GPIO_SEL3 0x08 +#define V_GPIO_SEL4 0x10 +#define V_GPIO_SEL5 0x20 +#define V_GPIO_SEL6 0x40 +#define V_GPIO_SEL7 0x80 +/* R_GPIO_IN0 */ +#define V_GPIO_IN0 0x01 +#define V_GPIO_IN1 0x02 +#define V_GPIO_IN2 0x04 +#define V_GPIO_IN3 0x08 +#define V_GPIO_IN4 0x10 +#define V_GPIO_IN5 0x20 +#define V_GPIO_IN6 0x40 +#define V_GPIO_IN7 0x80 +/* R_GPIO_IN1 */ +#define V_GPIO_IN8 0x01 +#define V_GPIO_IN9 0x02 +#define V_GPIO_IN10 0x04 +#define V_GPIO_IN11 0x08 +#define V_GPIO_IN12 0x10 +#define V_GPIO_IN13 0x20 +#define V_GPIO_IN14 0x40 +#define V_GPIO_IN15 0x80 +/* R_GPI_IN0 */ +#define V_GPI_IN0 0x01 +#define V_GPI_IN1 0x02 +#define V_GPI_IN2 0x04 +#define V_GPI_IN3 0x08 +#define V_GPI_IN4 0x10 +#define V_GPI_IN5 0x20 +#define V_GPI_IN6 0x40 +#define V_GPI_IN7 0x80 +/* R_GPI_IN1 */ +#define V_GPI_IN8 0x01 +#define V_GPI_IN9 0x02 +#define V_GPI_IN10 0x04 +#define V_GPI_IN11 0x08 +#define V_GPI_IN12 0x10 +#define V_GPI_IN13 0x20 +#define V_GPI_IN14 0x40 +#define V_GPI_IN15 0x80 +/* R_GPI_IN2 */ +#define V_GPI_IN16 0x01 +#define V_GPI_IN17 0x02 +#define V_GPI_IN18 0x04 +#define V_GPI_IN19 0x08 +#define V_GPI_IN20 0x10 +#define V_GPI_IN21 0x20 +#define V_GPI_IN22 0x40 +#define V_GPI_IN23 0x80 +/* R_GPI_IN3 */ +#define V_GPI_IN24 0x01 +#define V_GPI_IN25 0x02 +#define V_GPI_IN26 0x04 +#define V_GPI_IN27 0x08 +#define V_GPI_IN28 0x10 +#define V_GPI_IN29 0x20 +#define V_GPI_IN30 0x40 +#define V_GPI_IN31 0x80 + +/* map of all registers, used for debugging */ + +#ifdef HFC_REGISTER_DEBUG +struct hfc_register_names { + char *name; + u_char reg; +} hfc_register_names[] = { + /* write registers */ + {"R_CIRM", 0x00}, + {"R_CTRL", 0x01}, + {"R_BRG_PCM_CFG ", 0x02}, + {"R_RAM_ADDR0", 0x08}, + {"R_RAM_ADDR1", 0x09}, + {"R_RAM_ADDR2", 0x0A}, + {"R_FIRST_FIFO", 0x0B}, + {"R_RAM_SZ", 0x0C}, + {"R_FIFO_MD", 0x0D}, + {"R_INC_RES_FIFO", 0x0E}, + {"R_FIFO / R_FSM_IDX", 0x0F}, + {"R_SLOT", 0x10}, + {"R_IRQMSK_MISC", 0x11}, + {"R_SCI_MSK", 0x12}, + {"R_IRQ_CTRL", 0x13}, + {"R_PCM_MD0", 0x14}, + {"R_0x15", 0x15}, + {"R_ST_SEL", 0x16}, + {"R_ST_SYNC", 0x17}, + {"R_CONF_EN", 0x18}, + {"R_TI_WD", 0x1A}, + {"R_BERT_WD_MD", 0x1B}, + {"R_DTMF", 0x1C}, + {"R_DTMF_N", 0x1D}, + {"R_E1_XX_STA", 0x20}, + {"R_LOS0", 0x22}, + {"R_LOS1", 0x23}, + {"R_RX0", 0x24}, + {"R_RX_FR0", 0x25}, + {"R_RX_FR1", 0x26}, + {"R_TX0", 0x28}, + {"R_TX1", 0x29}, + {"R_TX_FR0", 0x2C}, + {"R_TX_FR1", 0x2D}, + {"R_TX_FR2", 0x2E}, + {"R_JATT_ATT", 0x2F}, + {"A_ST_xx_STA/R_RX_OFF", 0x30}, + {"A_ST_CTRL0/R_SYNC_OUT", 0x31}, + {"A_ST_CTRL1", 0x32}, + {"A_ST_CTRL2", 0x33}, + {"A_ST_SQ_WR", 0x34}, + {"R_TX_OFF", 0x34}, + {"R_SYNC_CTRL", 0x35}, + {"A_ST_CLK_DLY", 0x37}, + {"R_PWM0", 0x38}, + {"R_PWM1", 0x39}, + {"A_ST_B1_TX", 0x3C}, + {"A_ST_B2_TX", 0x3D}, + {"A_ST_D_TX", 0x3E}, + {"R_GPIO_OUT0", 0x40}, + {"R_GPIO_OUT1", 0x41}, + {"R_GPIO_EN0", 0x42}, + {"R_GPIO_EN1", 0x43}, + {"R_GPIO_SEL", 0x44}, + {"R_BRG_CTRL", 0x45}, + {"R_PWM_MD", 0x46}, + {"R_BRG_MD", 0x47}, + {"R_BRG_TIM0", 0x48}, + {"R_BRG_TIM1", 0x49}, + {"R_BRG_TIM2", 0x4A}, + {"R_BRG_TIM3", 0x4B}, + {"R_BRG_TIM_SEL01", 0x4C}, + {"R_BRG_TIM_SEL23", 0x4D}, + {"R_BRG_TIM_SEL45", 0x4E}, + {"R_BRG_TIM_SEL67", 0x4F}, + {"A_FIFO_DATA0-2", 0x80}, + {"A_FIFO_DATA0-2_NOINC", 0x84}, + {"R_RAM_DATA", 0xC0}, + {"A_SL_CFG", 0xD0}, + {"A_CONF", 0xD1}, + {"A_CH_MSK", 0xF4}, + {"A_CON_HDLC", 0xFA}, + {"A_SUBCH_CFG", 0xFB}, + {"A_CHANNEL", 0xFC}, + {"A_FIFO_SEQ", 0xFD}, + {"A_IRQ_MSK", 0xFF}, + {NULL, 0}, + + /* read registers */ + {"A_Z1", 0x04}, + {"A_Z1H", 0x05}, + {"A_Z2", 0x06}, + {"A_Z2H", 0x07}, + {"A_F1", 0x0C}, + {"A_F2", 0x0D}, + {"R_IRQ_OVIEW", 0x10}, + {"R_IRQ_MISC", 0x11}, + {"R_IRQ_STATECH", 0x12}, + {"R_CONF_OFLOW", 0x14}, + {"R_RAM_USE", 0x15}, + {"R_CHIP_ID", 0x16}, + {"R_BERT_STA", 0x17}, + {"R_F0_CNTL", 0x18}, + {"R_F0_CNTH", 0x19}, + {"R_BERT_ECL", 0x1A}, + {"R_BERT_ECH", 0x1B}, + {"R_STATUS", 0x1C}, + {"R_CHIP_RV", 0x1F}, + {"R_STATE", 0x20}, + {"R_SYNC_STA", 0x24}, + {"R_RX_SL0_0", 0x25}, + {"R_RX_SL0_1", 0x26}, + {"R_RX_SL0_2", 0x27}, + {"R_JATT_DIR", 0x2b}, + {"R_SLIP", 0x2c}, + {"A_ST_RD_STA", 0x30}, + {"R_FAS_ECL", 0x30}, + {"R_FAS_ECH", 0x31}, + {"R_VIO_ECL", 0x32}, + {"R_VIO_ECH", 0x33}, + {"R_CRC_ECL / A_ST_SQ_RD", 0x34}, + {"R_CRC_ECH", 0x35}, + {"R_E_ECL", 0x36}, + {"R_E_ECH", 0x37}, + {"R_SA6_SA13_ECL", 0x38}, + {"R_SA6_SA13_ECH", 0x39}, + {"R_SA6_SA23_ECL", 0x3A}, + {"R_SA6_SA23_ECH", 0x3B}, + {"A_ST_B1_RX", 0x3C}, + {"A_ST_B2_RX", 0x3D}, + {"A_ST_D_RX", 0x3E}, + {"A_ST_E_RX", 0x3F}, + {"R_GPIO_IN0", 0x40}, + {"R_GPIO_IN1", 0x41}, + {"R_GPI_IN0", 0x44}, + {"R_GPI_IN1", 0x45}, + {"R_GPI_IN2", 0x46}, + {"R_GPI_IN3", 0x47}, + {"A_FIFO_DATA0-2", 0x80}, + {"A_FIFO_DATA0-2_NOINC", 0x84}, + {"R_INT_DATA", 0x88}, + {"R_RAM_DATA", 0xC0}, + {"R_IRQ_FIFO_BL0", 0xC8}, + {"R_IRQ_FIFO_BL1", 0xC9}, + {"R_IRQ_FIFO_BL2", 0xCA}, + {"R_IRQ_FIFO_BL3", 0xCB}, + {"R_IRQ_FIFO_BL4", 0xCC}, + {"R_IRQ_FIFO_BL5", 0xCD}, + {"R_IRQ_FIFO_BL6", 0xCE}, + {"R_IRQ_FIFO_BL7", 0xCF}, +}; +#endif /* HFC_REGISTER_DEBUG */ diff --git a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h new file mode 100644 index 00000000000..0eafe9f04fc --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h @@ -0,0 +1,167 @@ +/* + * For License see notice in hfc_multi.c + * + * special IO and init functions for the embedded XHFC board + * from Speech Design + * + */ + +#include <asm/8xx_immap.h> + +/* Change this to the value used by your board */ +#ifndef IMAP_ADDR +#define IMAP_ADDR 0xFFF00000 +#endif + +static void +#ifdef HFC_REGISTER_DEBUG +HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val, + const char *function, int line) +#else + HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val) +#endif +{ + hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; + writeb(reg, hc->xhfc_memaddr); + hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); + writeb(val, hc->xhfc_memdata); +} +static u_char +#ifdef HFC_REGISTER_DEBUG +HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line) +#else + HFC_inb_embsd(struct hfc_multi *hc, u_char reg) +#endif +{ + hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; + writeb(reg, hc->xhfc_memaddr); + hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); + return readb(hc->xhfc_memdata); +} +static u_short +#ifdef HFC_REGISTER_DEBUG +HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line) +#else + HFC_inw_embsd(struct hfc_multi *hc, u_char reg) +#endif +{ + hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; + writeb(reg, hc->xhfc_memaddr); + hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); + return readb(hc->xhfc_memdata); +} +static void +#ifdef HFC_REGISTER_DEBUG +HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line) +#else + HFC_wait_embsd(struct hfc_multi *hc) +#endif +{ + hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; + writeb(R_STATUS, hc->xhfc_memaddr); + hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); + while (readb(hc->xhfc_memdata) & V_BUSY) + cpu_relax(); +} + +/* write fifo data (EMBSD) */ +void +write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len) +{ + hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; + *hc->xhfc_memaddr = A_FIFO_DATA0; + hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); + while (len) { + *hc->xhfc_memdata = *data; + data++; + len--; + } +} + +/* read fifo data (EMBSD) */ +void +read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len) +{ + hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; + *hc->xhfc_memaddr = A_FIFO_DATA0; + hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); + while (len) { + *data = (u_char)(*hc->xhfc_memdata); + data++; + len--; + } +} + +static int +setup_embedded(struct hfc_multi *hc, struct hm_map *m) +{ + printk(KERN_INFO + "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n", + m->vendor_name, m->card_name, m->clock2 ? "double" : "normal"); + + hc->pci_dev = NULL; + if (m->clock2) + test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip); + + hc->leds = m->leds; + hc->ledstate = 0xAFFEAFFE; + hc->opticalsupport = m->opticalsupport; + + hc->pci_iobase = 0; + hc->pci_membase = 0; + hc->xhfc_membase = NULL; + hc->xhfc_memaddr = NULL; + hc->xhfc_memdata = NULL; + + /* set memory access methods */ + if (m->io_mode) /* use mode from card config */ + hc->io_mode = m->io_mode; + switch (hc->io_mode) { + case HFC_IO_MODE_EMBSD: + test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip); + hc->slots = 128; /* required */ + /* fall through */ + hc->HFC_outb = HFC_outb_embsd; + hc->HFC_inb = HFC_inb_embsd; + hc->HFC_inw = HFC_inw_embsd; + hc->HFC_wait = HFC_wait_embsd; + hc->read_fifo = read_fifo_embsd; + hc->write_fifo = write_fifo_embsd; + hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id; + hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase, + XHFC_MEMSIZE); + if (!hc->xhfc_membase) { + printk(KERN_WARNING + "HFC-multi: failed to remap xhfc address space. " + "(internal error)\n"); + return -EIO; + } + hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4); + hc->xhfc_memdata = (u_long *)(hc->xhfc_membase); + printk(KERN_INFO + "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx " + "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n", + (u_long)hc->xhfc_membase, hc->xhfc_origmembase, + (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata); + break; + default: + printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); + return -EIO; + } + + /* Prepare the MPC8XX PortA 10 as output (address/data selector) */ + hc->immap = (struct immap *)(IMAP_ADDR); + hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0); + hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0); + hc->immap->im_ioport.iop_padir |= PA_XHFC_A0; + + /* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */ + hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id); + hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk); + hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk); + hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk); + + /* At this point the needed config is done */ + /* fifos are still not enabled */ + return 0; +} diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.h b/drivers/isdn/hardware/mISDN/hfc_pci.h new file mode 100644 index 00000000000..411cd10772e --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfc_pci.h @@ -0,0 +1,228 @@ +/* + * specific defines for CCD's HFC 2BDS0 PCI chips + * + * Author Werner Cornelius (werner@isdn4linux.de) + * + * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * thresholds for transparent B-channel mode + * change mask and threshold simultaneously + */ +#define HFCPCI_BTRANS_THRESHOLD 128 +#define HFCPCI_FILLEMPTY 64 +#define HFCPCI_BTRANS_THRESMASK 0x00 + +/* defines for PCI config */ +#define PCI_ENA_MEMIO 0x02 +#define PCI_ENA_MASTER 0x04 + +/* GCI/IOM bus monitor registers */ +#define HCFPCI_C_I 0x08 +#define HFCPCI_TRxR 0x0C +#define HFCPCI_MON1_D 0x28 +#define HFCPCI_MON2_D 0x2C + +/* GCI/IOM bus timeslot registers */ +#define HFCPCI_B1_SSL 0x80 +#define HFCPCI_B2_SSL 0x84 +#define HFCPCI_AUX1_SSL 0x88 +#define HFCPCI_AUX2_SSL 0x8C +#define HFCPCI_B1_RSL 0x90 +#define HFCPCI_B2_RSL 0x94 +#define HFCPCI_AUX1_RSL 0x98 +#define HFCPCI_AUX2_RSL 0x9C + +/* GCI/IOM bus data registers */ +#define HFCPCI_B1_D 0xA0 +#define HFCPCI_B2_D 0xA4 +#define HFCPCI_AUX1_D 0xA8 +#define HFCPCI_AUX2_D 0xAC + +/* GCI/IOM bus configuration registers */ +#define HFCPCI_MST_EMOD 0xB4 +#define HFCPCI_MST_MODE 0xB8 +#define HFCPCI_CONNECT 0xBC + + +/* Interrupt and status registers */ +#define HFCPCI_FIFO_EN 0x44 +#define HFCPCI_TRM 0x48 +#define HFCPCI_B_MODE 0x4C +#define HFCPCI_CHIP_ID 0x58 +#define HFCPCI_CIRM 0x60 +#define HFCPCI_CTMT 0x64 +#define HFCPCI_INT_M1 0x68 +#define HFCPCI_INT_M2 0x6C +#define HFCPCI_INT_S1 0x78 +#define HFCPCI_INT_S2 0x7C +#define HFCPCI_STATUS 0x70 + +/* S/T section registers */ +#define HFCPCI_STATES 0xC0 +#define HFCPCI_SCTRL 0xC4 +#define HFCPCI_SCTRL_E 0xC8 +#define HFCPCI_SCTRL_R 0xCC +#define HFCPCI_SQ 0xD0 +#define HFCPCI_CLKDEL 0xDC +#define HFCPCI_B1_REC 0xF0 +#define HFCPCI_B1_SEND 0xF0 +#define HFCPCI_B2_REC 0xF4 +#define HFCPCI_B2_SEND 0xF4 +#define HFCPCI_D_REC 0xF8 +#define HFCPCI_D_SEND 0xF8 +#define HFCPCI_E_REC 0xFC + + +/* bits in status register (READ) */ +#define HFCPCI_PCI_PROC 0x02 +#define HFCPCI_NBUSY 0x04 +#define HFCPCI_TIMER_ELAP 0x10 +#define HFCPCI_STATINT 0x20 +#define HFCPCI_FRAMEINT 0x40 +#define HFCPCI_ANYINT 0x80 + +/* bits in CTMT (Write) */ +#define HFCPCI_CLTIMER 0x80 +#define HFCPCI_TIM3_125 0x04 +#define HFCPCI_TIM25 0x10 +#define HFCPCI_TIM50 0x14 +#define HFCPCI_TIM400 0x18 +#define HFCPCI_TIM800 0x1C +#define HFCPCI_AUTO_TIMER 0x20 +#define HFCPCI_TRANSB2 0x02 +#define HFCPCI_TRANSB1 0x01 + +/* bits in CIRM (Write) */ +#define HFCPCI_AUX_MSK 0x07 +#define HFCPCI_RESET 0x08 +#define HFCPCI_B1_REV 0x40 +#define HFCPCI_B2_REV 0x80 + +/* bits in INT_M1 and INT_S1 */ +#define HFCPCI_INTS_B1TRANS 0x01 +#define HFCPCI_INTS_B2TRANS 0x02 +#define HFCPCI_INTS_DTRANS 0x04 +#define HFCPCI_INTS_B1REC 0x08 +#define HFCPCI_INTS_B2REC 0x10 +#define HFCPCI_INTS_DREC 0x20 +#define HFCPCI_INTS_L1STATE 0x40 +#define HFCPCI_INTS_TIMER 0x80 + +/* bits in INT_M2 */ +#define HFCPCI_PROC_TRANS 0x01 +#define HFCPCI_GCI_I_CHG 0x02 +#define HFCPCI_GCI_MON_REC 0x04 +#define HFCPCI_IRQ_ENABLE 0x08 +#define HFCPCI_PMESEL 0x80 + +/* bits in STATES */ +#define HFCPCI_STATE_MSK 0x0F +#define HFCPCI_LOAD_STATE 0x10 +#define HFCPCI_ACTIVATE 0x20 +#define HFCPCI_DO_ACTION 0x40 +#define HFCPCI_NT_G2_G3 0x80 + +/* bits in HFCD_MST_MODE */ +#define HFCPCI_MASTER 0x01 +#define HFCPCI_SLAVE 0x00 +#define HFCPCI_F0IO_POSITIV 0x02 +#define HFCPCI_F0_NEGATIV 0x04 +#define HFCPCI_F0_2C4 0x08 +/* remaining bits are for codecs control */ + +/* bits in HFCD_SCTRL */ +#define SCTRL_B1_ENA 0x01 +#define SCTRL_B2_ENA 0x02 +#define SCTRL_MODE_TE 0x00 +#define SCTRL_MODE_NT 0x04 +#define SCTRL_LOW_PRIO 0x08 +#define SCTRL_SQ_ENA 0x10 +#define SCTRL_TEST 0x20 +#define SCTRL_NONE_CAP 0x40 +#define SCTRL_PWR_DOWN 0x80 + +/* bits in SCTRL_E */ +#define HFCPCI_AUTO_AWAKE 0x01 +#define HFCPCI_DBIT_1 0x04 +#define HFCPCI_IGNORE_COL 0x08 +#define HFCPCI_CHG_B1_B2 0x80 + +/* bits in FIFO_EN register */ +#define HFCPCI_FIFOEN_B1 0x03 +#define HFCPCI_FIFOEN_B2 0x0C +#define HFCPCI_FIFOEN_DTX 0x10 +#define HFCPCI_FIFOEN_B1TX 0x01 +#define HFCPCI_FIFOEN_B1RX 0x02 +#define HFCPCI_FIFOEN_B2TX 0x04 +#define HFCPCI_FIFOEN_B2RX 0x08 + + +/* definitions of fifo memory area */ +#define MAX_D_FRAMES 15 +#define MAX_B_FRAMES 31 +#define B_SUB_VAL 0x200 +#define B_FIFO_SIZE (0x2000 - B_SUB_VAL) +#define D_FIFO_SIZE 512 +#define D_FREG_MASK 0xF + +struct zt { + __le16 z1; /* Z1 pointer 16 Bit */ + __le16 z2; /* Z2 pointer 16 Bit */ +}; + +struct dfifo { + u_char data[D_FIFO_SIZE]; /* FIFO data space */ + u_char fill1[0x20A0 - D_FIFO_SIZE]; /* reserved, do not use */ + u_char f1, f2; /* f pointers */ + u_char fill2[0x20C0 - 0x20A2]; /* reserved, do not use */ + /* mask index with D_FREG_MASK for access */ + struct zt za[MAX_D_FRAMES + 1]; + u_char fill3[0x4000 - 0x2100]; /* align 16K */ +}; + +struct bzfifo { + struct zt za[MAX_B_FRAMES + 1]; /* only range 0x0..0x1F allowed */ + u_char f1, f2; /* f pointers */ + u_char fill[0x2100 - 0x2082]; /* alignment */ +}; + + +union fifo_area { + struct { + struct dfifo d_tx; /* D-send channel */ + struct dfifo d_rx; /* D-receive channel */ + } d_chan; + struct { + u_char fill1[0x200]; + u_char txdat_b1[B_FIFO_SIZE]; + struct bzfifo txbz_b1; + struct bzfifo txbz_b2; + u_char txdat_b2[B_FIFO_SIZE]; + u_char fill2[D_FIFO_SIZE]; + u_char rxdat_b1[B_FIFO_SIZE]; + struct bzfifo rxbz_b1; + struct bzfifo rxbz_b2; + u_char rxdat_b2[B_FIFO_SIZE]; + } b_chans; + u_char fill[32768]; +}; + +#define Write_hfc(a, b, c) (writeb(c, (a->hw.pci_io) + b)) +#define Read_hfc(a, b) (readb((a->hw.pci_io) + b)) diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c new file mode 100644 index 00000000000..28543d79518 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -0,0 +1,5585 @@ +/* + * hfcmulti.c low level driver for hfc-4s/hfc-8s/hfc-e1 based cards + * + * Author Andreas Eversberg (jolly@eversberg.eu) + * ported to mqueue mechanism: + * Peter Sprenger (sprengermoving-bytes.de) + * + * inspired by existing hfc-pci driver: + * Copyright 1999 by Werner Cornelius (werner@isdn-development.de) + * Copyright 2008 by Karsten Keil (kkeil@suse.de) + * Copyright 2008 by Andreas Eversberg (jolly@eversberg.eu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * Thanks to Cologne Chip AG for this great controller! + */ + +/* + * module parameters: + * type: + * By default (0), the card is automatically detected. + * Or use the following combinations: + * Bit 0-7 = 0x00001 = HFC-E1 (1 port) + * or Bit 0-7 = 0x00004 = HFC-4S (4 ports) + * or Bit 0-7 = 0x00008 = HFC-8S (8 ports) + * Bit 8 = 0x00100 = uLaw (instead of aLaw) + * Bit 9 = 0x00200 = Disable DTMF detect on all B-channels via hardware + * Bit 10 = spare + * Bit 11 = 0x00800 = Force PCM bus into slave mode. (otherwhise auto) + * or Bit 12 = 0x01000 = Force PCM bus into master mode. (otherwhise auto) + * Bit 13 = spare + * Bit 14 = 0x04000 = Use external ram (128K) + * Bit 15 = 0x08000 = Use external ram (512K) + * Bit 16 = 0x10000 = Use 64 timeslots instead of 32 + * or Bit 17 = 0x20000 = Use 128 timeslots instead of anything else + * Bit 18 = spare + * Bit 19 = 0x80000 = Send the Watchdog a Signal (Dual E1 with Watchdog) + * (all other bits are reserved and shall be 0) + * example: 0x20204 one HFC-4S with dtmf detection and 128 timeslots on PCM + * bus (PCM master) + * + * port: (optional or required for all ports on all installed cards) + * HFC-4S/HFC-8S only bits: + * Bit 0 = 0x001 = Use master clock for this S/T interface + * (ony once per chip). + * Bit 1 = 0x002 = transmitter line setup (non capacitive mode) + * Don't use this unless you know what you are doing! + * Bit 2 = 0x004 = Disable E-channel. (No E-channel processing) + * example: 0x0001,0x0000,0x0000,0x0000 one HFC-4S with master clock + * received from port 1 + * + * HFC-E1 only bits: + * Bit 0 = 0x0001 = interface: 0=copper, 1=optical + * Bit 1 = 0x0002 = reserved (later for 32 B-channels transparent mode) + * Bit 2 = 0x0004 = Report LOS + * Bit 3 = 0x0008 = Report AIS + * Bit 4 = 0x0010 = Report SLIP + * Bit 5 = 0x0020 = Report RDI + * Bit 8 = 0x0100 = Turn off CRC-4 Multiframe Mode, use double frame + * mode instead. + * Bit 9 = 0x0200 = Force get clock from interface, even in NT mode. + * or Bit 10 = 0x0400 = Force put clock to interface, even in TE mode. + * Bit 11 = 0x0800 = Use direct RX clock for PCM sync rather than PLL. + * (E1 only) + * Bit 12-13 = 0xX000 = elastic jitter buffer (1-3), Set both bits to 0 + * for default. + * (all other bits are reserved and shall be 0) + * + * debug: + * NOTE: only one debug value must be given for all cards + * enable debugging (see hfc_multi.h for debug options) + * + * poll: + * NOTE: only one poll value must be given for all cards + * Give the number of samples for each fifo process. + * By default 128 is used. Decrease to reduce delay, increase to + * reduce cpu load. If unsure, don't mess with it! + * Valid is 8, 16, 32, 64, 128, 256. + * + * pcm: + * NOTE: only one pcm value must be given for every card. + * The PCM bus id tells the mISDNdsp module about the connected PCM bus. + * By default (0), the PCM bus id is 100 for the card that is PCM master. + * If multiple cards are PCM master (because they are not interconnected), + * each card with PCM master will have increasing PCM id. + * All PCM busses with the same ID are expected to be connected and have + * common time slots slots. + * Only one chip of the PCM bus must be master, the others slave. + * -1 means no support of PCM bus not even. + * Omit this value, if all cards are interconnected or none is connected. + * If unsure, don't give this parameter. + * + * dmask and bmask: + * NOTE: One dmask value must be given for every HFC-E1 card. + * If omitted, the E1 card has D-channel on time slot 16, which is default. + * dmask is a 32 bit mask. The bit must be set for an alternate time slot. + * If multiple bits are set, multiple virtual card fragments are created. + * For each bit set, a bmask value must be given. Each bit on the bmask + * value stands for a B-channel. The bmask may not overlap with dmask or + * with other bmask values for that card. + * Example: dmask=0x00020002 bmask=0x0000fffc,0xfffc0000 + * This will create one fragment with D-channel on slot 1 with + * B-channels on slots 2..15, and a second fragment with D-channel + * on slot 17 with B-channels on slot 18..31. Slot 16 is unused. + * If bit 0 is set (dmask=0x00000001) the D-channel is on slot 0 and will + * not function. + * Example: dmask=0x00000001 bmask=0xfffffffe + * This will create a port with all 31 usable timeslots as + * B-channels. + * If no bits are set on bmask, no B-channel is created for that fragment. + * Example: dmask=0xfffffffe bmask=0,0,0,0.... (31 0-values for bmask) + * This will create 31 ports with one D-channel only. + * If you don't know how to use it, you don't need it! + * + * iomode: + * NOTE: only one mode value must be given for every card. + * -> See hfc_multi.h for HFC_IO_MODE_* values + * By default, the IO mode is pci memory IO (MEMIO). + * Some cards require specific IO mode, so it cannot be changed. + * It may be useful to set IO mode to register io (REGIO) to solve + * PCI bridge problems. + * If unsure, don't give this parameter. + * + * clockdelay_nt: + * NOTE: only one clockdelay_nt value must be given once for all cards. + * Give the value of the clock control register (A_ST_CLK_DLY) + * of the S/T interfaces in NT mode. + * This register is needed for the TBR3 certification, so don't change it. + * + * clockdelay_te: + * NOTE: only one clockdelay_te value must be given once + * Give the value of the clock control register (A_ST_CLK_DLY) + * of the S/T interfaces in TE mode. + * This register is needed for the TBR3 certification, so don't change it. + * + * clock: + * NOTE: only one clock value must be given once + * Selects interface with clock source for mISDN and applications. + * Set to card number starting with 1. Set to -1 to disable. + * By default, the first card is used as clock source. + * + * hwid: + * NOTE: only one hwid value must be given once + * Enable special embedded devices with XHFC controllers. + */ + +/* + * debug register access (never use this, it will flood your system log) + * #define HFC_REGISTER_DEBUG + */ + +#define HFC_MULTI_VERSION "2.03" + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/mISDNhw.h> +#include <linux/mISDNdsp.h> + +/* + #define IRQCOUNT_DEBUG + #define IRQ_DEBUG +*/ + +#include "hfc_multi.h" +#ifdef ECHOPREP +#include "gaintab.h" +#endif + +#define MAX_CARDS 8 +#define MAX_PORTS (8 * MAX_CARDS) +#define MAX_FRAGS (32 * MAX_CARDS) + +static LIST_HEAD(HFClist); +static spinlock_t HFClock; /* global hfc list lock */ + +static void ph_state_change(struct dchannel *); + +static struct hfc_multi *syncmaster; +static int plxsd_master; /* if we have a master card (yet) */ +static spinlock_t plx_lock; /* may not acquire other lock inside */ + +#define TYP_E1 1 +#define TYP_4S 4 +#define TYP_8S 8 + +static int poll_timer = 6; /* default = 128 samples = 16ms */ +/* number of POLL_TIMER interrupts for G2 timeout (ca 1s) */ +static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 }; +#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */ +#define CLKDEL_NT 0x6c /* CLKDEL in NT mode + (0x60 MUST be included!) */ + +#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */ +#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */ +#define DIP_E1 0x3 /* DIP Switches for Beronet E1 cards */ + +/* + * module stuff + */ + +static uint type[MAX_CARDS]; +static int pcm[MAX_CARDS]; +static uint dmask[MAX_CARDS]; +static uint bmask[MAX_FRAGS]; +static uint iomode[MAX_CARDS]; +static uint port[MAX_PORTS]; +static uint debug; +static uint poll; +static int clock; +static uint timer; +static uint clockdelay_te = CLKDEL_TE; +static uint clockdelay_nt = CLKDEL_NT; +#define HWID_NONE 0 +#define HWID_MINIP4 1 +#define HWID_MINIP8 2 +#define HWID_MINIP16 3 +static uint hwid = HWID_NONE; + +static int HFC_cnt, E1_cnt, bmask_cnt, Port_cnt, PCM_cnt = 99; + +MODULE_AUTHOR("Andreas Eversberg"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(HFC_MULTI_VERSION); +module_param(debug, uint, S_IRUGO | S_IWUSR); +module_param(poll, uint, S_IRUGO | S_IWUSR); +module_param(clock, int, S_IRUGO | S_IWUSR); +module_param(timer, uint, S_IRUGO | S_IWUSR); +module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR); +module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR); +module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR); +module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR); +module_param_array(dmask, uint, NULL, S_IRUGO | S_IWUSR); +module_param_array(bmask, uint, NULL, S_IRUGO | S_IWUSR); +module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); +module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); +module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */ + +#ifdef HFC_REGISTER_DEBUG +#define HFC_outb(hc, reg, val) \ + (hc->HFC_outb(hc, reg, val, __func__, __LINE__)) +#define HFC_outb_nodebug(hc, reg, val) \ + (hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__)) +#define HFC_inb(hc, reg) \ + (hc->HFC_inb(hc, reg, __func__, __LINE__)) +#define HFC_inb_nodebug(hc, reg) \ + (hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__)) +#define HFC_inw(hc, reg) \ + (hc->HFC_inw(hc, reg, __func__, __LINE__)) +#define HFC_inw_nodebug(hc, reg) \ + (hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__)) +#define HFC_wait(hc) \ + (hc->HFC_wait(hc, __func__, __LINE__)) +#define HFC_wait_nodebug(hc) \ + (hc->HFC_wait_nodebug(hc, __func__, __LINE__)) +#else +#define HFC_outb(hc, reg, val) (hc->HFC_outb(hc, reg, val)) +#define HFC_outb_nodebug(hc, reg, val) (hc->HFC_outb_nodebug(hc, reg, val)) +#define HFC_inb(hc, reg) (hc->HFC_inb(hc, reg)) +#define HFC_inb_nodebug(hc, reg) (hc->HFC_inb_nodebug(hc, reg)) +#define HFC_inw(hc, reg) (hc->HFC_inw(hc, reg)) +#define HFC_inw_nodebug(hc, reg) (hc->HFC_inw_nodebug(hc, reg)) +#define HFC_wait(hc) (hc->HFC_wait(hc)) +#define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc)) +#endif + +#ifdef CONFIG_MISDN_HFCMULTI_8xx +#include "hfc_multi_8xx.h" +#endif + +/* HFC_IO_MODE_PCIMEM */ +static void +#ifdef HFC_REGISTER_DEBUG +HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val, + const char *function, int line) +#else + HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val) +#endif +{ + writeb(val, hc->pci_membase + reg); +} +static u_char +#ifdef HFC_REGISTER_DEBUG +HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line) +#else + HFC_inb_pcimem(struct hfc_multi *hc, u_char reg) +#endif +{ + return readb(hc->pci_membase + reg); +} +static u_short +#ifdef HFC_REGISTER_DEBUG +HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line) +#else + HFC_inw_pcimem(struct hfc_multi *hc, u_char reg) +#endif +{ + return readw(hc->pci_membase + reg); +} +static void +#ifdef HFC_REGISTER_DEBUG +HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line) +#else + HFC_wait_pcimem(struct hfc_multi *hc) +#endif +{ + while (readb(hc->pci_membase + R_STATUS) & V_BUSY) + cpu_relax(); +} + +/* HFC_IO_MODE_REGIO */ +static void +#ifdef HFC_REGISTER_DEBUG +HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val, + const char *function, int line) +#else + HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val) +#endif +{ + outb(reg, hc->pci_iobase + 4); + outb(val, hc->pci_iobase); +} +static u_char +#ifdef HFC_REGISTER_DEBUG +HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line) +#else + HFC_inb_regio(struct hfc_multi *hc, u_char reg) +#endif +{ + outb(reg, hc->pci_iobase + 4); + return inb(hc->pci_iobase); +} +static u_short +#ifdef HFC_REGISTER_DEBUG +HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line) +#else + HFC_inw_regio(struct hfc_multi *hc, u_char reg) +#endif +{ + outb(reg, hc->pci_iobase + 4); + return inw(hc->pci_iobase); +} +static void +#ifdef HFC_REGISTER_DEBUG +HFC_wait_regio(struct hfc_multi *hc, const char *function, int line) +#else + HFC_wait_regio(struct hfc_multi *hc) +#endif +{ + outb(R_STATUS, hc->pci_iobase + 4); + while (inb(hc->pci_iobase) & V_BUSY) + cpu_relax(); +} + +#ifdef HFC_REGISTER_DEBUG +static void +HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val, + const char *function, int line) +{ + char regname[256] = "", bits[9] = "xxxxxxxx"; + int i; + + i = -1; + while (hfc_register_names[++i].name) { + if (hfc_register_names[i].reg == reg) + strcat(regname, hfc_register_names[i].name); + } + if (regname[0] == '\0') + strcpy(regname, "register"); + + bits[7] = '0' + (!!(val & 1)); + bits[6] = '0' + (!!(val & 2)); + bits[5] = '0' + (!!(val & 4)); + bits[4] = '0' + (!!(val & 8)); + bits[3] = '0' + (!!(val & 16)); + bits[2] = '0' + (!!(val & 32)); + bits[1] = '0' + (!!(val & 64)); + bits[0] = '0' + (!!(val & 128)); + printk(KERN_DEBUG + "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n", + hc->id, reg, regname, val, bits, function, line); + HFC_outb_nodebug(hc, reg, val); +} +static u_char +HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line) +{ + char regname[256] = "", bits[9] = "xxxxxxxx"; + u_char val = HFC_inb_nodebug(hc, reg); + int i; + + i = 0; + while (hfc_register_names[i++].name) + ; + while (hfc_register_names[++i].name) { + if (hfc_register_names[i].reg == reg) + strcat(regname, hfc_register_names[i].name); + } + if (regname[0] == '\0') + strcpy(regname, "register"); + + bits[7] = '0' + (!!(val & 1)); + bits[6] = '0' + (!!(val & 2)); + bits[5] = '0' + (!!(val & 4)); + bits[4] = '0' + (!!(val & 8)); + bits[3] = '0' + (!!(val & 16)); + bits[2] = '0' + (!!(val & 32)); + bits[1] = '0' + (!!(val & 64)); + bits[0] = '0' + (!!(val & 128)); + printk(KERN_DEBUG + "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n", + hc->id, reg, regname, val, bits, function, line); + return val; +} +static u_short +HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line) +{ + char regname[256] = ""; + u_short val = HFC_inw_nodebug(hc, reg); + int i; + + i = 0; + while (hfc_register_names[i++].name) + ; + while (hfc_register_names[++i].name) { + if (hfc_register_names[i].reg == reg) + strcat(regname, hfc_register_names[i].name); + } + if (regname[0] == '\0') + strcpy(regname, "register"); + + printk(KERN_DEBUG + "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n", + hc->id, reg, regname, val, function, line); + return val; +} +static void +HFC_wait_debug(struct hfc_multi *hc, const char *function, int line) +{ + printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n", + hc->id, function, line); + HFC_wait_nodebug(hc); +} +#endif + +/* write fifo data (REGIO) */ +static void +write_fifo_regio(struct hfc_multi *hc, u_char *data, int len) +{ + outb(A_FIFO_DATA0, (hc->pci_iobase) + 4); + while (len >> 2) { + outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase); + data += 4; + len -= 4; + } + while (len >> 1) { + outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase); + data += 2; + len -= 2; + } + while (len) { + outb(*data, hc->pci_iobase); + data++; + len--; + } +} +/* write fifo data (PCIMEM) */ +static void +write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) +{ + while (len >> 2) { + writel(cpu_to_le32(*(u32 *)data), + hc->pci_membase + A_FIFO_DATA0); + data += 4; + len -= 4; + } + while (len >> 1) { + writew(cpu_to_le16(*(u16 *)data), + hc->pci_membase + A_FIFO_DATA0); + data += 2; + len -= 2; + } + while (len) { + writeb(*data, hc->pci_membase + A_FIFO_DATA0); + data++; + len--; + } +} + +/* read fifo data (REGIO) */ +static void +read_fifo_regio(struct hfc_multi *hc, u_char *data, int len) +{ + outb(A_FIFO_DATA0, (hc->pci_iobase) + 4); + while (len >> 2) { + *(u32 *)data = le32_to_cpu(inl(hc->pci_iobase)); + data += 4; + len -= 4; + } + while (len >> 1) { + *(u16 *)data = le16_to_cpu(inw(hc->pci_iobase)); + data += 2; + len -= 2; + } + while (len) { + *data = inb(hc->pci_iobase); + data++; + len--; + } +} + +/* read fifo data (PCIMEM) */ +static void +read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) +{ + while (len >> 2) { + *(u32 *)data = + le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0)); + data += 4; + len -= 4; + } + while (len >> 1) { + *(u16 *)data = + le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0)); + data += 2; + len -= 2; + } + while (len) { + *data = readb(hc->pci_membase + A_FIFO_DATA0); + data++; + len--; + } +} + +static void +enable_hwirq(struct hfc_multi *hc) +{ + hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN; + HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl); +} + +static void +disable_hwirq(struct hfc_multi *hc) +{ + hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN); + HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl); +} + +#define NUM_EC 2 +#define MAX_TDM_CHAN 32 + + +inline void +enablepcibridge(struct hfc_multi *c) +{ + HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); /* was _io before */ +} + +inline void +disablepcibridge(struct hfc_multi *c) +{ + HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x2); /* was _io before */ +} + +inline unsigned char +readpcibridge(struct hfc_multi *hc, unsigned char address) +{ + unsigned short cipv; + unsigned char data; + + if (!hc->pci_iobase) + return 0; + + /* slow down a PCI read access by 1 PCI clock cycle */ + HFC_outb(hc, R_CTRL, 0x4); /*was _io before*/ + + if (address == 0) + cipv = 0x4000; + else + cipv = 0x5800; + + /* select local bridge port address by writing to CIP port */ + /* data = HFC_inb(c, cipv); * was _io before */ + outw(cipv, hc->pci_iobase + 4); + data = inb(hc->pci_iobase); + + /* restore R_CTRL for normal PCI read cycle speed */ + HFC_outb(hc, R_CTRL, 0x0); /* was _io before */ + + return data; +} + +inline void +writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data) +{ + unsigned short cipv; + unsigned int datav; + + if (!hc->pci_iobase) + return; + + if (address == 0) + cipv = 0x4000; + else + cipv = 0x5800; + + /* select local bridge port address by writing to CIP port */ + outw(cipv, hc->pci_iobase + 4); + /* define a 32 bit dword with 4 identical bytes for write sequence */ + datav = data | ((__u32) data << 8) | ((__u32) data << 16) | + ((__u32) data << 24); + + /* + * write this 32 bit dword to the bridge data port + * this will initiate a write sequence of up to 4 writes to the same + * address on the local bus interface the number of write accesses + * is undefined but >=1 and depends on the next PCI transaction + * during write sequence on the local bus + */ + outl(datav, hc->pci_iobase); +} + +inline void +cpld_set_reg(struct hfc_multi *hc, unsigned char reg) +{ + /* Do data pin read low byte */ + HFC_outb(hc, R_GPIO_OUT1, reg); +} + +inline void +cpld_write_reg(struct hfc_multi *hc, unsigned char reg, unsigned char val) +{ + cpld_set_reg(hc, reg); + + enablepcibridge(hc); + writepcibridge(hc, 1, val); + disablepcibridge(hc); + + return; +} + +inline unsigned char +cpld_read_reg(struct hfc_multi *hc, unsigned char reg) +{ + unsigned char bytein; + + cpld_set_reg(hc, reg); + + /* Do data pin read low byte */ + HFC_outb(hc, R_GPIO_OUT1, reg); + + enablepcibridge(hc); + bytein = readpcibridge(hc, 1); + disablepcibridge(hc); + + return bytein; +} + +inline void +vpm_write_address(struct hfc_multi *hc, unsigned short addr) +{ + cpld_write_reg(hc, 0, 0xff & addr); + cpld_write_reg(hc, 1, 0x01 & (addr >> 8)); +} + +inline unsigned short +vpm_read_address(struct hfc_multi *c) +{ + unsigned short addr; + unsigned short highbit; + + addr = cpld_read_reg(c, 0); + highbit = cpld_read_reg(c, 1); + + addr = addr | (highbit << 8); + + return addr & 0x1ff; +} + +inline unsigned char +vpm_in(struct hfc_multi *c, int which, unsigned short addr) +{ + unsigned char res; + + vpm_write_address(c, addr); + + if (!which) + cpld_set_reg(c, 2); + else + cpld_set_reg(c, 3); + + enablepcibridge(c); + res = readpcibridge(c, 1); + disablepcibridge(c); + + cpld_set_reg(c, 0); + + return res; +} + +inline void +vpm_out(struct hfc_multi *c, int which, unsigned short addr, + unsigned char data) +{ + vpm_write_address(c, addr); + + enablepcibridge(c); + + if (!which) + cpld_set_reg(c, 2); + else + cpld_set_reg(c, 3); + + writepcibridge(c, 1, data); + + cpld_set_reg(c, 0); + + disablepcibridge(c); + + { + unsigned char regin; + regin = vpm_in(c, which, addr); + if (regin != data) + printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back " + "0x%x\n", data, addr, regin); + } + +} + + +static void +vpm_init(struct hfc_multi *wc) +{ + unsigned char reg; + unsigned int mask; + unsigned int i, x, y; + unsigned int ver; + + for (x = 0; x < NUM_EC; x++) { + /* Setup GPIO's */ + if (!x) { + ver = vpm_in(wc, x, 0x1a0); + printk(KERN_DEBUG "VPM: Chip %d: ver %02x\n", x, ver); + } + + for (y = 0; y < 4; y++) { + vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */ + vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */ + vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */ + } + + /* Setup TDM path - sets fsync and tdm_clk as inputs */ + reg = vpm_in(wc, x, 0x1a3); /* misc_con */ + vpm_out(wc, x, 0x1a3, reg & ~2); + + /* Setup Echo length (256 taps) */ + vpm_out(wc, x, 0x022, 1); + vpm_out(wc, x, 0x023, 0xff); + + /* Setup timeslots */ + vpm_out(wc, x, 0x02f, 0x00); + mask = 0x02020202 << (x * 4); + + /* Setup the tdm channel masks for all chips */ + for (i = 0; i < 4; i++) + vpm_out(wc, x, 0x33 - i, (mask >> (i << 3)) & 0xff); + + /* Setup convergence rate */ + printk(KERN_DEBUG "VPM: A-law mode\n"); + reg = 0x00 | 0x10 | 0x01; + vpm_out(wc, x, 0x20, reg); + printk(KERN_DEBUG "VPM reg 0x20 is %x\n", reg); + /*vpm_out(wc, x, 0x20, (0x00 | 0x08 | 0x20 | 0x10)); */ + + vpm_out(wc, x, 0x24, 0x02); + reg = vpm_in(wc, x, 0x24); + printk(KERN_DEBUG "NLP Thresh is set to %d (0x%x)\n", reg, reg); + + /* Initialize echo cans */ + for (i = 0; i < MAX_TDM_CHAN; i++) { + if (mask & (0x00000001 << i)) + vpm_out(wc, x, i, 0x00); + } + + /* + * ARM arch at least disallows a udelay of + * more than 2ms... it gives a fake "__bad_udelay" + * reference at link-time. + * long delays in kernel code are pretty sucky anyway + * for now work around it using 5 x 2ms instead of 1 x 10ms + */ + + udelay(2000); + udelay(2000); + udelay(2000); + udelay(2000); + udelay(2000); + + /* Put in bypass mode */ + for (i = 0; i < MAX_TDM_CHAN; i++) { + if (mask & (0x00000001 << i)) + vpm_out(wc, x, i, 0x01); + } + + /* Enable bypass */ + for (i = 0; i < MAX_TDM_CHAN; i++) { + if (mask & (0x00000001 << i)) + vpm_out(wc, x, 0x78 + i, 0x01); + } + + } +} + +#ifdef UNUSED +static void +vpm_check(struct hfc_multi *hctmp) +{ + unsigned char gpi2; + + gpi2 = HFC_inb(hctmp, R_GPI_IN2); + + if ((gpi2 & 0x3) != 0x3) + printk(KERN_DEBUG "Got interrupt 0x%x from VPM!\n", gpi2); +} +#endif /* UNUSED */ + + +/* + * Interface to enable/disable the HW Echocan + * + * these functions are called within a spin_lock_irqsave on + * the channel instance lock, so we are not disturbed by irqs + * + * we can later easily change the interface to make other + * things configurable, for now we configure the taps + * + */ + +static void +vpm_echocan_on(struct hfc_multi *hc, int ch, int taps) +{ + unsigned int timeslot; + unsigned int unit; + struct bchannel *bch = hc->chan[ch].bch; +#ifdef TXADJ + int txadj = -4; + struct sk_buff *skb; +#endif + if (hc->chan[ch].protocol != ISDN_P_B_RAW) + return; + + if (!bch) + return; + +#ifdef TXADJ + skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX, + sizeof(int), &txadj, GFP_ATOMIC); + if (skb) + recv_Bchannel_skb(bch, skb); +#endif + + timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1; + unit = ch % 4; + + printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n", + taps, timeslot); + + vpm_out(hc, unit, timeslot, 0x7e); +} + +static void +vpm_echocan_off(struct hfc_multi *hc, int ch) +{ + unsigned int timeslot; + unsigned int unit; + struct bchannel *bch = hc->chan[ch].bch; +#ifdef TXADJ + int txadj = 0; + struct sk_buff *skb; +#endif + + if (hc->chan[ch].protocol != ISDN_P_B_RAW) + return; + + if (!bch) + return; + +#ifdef TXADJ + skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX, + sizeof(int), &txadj, GFP_ATOMIC); + if (skb) + recv_Bchannel_skb(bch, skb); +#endif + + timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1; + unit = ch % 4; + + printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n", + timeslot); + /* FILLME */ + vpm_out(hc, unit, timeslot, 0x01); +} + + +/* + * Speech Design resync feature + * NOTE: This is called sometimes outside interrupt handler. + * We must lock irqsave, so no other interrupt (other card) will occur! + * Also multiple interrupts may nest, so must lock each access (lists, card)! + */ +static inline void +hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) +{ + struct hfc_multi *hc, *next, *pcmmaster = NULL; + void __iomem *plx_acc_32; + u_int pv; + u_long flags; + + spin_lock_irqsave(&HFClock, flags); + spin_lock(&plx_lock); /* must be locked inside other locks */ + + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n", + __func__, syncmaster); + + /* select new master */ + if (newmaster) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "using provided controller\n"); + } else { + list_for_each_entry_safe(hc, next, &HFClist, list) { + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + if (hc->syncronized) { + newmaster = hc; + break; + } + } + } + } + + /* Disable sync of all cards */ + list_for_each_entry_safe(hc, next, &HFClist, list) { + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + pv = readl(plx_acc_32); + pv &= ~PLX_SYNC_O_EN; + writel(pv, plx_acc_32); + if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { + pcmmaster = hc; + if (hc->ctype == HFC_TYPE_E1) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG + "Schedule SYNC_I\n"); + hc->e1_resync |= 1; /* get SYNC_I */ + } + } + } + } + + if (newmaster) { + hc = newmaster; + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "id=%d (0x%p) = syncronized with " + "interface.\n", hc->id, hc); + /* Enable new sync master */ + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + pv = readl(plx_acc_32); + pv |= PLX_SYNC_O_EN; + writel(pv, plx_acc_32); + /* switch to jatt PLL, if not disabled by RX_SYNC */ + if (hc->ctype == HFC_TYPE_E1 + && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "Schedule jatt PLL\n"); + hc->e1_resync |= 2; /* switch to jatt */ + } + } else { + if (pcmmaster) { + hc = pcmmaster; + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG + "id=%d (0x%p) = PCM master syncronized " + "with QUARTZ\n", hc->id, hc); + if (hc->ctype == HFC_TYPE_E1) { + /* Use the crystal clock for the PCM + master card */ + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG + "Schedule QUARTZ for HFC-E1\n"); + hc->e1_resync |= 4; /* switch quartz */ + } else { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG + "QUARTZ is automatically " + "enabled by HFC-%dS\n", hc->ctype); + } + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + pv = readl(plx_acc_32); + pv |= PLX_SYNC_O_EN; + writel(pv, plx_acc_32); + } else + if (!rm) + printk(KERN_ERR "%s no pcm master, this MUST " + "not happen!\n", __func__); + } + syncmaster = newmaster; + + spin_unlock(&plx_lock); + spin_unlock_irqrestore(&HFClock, flags); +} + +/* This must be called AND hc must be locked irqsave!!! */ +inline void +plxsd_checksync(struct hfc_multi *hc, int rm) +{ + if (hc->syncronized) { + if (syncmaster == NULL) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "%s: GOT sync on card %d" + " (id=%d)\n", __func__, hc->id + 1, + hc->id); + hfcmulti_resync(hc, hc, rm); + } + } else { + if (syncmaster == hc) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "%s: LOST sync on card %d" + " (id=%d)\n", __func__, hc->id + 1, + hc->id); + hfcmulti_resync(hc, NULL, rm); + } + } +} + + +/* + * free hardware resources used by driver + */ +static void +release_io_hfcmulti(struct hfc_multi *hc) +{ + void __iomem *plx_acc_32; + u_int pv; + u_long plx_flags; + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: entered\n", __func__); + + /* soft reset also masks all interrupts */ + hc->hw.r_cirm |= V_SRES; + HFC_outb(hc, R_CIRM, hc->hw.r_cirm); + udelay(1000); + hc->hw.r_cirm &= ~V_SRES; + HFC_outb(hc, R_CIRM, hc->hw.r_cirm); + udelay(1000); /* instead of 'wait' that may cause locking */ + + /* release Speech Design card, if PLX was initialized */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "%s: release PLXSD card %d\n", + __func__, hc->id + 1); + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + writel(PLX_GPIOC_INIT, plx_acc_32); + pv = readl(plx_acc_32); + /* Termination off */ + pv &= ~PLX_TERM_ON; + /* Disconnect the PCM */ + pv |= PLX_SLAVE_EN_N; + pv &= ~PLX_MASTER_EN; + pv &= ~PLX_SYNC_O_EN; + /* Put the DSP in Reset */ + pv &= ~PLX_DSP_RES_N; + writel(pv, plx_acc_32); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n", + __func__, pv); + spin_unlock_irqrestore(&plx_lock, plx_flags); + } + + /* disable memory mapped ports / io ports */ + test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */ + if (hc->pci_dev) + pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0); + if (hc->pci_membase) + iounmap(hc->pci_membase); + if (hc->plx_membase) + iounmap(hc->plx_membase); + if (hc->pci_iobase) + release_region(hc->pci_iobase, 8); + if (hc->xhfc_membase) + iounmap((void *)hc->xhfc_membase); + + if (hc->pci_dev) { + pci_disable_device(hc->pci_dev); + pci_set_drvdata(hc->pci_dev, NULL); + } + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: done\n", __func__); +} + +/* + * function called to reset the HFC chip. A complete software reset of chip + * and fifos is done. All configuration of the chip is done. + */ + +static int +init_chip(struct hfc_multi *hc) +{ + u_long flags, val, val2 = 0, rev; + int i, err = 0; + u_char r_conf_en, rval; + void __iomem *plx_acc_32; + u_int pv; + u_long plx_flags, hfc_flags; + int plx_count; + struct hfc_multi *pos, *next, *plx_last_hc; + + spin_lock_irqsave(&hc->lock, flags); + /* reset all registers */ + memset(&hc->hw, 0, sizeof(struct hfcm_hw)); + + /* revision check */ + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: entered\n", __func__); + val = HFC_inb(hc, R_CHIP_ID); + if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe && + (val >> 1) != 0x31) { + printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val); + err = -EIO; + goto out; + } + rev = HFC_inb(hc, R_CHIP_RV); + printk(KERN_INFO + "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n", + val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ? + " (old FIFO handling)" : ""); + if (hc->ctype != HFC_TYPE_XHFC && rev == 0) { + test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip); + printk(KERN_WARNING + "HFC_multi: NOTE: Your chip is revision 0, " + "ask Cologne Chip for update. Newer chips " + "have a better FIFO handling. Old chips " + "still work but may have slightly lower " + "HDLC transmit performance.\n"); + } + if (rev > 1) { + printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't " + "consider chip revision = %ld. The chip / " + "bridge may not work.\n", rev); + } + + /* set s-ram size */ + hc->Flen = 0x10; + hc->Zmin = 0x80; + hc->Zlen = 384; + hc->DTMFbase = 0x1000; + if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: changing to 128K external RAM\n", + __func__); + hc->hw.r_ctrl |= V_EXT_RAM; + hc->hw.r_ram_sz = 1; + hc->Flen = 0x20; + hc->Zmin = 0xc0; + hc->Zlen = 1856; + hc->DTMFbase = 0x2000; + } + if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: changing to 512K external RAM\n", + __func__); + hc->hw.r_ctrl |= V_EXT_RAM; + hc->hw.r_ram_sz = 2; + hc->Flen = 0x20; + hc->Zmin = 0xc0; + hc->Zlen = 8000; + hc->DTMFbase = 0x2000; + } + if (hc->ctype == HFC_TYPE_XHFC) { + hc->Flen = 0x8; + hc->Zmin = 0x0; + hc->Zlen = 64; + hc->DTMFbase = 0x0; + } + hc->max_trans = poll << 1; + if (hc->max_trans > hc->Zlen) + hc->max_trans = hc->Zlen; + + /* Speech Design PLX bridge */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "%s: initializing PLXSD card %d\n", + __func__, hc->id + 1); + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + writel(PLX_GPIOC_INIT, plx_acc_32); + pv = readl(plx_acc_32); + /* The first and the last cards are terminating the PCM bus */ + pv |= PLX_TERM_ON; /* hc is currently the last */ + /* Disconnect the PCM */ + pv |= PLX_SLAVE_EN_N; + pv &= ~PLX_MASTER_EN; + pv &= ~PLX_SYNC_O_EN; + /* Put the DSP in Reset */ + pv &= ~PLX_DSP_RES_N; + writel(pv, plx_acc_32); + spin_unlock_irqrestore(&plx_lock, plx_flags); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n", + __func__, pv); + /* + * If we are the 3rd PLXSD card or higher, we must turn + * termination of last PLXSD card off. + */ + spin_lock_irqsave(&HFClock, hfc_flags); + plx_count = 0; + plx_last_hc = NULL; + list_for_each_entry_safe(pos, next, &HFClist, list) { + if (test_bit(HFC_CHIP_PLXSD, &pos->chip)) { + plx_count++; + if (pos != hc) + plx_last_hc = pos; + } + } + if (plx_count >= 3) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "%s: card %d is between, so " + "we disable termination\n", + __func__, plx_last_hc->id + 1); + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC; + pv = readl(plx_acc_32); + pv &= ~PLX_TERM_ON; + writel(pv, plx_acc_32); + spin_unlock_irqrestore(&plx_lock, plx_flags); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: term off: PLX_GPIO=%x\n", + __func__, pv); + } + spin_unlock_irqrestore(&HFClock, hfc_flags); + hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ + } + + if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) + hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ + + /* we only want the real Z2 read-pointer for revision > 0 */ + if (!test_bit(HFC_CHIP_REVISION0, &hc->chip)) + hc->hw.r_ram_sz |= V_FZ_MD; + + /* select pcm mode */ + if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: setting PCM into slave mode\n", + __func__); + } else + if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: setting PCM into master mode\n", + __func__); + hc->hw.r_pcm_md0 |= V_PCM_MD; + } else { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: performing PCM auto detect\n", + __func__); + } + + /* soft reset */ + HFC_outb(hc, R_CTRL, hc->hw.r_ctrl); + if (hc->ctype == HFC_TYPE_XHFC) + HFC_outb(hc, 0x0C /* R_FIFO_THRES */, + 0x11 /* 16 Bytes TX/RX */); + else + HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); + HFC_outb(hc, R_FIFO_MD, 0); + if (hc->ctype == HFC_TYPE_XHFC) + hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES; + else + hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES + | V_RLD_EPR; + HFC_outb(hc, R_CIRM, hc->hw.r_cirm); + udelay(100); + hc->hw.r_cirm = 0; + HFC_outb(hc, R_CIRM, hc->hw.r_cirm); + udelay(100); + if (hc->ctype != HFC_TYPE_XHFC) + HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); + + /* Speech Design PLX bridge pcm and sync mode */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + pv = readl(plx_acc_32); + /* Connect PCM */ + if (hc->hw.r_pcm_md0 & V_PCM_MD) { + pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; + pv |= PLX_SYNC_O_EN; + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n", + __func__, pv); + } else { + pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N); + pv &= ~PLX_SYNC_O_EN; + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n", + __func__, pv); + } + writel(pv, plx_acc_32); + spin_unlock_irqrestore(&plx_lock, plx_flags); + } + + /* PCM setup */ + HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x90); + if (hc->slots == 32) + HFC_outb(hc, R_PCM_MD1, 0x00); + if (hc->slots == 64) + HFC_outb(hc, R_PCM_MD1, 0x10); + if (hc->slots == 128) + HFC_outb(hc, R_PCM_MD1, 0x20); + HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0); + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) + HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */ + else if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) + HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */ + else + HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */ + HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); + for (i = 0; i < 256; i++) { + HFC_outb_nodebug(hc, R_SLOT, i); + HFC_outb_nodebug(hc, A_SL_CFG, 0); + if (hc->ctype != HFC_TYPE_XHFC) + HFC_outb_nodebug(hc, A_CONF, 0); + hc->slot_owner[i] = -1; + } + + /* set clock speed */ + if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: setting double clock\n", __func__); + HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); + } + + if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) + HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */); + + /* B410P GPIO */ + if (test_bit(HFC_CHIP_B410P, &hc->chip)) { + printk(KERN_NOTICE "Setting GPIOs\n"); + HFC_outb(hc, R_GPIO_SEL, 0x30); + HFC_outb(hc, R_GPIO_EN1, 0x3); + udelay(1000); + printk(KERN_NOTICE "calling vpm_init\n"); + vpm_init(hc); + } + + /* check if R_F0_CNT counts (8 kHz frame count) */ + val = HFC_inb(hc, R_F0_CNTL); + val += HFC_inb(hc, R_F0_CNTH) << 8; + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "HFC_multi F0_CNT %ld after reset\n", val); + spin_unlock_irqrestore(&hc->lock, flags); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ / 100) ? : 1); /* Timeout minimum 10ms */ + spin_lock_irqsave(&hc->lock, flags); + val2 = HFC_inb(hc, R_F0_CNTL); + val2 += HFC_inb(hc, R_F0_CNTH) << 8; + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "HFC_multi F0_CNT %ld after 10 ms (1st try)\n", + val2); + if (val2 >= val + 8) { /* 1 ms */ + /* it counts, so we keep the pcm mode */ + if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) + printk(KERN_INFO "controller is PCM bus MASTER\n"); + else + if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) + printk(KERN_INFO "controller is PCM bus SLAVE\n"); + else { + test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); + printk(KERN_INFO "controller is PCM bus SLAVE " + "(auto detected)\n"); + } + } else { + /* does not count */ + if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { + controller_fail: + printk(KERN_ERR "HFC_multi ERROR, getting no 125us " + "pulse. Seems that controller fails.\n"); + err = -EIO; + goto out; + } + if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { + printk(KERN_INFO "controller is PCM bus SLAVE " + "(ignoring missing PCM clock)\n"); + } else { + /* only one pcm master */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip) + && plxsd_master) { + printk(KERN_ERR "HFC_multi ERROR, no clock " + "on another Speech Design card found. " + "Please be sure to connect PCM cable.\n"); + err = -EIO; + goto out; + } + /* retry with master clock */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + pv = readl(plx_acc_32); + pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; + pv |= PLX_SYNC_O_EN; + writel(pv, plx_acc_32); + spin_unlock_irqrestore(&plx_lock, plx_flags); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: master: " + "PLX_GPIO=%x\n", __func__, pv); + } + hc->hw.r_pcm_md0 |= V_PCM_MD; + HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); + spin_unlock_irqrestore(&hc->lock, flags); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ / 100) ?: 1); /* Timeout min. 10ms */ + spin_lock_irqsave(&hc->lock, flags); + val2 = HFC_inb(hc, R_F0_CNTL); + val2 += HFC_inb(hc, R_F0_CNTH) << 8; + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "HFC_multi F0_CNT %ld after " + "10 ms (2nd try)\n", val2); + if (val2 >= val + 8) { /* 1 ms */ + test_and_set_bit(HFC_CHIP_PCM_MASTER, + &hc->chip); + printk(KERN_INFO "controller is PCM bus MASTER " + "(auto detected)\n"); + } else + goto controller_fail; + } + } + + /* Release the DSP Reset */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) + plxsd_master = 1; + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc_32 = hc->plx_membase + PLX_GPIOC; + pv = readl(plx_acc_32); + pv |= PLX_DSP_RES_N; + writel(pv, plx_acc_32); + spin_unlock_irqrestore(&plx_lock, plx_flags); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n", + __func__, pv); + } + + /* pcm id */ + if (hc->pcm) + printk(KERN_INFO "controller has given PCM BUS ID %d\n", + hc->pcm); + else { + if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) + || test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + PCM_cnt++; /* SD has proprietary bridging */ + } + hc->pcm = PCM_cnt; + printk(KERN_INFO "controller has PCM BUS ID %d " + "(auto selected)\n", hc->pcm); + } + + /* set up timer */ + HFC_outb(hc, R_TI_WD, poll_timer); + hc->hw.r_irqmsk_misc |= V_TI_IRQMSK; + + /* set E1 state machine IRQ */ + if (hc->ctype == HFC_TYPE_E1) + hc->hw.r_irqmsk_misc |= V_STA_IRQMSK; + + /* set DTMF detection */ + if (test_bit(HFC_CHIP_DTMF, &hc->chip)) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: enabling DTMF detection " + "for all B-channel\n", __func__); + hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP; + if (test_bit(HFC_CHIP_ULAW, &hc->chip)) + hc->hw.r_dtmf |= V_ULAW_SEL; + HFC_outb(hc, R_DTMF_N, 102 - 1); + hc->hw.r_irqmsk_misc |= V_DTMF_IRQMSK; + } + + /* conference engine */ + if (test_bit(HFC_CHIP_ULAW, &hc->chip)) + r_conf_en = V_CONF_EN | V_ULAW; + else + r_conf_en = V_CONF_EN; + if (hc->ctype != HFC_TYPE_XHFC) + HFC_outb(hc, R_CONF_EN, r_conf_en); + + /* setting leds */ + switch (hc->leds) { + case 1: /* HFC-E1 OEM */ + if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip)) + HFC_outb(hc, R_GPIO_SEL, 0x32); + else + HFC_outb(hc, R_GPIO_SEL, 0x30); + + HFC_outb(hc, R_GPIO_EN1, 0x0f); + HFC_outb(hc, R_GPIO_OUT1, 0x00); + + HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3); + break; + + case 2: /* HFC-4S OEM */ + case 3: + HFC_outb(hc, R_GPIO_SEL, 0xf0); + HFC_outb(hc, R_GPIO_EN1, 0xff); + HFC_outb(hc, R_GPIO_OUT1, 0x00); + break; + } + + if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) { + hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */ + HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); + } + + /* set master clock */ + if (hc->masterclk >= 0) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: setting ST master clock " + "to port %d (0..%d)\n", + __func__, hc->masterclk, hc->ports - 1); + hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC); + HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); + } + + + + /* setting misc irq */ + HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n", + hc->hw.r_irqmsk_misc); + + /* RAM access test */ + HFC_outb(hc, R_RAM_ADDR0, 0); + HFC_outb(hc, R_RAM_ADDR1, 0); + HFC_outb(hc, R_RAM_ADDR2, 0); + for (i = 0; i < 256; i++) { + HFC_outb_nodebug(hc, R_RAM_ADDR0, i); + HFC_outb_nodebug(hc, R_RAM_DATA, ((i * 3) & 0xff)); + } + for (i = 0; i < 256; i++) { + HFC_outb_nodebug(hc, R_RAM_ADDR0, i); + HFC_inb_nodebug(hc, R_RAM_DATA); + rval = HFC_inb_nodebug(hc, R_INT_DATA); + if (rval != ((i * 3) & 0xff)) { + printk(KERN_DEBUG + "addr:%x val:%x should:%x\n", i, rval, + (i * 3) & 0xff); + err++; + } + } + if (err) { + printk(KERN_DEBUG "aborting - %d RAM access errors\n", err); + err = -EIO; + goto out; + } + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: done\n", __func__); +out: + spin_unlock_irqrestore(&hc->lock, flags); + return err; +} + + +/* + * control the watchdog + */ +static void +hfcmulti_watchdog(struct hfc_multi *hc) +{ + hc->wdcount++; + + if (hc->wdcount > 10) { + hc->wdcount = 0; + hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ? + V_GPIO_OUT3 : V_GPIO_OUT2; + + /* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */ + HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3); + HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte); + } +} + + + +/* + * output leds + */ +static void +hfcmulti_leds(struct hfc_multi *hc) +{ + unsigned long lled; + unsigned long leddw; + int i, state, active, leds; + struct dchannel *dch; + int led[4]; + + switch (hc->leds) { + case 1: /* HFC-E1 OEM */ + /* 2 red steady: LOS + * 1 red steady: L1 not active + * 2 green steady: L1 active + * 1st green flashing: activity on TX + * 2nd green flashing: activity on RX + */ + led[0] = 0; + led[1] = 0; + led[2] = 0; + led[3] = 0; + dch = hc->chan[hc->dnum[0]].dch; + if (dch) { + if (hc->chan[hc->dnum[0]].los) + led[1] = 1; + if (hc->e1_state != 1) { + led[0] = 1; + hc->flash[2] = 0; + hc->flash[3] = 0; + } else { + led[2] = 1; + led[3] = 1; + if (!hc->flash[2] && hc->activity_tx) + hc->flash[2] = poll; + if (!hc->flash[3] && hc->activity_rx) + hc->flash[3] = poll; + if (hc->flash[2] && hc->flash[2] < 1024) + led[2] = 0; + if (hc->flash[3] && hc->flash[3] < 1024) + led[3] = 0; + if (hc->flash[2] >= 2048) + hc->flash[2] = 0; + if (hc->flash[3] >= 2048) + hc->flash[3] = 0; + if (hc->flash[2]) + hc->flash[2] += poll; + if (hc->flash[3]) + hc->flash[3] += poll; + } + } + leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF; + /* leds are inverted */ + if (leds != (int)hc->ledstate) { + HFC_outb_nodebug(hc, R_GPIO_OUT1, leds); + hc->ledstate = leds; + } + break; + + case 2: /* HFC-4S OEM */ + /* red steady: PH_DEACTIVATE + * green steady: PH_ACTIVATE + * green flashing: activity on TX + */ + for (i = 0; i < 4; i++) { + state = 0; + active = -1; + dch = hc->chan[(i << 2) | 2].dch; + if (dch) { + state = dch->state; + if (dch->dev.D.protocol == ISDN_P_NT_S0) + active = 3; + else + active = 7; + } + if (state) { + if (state == active) { + led[i] = 1; /* led green */ + hc->activity_tx |= hc->activity_rx; + if (!hc->flash[i] && + (hc->activity_tx & (1 << i))) + hc->flash[i] = poll; + if (hc->flash[i] && hc->flash[i] < 1024) + led[i] = 0; /* led off */ + if (hc->flash[i] >= 2048) + hc->flash[i] = 0; + if (hc->flash[i]) + hc->flash[i] += poll; + } else { + led[i] = 2; /* led red */ + hc->flash[i] = 0; + } + } else + led[i] = 0; /* led off */ + } + if (test_bit(HFC_CHIP_B410P, &hc->chip)) { + leds = 0; + for (i = 0; i < 4; i++) { + if (led[i] == 1) { + /*green*/ + leds |= (0x2 << (i * 2)); + } else if (led[i] == 2) { + /*red*/ + leds |= (0x1 << (i * 2)); + } + } + if (leds != (int)hc->ledstate) { + vpm_out(hc, 0, 0x1a8 + 3, leds); + hc->ledstate = leds; + } + } else { + leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) | + ((led[0] > 0) << 2) | ((led[2] > 0) << 3) | + ((led[3] & 1) << 4) | ((led[1] & 1) << 5) | + ((led[0] & 1) << 6) | ((led[2] & 1) << 7); + if (leds != (int)hc->ledstate) { + HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F); + HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4); + hc->ledstate = leds; + } + } + break; + + case 3: /* HFC 1S/2S Beronet */ + /* red steady: PH_DEACTIVATE + * green steady: PH_ACTIVATE + * green flashing: activity on TX + */ + for (i = 0; i < 2; i++) { + state = 0; + active = -1; + dch = hc->chan[(i << 2) | 2].dch; + if (dch) { + state = dch->state; + if (dch->dev.D.protocol == ISDN_P_NT_S0) + active = 3; + else + active = 7; + } + if (state) { + if (state == active) { + led[i] = 1; /* led green */ + hc->activity_tx |= hc->activity_rx; + if (!hc->flash[i] && + (hc->activity_tx & (1 << i))) + hc->flash[i] = poll; + if (hc->flash[i] < 1024) + led[i] = 0; /* led off */ + if (hc->flash[i] >= 2048) + hc->flash[i] = 0; + if (hc->flash[i]) + hc->flash[i] += poll; + } else { + led[i] = 2; /* led red */ + hc->flash[i] = 0; + } + } else + led[i] = 0; /* led off */ + } + leds = (led[0] > 0) | ((led[1] > 0) << 1) | ((led[0]&1) << 2) + | ((led[1]&1) << 3); + if (leds != (int)hc->ledstate) { + HFC_outb_nodebug(hc, R_GPIO_EN1, + ((led[0] > 0) << 2) | ((led[1] > 0) << 3)); + HFC_outb_nodebug(hc, R_GPIO_OUT1, + ((led[0] & 1) << 2) | ((led[1] & 1) << 3)); + hc->ledstate = leds; + } + break; + case 8: /* HFC 8S+ Beronet */ + /* off: PH_DEACTIVATE + * steady: PH_ACTIVATE + * flashing: activity on TX + */ + lled = 0xff; /* leds off */ + for (i = 0; i < 8; i++) { + state = 0; + active = -1; + dch = hc->chan[(i << 2) | 2].dch; + if (dch) { + state = dch->state; + if (dch->dev.D.protocol == ISDN_P_NT_S0) + active = 3; + else + active = 7; + } + if (state) { + if (state == active) { + lled &= ~(1 << i); /* led on */ + hc->activity_tx |= hc->activity_rx; + if (!hc->flash[i] && + (hc->activity_tx & (1 << i))) + hc->flash[i] = poll; + if (hc->flash[i] < 1024) + lled |= 1 << i; /* led off */ + if (hc->flash[i] >= 2048) + hc->flash[i] = 0; + if (hc->flash[i]) + hc->flash[i] += poll; + } else + hc->flash[i] = 0; + } + } + leddw = lled << 24 | lled << 16 | lled << 8 | lled; + if (leddw != hc->ledstate) { + /* HFC_outb(hc, R_BRG_PCM_CFG, 1); + HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */ + /* was _io before */ + HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK); + outw(0x4000, hc->pci_iobase + 4); + outl(leddw, hc->pci_iobase); + HFC_outb_nodebug(hc, R_BRG_PCM_CFG, V_PCM_CLK); + hc->ledstate = leddw; + } + break; + } + hc->activity_tx = 0; + hc->activity_rx = 0; +} +/* + * read dtmf coefficients + */ + +static void +hfcmulti_dtmf(struct hfc_multi *hc) +{ + s32 *coeff; + u_int mantissa; + int co, ch; + struct bchannel *bch = NULL; + u8 exponent; + int dtmf = 0; + int addr; + u16 w_float; + struct sk_buff *skb; + struct mISDNhead *hh; + + if (debug & DEBUG_HFCMULTI_DTMF) + printk(KERN_DEBUG "%s: dtmf detection irq\n", __func__); + for (ch = 0; ch <= 31; ch++) { + /* only process enabled B-channels */ + bch = hc->chan[ch].bch; + if (!bch) + continue; + if (!hc->created[hc->chan[ch].port]) + continue; + if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) + continue; + if (debug & DEBUG_HFCMULTI_DTMF) + printk(KERN_DEBUG "%s: dtmf channel %d:", + __func__, ch); + coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]); + dtmf = 1; + for (co = 0; co < 8; co++) { + /* read W(n-1) coefficient */ + addr = hc->DTMFbase + ((co << 7) | (ch << 2)); + HFC_outb_nodebug(hc, R_RAM_ADDR0, addr); + HFC_outb_nodebug(hc, R_RAM_ADDR1, addr >> 8); + HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr >> 16) + | V_ADDR_INC); + w_float = HFC_inb_nodebug(hc, R_RAM_DATA); + w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8); + if (debug & DEBUG_HFCMULTI_DTMF) + printk(" %04x", w_float); + + /* decode float (see chip doc) */ + mantissa = w_float & 0x0fff; + if (w_float & 0x8000) + mantissa |= 0xfffff000; + exponent = (w_float >> 12) & 0x7; + if (exponent) { + mantissa ^= 0x1000; + mantissa <<= (exponent - 1); + } + + /* store coefficient */ + coeff[co << 1] = mantissa; + + /* read W(n) coefficient */ + w_float = HFC_inb_nodebug(hc, R_RAM_DATA); + w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8); + if (debug & DEBUG_HFCMULTI_DTMF) + printk(" %04x", w_float); + + /* decode float (see chip doc) */ + mantissa = w_float & 0x0fff; + if (w_float & 0x8000) + mantissa |= 0xfffff000; + exponent = (w_float >> 12) & 0x7; + if (exponent) { + mantissa ^= 0x1000; + mantissa <<= (exponent - 1); + } + + /* store coefficient */ + coeff[(co << 1) | 1] = mantissa; + } + if (debug & DEBUG_HFCMULTI_DTMF) + printk(" DTMF ready %08x %08x %08x %08x " + "%08x %08x %08x %08x\n", + coeff[0], coeff[1], coeff[2], coeff[3], + coeff[4], coeff[5], coeff[6], coeff[7]); + hc->chan[ch].coeff_count++; + if (hc->chan[ch].coeff_count == 8) { + hc->chan[ch].coeff_count = 0; + skb = mI_alloc_skb(512, GFP_ATOMIC); + if (!skb) { + printk(KERN_DEBUG "%s: No memory for skb\n", + __func__); + continue; + } + hh = mISDN_HEAD_P(skb); + hh->prim = PH_CONTROL_IND; + hh->id = DTMF_HFC_COEF; + memcpy(skb_put(skb, 512), hc->chan[ch].coeff, 512); + recv_Bchannel_skb(bch, skb); + } + } + + /* restart DTMF processing */ + hc->dtmf = dtmf; + if (dtmf) + HFC_outb_nodebug(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF); +} + + +/* + * fill fifo as much as possible + */ + +static void +hfcmulti_tx(struct hfc_multi *hc, int ch) +{ + int i, ii, temp, len = 0; + int Zspace, z1, z2; /* must be int for calculation */ + int Fspace, f1, f2; + u_char *d; + int *txpending, slot_tx; + struct bchannel *bch; + struct dchannel *dch; + struct sk_buff **sp = NULL; + int *idxp; + + bch = hc->chan[ch].bch; + dch = hc->chan[ch].dch; + if ((!dch) && (!bch)) + return; + + txpending = &hc->chan[ch].txpending; + slot_tx = hc->chan[ch].slot_tx; + if (dch) { + if (!test_bit(FLG_ACTIVE, &dch->Flags)) + return; + sp = &dch->tx_skb; + idxp = &dch->tx_idx; + } else { + if (!test_bit(FLG_ACTIVE, &bch->Flags)) + return; + sp = &bch->tx_skb; + idxp = &bch->tx_idx; + } + if (*sp) + len = (*sp)->len; + + if ((!len) && *txpending != 1) + return; /* no data */ + + if (test_bit(HFC_CHIP_B410P, &hc->chip) && + (hc->chan[ch].protocol == ISDN_P_B_RAW) && + (hc->chan[ch].slot_rx < 0) && + (hc->chan[ch].slot_tx < 0)) + HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1)); + else + HFC_outb_nodebug(hc, R_FIFO, ch << 1); + HFC_wait_nodebug(hc); + + if (*txpending == 2) { + /* reset fifo */ + HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait_nodebug(hc); + HFC_outb(hc, A_SUBCH_CFG, 0); + *txpending = 1; + } +next_frame: + if (dch || test_bit(FLG_HDLC, &bch->Flags)) { + f1 = HFC_inb_nodebug(hc, A_F1); + f2 = HFC_inb_nodebug(hc, A_F2); + while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) { + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG + "%s(card %d): reread f2 because %d!=%d\n", + __func__, hc->id + 1, temp, f2); + f2 = temp; /* repeat until F2 is equal */ + } + Fspace = f2 - f1 - 1; + if (Fspace < 0) + Fspace += hc->Flen; + /* + * Old FIFO handling doesn't give us the current Z2 read + * pointer, so we cannot send the next frame before the fifo + * is empty. It makes no difference except for a slightly + * lower performance. + */ + if (test_bit(HFC_CHIP_REVISION0, &hc->chip)) { + if (f1 != f2) + Fspace = 0; + else + Fspace = 1; + } + /* one frame only for ST D-channels, to allow resending */ + if (hc->ctype != HFC_TYPE_E1 && dch) { + if (f1 != f2) + Fspace = 0; + } + /* F-counter full condition */ + if (Fspace == 0) + return; + } + z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin; + z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin; + while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) { + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG "%s(card %d): reread z2 because " + "%d!=%d\n", __func__, hc->id + 1, temp, z2); + z2 = temp; /* repeat unti Z2 is equal */ + } + hc->chan[ch].Zfill = z1 - z2; + if (hc->chan[ch].Zfill < 0) + hc->chan[ch].Zfill += hc->Zlen; + Zspace = z2 - z1; + if (Zspace <= 0) + Zspace += hc->Zlen; + Zspace -= 4; /* keep not too full, so pointers will not overrun */ + /* fill transparent data only to maxinum transparent load (minus 4) */ + if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) + Zspace = Zspace - hc->Zlen + hc->max_trans; + if (Zspace <= 0) /* no space of 4 bytes */ + return; + + /* if no data */ + if (!len) { + if (z1 == z2) { /* empty */ + /* if done with FIFO audio data during PCM connection */ + if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && + *txpending && slot_tx >= 0) { + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG + "%s: reconnecting PCM due to no " + "more FIFO data: channel %d " + "slot_tx %d\n", + __func__, ch, slot_tx); + /* connect slot */ + if (hc->ctype == HFC_TYPE_XHFC) + HFC_outb(hc, A_CON_HDLC, 0xc0 + | 0x07 << 2 | V_HDLC_TRP | V_IFF); + /* Enable FIFO, no interrupt */ + else + HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | + V_HDLC_TRP | V_IFF); + HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1); + HFC_wait_nodebug(hc); + if (hc->ctype == HFC_TYPE_XHFC) + HFC_outb(hc, A_CON_HDLC, 0xc0 + | 0x07 << 2 | V_HDLC_TRP | V_IFF); + /* Enable FIFO, no interrupt */ + else + HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | + V_HDLC_TRP | V_IFF); + HFC_outb_nodebug(hc, R_FIFO, ch << 1); + HFC_wait_nodebug(hc); + } + *txpending = 0; + } + return; /* no data */ + } + + /* "fill fifo if empty" feature */ + if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags) + && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) { + if (debug & DEBUG_HFCMULTI_FILL) + printk(KERN_DEBUG "%s: buffer empty, so we have " + "underrun\n", __func__); + /* fill buffer, to prevent future underrun */ + hc->write_fifo(hc, hc->silence_data, poll >> 1); + Zspace -= (poll >> 1); + } + + /* if audio data and connected slot */ + if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending) + && slot_tx >= 0) { + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG "%s: disconnecting PCM due to " + "FIFO data: channel %d slot_tx %d\n", + __func__, ch, slot_tx); + /* disconnect slot */ + if (hc->ctype == HFC_TYPE_XHFC) + HFC_outb(hc, A_CON_HDLC, 0x80 + | 0x07 << 2 | V_HDLC_TRP | V_IFF); + /* Enable FIFO, no interrupt */ + else + HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | + V_HDLC_TRP | V_IFF); + HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1); + HFC_wait_nodebug(hc); + if (hc->ctype == HFC_TYPE_XHFC) + HFC_outb(hc, A_CON_HDLC, 0x80 + | 0x07 << 2 | V_HDLC_TRP | V_IFF); + /* Enable FIFO, no interrupt */ + else + HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | + V_HDLC_TRP | V_IFF); + HFC_outb_nodebug(hc, R_FIFO, ch << 1); + HFC_wait_nodebug(hc); + } + *txpending = 1; + + /* show activity */ + if (dch) + hc->activity_tx |= 1 << hc->chan[ch].port; + + /* fill fifo to what we have left */ + ii = len; + if (dch || test_bit(FLG_HDLC, &bch->Flags)) + temp = 1; + else + temp = 0; + i = *idxp; + d = (*sp)->data + i; + if (ii - i > Zspace) + ii = Zspace + i; + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space " + "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n", + __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i, + temp ? "HDLC" : "TRANS"); + + /* Have to prep the audio data */ + hc->write_fifo(hc, d, ii - i); + hc->chan[ch].Zfill += ii - i; + *idxp = ii; + + /* if not all data has been written */ + if (ii != len) { + /* NOTE: fifo is started by the calling function */ + return; + } + + /* if all data has been written, terminate frame */ + if (dch || test_bit(FLG_HDLC, &bch->Flags)) { + /* increment f-counter */ + HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F); + HFC_wait_nodebug(hc); + } + + dev_kfree_skb(*sp); + /* check for next frame */ + if (bch && get_next_bframe(bch)) { + len = (*sp)->len; + goto next_frame; + } + if (dch && get_next_dframe(dch)) { + len = (*sp)->len; + goto next_frame; + } + + /* + * now we have no more data, so in case of transparent, + * we set the last byte in fifo to 'silence' in case we will get + * no more data at all. this prevents sending an undefined value. + */ + if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) + HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence); +} + + +/* NOTE: only called if E1 card is in active state */ +static void +hfcmulti_rx(struct hfc_multi *hc, int ch) +{ + int temp; + int Zsize, z1, z2 = 0; /* = 0, to make GCC happy */ + int f1 = 0, f2 = 0; /* = 0, to make GCC happy */ + int again = 0; + struct bchannel *bch; + struct dchannel *dch = NULL; + struct sk_buff *skb, **sp = NULL; + int maxlen; + + bch = hc->chan[ch].bch; + if (bch) { + if (!test_bit(FLG_ACTIVE, &bch->Flags)) + return; + } else if (hc->chan[ch].dch) { + dch = hc->chan[ch].dch; + if (!test_bit(FLG_ACTIVE, &dch->Flags)) + return; + } else { + return; + } +next_frame: + /* on first AND before getting next valid frame, R_FIFO must be written + to. */ + if (test_bit(HFC_CHIP_B410P, &hc->chip) && + (hc->chan[ch].protocol == ISDN_P_B_RAW) && + (hc->chan[ch].slot_rx < 0) && + (hc->chan[ch].slot_tx < 0)) + HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1) | 1); + else + HFC_outb_nodebug(hc, R_FIFO, (ch << 1) | 1); + HFC_wait_nodebug(hc); + + /* ignore if rx is off BUT change fifo (above) to start pending TX */ + if (hc->chan[ch].rx_off) { + if (bch) + bch->dropcnt += poll; /* not exact but fair enough */ + return; + } + + if (dch || test_bit(FLG_HDLC, &bch->Flags)) { + f1 = HFC_inb_nodebug(hc, A_F1); + while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) { + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG + "%s(card %d): reread f1 because %d!=%d\n", + __func__, hc->id + 1, temp, f1); + f1 = temp; /* repeat until F1 is equal */ + } + f2 = HFC_inb_nodebug(hc, A_F2); + } + z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin; + while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) { + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG "%s(card %d): reread z2 because " + "%d!=%d\n", __func__, hc->id + 1, temp, z2); + z1 = temp; /* repeat until Z1 is equal */ + } + z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin; + Zsize = z1 - z2; + if ((dch || test_bit(FLG_HDLC, &bch->Flags)) && f1 != f2) + /* complete hdlc frame */ + Zsize++; + if (Zsize < 0) + Zsize += hc->Zlen; + /* if buffer is empty */ + if (Zsize <= 0) + return; + + if (bch) { + maxlen = bchannel_get_rxbuf(bch, Zsize); + if (maxlen < 0) { + pr_warning("card%d.B%d: No bufferspace for %d bytes\n", + hc->id + 1, bch->nr, Zsize); + return; + } + sp = &bch->rx_skb; + maxlen = bch->maxlen; + } else { /* Dchannel */ + sp = &dch->rx_skb; + maxlen = dch->maxlen + 3; + if (*sp == NULL) { + *sp = mI_alloc_skb(maxlen, GFP_ATOMIC); + if (*sp == NULL) { + pr_warning("card%d: No mem for dch rx_skb\n", + hc->id + 1); + return; + } + } + } + /* show activity */ + if (dch) + hc->activity_rx |= 1 << hc->chan[ch].port; + + /* empty fifo with what we have */ + if (dch || test_bit(FLG_HDLC, &bch->Flags)) { + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d " + "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) " + "got=%d (again %d)\n", __func__, hc->id + 1, ch, + Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE", + f1, f2, Zsize + (*sp)->len, again); + /* HDLC */ + if ((Zsize + (*sp)->len) > maxlen) { + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG + "%s(card %d): hdlc-frame too large.\n", + __func__, hc->id + 1); + skb_trim(*sp, 0); + HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait_nodebug(hc); + return; + } + + hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); + + if (f1 != f2) { + /* increment Z2,F2-counter */ + HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F); + HFC_wait_nodebug(hc); + /* check size */ + if ((*sp)->len < 4) { + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG + "%s(card %d): Frame below minimum " + "size\n", __func__, hc->id + 1); + skb_trim(*sp, 0); + goto next_frame; + } + /* there is at least one complete frame, check crc */ + if ((*sp)->data[(*sp)->len - 1]) { + if (debug & DEBUG_HFCMULTI_CRC) + printk(KERN_DEBUG + "%s: CRC-error\n", __func__); + skb_trim(*sp, 0); + goto next_frame; + } + skb_trim(*sp, (*sp)->len - 3); + if ((*sp)->len < MISDN_COPY_SIZE) { + skb = *sp; + *sp = mI_alloc_skb(skb->len, GFP_ATOMIC); + if (*sp) { + memcpy(skb_put(*sp, skb->len), + skb->data, skb->len); + skb_trim(skb, 0); + } else { + printk(KERN_DEBUG "%s: No mem\n", + __func__); + *sp = skb; + skb = NULL; + } + } else { + skb = NULL; + } + if (debug & DEBUG_HFCMULTI_FIFO) { + printk(KERN_DEBUG "%s(card %d):", + __func__, hc->id + 1); + temp = 0; + while (temp < (*sp)->len) + printk(" %02x", (*sp)->data[temp++]); + printk("\n"); + } + if (dch) + recv_Dchannel(dch); + else + recv_Bchannel(bch, MISDN_ID_ANY, false); + *sp = skb; + again++; + goto next_frame; + } + /* there is an incomplete frame */ + } else { + /* transparent */ + hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); + if (debug & DEBUG_HFCMULTI_FIFO) + printk(KERN_DEBUG + "%s(card %d): fifo(%d) reading %d bytes " + "(z1=%04x, z2=%04x) TRANS\n", + __func__, hc->id + 1, ch, Zsize, z1, z2); + /* only bch is transparent */ + recv_Bchannel(bch, hc->chan[ch].Zfill, false); + } +} + + +/* + * Interrupt handler + */ +static void +signal_state_up(struct dchannel *dch, int info, char *msg) +{ + struct sk_buff *skb; + int id, data = info; + + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG "%s: %s\n", __func__, msg); + + id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */ + + skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data, + GFP_ATOMIC); + if (!skb) + return; + recv_Dchannel_skb(dch, skb); +} + +static inline void +handle_timer_irq(struct hfc_multi *hc) +{ + int ch, temp; + struct dchannel *dch; + u_long flags; + + /* process queued resync jobs */ + if (hc->e1_resync) { + /* lock, so e1_resync gets not changed */ + spin_lock_irqsave(&HFClock, flags); + if (hc->e1_resync & 1) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "Enable SYNC_I\n"); + HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC); + /* disable JATT, if RX_SYNC is set */ + if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) + HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX); + } + if (hc->e1_resync & 2) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG "Enable jatt PLL\n"); + HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS); + } + if (hc->e1_resync & 4) { + if (debug & DEBUG_HFCMULTI_PLXSD) + printk(KERN_DEBUG + "Enable QUARTZ for HFC-E1\n"); + /* set jatt to quartz */ + HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC + | V_JATT_OFF); + /* switch to JATT, in case it is not already */ + HFC_outb(hc, R_SYNC_OUT, 0); + } + hc->e1_resync = 0; + spin_unlock_irqrestore(&HFClock, flags); + } + + if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1) + for (ch = 0; ch <= 31; ch++) { + if (hc->created[hc->chan[ch].port]) { + hfcmulti_tx(hc, ch); + /* fifo is started when switching to rx-fifo */ + hfcmulti_rx(hc, ch); + if (hc->chan[ch].dch && + hc->chan[ch].nt_timer > -1) { + dch = hc->chan[ch].dch; + if (!(--hc->chan[ch].nt_timer)) { + schedule_event(dch, + FLG_PHCHANGE); + if (debug & + DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG + "%s: nt_timer at " + "state %x\n", + __func__, + dch->state); + } + } + } + } + if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) { + dch = hc->chan[hc->dnum[0]].dch; + /* LOS */ + temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS; + hc->chan[hc->dnum[0]].los = temp; + if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) { + if (!temp && hc->chan[hc->dnum[0]].los) + signal_state_up(dch, L1_SIGNAL_LOS_ON, + "LOS detected"); + if (temp && !hc->chan[hc->dnum[0]].los) + signal_state_up(dch, L1_SIGNAL_LOS_OFF, + "LOS gone"); + } + if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) { + /* AIS */ + temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS; + if (!temp && hc->chan[hc->dnum[0]].ais) + signal_state_up(dch, L1_SIGNAL_AIS_ON, + "AIS detected"); + if (temp && !hc->chan[hc->dnum[0]].ais) + signal_state_up(dch, L1_SIGNAL_AIS_OFF, + "AIS gone"); + hc->chan[hc->dnum[0]].ais = temp; + } + if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) { + /* SLIP */ + temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX; + if (!temp && hc->chan[hc->dnum[0]].slip_rx) + signal_state_up(dch, L1_SIGNAL_SLIP_RX, + " bit SLIP detected RX"); + hc->chan[hc->dnum[0]].slip_rx = temp; + temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX; + if (!temp && hc->chan[hc->dnum[0]].slip_tx) + signal_state_up(dch, L1_SIGNAL_SLIP_TX, + " bit SLIP detected TX"); + hc->chan[hc->dnum[0]].slip_tx = temp; + } + if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) { + /* RDI */ + temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A; + if (!temp && hc->chan[hc->dnum[0]].rdi) + signal_state_up(dch, L1_SIGNAL_RDI_ON, + "RDI detected"); + if (temp && !hc->chan[hc->dnum[0]].rdi) + signal_state_up(dch, L1_SIGNAL_RDI_OFF, + "RDI gone"); + hc->chan[hc->dnum[0]].rdi = temp; + } + temp = HFC_inb_nodebug(hc, R_JATT_DIR); + switch (hc->chan[hc->dnum[0]].sync) { + case 0: + if ((temp & 0x60) == 0x60) { + if (debug & DEBUG_HFCMULTI_SYNC) + printk(KERN_DEBUG + "%s: (id=%d) E1 now " + "in clock sync\n", + __func__, hc->id); + HFC_outb(hc, R_RX_OFF, + hc->chan[hc->dnum[0]].jitter | V_RX_INIT); + HFC_outb(hc, R_TX_OFF, + hc->chan[hc->dnum[0]].jitter | V_RX_INIT); + hc->chan[hc->dnum[0]].sync = 1; + goto check_framesync; + } + break; + case 1: + if ((temp & 0x60) != 0x60) { + if (debug & DEBUG_HFCMULTI_SYNC) + printk(KERN_DEBUG + "%s: (id=%d) E1 " + "lost clock sync\n", + __func__, hc->id); + hc->chan[hc->dnum[0]].sync = 0; + break; + } + check_framesync: + temp = HFC_inb_nodebug(hc, R_SYNC_STA); + if (temp == 0x27) { + if (debug & DEBUG_HFCMULTI_SYNC) + printk(KERN_DEBUG + "%s: (id=%d) E1 " + "now in frame sync\n", + __func__, hc->id); + hc->chan[hc->dnum[0]].sync = 2; + } + break; + case 2: + if ((temp & 0x60) != 0x60) { + if (debug & DEBUG_HFCMULTI_SYNC) + printk(KERN_DEBUG + "%s: (id=%d) E1 lost " + "clock & frame sync\n", + __func__, hc->id); + hc->chan[hc->dnum[0]].sync = 0; + break; + } + temp = HFC_inb_nodebug(hc, R_SYNC_STA); + if (temp != 0x27) { + if (debug & DEBUG_HFCMULTI_SYNC) + printk(KERN_DEBUG + "%s: (id=%d) E1 " + "lost frame sync\n", + __func__, hc->id); + hc->chan[hc->dnum[0]].sync = 1; + } + break; + } + } + + if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip)) + hfcmulti_watchdog(hc); + + if (hc->leds) + hfcmulti_leds(hc); +} + +static void +ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech) +{ + struct dchannel *dch; + int ch; + int active; + u_char st_status, temp; + + /* state machine */ + for (ch = 0; ch <= 31; ch++) { + if (hc->chan[ch].dch) { + dch = hc->chan[ch].dch; + if (r_irq_statech & 1) { + HFC_outb_nodebug(hc, R_ST_SEL, + hc->chan[ch].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + /* undocumented: status changes during read */ + st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE); + while (st_status != (temp = + HFC_inb_nodebug(hc, A_ST_RD_STATE))) { + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG "%s: reread " + "STATE because %d!=%d\n", + __func__, temp, + st_status); + st_status = temp; /* repeat */ + } + + /* Speech Design TE-sync indication */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && + dch->dev.D.protocol == ISDN_P_TE_S0) { + if (st_status & V_FR_SYNC_ST) + hc->syncronized |= + (1 << hc->chan[ch].port); + else + hc->syncronized &= + ~(1 << hc->chan[ch].port); + } + dch->state = st_status & 0x0f; + if (dch->dev.D.protocol == ISDN_P_NT_S0) + active = 3; + else + active = 7; + if (dch->state == active) { + HFC_outb_nodebug(hc, R_FIFO, + (ch << 1) | 1); + HFC_wait_nodebug(hc); + HFC_outb_nodebug(hc, + R_INC_RES_FIFO, V_RES_F); + HFC_wait_nodebug(hc); + dch->tx_idx = 0; + } + schedule_event(dch, FLG_PHCHANGE); + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG + "%s: S/T newstate %x port %d\n", + __func__, dch->state, + hc->chan[ch].port); + } + r_irq_statech >>= 1; + } + } + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) + plxsd_checksync(hc, 0); +} + +static void +fifo_irq(struct hfc_multi *hc, int block) +{ + int ch, j; + struct dchannel *dch; + struct bchannel *bch; + u_char r_irq_fifo_bl; + + r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block); + j = 0; + while (j < 8) { + ch = (block << 2) + (j >> 1); + dch = hc->chan[ch].dch; + bch = hc->chan[ch].bch; + if (((!dch) && (!bch)) || (!hc->created[hc->chan[ch].port])) { + j += 2; + continue; + } + if (dch && (r_irq_fifo_bl & (1 << j)) && + test_bit(FLG_ACTIVE, &dch->Flags)) { + hfcmulti_tx(hc, ch); + /* start fifo */ + HFC_outb_nodebug(hc, R_FIFO, 0); + HFC_wait_nodebug(hc); + } + if (bch && (r_irq_fifo_bl & (1 << j)) && + test_bit(FLG_ACTIVE, &bch->Flags)) { + hfcmulti_tx(hc, ch); + /* start fifo */ + HFC_outb_nodebug(hc, R_FIFO, 0); + HFC_wait_nodebug(hc); + } + j++; + if (dch && (r_irq_fifo_bl & (1 << j)) && + test_bit(FLG_ACTIVE, &dch->Flags)) { + hfcmulti_rx(hc, ch); + } + if (bch && (r_irq_fifo_bl & (1 << j)) && + test_bit(FLG_ACTIVE, &bch->Flags)) { + hfcmulti_rx(hc, ch); + } + j++; + } +} + +#ifdef IRQ_DEBUG +int irqsem; +#endif +static irqreturn_t +hfcmulti_interrupt(int intno, void *dev_id) +{ +#ifdef IRQCOUNT_DEBUG + static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0, + iq5 = 0, iq6 = 0, iqcnt = 0; +#endif + struct hfc_multi *hc = dev_id; + struct dchannel *dch; + u_char r_irq_statech, status, r_irq_misc, r_irq_oview; + int i; + void __iomem *plx_acc; + u_short wval; + u_char e1_syncsta, temp, temp2; + u_long flags; + + if (!hc) { + printk(KERN_ERR "HFC-multi: Spurious interrupt!\n"); + return IRQ_NONE; + } + + spin_lock(&hc->lock); + +#ifdef IRQ_DEBUG + if (irqsem) + printk(KERN_ERR "irq for card %d during irq from " + "card %d, this is no bug.\n", hc->id + 1, irqsem); + irqsem = hc->id + 1; +#endif +#ifdef CONFIG_MISDN_HFCMULTI_8xx + if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk) + goto irq_notforus; +#endif + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + spin_lock_irqsave(&plx_lock, flags); + plx_acc = hc->plx_membase + PLX_INTCSR; + wval = readw(plx_acc); + spin_unlock_irqrestore(&plx_lock, flags); + if (!(wval & PLX_INTCSR_LINTI1_STATUS)) + goto irq_notforus; + } + + status = HFC_inb_nodebug(hc, R_STATUS); + r_irq_statech = HFC_inb_nodebug(hc, R_IRQ_STATECH); +#ifdef IRQCOUNT_DEBUG + if (r_irq_statech) + iq1++; + if (status & V_DTMF_STA) + iq2++; + if (status & V_LOST_STA) + iq3++; + if (status & V_EXT_IRQSTA) + iq4++; + if (status & V_MISC_IRQSTA) + iq5++; + if (status & V_FR_IRQSTA) + iq6++; + if (iqcnt++ > 5000) { + printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n", + iq1, iq2, iq3, iq4, iq5, iq6); + iqcnt = 0; + } +#endif + + if (!r_irq_statech && + !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA | + V_MISC_IRQSTA | V_FR_IRQSTA))) { + /* irq is not for us */ + goto irq_notforus; + } + hc->irqcnt++; + if (r_irq_statech) { + if (hc->ctype != HFC_TYPE_E1) + ph_state_irq(hc, r_irq_statech); + } + if (status & V_EXT_IRQSTA) + ; /* external IRQ */ + if (status & V_LOST_STA) { + /* LOST IRQ */ + HFC_outb(hc, R_INC_RES_FIFO, V_RES_LOST); /* clear irq! */ + } + if (status & V_MISC_IRQSTA) { + /* misc IRQ */ + r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC); + r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */ + if (r_irq_misc & V_STA_IRQ) { + if (hc->ctype == HFC_TYPE_E1) { + /* state machine */ + dch = hc->chan[hc->dnum[0]].dch; + e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); + if (test_bit(HFC_CHIP_PLXSD, &hc->chip) + && hc->e1_getclock) { + if (e1_syncsta & V_FR_SYNC_E1) + hc->syncronized = 1; + else + hc->syncronized = 0; + } + /* undocumented: status changes during read */ + temp = HFC_inb_nodebug(hc, R_E1_RD_STA); + while (temp != (temp2 = + HFC_inb_nodebug(hc, R_E1_RD_STA))) { + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG "%s: reread " + "STATE because %d!=%d\n", + __func__, temp, temp2); + temp = temp2; /* repeat */ + } + /* broadcast state change to all fragments */ + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG + "%s: E1 (id=%d) newstate %x\n", + __func__, hc->id, temp & 0x7); + for (i = 0; i < hc->ports; i++) { + dch = hc->chan[hc->dnum[i]].dch; + dch->state = temp & 0x7; + schedule_event(dch, FLG_PHCHANGE); + } + + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) + plxsd_checksync(hc, 0); + } + } + if (r_irq_misc & V_TI_IRQ) { + if (hc->iclock_on) + mISDN_clock_update(hc->iclock, poll, NULL); + handle_timer_irq(hc); + } + + if (r_irq_misc & V_DTMF_IRQ) + hfcmulti_dtmf(hc); + + if (r_irq_misc & V_IRQ_PROC) { + static int irq_proc_cnt; + if (!irq_proc_cnt++) + printk(KERN_DEBUG "%s: got V_IRQ_PROC -" + " this should not happen\n", __func__); + } + + } + if (status & V_FR_IRQSTA) { + /* FIFO IRQ */ + r_irq_oview = HFC_inb_nodebug(hc, R_IRQ_OVIEW); + for (i = 0; i < 8; i++) { + if (r_irq_oview & (1 << i)) + fifo_irq(hc, i); + } + } + +#ifdef IRQ_DEBUG + irqsem = 0; +#endif + spin_unlock(&hc->lock); + return IRQ_HANDLED; + +irq_notforus: +#ifdef IRQ_DEBUG + irqsem = 0; +#endif + spin_unlock(&hc->lock); + return IRQ_NONE; +} + + +/* + * timer callback for D-chan busy resolution. Currently no function + */ + +static void +hfcmulti_dbusy_timer(struct hfc_multi *hc) +{ +} + + +/* + * activate/deactivate hardware for selected channels and mode + * + * configure B-channel with the given protocol + * ch eqals to the HFC-channel (0-31) + * ch is the number of channel (0-4,4-7,8-11,12-15,16-19,20-23,24-27,28-31 + * for S/T, 1-31 for E1) + * the hdlc interrupts will be set/unset + */ +static int +mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, + int bank_tx, int slot_rx, int bank_rx) +{ + int flow_tx = 0, flow_rx = 0, routing = 0; + int oslot_tx, oslot_rx; + int conf; + + if (ch < 0 || ch > 31) + return -EINVAL; + oslot_tx = hc->chan[ch].slot_tx; + oslot_rx = hc->chan[ch].slot_rx; + conf = hc->chan[ch].conf; + + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG + "%s: card %d channel %d protocol %x slot old=%d new=%d " + "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n", + __func__, hc->id, ch, protocol, oslot_tx, slot_tx, + bank_tx, oslot_rx, slot_rx, bank_rx); + + if (oslot_tx >= 0 && slot_tx != oslot_tx) { + /* remove from slot */ + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG "%s: remove from slot %d (TX)\n", + __func__, oslot_tx); + if (hc->slot_owner[oslot_tx << 1] == ch) { + HFC_outb(hc, R_SLOT, oslot_tx << 1); + HFC_outb(hc, A_SL_CFG, 0); + if (hc->ctype != HFC_TYPE_XHFC) + HFC_outb(hc, A_CONF, 0); + hc->slot_owner[oslot_tx << 1] = -1; + } else { + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG + "%s: we are not owner of this tx slot " + "anymore, channel %d is.\n", + __func__, hc->slot_owner[oslot_tx << 1]); + } + } + + if (oslot_rx >= 0 && slot_rx != oslot_rx) { + /* remove from slot */ + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG + "%s: remove from slot %d (RX)\n", + __func__, oslot_rx); + if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) { + HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR); + HFC_outb(hc, A_SL_CFG, 0); + hc->slot_owner[(oslot_rx << 1) | 1] = -1; + } else { + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG + "%s: we are not owner of this rx slot " + "anymore, channel %d is.\n", + __func__, + hc->slot_owner[(oslot_rx << 1) | 1]); + } + } + + if (slot_tx < 0) { + flow_tx = 0x80; /* FIFO->ST */ + /* disable pcm slot */ + hc->chan[ch].slot_tx = -1; + hc->chan[ch].bank_tx = 0; + } else { + /* set pcm slot */ + if (hc->chan[ch].txpending) + flow_tx = 0x80; /* FIFO->ST */ + else + flow_tx = 0xc0; /* PCM->ST */ + /* put on slot */ + routing = bank_tx ? 0xc0 : 0x80; + if (conf >= 0 || bank_tx > 1) + routing = 0x40; /* loop */ + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG "%s: put channel %d to slot %d bank" + " %d flow %02x routing %02x conf %d (TX)\n", + __func__, ch, slot_tx, bank_tx, + flow_tx, routing, conf); + HFC_outb(hc, R_SLOT, slot_tx << 1); + HFC_outb(hc, A_SL_CFG, (ch << 1) | routing); + if (hc->ctype != HFC_TYPE_XHFC) + HFC_outb(hc, A_CONF, + (conf < 0) ? 0 : (conf | V_CONF_SL)); + hc->slot_owner[slot_tx << 1] = ch; + hc->chan[ch].slot_tx = slot_tx; + hc->chan[ch].bank_tx = bank_tx; + } + if (slot_rx < 0) { + /* disable pcm slot */ + flow_rx = 0x80; /* ST->FIFO */ + hc->chan[ch].slot_rx = -1; + hc->chan[ch].bank_rx = 0; + } else { + /* set pcm slot */ + if (hc->chan[ch].txpending) + flow_rx = 0x80; /* ST->FIFO */ + else + flow_rx = 0xc0; /* ST->(FIFO,PCM) */ + /* put on slot */ + routing = bank_rx ? 0x80 : 0xc0; /* reversed */ + if (conf >= 0 || bank_rx > 1) + routing = 0x40; /* loop */ + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG "%s: put channel %d to slot %d bank" + " %d flow %02x routing %02x conf %d (RX)\n", + __func__, ch, slot_rx, bank_rx, + flow_rx, routing, conf); + HFC_outb(hc, R_SLOT, (slot_rx << 1) | V_SL_DIR); + HFC_outb(hc, A_SL_CFG, (ch << 1) | V_CH_DIR | routing); + hc->slot_owner[(slot_rx << 1) | 1] = ch; + hc->chan[ch].slot_rx = slot_rx; + hc->chan[ch].bank_rx = bank_rx; + } + + switch (protocol) { + case (ISDN_P_NONE): + /* disable TX fifo */ + HFC_outb(hc, R_FIFO, ch << 1); + HFC_wait(hc); + HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_IFF); + HFC_outb(hc, A_SUBCH_CFG, 0); + HFC_outb(hc, A_IRQ_MSK, 0); + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + /* disable RX fifo */ + HFC_outb(hc, R_FIFO, (ch << 1) | 1); + HFC_wait(hc); + HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00); + HFC_outb(hc, A_SUBCH_CFG, 0); + HFC_outb(hc, A_IRQ_MSK, 0); + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) { + hc->hw.a_st_ctrl0[hc->chan[ch].port] &= + ((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN; + HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_CTRL0, + hc->hw.a_st_ctrl0[hc->chan[ch].port]); + } + if (hc->chan[ch].bch) { + test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); + test_and_clear_bit(FLG_TRANSPARENT, + &hc->chan[ch].bch->Flags); + } + break; + case (ISDN_P_B_RAW): /* B-channel */ + + if (test_bit(HFC_CHIP_B410P, &hc->chip) && + (hc->chan[ch].slot_rx < 0) && + (hc->chan[ch].slot_tx < 0)) { + + printk(KERN_DEBUG + "Setting B-channel %d to echo cancelable " + "state on PCM slot %d\n", ch, + ((ch / 4) * 8) + ((ch % 4) * 4) + 1); + printk(KERN_DEBUG + "Enabling pass through for channel\n"); + vpm_out(hc, ch, ((ch / 4) * 8) + + ((ch % 4) * 4) + 1, 0x01); + /* rx path */ + /* S/T -> PCM */ + HFC_outb(hc, R_FIFO, (ch << 1)); + HFC_wait(hc); + HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF); + HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + + ((ch % 4) * 4) + 1) << 1); + HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1)); + + /* PCM -> FIFO */ + HFC_outb(hc, R_FIFO, 0x20 | (ch << 1) | 1); + HFC_wait(hc); + HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF); + HFC_outb(hc, A_SUBCH_CFG, 0); + HFC_outb(hc, A_IRQ_MSK, 0); + if (hc->chan[ch].protocol != protocol) { + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + } + HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) + + ((ch % 4) * 4) + 1) << 1) | 1); + HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1); + + /* tx path */ + /* PCM -> S/T */ + HFC_outb(hc, R_FIFO, (ch << 1) | 1); + HFC_wait(hc); + HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF); + HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) + + ((ch % 4) * 4)) << 1) | 1); + HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1); + + /* FIFO -> PCM */ + HFC_outb(hc, R_FIFO, 0x20 | (ch << 1)); + HFC_wait(hc); + HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF); + HFC_outb(hc, A_SUBCH_CFG, 0); + HFC_outb(hc, A_IRQ_MSK, 0); + if (hc->chan[ch].protocol != protocol) { + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + } + /* tx silence */ + HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence); + HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + + ((ch % 4) * 4)) << 1); + HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1)); + } else { + /* enable TX fifo */ + HFC_outb(hc, R_FIFO, ch << 1); + HFC_wait(hc); + if (hc->ctype == HFC_TYPE_XHFC) + HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 | + V_HDLC_TRP | V_IFF); + /* Enable FIFO, no interrupt */ + else + HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | + V_HDLC_TRP | V_IFF); + HFC_outb(hc, A_SUBCH_CFG, 0); + HFC_outb(hc, A_IRQ_MSK, 0); + if (hc->chan[ch].protocol != protocol) { + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + } + /* tx silence */ + HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence); + /* enable RX fifo */ + HFC_outb(hc, R_FIFO, (ch << 1) | 1); + HFC_wait(hc); + if (hc->ctype == HFC_TYPE_XHFC) + HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 | + V_HDLC_TRP); + /* Enable FIFO, no interrupt*/ + else + HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | + V_HDLC_TRP); + HFC_outb(hc, A_SUBCH_CFG, 0); + HFC_outb(hc, A_IRQ_MSK, 0); + if (hc->chan[ch].protocol != protocol) { + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + } + } + if (hc->ctype != HFC_TYPE_E1) { + hc->hw.a_st_ctrl0[hc->chan[ch].port] |= + ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; + HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_CTRL0, + hc->hw.a_st_ctrl0[hc->chan[ch].port]); + } + if (hc->chan[ch].bch) + test_and_set_bit(FLG_TRANSPARENT, + &hc->chan[ch].bch->Flags); + break; + case (ISDN_P_B_HDLC): /* B-channel */ + case (ISDN_P_TE_S0): /* D-channel */ + case (ISDN_P_NT_S0): + case (ISDN_P_TE_E1): + case (ISDN_P_NT_E1): + /* enable TX fifo */ + HFC_outb(hc, R_FIFO, ch << 1); + HFC_wait(hc); + if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) { + /* E1 or B-channel */ + HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04); + HFC_outb(hc, A_SUBCH_CFG, 0); + } else { + /* D-Channel without HDLC fill flags */ + HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04 | V_IFF); + HFC_outb(hc, A_SUBCH_CFG, 2); + } + HFC_outb(hc, A_IRQ_MSK, V_IRQ); + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + /* enable RX fifo */ + HFC_outb(hc, R_FIFO, (ch << 1) | 1); + HFC_wait(hc); + HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04); + if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) + HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */ + else + HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */ + HFC_outb(hc, A_IRQ_MSK, V_IRQ); + HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait(hc); + if (hc->chan[ch].bch) { + test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); + if (hc->ctype != HFC_TYPE_E1) { + hc->hw.a_st_ctrl0[hc->chan[ch].port] |= + ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; + HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_CTRL0, + hc->hw.a_st_ctrl0[hc->chan[ch].port]); + } + } + break; + default: + printk(KERN_DEBUG "%s: protocol not known %x\n", + __func__, protocol); + hc->chan[ch].protocol = ISDN_P_NONE; + return -ENOPROTOOPT; + } + hc->chan[ch].protocol = protocol; + return 0; +} + + +/* + * connect/disconnect PCM + */ + +static void +hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx, + int slot_rx, int bank_rx) +{ + if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { + /* disable PCM */ + mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); + return; + } + + /* enable pcm */ + mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx, + slot_rx, bank_rx); +} + +/* + * set/disable conference + */ + +static void +hfcmulti_conf(struct hfc_multi *hc, int ch, int num) +{ + if (num >= 0 && num <= 7) + hc->chan[ch].conf = num; + else + hc->chan[ch].conf = -1; + mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx, + hc->chan[ch].bank_tx, hc->chan[ch].slot_rx, + hc->chan[ch].bank_rx); +} + + +/* + * set/disable sample loop + */ + +/* NOTE: this function is experimental and therefore disabled */ + +/* + * Layer 1 callback function + */ +static int +hfcm_l1callback(struct dchannel *dch, u_int cmd) +{ + struct hfc_multi *hc = dch->hw; + u_long flags; + + switch (cmd) { + case INFO3_P8: + case INFO3_P10: + break; + case HW_RESET_REQ: + /* start activation */ + spin_lock_irqsave(&hc->lock, flags); + if (hc->ctype == HFC_TYPE_E1) { + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: HW_RESET_REQ no BRI\n", + __func__); + } else { + HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */ + udelay(6); /* wait at least 5,21us */ + HFC_outb(hc, A_ST_WR_STATE, 3); + HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT * 3)); + /* activate */ + } + spin_unlock_irqrestore(&hc->lock, flags); + l1_event(dch->l1, HW_POWERUP_IND); + break; + case HW_DEACT_REQ: + /* start deactivation */ + spin_lock_irqsave(&hc->lock, flags); + if (hc->ctype == HFC_TYPE_E1) { + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: HW_DEACT_REQ no BRI\n", + __func__); + } else { + HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2); + /* deactivate */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + hc->syncronized &= + ~(1 << hc->chan[dch->slot].port); + plxsd_checksync(hc, 0); + } + } + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) + del_timer(&dch->timer); + spin_unlock_irqrestore(&hc->lock, flags); + break; + case HW_POWERUP_REQ: + spin_lock_irqsave(&hc->lock, flags); + if (hc->ctype == HFC_TYPE_E1) { + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: HW_POWERUP_REQ no BRI\n", + __func__); + } else { + HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_WR_STATE, 3 | 0x10); /* activate */ + udelay(6); /* wait at least 5,21us */ + HFC_outb(hc, A_ST_WR_STATE, 3); /* activate */ + } + spin_unlock_irqrestore(&hc->lock, flags); + break; + case PH_ACTIVATE_IND: + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + case PH_DEACTIVATE_IND: + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + default: + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: unknown command %x\n", + __func__, cmd); + return -1; + } + return 0; +} + +/* + * Layer2 -> Layer 1 Transfer + */ + +static int +handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct hfc_multi *hc = dch->hw; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + int ret = -EINVAL; + unsigned int id; + u_long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + if (skb->len < 1) + break; + spin_lock_irqsave(&hc->lock, flags); + ret = dchannel_senddata(dch, skb); + if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ + hfcmulti_tx(hc, dch->slot); + ret = 0; + /* start fifo */ + HFC_outb(hc, R_FIFO, 0); + HFC_wait(hc); + spin_unlock_irqrestore(&hc->lock, flags); + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&hc->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + if (dch->dev.D.protocol != ISDN_P_TE_S0) { + spin_lock_irqsave(&hc->lock, flags); + ret = 0; + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: PH_ACTIVATE port %d (0..%d)\n", + __func__, hc->chan[dch->slot].port, + hc->ports - 1); + /* start activation */ + if (hc->ctype == HFC_TYPE_E1) { + ph_state_change(dch); + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG + "%s: E1 report state %x \n", + __func__, dch->state); + } else { + HFC_outb(hc, R_ST_SEL, + hc->chan[dch->slot].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1); + /* G1 */ + udelay(6); /* wait at least 5,21us */ + HFC_outb(hc, A_ST_WR_STATE, 1); + HFC_outb(hc, A_ST_WR_STATE, 1 | + (V_ST_ACT * 3)); /* activate */ + dch->state = 1; + } + spin_unlock_irqrestore(&hc->lock, flags); + } else + ret = l1_event(dch->l1, hh->prim); + break; + case PH_DEACTIVATE_REQ: + test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); + if (dch->dev.D.protocol != ISDN_P_TE_S0) { + spin_lock_irqsave(&hc->lock, flags); + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: PH_DEACTIVATE port %d (0..%d)\n", + __func__, hc->chan[dch->slot].port, + hc->ports - 1); + /* start deactivation */ + if (hc->ctype == HFC_TYPE_E1) { + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: PH_DEACTIVATE no BRI\n", + __func__); + } else { + HFC_outb(hc, R_ST_SEL, + hc->chan[dch->slot].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2); + /* deactivate */ + dch->state = 1; + } + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) + del_timer(&dch->timer); +#ifdef FIXME + if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) + dchannel_sched_event(&hc->dch, D_CLEARBUSY); +#endif + ret = 0; + spin_unlock_irqrestore(&hc->lock, flags); + } else + ret = l1_event(dch->l1, hh->prim); + break; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static void +deactivate_bchannel(struct bchannel *bch) +{ + struct hfc_multi *hc = bch->hw; + u_long flags; + + spin_lock_irqsave(&hc->lock, flags); + mISDN_clear_bchannel(bch); + hc->chan[bch->slot].coeff_count = 0; + hc->chan[bch->slot].rx_off = 0; + hc->chan[bch->slot].conf = -1; + mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0); + spin_unlock_irqrestore(&hc->lock, flags); +} + +static int +handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct hfc_multi *hc = bch->hw; + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + unsigned long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + if (!skb->len) + break; + spin_lock_irqsave(&hc->lock, flags); + ret = bchannel_senddata(bch, skb); + if (ret > 0) { /* direct TX */ + hfcmulti_tx(hc, bch->slot); + ret = 0; + /* start fifo */ + HFC_outb_nodebug(hc, R_FIFO, 0); + HFC_wait_nodebug(hc); + } + spin_unlock_irqrestore(&hc->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n", + __func__, bch->slot); + spin_lock_irqsave(&hc->lock, flags); + /* activate B-channel if not already activated */ + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) { + hc->chan[bch->slot].txpending = 0; + ret = mode_hfcmulti(hc, bch->slot, + ch->protocol, + hc->chan[bch->slot].slot_tx, + hc->chan[bch->slot].bank_tx, + hc->chan[bch->slot].slot_rx, + hc->chan[bch->slot].bank_rx); + if (!ret) { + if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf + && test_bit(HFC_CHIP_DTMF, &hc->chip)) { + /* start decoder */ + hc->dtmf = 1; + if (debug & DEBUG_HFCMULTI_DTMF) + printk(KERN_DEBUG + "%s: start dtmf decoder\n", + __func__); + HFC_outb(hc, R_DTMF, hc->hw.r_dtmf | + V_RST_DTMF); + } + } + } else + ret = 0; + spin_unlock_irqrestore(&hc->lock, flags); + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL, + GFP_KERNEL); + break; + case PH_CONTROL_REQ: + spin_lock_irqsave(&hc->lock, flags); + switch (hh->id) { + case HFC_SPL_LOOP_ON: /* set sample loop */ + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: HFC_SPL_LOOP_ON (len = %d)\n", + __func__, skb->len); + ret = 0; + break; + case HFC_SPL_LOOP_OFF: /* set silence */ + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n", + __func__); + ret = 0; + break; + default: + printk(KERN_ERR + "%s: unknown PH_CONTROL_REQ info %x\n", + __func__, hh->id); + ret = -EINVAL; + } + spin_unlock_irqrestore(&hc->lock, flags); + break; + case PH_DEACTIVATE_REQ: + deactivate_bchannel(bch); /* locked there */ + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL, + GFP_KERNEL); + ret = 0; + break; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +/* + * bchannel control function + */ +static int +channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + struct dsp_features *features = + (struct dsp_features *)(*((u_long *)&cq->p1)); + struct hfc_multi *hc = bch->hw; + int slot_tx; + int bank_tx; + int slot_rx; + int bank_rx; + int num; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + ret = mISDN_ctrl_bchannel(bch, cq); + cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP; + break; + case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ + ret = mISDN_ctrl_bchannel(bch, cq); + hc->chan[bch->slot].rx_off = !!cq->p1; + if (!hc->chan[bch->slot].rx_off) { + /* reset fifo on rx on */ + HFC_outb_nodebug(hc, R_FIFO, (bch->slot << 1) | 1); + HFC_wait_nodebug(hc); + HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); + HFC_wait_nodebug(hc); + } + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", + __func__, bch->nr, hc->chan[bch->slot].rx_off); + break; + case MISDN_CTRL_FILL_EMPTY: + ret = mISDN_ctrl_bchannel(bch, cq); + hc->silence = bch->fill[0]; + memset(hc->silence_data, hc->silence, sizeof(hc->silence_data)); + break; + case MISDN_CTRL_HW_FEATURES: /* fill features structure */ + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: HW_FEATURE request\n", + __func__); + /* create confirm */ + features->hfc_id = hc->id; + if (test_bit(HFC_CHIP_DTMF, &hc->chip)) + features->hfc_dtmf = 1; + if (test_bit(HFC_CHIP_CONF, &hc->chip)) + features->hfc_conf = 1; + features->hfc_loops = 0; + if (test_bit(HFC_CHIP_B410P, &hc->chip)) { + features->hfc_echocanhw = 1; + } else { + features->pcm_id = hc->pcm; + features->pcm_slots = hc->slots; + features->pcm_banks = 2; + } + break; + case MISDN_CTRL_HFC_PCM_CONN: /* connect to pcm timeslot (0..N) */ + slot_tx = cq->p1 & 0xff; + bank_tx = cq->p1 >> 8; + slot_rx = cq->p2 & 0xff; + bank_rx = cq->p2 >> 8; + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG + "%s: HFC_PCM_CONN slot %d bank %d (TX) " + "slot %d bank %d (RX)\n", + __func__, slot_tx, bank_tx, + slot_rx, bank_rx); + if (slot_tx < hc->slots && bank_tx <= 2 && + slot_rx < hc->slots && bank_rx <= 2) + hfcmulti_pcm(hc, bch->slot, + slot_tx, bank_tx, slot_rx, bank_rx); + else { + printk(KERN_WARNING + "%s: HFC_PCM_CONN slot %d bank %d (TX) " + "slot %d bank %d (RX) out of range\n", + __func__, slot_tx, bank_tx, + slot_rx, bank_rx); + ret = -EINVAL; + } + break; + case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */ + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: HFC_PCM_DISC\n", + __func__); + hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0); + break; + case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */ + num = cq->p1 & 0xff; + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n", + __func__, num); + if (num <= 7) + hfcmulti_conf(hc, bch->slot, num); + else { + printk(KERN_WARNING + "%s: HW_CONF_JOIN conf %d out of range\n", + __func__, num); + ret = -EINVAL; + } + break; + case MISDN_CTRL_HFC_CONF_SPLIT: /* split conference */ + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: HFC_CONF_SPLIT\n", __func__); + hfcmulti_conf(hc, bch->slot, -1); + break; + case MISDN_CTRL_HFC_ECHOCAN_ON: + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: HFC_ECHOCAN_ON\n", __func__); + if (test_bit(HFC_CHIP_B410P, &hc->chip)) + vpm_echocan_on(hc, bch->slot, cq->p1); + else + ret = -EINVAL; + break; + + case MISDN_CTRL_HFC_ECHOCAN_OFF: + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n", + __func__); + if (test_bit(HFC_CHIP_B410P, &hc->chip)) + vpm_echocan_off(hc, bch->slot); + else + ret = -EINVAL; + break; + default: + ret = mISDN_ctrl_bchannel(bch, cq); + break; + } + return ret; +} + +static int +hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct hfc_multi *hc = bch->hw; + int err = -EINVAL; + u_long flags; + + if (bch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: cmd:%x %p\n", + __func__, cmd, arg); + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + deactivate_bchannel(bch); /* locked there */ + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(THIS_MODULE); + err = 0; + break; + case CONTROL_CHANNEL: + spin_lock_irqsave(&hc->lock, flags); + err = channel_bctrl(bch, arg); + spin_unlock_irqrestore(&hc->lock, flags); + break; + default: + printk(KERN_WARNING "%s: unknown prim(%x)\n", + __func__, cmd); + } + return err; +} + +/* + * handle D-channel events + * + * handle state change event + */ +static void +ph_state_change(struct dchannel *dch) +{ + struct hfc_multi *hc; + int ch, i; + + if (!dch) { + printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__); + return; + } + hc = dch->hw; + ch = dch->slot; + + if (hc->ctype == HFC_TYPE_E1) { + if (dch->dev.D.protocol == ISDN_P_TE_E1) { + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG + "%s: E1 TE (id=%d) newstate %x\n", + __func__, hc->id, dch->state); + } else { + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG + "%s: E1 NT (id=%d) newstate %x\n", + __func__, hc->id, dch->state); + } + switch (dch->state) { + case (1): + if (hc->e1_state != 1) { + for (i = 1; i <= 31; i++) { + /* reset fifos on e1 activation */ + HFC_outb_nodebug(hc, R_FIFO, + (i << 1) | 1); + HFC_wait_nodebug(hc); + HFC_outb_nodebug(hc, R_INC_RES_FIFO, + V_RES_F); + HFC_wait_nodebug(hc); + } + } + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, PH_ACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + break; + + default: + if (hc->e1_state != 1) + return; + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + } + hc->e1_state = dch->state; + } else { + if (dch->dev.D.protocol == ISDN_P_TE_S0) { + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG + "%s: S/T TE newstate %x\n", + __func__, dch->state); + switch (dch->state) { + case (0): + l1_event(dch->l1, HW_RESET_IND); + break; + case (3): + l1_event(dch->l1, HW_DEACT_IND); + break; + case (5): + case (8): + l1_event(dch->l1, ANYSIGNAL); + break; + case (6): + l1_event(dch->l1, INFO2); + break; + case (7): + l1_event(dch->l1, INFO4_P8); + break; + } + } else { + if (debug & DEBUG_HFCMULTI_STATE) + printk(KERN_DEBUG "%s: S/T NT newstate %x\n", + __func__, dch->state); + switch (dch->state) { + case (2): + if (hc->chan[ch].nt_timer == 0) { + hc->chan[ch].nt_timer = -1; + HFC_outb(hc, R_ST_SEL, + hc->chan[ch].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + HFC_outb(hc, A_ST_WR_STATE, 4 | + V_ST_LD_STA); /* G4 */ + udelay(6); /* wait at least 5,21us */ + HFC_outb(hc, A_ST_WR_STATE, 4); + dch->state = 4; + } else { + /* one extra count for the next event */ + hc->chan[ch].nt_timer = + nt_t1_count[poll_timer] + 1; + HFC_outb(hc, R_ST_SEL, + hc->chan[ch].port); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + /* allow G2 -> G3 transition */ + HFC_outb(hc, A_ST_WR_STATE, 2 | + V_SET_G2_G3); + } + break; + case (1): + hc->chan[ch].nt_timer = -1; + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + break; + case (4): + hc->chan[ch].nt_timer = -1; + break; + case (3): + hc->chan[ch].nt_timer = -1; + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, PH_ACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + break; + } + } + } +} + +/* + * called for card mode init message + */ + +static void +hfcmulti_initmode(struct dchannel *dch) +{ + struct hfc_multi *hc = dch->hw; + u_char a_st_wr_state, r_e1_wr_sta; + int i, pt; + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: entered\n", __func__); + + i = dch->slot; + pt = hc->chan[i].port; + if (hc->ctype == HFC_TYPE_E1) { + /* E1 */ + hc->chan[hc->dnum[pt]].slot_tx = -1; + hc->chan[hc->dnum[pt]].slot_rx = -1; + hc->chan[hc->dnum[pt]].conf = -1; + if (hc->dnum[pt]) { + mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol, + -1, 0, -1, 0); + dch->timer.function = (void *) hfcmulti_dbusy_timer; + dch->timer.data = (long) dch; + init_timer(&dch->timer); + } + for (i = 1; i <= 31; i++) { + if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */ + continue; + hc->chan[i].slot_tx = -1; + hc->chan[i].slot_rx = -1; + hc->chan[i].conf = -1; + mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0); + } + } + if (hc->ctype == HFC_TYPE_E1 && pt == 0) { + /* E1, port 0 */ + dch = hc->chan[hc->dnum[0]].dch; + if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) { + HFC_outb(hc, R_LOS0, 255); /* 2 ms */ + HFC_outb(hc, R_LOS1, 255); /* 512 ms */ + } + if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[0]].cfg)) { + HFC_outb(hc, R_RX0, 0); + hc->hw.r_tx0 = 0 | V_OUT_EN; + } else { + HFC_outb(hc, R_RX0, 1); + hc->hw.r_tx0 = 1 | V_OUT_EN; + } + hc->hw.r_tx1 = V_ATX | V_NTRI; + HFC_outb(hc, R_TX0, hc->hw.r_tx0); + HFC_outb(hc, R_TX1, hc->hw.r_tx1); + HFC_outb(hc, R_TX_FR0, 0x00); + HFC_outb(hc, R_TX_FR1, 0xf8); + + if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg)) + HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E); + + HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0); + + if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg)) + HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC); + + if (dch->dev.D.protocol == ISDN_P_NT_E1) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: E1 port is NT-mode\n", + __func__); + r_e1_wr_sta = 0; /* G0 */ + hc->e1_getclock = 0; + } else { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: E1 port is TE-mode\n", + __func__); + r_e1_wr_sta = 0; /* F0 */ + hc->e1_getclock = 1; + } + if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) + HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX); + else + HFC_outb(hc, R_SYNC_OUT, 0); + if (test_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip)) + hc->e1_getclock = 1; + if (test_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip)) + hc->e1_getclock = 0; + if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { + /* SLAVE (clock master) */ + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: E1 port is clock master " + "(clock from PCM)\n", __func__); + HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC); + } else { + if (hc->e1_getclock) { + /* MASTER (clock slave) */ + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: E1 port is clock slave " + "(clock to PCM)\n", __func__); + HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS); + } else { + /* MASTER (clock master) */ + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: E1 port is " + "clock master " + "(clock from QUARTZ)\n", + __func__); + HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | + V_PCM_SYNC | V_JATT_OFF); + HFC_outb(hc, R_SYNC_OUT, 0); + } + } + HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */ + HFC_outb(hc, R_PWM_MD, V_PWM0_MD); + HFC_outb(hc, R_PWM0, 0x50); + HFC_outb(hc, R_PWM1, 0xff); + /* state machine setup */ + HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta | V_E1_LD_STA); + udelay(6); /* wait at least 5,21us */ + HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta); + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + hc->syncronized = 0; + plxsd_checksync(hc, 0); + } + } + if (hc->ctype != HFC_TYPE_E1) { + /* ST */ + hc->chan[i].slot_tx = -1; + hc->chan[i].slot_rx = -1; + hc->chan[i].conf = -1; + mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0); + dch->timer.function = (void *) hfcmulti_dbusy_timer; + dch->timer.data = (long) dch; + init_timer(&dch->timer); + hc->chan[i - 2].slot_tx = -1; + hc->chan[i - 2].slot_rx = -1; + hc->chan[i - 2].conf = -1; + mode_hfcmulti(hc, i - 2, ISDN_P_NONE, -1, 0, -1, 0); + hc->chan[i - 1].slot_tx = -1; + hc->chan[i - 1].slot_rx = -1; + hc->chan[i - 1].conf = -1; + mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0); + /* select interface */ + HFC_outb(hc, R_ST_SEL, pt); + /* undocumented: delay after R_ST_SEL */ + udelay(1); + if (dch->dev.D.protocol == ISDN_P_NT_S0) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: ST port %d is NT-mode\n", + __func__, pt); + /* clock delay */ + HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt); + a_st_wr_state = 1; /* G1 */ + hc->hw.a_st_ctrl0[pt] = V_ST_MD; + } else { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: ST port %d is TE-mode\n", + __func__, pt); + /* clock delay */ + HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te); + a_st_wr_state = 2; /* F2 */ + hc->hw.a_st_ctrl0[pt] = 0; + } + if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg)) + hc->hw.a_st_ctrl0[pt] |= V_TX_LI; + if (hc->ctype == HFC_TYPE_XHFC) { + hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */; + HFC_outb(hc, 0x35 /* A_ST_CTRL3 */, + 0x7c << 1 /* V_ST_PULSE */); + } + /* line setup */ + HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]); + /* disable E-channel */ + if ((dch->dev.D.protocol == ISDN_P_NT_S0) || + test_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i].cfg)) + HFC_outb(hc, A_ST_CTRL1, V_E_IGNO); + else + HFC_outb(hc, A_ST_CTRL1, 0); + /* enable B-channel receive */ + HFC_outb(hc, A_ST_CTRL2, V_B1_RX_EN | V_B2_RX_EN); + /* state machine setup */ + HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state | V_ST_LD_STA); + udelay(6); /* wait at least 5,21us */ + HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state); + hc->hw.r_sci_msk |= 1 << pt; + /* state machine interrupts */ + HFC_outb(hc, R_SCI_MSK, hc->hw.r_sci_msk); + /* unset sync on port */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + hc->syncronized &= + ~(1 << hc->chan[dch->slot].port); + plxsd_checksync(hc, 0); + } + } + if (debug & DEBUG_HFCMULTI_INIT) + printk("%s: done\n", __func__); +} + + +static int +open_dchannel(struct hfc_multi *hc, struct dchannel *dch, + struct channel_req *rq) +{ + int err = 0; + u_long flags; + + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__, + dch->dev.id, __builtin_return_address(0)); + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + if ((dch->dev.D.protocol != ISDN_P_NONE) && + (dch->dev.D.protocol != rq->protocol)) { + if (debug & DEBUG_HFCMULTI_MODE) + printk(KERN_DEBUG "%s: change protocol %x to %x\n", + __func__, dch->dev.D.protocol, rq->protocol); + } + if ((dch->dev.D.protocol == ISDN_P_TE_S0) && + (rq->protocol != ISDN_P_TE_S0)) + l1_event(dch->l1, CLOSE_CHANNEL); + if (dch->dev.D.protocol != rq->protocol) { + if (rq->protocol == ISDN_P_TE_S0) { + err = create_l1(dch, hfcm_l1callback); + if (err) + return err; + } + dch->dev.D.protocol = rq->protocol; + spin_lock_irqsave(&hc->lock, flags); + hfcmulti_initmode(dch); + spin_unlock_irqrestore(&hc->lock, flags); + } + if (test_bit(FLG_ACTIVE, &dch->Flags)) + _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, + 0, NULL, GFP_KERNEL); + rq->ch = &dch->dev.D; + if (!try_module_get(THIS_MODULE)) + printk(KERN_WARNING "%s:cannot get module\n", __func__); + return 0; +} + +static int +open_bchannel(struct hfc_multi *hc, struct dchannel *dch, + struct channel_req *rq) +{ + struct bchannel *bch; + int ch; + + if (!test_channelmap(rq->adr.channel, dch->dev.channelmap)) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + if (hc->ctype == HFC_TYPE_E1) + ch = rq->adr.channel; + else + ch = (rq->adr.channel - 1) + (dch->slot - 2); + bch = hc->chan[ch].bch; + if (!bch) { + printk(KERN_ERR "%s:internal error ch %d has no bch\n", + __func__, ch); + return -EINVAL; + } + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + bch->ch.protocol = rq->protocol; + hc->chan[ch].rx_off = 0; + rq->ch = &bch->ch; + if (!try_module_get(THIS_MODULE)) + printk(KERN_WARNING "%s:cannot get module\n", __func__); + return 0; +} + +/* + * device control function + */ +static int +channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) +{ + struct hfc_multi *hc = dch->hw; + int ret = 0; + int wd_mode, wd_cnt; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_L1_TIMER3; + break; + case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */ + wd_cnt = cq->p1 & 0xf; + wd_mode = !!(cq->p1 >> 4); + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s" + ", counter 0x%x\n", __func__, + wd_mode ? "AUTO" : "MANUAL", wd_cnt); + /* set the watchdog timer */ + HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4)); + hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0); + if (hc->ctype == HFC_TYPE_XHFC) + hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */; + /* init the watchdog register and reset the counter */ + HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES); + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + /* enable the watchdog output for Speech-Design */ + HFC_outb(hc, R_GPIO_SEL, V_GPIO_SEL7); + HFC_outb(hc, R_GPIO_EN1, V_GPIO_EN15); + HFC_outb(hc, R_GPIO_OUT1, 0); + HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15); + } + break; + case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */ + if (debug & DEBUG_HFCMULTI_MSG) + printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n", + __func__); + HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES); + break; + case MISDN_CTRL_L1_TIMER3: + ret = l1_event(dch->l1, HW_TIMER3_VALUE | (cq->p1 & 0xff)); + break; + default: + printk(KERN_WARNING "%s: unknown Op %x\n", + __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +static int +hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct hfc_multi *hc = dch->hw; + struct channel_req *rq; + int err = 0; + u_long flags; + + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: cmd:%x %p\n", + __func__, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + switch (rq->protocol) { + case ISDN_P_TE_S0: + case ISDN_P_NT_S0: + if (hc->ctype == HFC_TYPE_E1) { + err = -EINVAL; + break; + } + err = open_dchannel(hc, dch, rq); /* locked there */ + break; + case ISDN_P_TE_E1: + case ISDN_P_NT_E1: + if (hc->ctype != HFC_TYPE_E1) { + err = -EINVAL; + break; + } + err = open_dchannel(hc, dch, rq); /* locked there */ + break; + default: + spin_lock_irqsave(&hc->lock, flags); + err = open_bchannel(hc, dch, rq); + spin_unlock_irqrestore(&hc->lock, flags); + } + break; + case CLOSE_CHANNEL: + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG "%s: dev(%d) close from %p\n", + __func__, dch->dev.id, + __builtin_return_address(0)); + module_put(THIS_MODULE); + break; + case CONTROL_CHANNEL: + spin_lock_irqsave(&hc->lock, flags); + err = channel_dctrl(dch, arg); + spin_unlock_irqrestore(&hc->lock, flags); + break; + default: + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: unknown command %x\n", + __func__, cmd); + err = -EINVAL; + } + return err; +} + +static int +clockctl(void *priv, int enable) +{ + struct hfc_multi *hc = priv; + + hc->iclock_on = enable; + return 0; +} + +/* + * initialize the card + */ + +/* + * start timer irq, wait some time and check if we have interrupts. + * if not, reset chip and try again. + */ +static int +init_card(struct hfc_multi *hc) +{ + int err = -EIO; + u_long flags; + void __iomem *plx_acc; + u_long plx_flags; + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: entered\n", __func__); + + spin_lock_irqsave(&hc->lock, flags); + /* set interrupts but leave global interrupt disabled */ + hc->hw.r_irq_ctrl = V_FIFO_IRQ; + disable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + + if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED, + "HFC-multi", hc)) { + printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", + hc->irq); + hc->irq = 0; + return -EIO; + } + + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc = hc->plx_membase + PLX_INTCSR; + writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE), + plx_acc); /* enable PCI & LINT1 irq */ + spin_unlock_irqrestore(&plx_lock, plx_flags); + } + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: IRQ %d count %d\n", + __func__, hc->irq, hc->irqcnt); + err = init_chip(hc); + if (err) + goto error; + /* + * Finally enable IRQ output + * this is only allowed, if an IRQ routine is already + * established for this HFC, so don't do that earlier + */ + spin_lock_irqsave(&hc->lock, flags); + enable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + /* printk(KERN_DEBUG "no master irq set!!!\n"); */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((100 * HZ) / 1000); /* Timeout 100ms */ + /* turn IRQ off until chip is completely initialized */ + spin_lock_irqsave(&hc->lock, flags); + disable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: IRQ %d count %d\n", + __func__, hc->irq, hc->irqcnt); + if (hc->irqcnt) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: done\n", __func__); + + return 0; + } + if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { + printk(KERN_INFO "ignoring missing interrupts\n"); + return 0; + } + + printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n", + hc->irq); + + err = -EIO; + +error: + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + spin_lock_irqsave(&plx_lock, plx_flags); + plx_acc = hc->plx_membase + PLX_INTCSR; + writew(0x00, plx_acc); /*disable IRQs*/ + spin_unlock_irqrestore(&plx_lock, plx_flags); + } + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq); + if (hc->irq) { + free_irq(hc->irq, hc); + hc->irq = 0; + } + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: done (err=%d)\n", __func__, err); + return err; +} + +/* + * find pci device and set it up + */ + +static int +setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct hm_map *m = (struct hm_map *)ent->driver_data; + + printk(KERN_INFO + "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n", + m->vendor_name, m->card_name, m->clock2 ? "double" : "normal"); + + hc->pci_dev = pdev; + if (m->clock2) + test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip); + + if (ent->device == 0xB410) { + test_and_set_bit(HFC_CHIP_B410P, &hc->chip); + test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip); + test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); + hc->slots = 32; + } + + if (hc->pci_dev->irq <= 0) { + printk(KERN_WARNING "HFC-multi: No IRQ for PCI card found.\n"); + return -EIO; + } + if (pci_enable_device(hc->pci_dev)) { + printk(KERN_WARNING "HFC-multi: Error enabling PCI card.\n"); + return -EIO; + } + hc->leds = m->leds; + hc->ledstate = 0xAFFEAFFE; + hc->opticalsupport = m->opticalsupport; + + hc->pci_iobase = 0; + hc->pci_membase = NULL; + hc->plx_membase = NULL; + + /* set memory access methods */ + if (m->io_mode) /* use mode from card config */ + hc->io_mode = m->io_mode; + switch (hc->io_mode) { + case HFC_IO_MODE_PLXSD: + test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip); + hc->slots = 128; /* required */ + hc->HFC_outb = HFC_outb_pcimem; + hc->HFC_inb = HFC_inb_pcimem; + hc->HFC_inw = HFC_inw_pcimem; + hc->HFC_wait = HFC_wait_pcimem; + hc->read_fifo = read_fifo_pcimem; + hc->write_fifo = write_fifo_pcimem; + hc->plx_origmembase = hc->pci_dev->resource[0].start; + /* MEMBASE 1 is PLX PCI Bridge */ + + if (!hc->plx_origmembase) { + printk(KERN_WARNING + "HFC-multi: No IO-Memory for PCI PLX bridge found\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + + hc->plx_membase = ioremap(hc->plx_origmembase, 0x80); + if (!hc->plx_membase) { + printk(KERN_WARNING + "HFC-multi: failed to remap plx address space. " + "(internal error)\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + printk(KERN_INFO + "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n", + (u_long)hc->plx_membase, hc->plx_origmembase); + + hc->pci_origmembase = hc->pci_dev->resource[2].start; + /* MEMBASE 1 is PLX PCI Bridge */ + if (!hc->pci_origmembase) { + printk(KERN_WARNING + "HFC-multi: No IO-Memory for PCI card found\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + + hc->pci_membase = ioremap(hc->pci_origmembase, 0x400); + if (!hc->pci_membase) { + printk(KERN_WARNING "HFC-multi: failed to remap io " + "address space. (internal error)\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + + printk(KERN_INFO + "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d " + "leds-type %d\n", + hc->id, (u_long)hc->pci_membase, hc->pci_origmembase, + hc->pci_dev->irq, HZ, hc->leds); + pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); + break; + case HFC_IO_MODE_PCIMEM: + hc->HFC_outb = HFC_outb_pcimem; + hc->HFC_inb = HFC_inb_pcimem; + hc->HFC_inw = HFC_inw_pcimem; + hc->HFC_wait = HFC_wait_pcimem; + hc->read_fifo = read_fifo_pcimem; + hc->write_fifo = write_fifo_pcimem; + hc->pci_origmembase = hc->pci_dev->resource[1].start; + if (!hc->pci_origmembase) { + printk(KERN_WARNING + "HFC-multi: No IO-Memory for PCI card found\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + + hc->pci_membase = ioremap(hc->pci_origmembase, 256); + if (!hc->pci_membase) { + printk(KERN_WARNING + "HFC-multi: failed to remap io address space. " + "(internal error)\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ " + "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase, + hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); + pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); + break; + case HFC_IO_MODE_REGIO: + hc->HFC_outb = HFC_outb_regio; + hc->HFC_inb = HFC_inb_regio; + hc->HFC_inw = HFC_inw_regio; + hc->HFC_wait = HFC_wait_regio; + hc->read_fifo = read_fifo_regio; + hc->write_fifo = write_fifo_regio; + hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start; + if (!hc->pci_iobase) { + printk(KERN_WARNING + "HFC-multi: No IO for PCI card found\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + + if (!request_region(hc->pci_iobase, 8, "hfcmulti")) { + printk(KERN_WARNING "HFC-multi: failed to request " + "address space at 0x%08lx (internal error)\n", + hc->pci_iobase); + pci_disable_device(hc->pci_dev); + return -EIO; + } + + printk(KERN_INFO + "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n", + m->vendor_name, m->card_name, (u_int) hc->pci_iobase, + hc->pci_dev->irq, HZ, hc->leds); + pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO); + break; + default: + printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); + pci_disable_device(hc->pci_dev); + return -EIO; + } + + pci_set_drvdata(hc->pci_dev, hc); + + /* At this point the needed PCI config is done */ + /* fifos are still not enabled */ + return 0; +} + + +/* + * remove port + */ + +static void +release_port(struct hfc_multi *hc, struct dchannel *dch) +{ + int pt, ci, i = 0; + u_long flags; + struct bchannel *pb; + + ci = dch->slot; + pt = hc->chan[ci].port; + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: entered for port %d\n", + __func__, pt + 1); + + if (pt >= hc->ports) { + printk(KERN_WARNING "%s: ERROR port out of range (%d).\n", + __func__, pt + 1); + return; + } + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: releasing port=%d\n", + __func__, pt + 1); + + if (dch->dev.D.protocol == ISDN_P_TE_S0) + l1_event(dch->l1, CLOSE_CHANNEL); + + hc->chan[ci].dch = NULL; + + if (hc->created[pt]) { + hc->created[pt] = 0; + mISDN_unregister_device(&dch->dev); + } + + spin_lock_irqsave(&hc->lock, flags); + + if (dch->timer.function) { + del_timer(&dch->timer); + dch->timer.function = NULL; + } + + if (hc->ctype == HFC_TYPE_E1) { /* E1 */ + /* remove sync */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + hc->syncronized = 0; + plxsd_checksync(hc, 1); + } + /* free channels */ + for (i = 0; i <= 31; i++) { + if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */ + continue; + if (hc->chan[i].bch) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: free port %d channel %d\n", + __func__, hc->chan[i].port + 1, i); + pb = hc->chan[i].bch; + hc->chan[i].bch = NULL; + spin_unlock_irqrestore(&hc->lock, flags); + mISDN_freebchannel(pb); + kfree(pb); + kfree(hc->chan[i].coeff); + spin_lock_irqsave(&hc->lock, flags); + } + } + } else { + /* remove sync */ + if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { + hc->syncronized &= + ~(1 << hc->chan[ci].port); + plxsd_checksync(hc, 1); + } + /* free channels */ + if (hc->chan[ci - 2].bch) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: free port %d channel %d\n", + __func__, hc->chan[ci - 2].port + 1, + ci - 2); + pb = hc->chan[ci - 2].bch; + hc->chan[ci - 2].bch = NULL; + spin_unlock_irqrestore(&hc->lock, flags); + mISDN_freebchannel(pb); + kfree(pb); + kfree(hc->chan[ci - 2].coeff); + spin_lock_irqsave(&hc->lock, flags); + } + if (hc->chan[ci - 1].bch) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: free port %d channel %d\n", + __func__, hc->chan[ci - 1].port + 1, + ci - 1); + pb = hc->chan[ci - 1].bch; + hc->chan[ci - 1].bch = NULL; + spin_unlock_irqrestore(&hc->lock, flags); + mISDN_freebchannel(pb); + kfree(pb); + kfree(hc->chan[ci - 1].coeff); + spin_lock_irqsave(&hc->lock, flags); + } + } + + spin_unlock_irqrestore(&hc->lock, flags); + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: free port %d channel D(%d)\n", __func__, + pt+1, ci); + mISDN_freedchannel(dch); + kfree(dch); + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: done!\n", __func__); +} + +static void +release_card(struct hfc_multi *hc) +{ + u_long flags; + int ch; + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: release card (%d) entered\n", + __func__, hc->id); + + /* unregister clock source */ + if (hc->iclock) + mISDN_unregister_clock(hc->iclock); + + /* disable and free irq */ + spin_lock_irqsave(&hc->lock, flags); + disable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + udelay(1000); + if (hc->irq) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: free irq %d (hc=%p)\n", + __func__, hc->irq, hc); + free_irq(hc->irq, hc); + hc->irq = 0; + + } + + /* disable D-channels & B-channels */ + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: disable all channels (d and b)\n", + __func__); + for (ch = 0; ch <= 31; ch++) { + if (hc->chan[ch].dch) + release_port(hc, hc->chan[ch].dch); + } + + /* dimm leds */ + if (hc->leds) + hfcmulti_leds(hc); + + /* release hardware */ + release_io_hfcmulti(hc); + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: remove instance from list\n", + __func__); + list_del(&hc->list); + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: delete instance\n", __func__); + if (hc == syncmaster) + syncmaster = NULL; + kfree(hc); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: card successfully removed\n", + __func__); +} + +static void +init_e1_port_hw(struct hfc_multi *hc, struct hm_map *m) +{ + /* set optical line type */ + if (port[Port_cnt] & 0x001) { + if (!m->opticalsupport) { + printk(KERN_INFO + "This board has no optical " + "support\n"); + } else { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: PORT set optical " + "interfacs: card(%d) " + "port(%d)\n", + __func__, + HFC_cnt + 1, 1); + test_and_set_bit(HFC_CFG_OPTICAL, + &hc->chan[hc->dnum[0]].cfg); + } + } + /* set LOS report */ + if (port[Port_cnt] & 0x004) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PORT set " + "LOS report: card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CFG_REPORT_LOS, + &hc->chan[hc->dnum[0]].cfg); + } + /* set AIS report */ + if (port[Port_cnt] & 0x008) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PORT set " + "AIS report: card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CFG_REPORT_AIS, + &hc->chan[hc->dnum[0]].cfg); + } + /* set SLIP report */ + if (port[Port_cnt] & 0x010) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: PORT set SLIP report: " + "card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CFG_REPORT_SLIP, + &hc->chan[hc->dnum[0]].cfg); + } + /* set RDI report */ + if (port[Port_cnt] & 0x020) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: PORT set RDI report: " + "card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CFG_REPORT_RDI, + &hc->chan[hc->dnum[0]].cfg); + } + /* set CRC-4 Mode */ + if (!(port[Port_cnt] & 0x100)) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PORT turn on CRC4 report:" + " card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CFG_CRC4, + &hc->chan[hc->dnum[0]].cfg); + } else { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PORT turn off CRC4" + " report: card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + } + /* set forced clock */ + if (port[Port_cnt] & 0x0200) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PORT force getting clock from " + "E1: card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip); + } else + if (port[Port_cnt] & 0x0400) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PORT force putting clock to " + "E1: card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip); + } + /* set JATT PLL */ + if (port[Port_cnt] & 0x0800) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: PORT disable JATT PLL on " + "E1: card(%d) port(%d)\n", + __func__, HFC_cnt + 1, 1); + test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip); + } + /* set elastic jitter buffer */ + if (port[Port_cnt] & 0x3000) { + hc->chan[hc->dnum[0]].jitter = (port[Port_cnt]>>12) & 0x3; + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: PORT set elastic " + "buffer to %d: card(%d) port(%d)\n", + __func__, hc->chan[hc->dnum[0]].jitter, + HFC_cnt + 1, 1); + } else + hc->chan[hc->dnum[0]].jitter = 2; /* default */ +} + +static int +init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt) +{ + struct dchannel *dch; + struct bchannel *bch; + int ch, ret = 0; + char name[MISDN_MAX_IDLEN]; + int bcount = 0; + + dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); + if (!dch) + return -ENOMEM; + dch->debug = debug; + mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change); + dch->hw = hc; + dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1); + dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + dch->dev.D.send = handle_dmsg; + dch->dev.D.ctrl = hfcm_dctrl; + dch->slot = hc->dnum[pt]; + hc->chan[hc->dnum[pt]].dch = dch; + hc->chan[hc->dnum[pt]].port = pt; + hc->chan[hc->dnum[pt]].nt_timer = -1; + for (ch = 1; ch <= 31; ch++) { + if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */ + continue; + bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); + if (!bch) { + printk(KERN_ERR "%s: no memory for bchannel\n", + __func__); + ret = -ENOMEM; + goto free_chan; + } + hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL); + if (!hc->chan[ch].coeff) { + printk(KERN_ERR "%s: no memory for coeffs\n", + __func__); + ret = -ENOMEM; + kfree(bch); + goto free_chan; + } + bch->nr = ch; + bch->slot = ch; + bch->debug = debug; + mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1); + bch->hw = hc; + bch->ch.send = handle_bmsg; + bch->ch.ctrl = hfcm_bctrl; + bch->ch.nr = ch; + list_add(&bch->ch.list, &dch->dev.bchannels); + hc->chan[ch].bch = bch; + hc->chan[ch].port = pt; + set_channelmap(bch->nr, dch->dev.channelmap); + bcount++; + } + dch->dev.nrbchan = bcount; + if (pt == 0) + init_e1_port_hw(hc, m); + if (hc->ports > 1) + snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d", + HFC_cnt + 1, pt+1); + else + snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1); + ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); + if (ret) + goto free_chan; + hc->created[pt] = 1; + return ret; +free_chan: + release_port(hc, dch); + return ret; +} + +static int +init_multi_port(struct hfc_multi *hc, int pt) +{ + struct dchannel *dch; + struct bchannel *bch; + int ch, i, ret = 0; + char name[MISDN_MAX_IDLEN]; + + dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); + if (!dch) + return -ENOMEM; + dch->debug = debug; + mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change); + dch->hw = hc; + dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0); + dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + dch->dev.D.send = handle_dmsg; + dch->dev.D.ctrl = hfcm_dctrl; + dch->dev.nrbchan = 2; + i = pt << 2; + dch->slot = i + 2; + hc->chan[i + 2].dch = dch; + hc->chan[i + 2].port = pt; + hc->chan[i + 2].nt_timer = -1; + for (ch = 0; ch < dch->dev.nrbchan; ch++) { + bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); + if (!bch) { + printk(KERN_ERR "%s: no memory for bchannel\n", + __func__); + ret = -ENOMEM; + goto free_chan; + } + hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL); + if (!hc->chan[i + ch].coeff) { + printk(KERN_ERR "%s: no memory for coeffs\n", + __func__); + ret = -ENOMEM; + kfree(bch); + goto free_chan; + } + bch->nr = ch + 1; + bch->slot = i + ch; + bch->debug = debug; + mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1); + bch->hw = hc; + bch->ch.send = handle_bmsg; + bch->ch.ctrl = hfcm_bctrl; + bch->ch.nr = ch + 1; + list_add(&bch->ch.list, &dch->dev.bchannels); + hc->chan[i + ch].bch = bch; + hc->chan[i + ch].port = pt; + set_channelmap(bch->nr, dch->dev.channelmap); + } + /* set master clock */ + if (port[Port_cnt] & 0x001) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: PROTOCOL set master clock: " + "card(%d) port(%d)\n", + __func__, HFC_cnt + 1, pt + 1); + if (dch->dev.D.protocol != ISDN_P_TE_S0) { + printk(KERN_ERR "Error: Master clock " + "for port(%d) of card(%d) is only" + " possible with TE-mode\n", + pt + 1, HFC_cnt + 1); + ret = -EINVAL; + goto free_chan; + } + if (hc->masterclk >= 0) { + printk(KERN_ERR "Error: Master clock " + "for port(%d) of card(%d) already " + "defined for port(%d)\n", + pt + 1, HFC_cnt + 1, hc->masterclk + 1); + ret = -EINVAL; + goto free_chan; + } + hc->masterclk = pt; + } + /* set transmitter line to non capacitive */ + if (port[Port_cnt] & 0x002) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: PROTOCOL set non capacitive " + "transmitter: card(%d) port(%d)\n", + __func__, HFC_cnt + 1, pt + 1); + test_and_set_bit(HFC_CFG_NONCAP_TX, + &hc->chan[i + 2].cfg); + } + /* disable E-channel */ + if (port[Port_cnt] & 0x004) { + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: PROTOCOL disable E-channel: " + "card(%d) port(%d)\n", + __func__, HFC_cnt + 1, pt + 1); + test_and_set_bit(HFC_CFG_DIS_ECHANNEL, + &hc->chan[i + 2].cfg); + } + if (hc->ctype == HFC_TYPE_XHFC) { + snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d", + HFC_cnt + 1, pt + 1); + ret = mISDN_register_device(&dch->dev, NULL, name); + } else { + snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d", + hc->ctype, HFC_cnt + 1, pt + 1); + ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); + } + if (ret) + goto free_chan; + hc->created[pt] = 1; + return ret; +free_chan: + release_port(hc, dch); + return ret; +} + +static int +hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret_err = 0; + int pt; + struct hfc_multi *hc; + u_long flags; + u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */ + int i, ch; + u_int maskcheck; + + if (HFC_cnt >= MAX_CARDS) { + printk(KERN_ERR "too many cards (max=%d).\n", + MAX_CARDS); + return -EINVAL; + } + if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) { + printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but " + "type[%d] %d was supplied as module parameter\n", + m->vendor_name, m->card_name, m->type, HFC_cnt, + type[HFC_cnt] & 0xff); + printk(KERN_WARNING "HFC-MULTI: Load module without parameters " + "first, to see cards and their types."); + return -EINVAL; + } + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n", + __func__, m->vendor_name, m->card_name, m->type, + type[HFC_cnt]); + + /* allocate card+fifo structure */ + hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL); + if (!hc) { + printk(KERN_ERR "No kmem for HFC-Multi card\n"); + return -ENOMEM; + } + spin_lock_init(&hc->lock); + hc->mtyp = m; + hc->ctype = m->type; + hc->ports = m->ports; + hc->id = HFC_cnt; + hc->pcm = pcm[HFC_cnt]; + hc->io_mode = iomode[HFC_cnt]; + if (hc->ctype == HFC_TYPE_E1 && dmask[E1_cnt]) { + /* fragment card */ + pt = 0; + maskcheck = 0; + for (ch = 0; ch <= 31; ch++) { + if (!((1 << ch) & dmask[E1_cnt])) + continue; + hc->dnum[pt] = ch; + hc->bmask[pt] = bmask[bmask_cnt++]; + if ((maskcheck & hc->bmask[pt]) + || (dmask[E1_cnt] & hc->bmask[pt])) { + printk(KERN_INFO + "HFC-E1 #%d has overlapping B-channels on fragment #%d\n", + E1_cnt + 1, pt); + kfree(hc); + return -EINVAL; + } + maskcheck |= hc->bmask[pt]; + printk(KERN_INFO + "HFC-E1 #%d uses D-channel on slot %d and a B-channel map of 0x%08x\n", + E1_cnt + 1, ch, hc->bmask[pt]); + pt++; + } + hc->ports = pt; + } + if (hc->ctype == HFC_TYPE_E1 && !dmask[E1_cnt]) { + /* default card layout */ + hc->dnum[0] = 16; + hc->bmask[0] = 0xfffefffe; + hc->ports = 1; + } + + /* set chip specific features */ + hc->masterclk = -1; + if (type[HFC_cnt] & 0x100) { + test_and_set_bit(HFC_CHIP_ULAW, &hc->chip); + hc->silence = 0xff; /* ulaw silence */ + } else + hc->silence = 0x2a; /* alaw silence */ + if ((poll >> 1) > sizeof(hc->silence_data)) { + printk(KERN_ERR "HFCMULTI error: silence_data too small, " + "please fix\n"); + kfree(hc); + return -EINVAL; + } + for (i = 0; i < (poll >> 1); i++) + hc->silence_data[i] = hc->silence; + + if (hc->ctype != HFC_TYPE_XHFC) { + if (!(type[HFC_cnt] & 0x200)) + test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); + test_and_set_bit(HFC_CHIP_CONF, &hc->chip); + } + + if (type[HFC_cnt] & 0x800) + test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); + if (type[HFC_cnt] & 0x1000) { + test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip); + test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); + } + if (type[HFC_cnt] & 0x4000) + test_and_set_bit(HFC_CHIP_EXRAM_128, &hc->chip); + if (type[HFC_cnt] & 0x8000) + test_and_set_bit(HFC_CHIP_EXRAM_512, &hc->chip); + hc->slots = 32; + if (type[HFC_cnt] & 0x10000) + hc->slots = 64; + if (type[HFC_cnt] & 0x20000) + hc->slots = 128; + if (type[HFC_cnt] & 0x80000) { + test_and_set_bit(HFC_CHIP_WATCHDOG, &hc->chip); + hc->wdcount = 0; + hc->wdbyte = V_GPIO_OUT2; + printk(KERN_NOTICE "Watchdog enabled\n"); + } + + if (pdev && ent) + /* setup pci, hc->slots may change due to PLXSD */ + ret_err = setup_pci(hc, pdev, ent); + else +#ifdef CONFIG_MISDN_HFCMULTI_8xx + ret_err = setup_embedded(hc, m); +#else + { + printk(KERN_WARNING "Embedded IO Mode not selected\n"); + ret_err = -EIO; + } +#endif + if (ret_err) { + if (hc == syncmaster) + syncmaster = NULL; + kfree(hc); + return ret_err; + } + + hc->HFC_outb_nodebug = hc->HFC_outb; + hc->HFC_inb_nodebug = hc->HFC_inb; + hc->HFC_inw_nodebug = hc->HFC_inw; + hc->HFC_wait_nodebug = hc->HFC_wait; +#ifdef HFC_REGISTER_DEBUG + hc->HFC_outb = HFC_outb_debug; + hc->HFC_inb = HFC_inb_debug; + hc->HFC_inw = HFC_inw_debug; + hc->HFC_wait = HFC_wait_debug; +#endif + /* create channels */ + for (pt = 0; pt < hc->ports; pt++) { + if (Port_cnt >= MAX_PORTS) { + printk(KERN_ERR "too many ports (max=%d).\n", + MAX_PORTS); + ret_err = -EINVAL; + goto free_card; + } + if (hc->ctype == HFC_TYPE_E1) + ret_err = init_e1_port(hc, m, pt); + else + ret_err = init_multi_port(hc, pt); + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG + "%s: Registering D-channel, card(%d) port(%d) " + "result %d\n", + __func__, HFC_cnt + 1, pt + 1, ret_err); + + if (ret_err) { + while (pt) { /* release already registered ports */ + pt--; + if (hc->ctype == HFC_TYPE_E1) + release_port(hc, + hc->chan[hc->dnum[pt]].dch); + else + release_port(hc, + hc->chan[(pt << 2) + 2].dch); + } + goto free_card; + } + if (hc->ctype != HFC_TYPE_E1) + Port_cnt++; /* for each S0 port */ + } + if (hc->ctype == HFC_TYPE_E1) { + Port_cnt++; /* for each E1 port */ + E1_cnt++; + } + + /* disp switches */ + switch (m->dip_type) { + case DIP_4S: + /* + * Get DIP setting for beroNet 1S/2S/4S cards + * DIP Setting: (collect GPIO 13/14/15 (R_GPIO_IN1) + + * GPI 19/23 (R_GPI_IN2)) + */ + dips = ((~HFC_inb(hc, R_GPIO_IN1) & 0xE0) >> 5) | + ((~HFC_inb(hc, R_GPI_IN2) & 0x80) >> 3) | + (~HFC_inb(hc, R_GPI_IN2) & 0x08); + + /* Port mode (TE/NT) jumpers */ + pmj = ((HFC_inb(hc, R_GPI_IN3) >> 4) & 0xf); + + if (test_bit(HFC_CHIP_B410P, &hc->chip)) + pmj = ~pmj & 0xf; + + printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n", + m->vendor_name, m->card_name, dips, pmj); + break; + case DIP_8S: + /* + * Get DIP Setting for beroNet 8S0+ cards + * Enable PCI auxbridge function + */ + HFC_outb(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK); + /* prepare access to auxport */ + outw(0x4000, hc->pci_iobase + 4); + /* + * some dummy reads are required to + * read valid DIP switch data + */ + dips = inb(hc->pci_iobase); + dips = inb(hc->pci_iobase); + dips = inb(hc->pci_iobase); + dips = ~inb(hc->pci_iobase) & 0x3F; + outw(0x0, hc->pci_iobase + 4); + /* disable PCI auxbridge function */ + HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); + printk(KERN_INFO "%s: %s DIPs(0x%x)\n", + m->vendor_name, m->card_name, dips); + break; + case DIP_E1: + /* + * get DIP Setting for beroNet E1 cards + * DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0) + */ + dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0) >> 4; + printk(KERN_INFO "%s: %s DIPs(0x%x)\n", + m->vendor_name, m->card_name, dips); + break; + } + + /* add to list */ + spin_lock_irqsave(&HFClock, flags); + list_add_tail(&hc->list, &HFClist); + spin_unlock_irqrestore(&HFClock, flags); + + /* use as clock source */ + if (clock == HFC_cnt + 1) + hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc); + + /* initialize hardware */ + hc->irq = (m->irq) ? : hc->pci_dev->irq; + ret_err = init_card(hc); + if (ret_err) { + printk(KERN_ERR "init card returns %d\n", ret_err); + release_card(hc); + return ret_err; + } + + /* start IRQ and return */ + spin_lock_irqsave(&hc->lock, flags); + enable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + return 0; + +free_card: + release_io_hfcmulti(hc); + if (hc == syncmaster) + syncmaster = NULL; + kfree(hc); + return ret_err; +} + +static void hfc_remove_pci(struct pci_dev *pdev) +{ + struct hfc_multi *card = pci_get_drvdata(pdev); + u_long flags; + + if (debug) + printk(KERN_INFO "removing hfc_multi card vendor:%x " + "device:%x subvendor:%x subdevice:%x\n", + pdev->vendor, pdev->device, + pdev->subsystem_vendor, pdev->subsystem_device); + + if (card) { + spin_lock_irqsave(&HFClock, flags); + release_card(card); + spin_unlock_irqrestore(&HFClock, flags); + } else { + if (debug) + printk(KERN_DEBUG "%s: drvdata already removed\n", + __func__); + } +} + +#define VENDOR_CCD "Cologne Chip AG" +#define VENDOR_BN "beroNet GmbH" +#define VENDOR_DIG "Digium Inc." +#define VENDOR_JH "Junghanns.NET GmbH" +#define VENDOR_PRIM "PrimuX" + +static const struct hm_map hfcm_map[] = { + /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0}, + /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, + /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, + /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, + /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0}, + /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0}, + /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, + /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0}, + /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0}, + /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0}, + /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0}, + /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0}, + + /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0}, + /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S, + HFC_IO_MODE_REGIO, 0}, + /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0}, + /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0}, + + /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0}, + /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0}, + /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0}, + + /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, + /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0}, + /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, + /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, + + /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0}, + /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0}, + /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0}, + + /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0, + HFC_IO_MODE_PLXSD, 0}, + /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0, + HFC_IO_MODE_PLXSD, 0}, + /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0}, + /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0}, + /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0}, + /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0, + HFC_IO_MODE_EMBSD, XHFC_IRQ}, + /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0}, + /*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, + /*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, +}; + +#undef H +#define H(x) ((unsigned long)&hfcm_map[x]) +static struct pci_device_id hfmultipci_ids[] = { + + /* Cards with HFC-4S Chip */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */ + { PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, + PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)}, + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)}, + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + 0xb761, 0, 0, H(33)}, /* BN2S PCIe */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + 0xb762, 0, 0, H(34)}, /* BN4S PCIe */ + + /* Cards with HFC-8S Chip */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S */ + + + /* Cards with HFC-E1 Chip */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */ + + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */ + + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */ + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */ + + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, + PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */ + + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC4S), 0 }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC8S), 0 }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFCE1), 0 }, + {0, } +}; +#undef H + +MODULE_DEVICE_TABLE(pci, hfmultipci_ids); + +static int +hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct hm_map *m = (struct hm_map *)ent->driver_data; + int ret; + + if (m == NULL && ent->vendor == PCI_VENDOR_ID_CCD && ( + ent->device == PCI_DEVICE_ID_CCD_HFC4S || + ent->device == PCI_DEVICE_ID_CCD_HFC8S || + ent->device == PCI_DEVICE_ID_CCD_HFCE1)) { + printk(KERN_ERR + "Unknown HFC multiport controller (vendor:%04x device:%04x " + "subvendor:%04x subdevice:%04x)\n", pdev->vendor, + pdev->device, pdev->subsystem_vendor, + pdev->subsystem_device); + printk(KERN_ERR + "Please contact the driver maintainer for support.\n"); + return -ENODEV; + } + ret = hfcmulti_init(m, pdev, ent); + if (ret) + return ret; + HFC_cnt++; + printk(KERN_INFO "%d devices registered\n", HFC_cnt); + return 0; +} + +static struct pci_driver hfcmultipci_driver = { + .name = "hfc_multi", + .probe = hfcmulti_probe, + .remove = hfc_remove_pci, + .id_table = hfmultipci_ids, +}; + +static void __exit +HFCmulti_cleanup(void) +{ + struct hfc_multi *card, *next; + + /* get rid of all devices of this driver */ + list_for_each_entry_safe(card, next, &HFClist, list) + release_card(card); + pci_unregister_driver(&hfcmultipci_driver); +} + +static int __init +HFCmulti_init(void) +{ + int err; + int i, xhfc = 0; + struct hm_map m; + + printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION); + +#ifdef IRQ_DEBUG + printk(KERN_DEBUG "%s: IRQ_DEBUG IS ENABLED!\n", __func__); +#endif + + spin_lock_init(&HFClock); + spin_lock_init(&plx_lock); + + if (debug & DEBUG_HFCMULTI_INIT) + printk(KERN_DEBUG "%s: init entered\n", __func__); + + switch (poll) { + case 0: + poll_timer = 6; + poll = 128; + break; + case 8: + poll_timer = 2; + break; + case 16: + poll_timer = 3; + break; + case 32: + poll_timer = 4; + break; + case 64: + poll_timer = 5; + break; + case 128: + poll_timer = 6; + break; + case 256: + poll_timer = 7; + break; + default: + printk(KERN_ERR + "%s: Wrong poll value (%d).\n", __func__, poll); + err = -EINVAL; + return err; + + } + + if (!clock) + clock = 1; + + /* Register the embedded devices. + * This should be done before the PCI cards registration */ + switch (hwid) { + case HWID_MINIP4: + xhfc = 1; + m = hfcm_map[31]; + break; + case HWID_MINIP8: + xhfc = 2; + m = hfcm_map[31]; + break; + case HWID_MINIP16: + xhfc = 4; + m = hfcm_map[31]; + break; + default: + xhfc = 0; + } + + for (i = 0; i < xhfc; ++i) { + err = hfcmulti_init(&m, NULL, NULL); + if (err) { + printk(KERN_ERR "error registering embedded driver: " + "%x\n", err); + return err; + } + HFC_cnt++; + printk(KERN_INFO "%d devices registered\n", HFC_cnt); + } + + /* Register the PCI cards */ + err = pci_register_driver(&hfcmultipci_driver); + if (err < 0) { + printk(KERN_ERR "error registering pci driver: %x\n", err); + return err; + } + + return 0; +} + + +module_init(HFCmulti_init); +module_exit(HFCmulti_cleanup); diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c new file mode 100644 index 00000000000..3c92780bda0 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -0,0 +1,2363 @@ +/* + * + * hfcpci.c low level driver for CCD's hfc-pci based cards + * + * Author Werner Cornelius (werner@isdn4linux.de) + * based on existing driver for CCD hfc ISA cards + * type approval valid for HFC-S PCI A based card + * + * Copyright 1999 by Werner Cornelius (werner@isdn-development.de) + * Copyright 2008 by Karsten Keil <kkeil@novell.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Module options: + * + * debug: + * NOTE: only one poll value must be given for all cards + * See hfc_pci.h for debug flags. + * + * poll: + * NOTE: only one poll value must be given for all cards + * Give the number of samples for each fifo process. + * By default 128 is used. Decrease to reduce delay, increase to + * reduce cpu load. If unsure, don't mess with it! + * A value of 128 will use controller's interrupt. Other values will + * use kernel timer, because the controller will not allow lower values + * than 128. + * Also note that the value depends on the kernel timer frequency. + * If kernel uses a frequency of 1000 Hz, steps of 8 samples are possible. + * If the kernel uses 100 Hz, steps of 80 samples are possible. + * If the kernel uses 300 Hz, steps of about 26 samples are possible. + * + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/mISDNhw.h> +#include <linux/slab.h> + +#include "hfc_pci.h" + +static const char *hfcpci_revision = "2.0"; + +static int HFC_cnt; +static uint debug; +static uint poll, tics; +static struct timer_list hfc_tl; +static unsigned long hfc_jiffies; + +MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL"); +module_param(debug, uint, S_IRUGO | S_IWUSR); +module_param(poll, uint, S_IRUGO | S_IWUSR); + +enum { + HFC_CCD_2BD0, + HFC_CCD_B000, + HFC_CCD_B006, + HFC_CCD_B007, + HFC_CCD_B008, + HFC_CCD_B009, + HFC_CCD_B00A, + HFC_CCD_B00B, + HFC_CCD_B00C, + HFC_CCD_B100, + HFC_CCD_B700, + HFC_CCD_B701, + HFC_ASUS_0675, + HFC_BERKOM_A1T, + HFC_BERKOM_TCONCEPT, + HFC_ANIGMA_MC145575, + HFC_ZOLTRIX_2BD0, + HFC_DIGI_DF_M_IOM2_E, + HFC_DIGI_DF_M_E, + HFC_DIGI_DF_M_IOM2_A, + HFC_DIGI_DF_M_A, + HFC_ABOCOM_2BD1, + HFC_SITECOM_DC105V2, +}; + +struct hfcPCI_hw { + unsigned char cirm; + unsigned char ctmt; + unsigned char clkdel; + unsigned char states; + unsigned char conn; + unsigned char mst_m; + unsigned char int_m1; + unsigned char int_m2; + unsigned char sctrl; + unsigned char sctrl_r; + unsigned char sctrl_e; + unsigned char trm; + unsigned char fifo_en; + unsigned char bswapped; + unsigned char protocol; + int nt_timer; + unsigned char __iomem *pci_io; /* start of PCI IO memory */ + dma_addr_t dmahandle; + void *fifos; /* FIFO memory */ + int last_bfifo_cnt[2]; + /* marker saving last b-fifo frame count */ + struct timer_list timer; +}; + +#define HFC_CFG_MASTER 1 +#define HFC_CFG_SLAVE 2 +#define HFC_CFG_PCM 3 +#define HFC_CFG_2HFC 4 +#define HFC_CFG_SLAVEHFC 5 +#define HFC_CFG_NEG_F0 6 +#define HFC_CFG_SW_DD_DU 7 + +#define FLG_HFC_TIMER_T1 16 +#define FLG_HFC_TIMER_T3 17 + +#define NT_T1_COUNT 1120 /* number of 3.125ms interrupts (3.5s) */ +#define NT_T3_COUNT 31 /* number of 3.125ms interrupts (97 ms) */ +#define CLKDEL_TE 0x0e /* CLKDEL in TE mode */ +#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */ + + +struct hfc_pci { + u_char subtype; + u_char chanlimit; + u_char initdone; + u_long cfg; + u_int irq; + u_int irqcnt; + struct pci_dev *pdev; + struct hfcPCI_hw hw; + spinlock_t lock; /* card lock */ + struct dchannel dch; + struct bchannel bch[2]; +}; + +/* Interface functions */ +static void +enable_hwirq(struct hfc_pci *hc) +{ + hc->hw.int_m2 |= HFCPCI_IRQ_ENABLE; + Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2); +} + +static void +disable_hwirq(struct hfc_pci *hc) +{ + hc->hw.int_m2 &= ~((u_char)HFCPCI_IRQ_ENABLE); + Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2); +} + +/* + * free hardware resources used by driver + */ +static void +release_io_hfcpci(struct hfc_pci *hc) +{ + /* disable memory mapped ports + busmaster */ + pci_write_config_word(hc->pdev, PCI_COMMAND, 0); + del_timer(&hc->hw.timer); + pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos, hc->hw.dmahandle); + iounmap(hc->hw.pci_io); +} + +/* + * set mode (NT or TE) + */ +static void +hfcpci_setmode(struct hfc_pci *hc) +{ + if (hc->hw.protocol == ISDN_P_NT_S0) { + hc->hw.clkdel = CLKDEL_NT; /* ST-Bit delay for NT-Mode */ + hc->hw.sctrl |= SCTRL_MODE_NT; /* NT-MODE */ + hc->hw.states = 1; /* G1 */ + } else { + hc->hw.clkdel = CLKDEL_TE; /* ST-Bit delay for TE-Mode */ + hc->hw.sctrl &= ~SCTRL_MODE_NT; /* TE-MODE */ + hc->hw.states = 2; /* F2 */ + } + Write_hfc(hc, HFCPCI_CLKDEL, hc->hw.clkdel); + Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | hc->hw.states); + udelay(10); + Write_hfc(hc, HFCPCI_STATES, hc->hw.states | 0x40); /* Deactivate */ + Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl); +} + +/* + * function called to reset the HFC PCI chip. A complete software reset of chip + * and fifos is done. + */ +static void +reset_hfcpci(struct hfc_pci *hc) +{ + u_char val; + int cnt = 0; + + printk(KERN_DEBUG "reset_hfcpci: entered\n"); + val = Read_hfc(hc, HFCPCI_CHIP_ID); + printk(KERN_INFO "HFC_PCI: resetting HFC ChipId(%x)\n", val); + /* enable memory mapped ports, disable busmaster */ + pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO); + disable_hwirq(hc); + /* enable memory ports + busmaster */ + pci_write_config_word(hc->pdev, PCI_COMMAND, + PCI_ENA_MEMIO + PCI_ENA_MASTER); + val = Read_hfc(hc, HFCPCI_STATUS); + printk(KERN_DEBUG "HFC-PCI status(%x) before reset\n", val); + hc->hw.cirm = HFCPCI_RESET; /* Reset On */ + Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); + set_current_state(TASK_UNINTERRUPTIBLE); + mdelay(10); /* Timeout 10ms */ + hc->hw.cirm = 0; /* Reset Off */ + Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); + val = Read_hfc(hc, HFCPCI_STATUS); + printk(KERN_DEBUG "HFC-PCI status(%x) after reset\n", val); + while (cnt < 50000) { /* max 50000 us */ + udelay(5); + cnt += 5; + val = Read_hfc(hc, HFCPCI_STATUS); + if (!(val & 2)) + break; + } + printk(KERN_DEBUG "HFC-PCI status(%x) after %dus\n", val, cnt); + + hc->hw.fifo_en = 0x30; /* only D fifos enabled */ + + hc->hw.bswapped = 0; /* no exchange */ + hc->hw.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER; + hc->hw.trm = HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */ + hc->hw.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */ + hc->hw.sctrl_r = 0; + hc->hw.sctrl_e = HFCPCI_AUTO_AWAKE; /* S/T Auto awake */ + hc->hw.mst_m = 0; + if (test_bit(HFC_CFG_MASTER, &hc->cfg)) + hc->hw.mst_m |= HFCPCI_MASTER; /* HFC Master Mode */ + if (test_bit(HFC_CFG_NEG_F0, &hc->cfg)) + hc->hw.mst_m |= HFCPCI_F0_NEGATIV; + Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); + Write_hfc(hc, HFCPCI_TRM, hc->hw.trm); + Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e); + Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt); + + hc->hw.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC | + HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + + /* Clear already pending ints */ + val = Read_hfc(hc, HFCPCI_INT_S1); + + /* set NT/TE mode */ + hfcpci_setmode(hc); + + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r); + + /* + * Init GCI/IOM2 in master mode + * Slots 0 and 1 are set for B-chan 1 and 2 + * D- and monitor/CI channel are not enabled + * STIO1 is used as output for data, B1+B2 from ST->IOM+HFC + * STIO2 is used as data input, B1+B2 from IOM->ST + * ST B-channel send disabled -> continuous 1s + * The IOM slots are always enabled + */ + if (test_bit(HFC_CFG_PCM, &hc->cfg)) { + /* set data flow directions: connect B1,B2: HFC to/from PCM */ + hc->hw.conn = 0x09; + } else { + hc->hw.conn = 0x36; /* set data flow directions */ + if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) { + Write_hfc(hc, HFCPCI_B1_SSL, 0xC0); + Write_hfc(hc, HFCPCI_B2_SSL, 0xC1); + Write_hfc(hc, HFCPCI_B1_RSL, 0xC0); + Write_hfc(hc, HFCPCI_B2_RSL, 0xC1); + } else { + Write_hfc(hc, HFCPCI_B1_SSL, 0x80); + Write_hfc(hc, HFCPCI_B2_SSL, 0x81); + Write_hfc(hc, HFCPCI_B1_RSL, 0x80); + Write_hfc(hc, HFCPCI_B2_RSL, 0x81); + } + } + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); + val = Read_hfc(hc, HFCPCI_INT_S2); +} + +/* + * Timer function called when kernel timer expires + */ +static void +hfcpci_Timer(struct hfc_pci *hc) +{ + hc->hw.timer.expires = jiffies + 75; + /* WD RESET */ +/* + * WriteReg(hc, HFCD_DATA, HFCD_CTMT, hc->hw.ctmt | 0x80); + * add_timer(&hc->hw.timer); + */ +} + + +/* + * select a b-channel entry matching and active + */ +static struct bchannel * +Sel_BCS(struct hfc_pci *hc, int channel) +{ + if (test_bit(FLG_ACTIVE, &hc->bch[0].Flags) && + (hc->bch[0].nr & channel)) + return &hc->bch[0]; + else if (test_bit(FLG_ACTIVE, &hc->bch[1].Flags) && + (hc->bch[1].nr & channel)) + return &hc->bch[1]; + else + return NULL; +} + +/* + * clear the desired B-channel rx fifo + */ +static void +hfcpci_clear_fifo_rx(struct hfc_pci *hc, int fifo) +{ + u_char fifo_state; + struct bzfifo *bzr; + + if (fifo) { + bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; + fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2RX; + } else { + bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1; + fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1RX; + } + if (fifo_state) + hc->hw.fifo_en ^= fifo_state; + Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); + hc->hw.last_bfifo_cnt[fifo] = 0; + bzr->f1 = MAX_B_FRAMES; + bzr->f2 = bzr->f1; /* init F pointers to remain constant */ + bzr->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1); + bzr->za[MAX_B_FRAMES].z2 = cpu_to_le16( + le16_to_cpu(bzr->za[MAX_B_FRAMES].z1)); + if (fifo_state) + hc->hw.fifo_en |= fifo_state; + Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); +} + +/* + * clear the desired B-channel tx fifo + */ +static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo) +{ + u_char fifo_state; + struct bzfifo *bzt; + + if (fifo) { + bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; + fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2TX; + } else { + bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1; + fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1TX; + } + if (fifo_state) + hc->hw.fifo_en ^= fifo_state; + Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); + if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) " + "z1(%x) z2(%x) state(%x)\n", + fifo, bzt->f1, bzt->f2, + le16_to_cpu(bzt->za[MAX_B_FRAMES].z1), + le16_to_cpu(bzt->za[MAX_B_FRAMES].z2), + fifo_state); + bzt->f2 = MAX_B_FRAMES; + bzt->f1 = bzt->f2; /* init F pointers to remain constant */ + bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1); + bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 2); + if (fifo_state) + hc->hw.fifo_en |= fifo_state; + Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); + if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG + "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) z1(%x) z2(%x)\n", + fifo, bzt->f1, bzt->f2, + le16_to_cpu(bzt->za[MAX_B_FRAMES].z1), + le16_to_cpu(bzt->za[MAX_B_FRAMES].z2)); +} + +/* + * read a complete B-frame out of the buffer + */ +static void +hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz, + u_char *bdata, int count) +{ + u_char *ptr, *ptr1, new_f2; + int maxlen, new_z2; + struct zt *zp; + + if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) + printk(KERN_DEBUG "hfcpci_empty_fifo\n"); + zp = &bz->za[bz->f2]; /* point to Z-Regs */ + new_z2 = le16_to_cpu(zp->z2) + count; /* new position in fifo */ + if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z2 -= B_FIFO_SIZE; /* buffer wrap */ + new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; + if ((count > MAX_DATA_SIZE + 3) || (count < 4) || + (*(bdata + (le16_to_cpu(zp->z1) - B_SUB_VAL)))) { + if (bch->debug & DEBUG_HW) + printk(KERN_DEBUG "hfcpci_empty_fifo: incoming packet " + "invalid length %d or crc\n", count); +#ifdef ERROR_STATISTIC + bch->err_inv++; +#endif + bz->za[new_f2].z2 = cpu_to_le16(new_z2); + bz->f2 = new_f2; /* next buffer */ + } else { + bch->rx_skb = mI_alloc_skb(count - 3, GFP_ATOMIC); + if (!bch->rx_skb) { + printk(KERN_WARNING "HFCPCI: receive out of memory\n"); + return; + } + count -= 3; + ptr = skb_put(bch->rx_skb, count); + + if (le16_to_cpu(zp->z2) + count <= B_FIFO_SIZE + B_SUB_VAL) + maxlen = count; /* complete transfer */ + else + maxlen = B_FIFO_SIZE + B_SUB_VAL - + le16_to_cpu(zp->z2); /* maximum */ + + ptr1 = bdata + (le16_to_cpu(zp->z2) - B_SUB_VAL); + /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + count -= maxlen; + + if (count) { /* rest remaining */ + ptr += maxlen; + ptr1 = bdata; /* start of buffer */ + memcpy(ptr, ptr1, count); /* rest */ + } + bz->za[new_f2].z2 = cpu_to_le16(new_z2); + bz->f2 = new_f2; /* next buffer */ + recv_Bchannel(bch, MISDN_ID_ANY, false); + } +} + +/* + * D-channel receive procedure + */ +static int +receive_dmsg(struct hfc_pci *hc) +{ + struct dchannel *dch = &hc->dch; + int maxlen; + int rcnt, total; + int count = 5; + u_char *ptr, *ptr1; + struct dfifo *df; + struct zt *zp; + + df = &((union fifo_area *)(hc->hw.fifos))->d_chan.d_rx; + while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) { + zp = &df->za[df->f2 & D_FREG_MASK]; + rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2); + if (rcnt < 0) + rcnt += D_FIFO_SIZE; + rcnt++; + if (dch->debug & DEBUG_HW_DCHANNEL) + printk(KERN_DEBUG + "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)\n", + df->f1, df->f2, + le16_to_cpu(zp->z1), + le16_to_cpu(zp->z2), + rcnt); + + if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) || + (df->data[le16_to_cpu(zp->z1)])) { + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG + "empty_fifo hfcpci packet inv. len " + "%d or crc %d\n", + rcnt, + df->data[le16_to_cpu(zp->z1)]); +#ifdef ERROR_STATISTIC + cs->err_rx++; +#endif + df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | + (MAX_D_FRAMES + 1); /* next buffer */ + df->za[df->f2 & D_FREG_MASK].z2 = + cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) & + (D_FIFO_SIZE - 1)); + } else { + dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC); + if (!dch->rx_skb) { + printk(KERN_WARNING + "HFC-PCI: D receive out of memory\n"); + break; + } + total = rcnt; + rcnt -= 3; + ptr = skb_put(dch->rx_skb, rcnt); + + if (le16_to_cpu(zp->z2) + rcnt <= D_FIFO_SIZE) + maxlen = rcnt; /* complete transfer */ + else + maxlen = D_FIFO_SIZE - le16_to_cpu(zp->z2); + /* maximum */ + + ptr1 = df->data + le16_to_cpu(zp->z2); + /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + rcnt -= maxlen; + + if (rcnt) { /* rest remaining */ + ptr += maxlen; + ptr1 = df->data; /* start of buffer */ + memcpy(ptr, ptr1, rcnt); /* rest */ + } + df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | + (MAX_D_FRAMES + 1); /* next buffer */ + df->za[df->f2 & D_FREG_MASK].z2 = cpu_to_le16(( + le16_to_cpu(zp->z2) + total) & (D_FIFO_SIZE - 1)); + recv_Dchannel(dch); + } + } + return 1; +} + +/* + * check for transparent receive data and read max one 'poll' size if avail + */ +static void +hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz, + struct bzfifo *txbz, u_char *bdata) +{ + __le16 *z1r, *z2r, *z1t, *z2t; + int new_z2, fcnt_rx, fcnt_tx, maxlen; + u_char *ptr, *ptr1; + + z1r = &rxbz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ + z2r = z1r + 1; + z1t = &txbz->za[MAX_B_FRAMES].z1; + z2t = z1t + 1; + + fcnt_rx = le16_to_cpu(*z1r) - le16_to_cpu(*z2r); + if (!fcnt_rx) + return; /* no data avail */ + + if (fcnt_rx <= 0) + fcnt_rx += B_FIFO_SIZE; /* bytes actually buffered */ + new_z2 = le16_to_cpu(*z2r) + fcnt_rx; /* new position in fifo */ + if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z2 -= B_FIFO_SIZE; /* buffer wrap */ + + fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); + if (fcnt_tx <= 0) + fcnt_tx += B_FIFO_SIZE; + /* fcnt_tx contains available bytes in tx-fifo */ + fcnt_tx = B_FIFO_SIZE - fcnt_tx; + /* remaining bytes to send (bytes in tx-fifo) */ + + if (test_bit(FLG_RX_OFF, &bch->Flags)) { + bch->dropcnt += fcnt_rx; + *z2r = cpu_to_le16(new_z2); + return; + } + maxlen = bchannel_get_rxbuf(bch, fcnt_rx); + if (maxlen < 0) { + pr_warning("B%d: No bufferspace for %d bytes\n", + bch->nr, fcnt_rx); + } else { + ptr = skb_put(bch->rx_skb, fcnt_rx); + if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL) + maxlen = fcnt_rx; /* complete transfer */ + else + maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r); + /* maximum */ + + ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL); + /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + fcnt_rx -= maxlen; + + if (fcnt_rx) { /* rest remaining */ + ptr += maxlen; + ptr1 = bdata; /* start of buffer */ + memcpy(ptr, ptr1, fcnt_rx); /* rest */ + } + recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */ + } + *z2r = cpu_to_le16(new_z2); /* new position */ +} + +/* + * B-channel main receive routine + */ +static void +main_rec_hfcpci(struct bchannel *bch) +{ + struct hfc_pci *hc = bch->hw; + int rcnt, real_fifo; + int receive = 0, count = 5; + struct bzfifo *txbz, *rxbz; + u_char *bdata; + struct zt *zp; + + if ((bch->nr & 2) && (!hc->hw.bswapped)) { + rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; + txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; + bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2; + real_fifo = 1; + } else { + rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1; + txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1; + bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1; + real_fifo = 0; + } +Begin: + count--; + if (rxbz->f1 != rxbz->f2) { + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n", + bch->nr, rxbz->f1, rxbz->f2); + zp = &rxbz->za[rxbz->f2]; + + rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2); + if (rcnt < 0) + rcnt += B_FIFO_SIZE; + rcnt++; + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG + "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n", + bch->nr, le16_to_cpu(zp->z1), + le16_to_cpu(zp->z2), rcnt); + hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt); + rcnt = rxbz->f1 - rxbz->f2; + if (rcnt < 0) + rcnt += MAX_B_FRAMES + 1; + if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) { + rcnt = 0; + hfcpci_clear_fifo_rx(hc, real_fifo); + } + hc->hw.last_bfifo_cnt[real_fifo] = rcnt; + if (rcnt > 1) + receive = 1; + else + receive = 0; + } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { + hfcpci_empty_fifo_trans(bch, rxbz, txbz, bdata); + return; + } else + receive = 0; + if (count && receive) + goto Begin; + +} + +/* + * D-channel send routine + */ +static void +hfcpci_fill_dfifo(struct hfc_pci *hc) +{ + struct dchannel *dch = &hc->dch; + int fcnt; + int count, new_z1, maxlen; + struct dfifo *df; + u_char *src, *dst, new_f1; + + if ((dch->debug & DEBUG_HW_DCHANNEL) && !(dch->debug & DEBUG_HW_DFIFO)) + printk(KERN_DEBUG "%s\n", __func__); + + if (!dch->tx_skb) + return; + count = dch->tx_skb->len - dch->tx_idx; + if (count <= 0) + return; + df = &((union fifo_area *) (hc->hw.fifos))->d_chan.d_tx; + + if (dch->debug & DEBUG_HW_DFIFO) + printk(KERN_DEBUG "%s:f1(%d) f2(%d) z1(f1)(%x)\n", __func__, + df->f1, df->f2, + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1)); + fcnt = df->f1 - df->f2; /* frame count actually buffered */ + if (fcnt < 0) + fcnt += (MAX_D_FRAMES + 1); /* if wrap around */ + if (fcnt > (MAX_D_FRAMES - 1)) { + if (dch->debug & DEBUG_HW_DCHANNEL) + printk(KERN_DEBUG + "hfcpci_fill_Dfifo more as 14 frames\n"); +#ifdef ERROR_STATISTIC + cs->err_tx++; +#endif + return; + } + /* now determine free bytes in FIFO buffer */ + maxlen = le16_to_cpu(df->za[df->f2 & D_FREG_MASK].z2) - + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) - 1; + if (maxlen <= 0) + maxlen += D_FIFO_SIZE; /* count now contains available bytes */ + + if (dch->debug & DEBUG_HW_DCHANNEL) + printk(KERN_DEBUG "hfcpci_fill_Dfifo count(%d/%d)\n", + count, maxlen); + if (count > maxlen) { + if (dch->debug & DEBUG_HW_DCHANNEL) + printk(KERN_DEBUG "hfcpci_fill_Dfifo no fifo mem\n"); + return; + } + new_z1 = (le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) + count) & + (D_FIFO_SIZE - 1); + new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1); + src = dch->tx_skb->data + dch->tx_idx; /* source pointer */ + dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1); + maxlen = D_FIFO_SIZE - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1); + /* end fifo */ + if (maxlen > count) + maxlen = count; /* limit size */ + memcpy(dst, src, maxlen); /* first copy */ + + count -= maxlen; /* remaining bytes */ + if (count) { + dst = df->data; /* start of buffer */ + src += maxlen; /* new position */ + memcpy(dst, src, count); + } + df->za[new_f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1); + /* for next buffer */ + df->za[df->f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1); + /* new pos actual buffer */ + df->f1 = new_f1; /* next frame */ + dch->tx_idx = dch->tx_skb->len; +} + +/* + * B-channel send routine + */ +static void +hfcpci_fill_fifo(struct bchannel *bch) +{ + struct hfc_pci *hc = bch->hw; + int maxlen, fcnt; + int count, new_z1; + struct bzfifo *bz; + u_char *bdata; + u_char new_f1, *src, *dst; + __le16 *z1t, *z2t; + + if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) + printk(KERN_DEBUG "%s\n", __func__); + if ((!bch->tx_skb) || bch->tx_skb->len == 0) { + if (!test_bit(FLG_FILLEMPTY, &bch->Flags) && + !test_bit(FLG_TRANSPARENT, &bch->Flags)) + return; + count = HFCPCI_FILLEMPTY; + } else { + count = bch->tx_skb->len - bch->tx_idx; + } + if ((bch->nr & 2) && (!hc->hw.bswapped)) { + bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; + bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2; + } else { + bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1; + bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b1; + } + + if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { + z1t = &bz->za[MAX_B_FRAMES].z1; + z2t = z1t + 1; + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG "hfcpci_fill_fifo_trans ch(%x) " + "cnt(%d) z1(%x) z2(%x)\n", bch->nr, count, + le16_to_cpu(*z1t), le16_to_cpu(*z2t)); + fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); + if (fcnt <= 0) + fcnt += B_FIFO_SIZE; + if (test_bit(FLG_FILLEMPTY, &bch->Flags)) { + /* fcnt contains available bytes in fifo */ + if (count > fcnt) + count = fcnt; + new_z1 = le16_to_cpu(*z1t) + count; + /* new buffer Position */ + if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z1 -= B_FIFO_SIZE; /* buffer wrap */ + dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL); + maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t); + /* end of fifo */ + if (bch->debug & DEBUG_HW_BFIFO) + printk(KERN_DEBUG "hfcpci_FFt fillempty " + "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n", + fcnt, maxlen, new_z1, dst); + if (maxlen > count) + maxlen = count; /* limit size */ + memset(dst, bch->fill[0], maxlen); /* first copy */ + count -= maxlen; /* remaining bytes */ + if (count) { + dst = bdata; /* start of buffer */ + memset(dst, bch->fill[0], count); + } + *z1t = cpu_to_le16(new_z1); /* now send data */ + return; + } + /* fcnt contains available bytes in fifo */ + fcnt = B_FIFO_SIZE - fcnt; + /* remaining bytes to send (bytes in fifo) */ + + next_t_frame: + count = bch->tx_skb->len - bch->tx_idx; + /* maximum fill shall be poll*2 */ + if (count > (poll << 1) - fcnt) + count = (poll << 1) - fcnt; + if (count <= 0) + return; + /* data is suitable for fifo */ + new_z1 = le16_to_cpu(*z1t) + count; + /* new buffer Position */ + if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z1 -= B_FIFO_SIZE; /* buffer wrap */ + src = bch->tx_skb->data + bch->tx_idx; + /* source pointer */ + dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL); + maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t); + /* end of fifo */ + if (bch->debug & DEBUG_HW_BFIFO) + printk(KERN_DEBUG "hfcpci_FFt fcnt(%d) " + "maxl(%d) nz1(%x) dst(%p)\n", + fcnt, maxlen, new_z1, dst); + fcnt += count; + bch->tx_idx += count; + if (maxlen > count) + maxlen = count; /* limit size */ + memcpy(dst, src, maxlen); /* first copy */ + count -= maxlen; /* remaining bytes */ + if (count) { + dst = bdata; /* start of buffer */ + src += maxlen; /* new position */ + memcpy(dst, src, count); + } + *z1t = cpu_to_le16(new_z1); /* now send data */ + if (bch->tx_idx < bch->tx_skb->len) + return; + dev_kfree_skb(bch->tx_skb); + if (get_next_bframe(bch)) + goto next_t_frame; + return; + } + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG + "%s: ch(%x) f1(%d) f2(%d) z1(f1)(%x)\n", + __func__, bch->nr, bz->f1, bz->f2, + bz->za[bz->f1].z1); + fcnt = bz->f1 - bz->f2; /* frame count actually buffered */ + if (fcnt < 0) + fcnt += (MAX_B_FRAMES + 1); /* if wrap around */ + if (fcnt > (MAX_B_FRAMES - 1)) { + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG + "hfcpci_fill_Bfifo more as 14 frames\n"); + return; + } + /* now determine free bytes in FIFO buffer */ + maxlen = le16_to_cpu(bz->za[bz->f2].z2) - + le16_to_cpu(bz->za[bz->f1].z1) - 1; + if (maxlen <= 0) + maxlen += B_FIFO_SIZE; /* count now contains available bytes */ + + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG "hfcpci_fill_fifo ch(%x) count(%d/%d)\n", + bch->nr, count, maxlen); + + if (maxlen < count) { + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG "hfcpci_fill_fifo no fifo mem\n"); + return; + } + new_z1 = le16_to_cpu(bz->za[bz->f1].z1) + count; + /* new buffer Position */ + if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z1 -= B_FIFO_SIZE; /* buffer wrap */ + + new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES); + src = bch->tx_skb->data + bch->tx_idx; /* source pointer */ + dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL); + maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(bz->za[bz->f1].z1); + /* end fifo */ + if (maxlen > count) + maxlen = count; /* limit size */ + memcpy(dst, src, maxlen); /* first copy */ + + count -= maxlen; /* remaining bytes */ + if (count) { + dst = bdata; /* start of buffer */ + src += maxlen; /* new position */ + memcpy(dst, src, count); + } + bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */ + bz->f1 = new_f1; /* next frame */ + dev_kfree_skb(bch->tx_skb); + get_next_bframe(bch); +} + + + +/* + * handle L1 state changes TE + */ + +static void +ph_state_te(struct dchannel *dch) +{ + if (dch->debug) + printk(KERN_DEBUG "%s: TE newstate %x\n", + __func__, dch->state); + switch (dch->state) { + case 0: + l1_event(dch->l1, HW_RESET_IND); + break; + case 3: + l1_event(dch->l1, HW_DEACT_IND); + break; + case 5: + case 8: + l1_event(dch->l1, ANYSIGNAL); + break; + case 6: + l1_event(dch->l1, INFO2); + break; + case 7: + l1_event(dch->l1, INFO4_P8); + break; + } +} + +/* + * handle L1 state changes NT + */ + +static void +handle_nt_timer3(struct dchannel *dch) { + struct hfc_pci *hc = dch->hw; + + test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); + hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + hc->hw.nt_timer = 0; + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + if (test_bit(HFC_CFG_MASTER, &hc->cfg)) + hc->hw.mst_m |= HFCPCI_MASTER; + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + _queue_data(&dch->dev.D, PH_ACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); +} + +static void +ph_state_nt(struct dchannel *dch) +{ + struct hfc_pci *hc = dch->hw; + + if (dch->debug) + printk(KERN_DEBUG "%s: NT newstate %x\n", + __func__, dch->state); + switch (dch->state) { + case 2: + if (hc->hw.nt_timer < 0) { + hc->hw.nt_timer = 0; + test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); + test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); + hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + /* Clear already pending ints */ + (void) Read_hfc(hc, HFCPCI_INT_S1); + Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); + udelay(10); + Write_hfc(hc, HFCPCI_STATES, 4); + dch->state = 4; + } else if (hc->hw.nt_timer == 0) { + hc->hw.int_m1 |= HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + hc->hw.nt_timer = NT_T1_COUNT; + hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER; + hc->hw.ctmt |= HFCPCI_TIM3_125; + Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | + HFCPCI_CLTIMER); + test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); + test_and_set_bit(FLG_HFC_TIMER_T1, &dch->Flags); + /* allow G2 -> G3 transition */ + Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); + } else { + Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); + } + break; + case 1: + hc->hw.nt_timer = 0; + test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); + test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); + hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + hc->hw.mst_m &= ~HFCPCI_MASTER; + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); + _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + break; + case 4: + hc->hw.nt_timer = 0; + test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags); + test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); + hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + break; + case 3: + if (!test_and_set_bit(FLG_HFC_TIMER_T3, &dch->Flags)) { + if (!test_and_clear_bit(FLG_L2_ACTIVATED, + &dch->Flags)) { + handle_nt_timer3(dch); + break; + } + test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags); + hc->hw.int_m1 |= HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + hc->hw.nt_timer = NT_T3_COUNT; + hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER; + hc->hw.ctmt |= HFCPCI_TIM3_125; + Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | + HFCPCI_CLTIMER); + } + break; + } +} + +static void +ph_state(struct dchannel *dch) +{ + struct hfc_pci *hc = dch->hw; + + if (hc->hw.protocol == ISDN_P_NT_S0) { + if (test_bit(FLG_HFC_TIMER_T3, &dch->Flags) && + hc->hw.nt_timer < 0) + handle_nt_timer3(dch); + else + ph_state_nt(dch); + } else + ph_state_te(dch); +} + +/* + * Layer 1 callback function + */ +static int +hfc_l1callback(struct dchannel *dch, u_int cmd) +{ + struct hfc_pci *hc = dch->hw; + + switch (cmd) { + case INFO3_P8: + case INFO3_P10: + if (test_bit(HFC_CFG_MASTER, &hc->cfg)) + hc->hw.mst_m |= HFCPCI_MASTER; + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + break; + case HW_RESET_REQ: + Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3); + /* HFC ST 3 */ + udelay(6); + Write_hfc(hc, HFCPCI_STATES, 3); /* HFC ST 2 */ + if (test_bit(HFC_CFG_MASTER, &hc->cfg)) + hc->hw.mst_m |= HFCPCI_MASTER; + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE | + HFCPCI_DO_ACTION); + l1_event(dch->l1, HW_POWERUP_IND); + break; + case HW_DEACT_REQ: + hc->hw.mst_m &= ~HFCPCI_MASTER; + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) + del_timer(&dch->timer); + break; + case HW_POWERUP_REQ: + Write_hfc(hc, HFCPCI_STATES, HFCPCI_DO_ACTION); + break; + case PH_ACTIVATE_IND: + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + case PH_DEACTIVATE_IND: + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + default: + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: unknown command %x\n", + __func__, cmd); + return -1; + } + return 0; +} + +/* + * Interrupt handler + */ +static inline void +tx_birq(struct bchannel *bch) +{ + if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) + hfcpci_fill_fifo(bch); + else { + if (bch->tx_skb) + dev_kfree_skb(bch->tx_skb); + if (get_next_bframe(bch)) + hfcpci_fill_fifo(bch); + } +} + +static inline void +tx_dirq(struct dchannel *dch) +{ + if (dch->tx_skb && dch->tx_idx < dch->tx_skb->len) + hfcpci_fill_dfifo(dch->hw); + else { + if (dch->tx_skb) + dev_kfree_skb(dch->tx_skb); + if (get_next_dframe(dch)) + hfcpci_fill_dfifo(dch->hw); + } +} + +static irqreturn_t +hfcpci_int(int intno, void *dev_id) +{ + struct hfc_pci *hc = dev_id; + u_char exval; + struct bchannel *bch; + u_char val, stat; + + spin_lock(&hc->lock); + if (!(hc->hw.int_m2 & 0x08)) { + spin_unlock(&hc->lock); + return IRQ_NONE; /* not initialised */ + } + stat = Read_hfc(hc, HFCPCI_STATUS); + if (HFCPCI_ANYINT & stat) { + val = Read_hfc(hc, HFCPCI_INT_S1); + if (hc->dch.debug & DEBUG_HW_DCHANNEL) + printk(KERN_DEBUG + "HFC-PCI: stat(%02x) s1(%02x)\n", stat, val); + } else { + /* shared */ + spin_unlock(&hc->lock); + return IRQ_NONE; + } + hc->irqcnt++; + + if (hc->dch.debug & DEBUG_HW_DCHANNEL) + printk(KERN_DEBUG "HFC-PCI irq %x\n", val); + val &= hc->hw.int_m1; + if (val & 0x40) { /* state machine irq */ + exval = Read_hfc(hc, HFCPCI_STATES) & 0xf; + if (hc->dch.debug & DEBUG_HW_DCHANNEL) + printk(KERN_DEBUG "ph_state chg %d->%d\n", + hc->dch.state, exval); + hc->dch.state = exval; + schedule_event(&hc->dch, FLG_PHCHANGE); + val &= ~0x40; + } + if (val & 0x80) { /* timer irq */ + if (hc->hw.protocol == ISDN_P_NT_S0) { + if ((--hc->hw.nt_timer) < 0) + schedule_event(&hc->dch, FLG_PHCHANGE); + } + val &= ~0x80; + Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER); + } + if (val & 0x08) { /* B1 rx */ + bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); + if (bch) + main_rec_hfcpci(bch); + else if (hc->dch.debug) + printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n"); + } + if (val & 0x10) { /* B2 rx */ + bch = Sel_BCS(hc, 2); + if (bch) + main_rec_hfcpci(bch); + else if (hc->dch.debug) + printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n"); + } + if (val & 0x01) { /* B1 tx */ + bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); + if (bch) + tx_birq(bch); + else if (hc->dch.debug) + printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n"); + } + if (val & 0x02) { /* B2 tx */ + bch = Sel_BCS(hc, 2); + if (bch) + tx_birq(bch); + else if (hc->dch.debug) + printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n"); + } + if (val & 0x20) /* D rx */ + receive_dmsg(hc); + if (val & 0x04) { /* D tx */ + if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags)) + del_timer(&hc->dch.timer); + tx_dirq(&hc->dch); + } + spin_unlock(&hc->lock); + return IRQ_HANDLED; +} + +/* + * timer callback for D-chan busy resolution. Currently no function + */ +static void +hfcpci_dbusy_timer(struct hfc_pci *hc) +{ +} + +/* + * activate/deactivate hardware for selected channels and mode + */ +static int +mode_hfcpci(struct bchannel *bch, int bc, int protocol) +{ + struct hfc_pci *hc = bch->hw; + int fifo2; + u_char rx_slot = 0, tx_slot = 0, pcm_mode; + + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG + "HFCPCI bchannel protocol %x-->%x ch %x-->%x\n", + bch->state, protocol, bch->nr, bc); + + fifo2 = bc; + pcm_mode = (bc >> 24) & 0xff; + if (pcm_mode) { /* PCM SLOT USE */ + if (!test_bit(HFC_CFG_PCM, &hc->cfg)) + printk(KERN_WARNING + "%s: pcm channel id without HFC_CFG_PCM\n", + __func__); + rx_slot = (bc >> 8) & 0xff; + tx_slot = (bc >> 16) & 0xff; + bc = bc & 0xff; + } else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE)) + printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n", + __func__); + if (hc->chanlimit > 1) { + hc->hw.bswapped = 0; /* B1 and B2 normal mode */ + hc->hw.sctrl_e &= ~0x80; + } else { + if (bc & 2) { + if (protocol != ISDN_P_NONE) { + hc->hw.bswapped = 1; /* B1 and B2 exchanged */ + hc->hw.sctrl_e |= 0x80; + } else { + hc->hw.bswapped = 0; /* B1 and B2 normal mode */ + hc->hw.sctrl_e &= ~0x80; + } + fifo2 = 1; + } else { + hc->hw.bswapped = 0; /* B1 and B2 normal mode */ + hc->hw.sctrl_e &= ~0x80; + } + } + switch (protocol) { + case (-1): /* used for init */ + bch->state = -1; + bch->nr = bc; + case (ISDN_P_NONE): + if (bch->state == ISDN_P_NONE) + return 0; + if (bc & 2) { + hc->hw.sctrl &= ~SCTRL_B2_ENA; + hc->hw.sctrl_r &= ~SCTRL_B2_ENA; + } else { + hc->hw.sctrl &= ~SCTRL_B1_ENA; + hc->hw.sctrl_r &= ~SCTRL_B1_ENA; + } + if (fifo2 & 2) { + hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2; + hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS | + HFCPCI_INTS_B2REC); + } else { + hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1; + hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS | + HFCPCI_INTS_B1REC); + } +#ifdef REVERSE_BITORDER + if (bch->nr & 2) + hc->hw.cirm &= 0x7f; + else + hc->hw.cirm &= 0xbf; +#endif + bch->state = ISDN_P_NONE; + bch->nr = bc; + test_and_clear_bit(FLG_HDLC, &bch->Flags); + test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags); + break; + case (ISDN_P_B_RAW): + bch->state = protocol; + bch->nr = bc; + hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0); + hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0); + if (bc & 2) { + hc->hw.sctrl |= SCTRL_B2_ENA; + hc->hw.sctrl_r |= SCTRL_B2_ENA; +#ifdef REVERSE_BITORDER + hc->hw.cirm |= 0x80; +#endif + } else { + hc->hw.sctrl |= SCTRL_B1_ENA; + hc->hw.sctrl_r |= SCTRL_B1_ENA; +#ifdef REVERSE_BITORDER + hc->hw.cirm |= 0x40; +#endif + } + if (fifo2 & 2) { + hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; + if (!tics) + hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS | + HFCPCI_INTS_B2REC); + hc->hw.ctmt |= 2; + hc->hw.conn &= ~0x18; + } else { + hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; + if (!tics) + hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS | + HFCPCI_INTS_B1REC); + hc->hw.ctmt |= 1; + hc->hw.conn &= ~0x03; + } + test_and_set_bit(FLG_TRANSPARENT, &bch->Flags); + break; + case (ISDN_P_B_HDLC): + bch->state = protocol; + bch->nr = bc; + hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0); + hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0); + if (bc & 2) { + hc->hw.sctrl |= SCTRL_B2_ENA; + hc->hw.sctrl_r |= SCTRL_B2_ENA; + } else { + hc->hw.sctrl |= SCTRL_B1_ENA; + hc->hw.sctrl_r |= SCTRL_B1_ENA; + } + if (fifo2 & 2) { + hc->hw.last_bfifo_cnt[1] = 0; + hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; + hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS | + HFCPCI_INTS_B2REC); + hc->hw.ctmt &= ~2; + hc->hw.conn &= ~0x18; + } else { + hc->hw.last_bfifo_cnt[0] = 0; + hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; + hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS | + HFCPCI_INTS_B1REC); + hc->hw.ctmt &= ~1; + hc->hw.conn &= ~0x03; + } + test_and_set_bit(FLG_HDLC, &bch->Flags); + break; + default: + printk(KERN_DEBUG "prot not known %x\n", protocol); + return -ENOPROTOOPT; + } + if (test_bit(HFC_CFG_PCM, &hc->cfg)) { + if ((protocol == ISDN_P_NONE) || + (protocol == -1)) { /* init case */ + rx_slot = 0; + tx_slot = 0; + } else { + if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) { + rx_slot |= 0xC0; + tx_slot |= 0xC0; + } else { + rx_slot |= 0x80; + tx_slot |= 0x80; + } + } + if (bc & 2) { + hc->hw.conn &= 0xc7; + hc->hw.conn |= 0x08; + printk(KERN_DEBUG "%s: Write_hfc: B2_SSL 0x%x\n", + __func__, tx_slot); + printk(KERN_DEBUG "%s: Write_hfc: B2_RSL 0x%x\n", + __func__, rx_slot); + Write_hfc(hc, HFCPCI_B2_SSL, tx_slot); + Write_hfc(hc, HFCPCI_B2_RSL, rx_slot); + } else { + hc->hw.conn &= 0xf8; + hc->hw.conn |= 0x01; + printk(KERN_DEBUG "%s: Write_hfc: B1_SSL 0x%x\n", + __func__, tx_slot); + printk(KERN_DEBUG "%s: Write_hfc: B1_RSL 0x%x\n", + __func__, rx_slot); + Write_hfc(hc, HFCPCI_B1_SSL, tx_slot); + Write_hfc(hc, HFCPCI_B1_RSL, rx_slot); + } + } + Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e); + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); + Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl); + Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r); + Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt); + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); +#ifdef REVERSE_BITORDER + Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); +#endif + return 0; +} + +static int +set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan) +{ + struct hfc_pci *hc = bch->hw; + + if (bch->debug & DEBUG_HW_BCHANNEL) + printk(KERN_DEBUG + "HFCPCI bchannel test rx protocol %x-->%x ch %x-->%x\n", + bch->state, protocol, bch->nr, chan); + if (bch->nr != chan) { + printk(KERN_DEBUG + "HFCPCI rxtest wrong channel parameter %x/%x\n", + bch->nr, chan); + return -EINVAL; + } + switch (protocol) { + case (ISDN_P_B_RAW): + bch->state = protocol; + hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0); + if (chan & 2) { + hc->hw.sctrl_r |= SCTRL_B2_ENA; + hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; + if (!tics) + hc->hw.int_m1 |= HFCPCI_INTS_B2REC; + hc->hw.ctmt |= 2; + hc->hw.conn &= ~0x18; +#ifdef REVERSE_BITORDER + hc->hw.cirm |= 0x80; +#endif + } else { + hc->hw.sctrl_r |= SCTRL_B1_ENA; + hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX; + if (!tics) + hc->hw.int_m1 |= HFCPCI_INTS_B1REC; + hc->hw.ctmt |= 1; + hc->hw.conn &= ~0x03; +#ifdef REVERSE_BITORDER + hc->hw.cirm |= 0x40; +#endif + } + break; + case (ISDN_P_B_HDLC): + bch->state = protocol; + hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0); + if (chan & 2) { + hc->hw.sctrl_r |= SCTRL_B2_ENA; + hc->hw.last_bfifo_cnt[1] = 0; + hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; + hc->hw.int_m1 |= HFCPCI_INTS_B2REC; + hc->hw.ctmt &= ~2; + hc->hw.conn &= ~0x18; + } else { + hc->hw.sctrl_r |= SCTRL_B1_ENA; + hc->hw.last_bfifo_cnt[0] = 0; + hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX; + hc->hw.int_m1 |= HFCPCI_INTS_B1REC; + hc->hw.ctmt &= ~1; + hc->hw.conn &= ~0x03; + } + break; + default: + printk(KERN_DEBUG "prot not known %x\n", protocol); + return -ENOPROTOOPT; + } + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); + Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r); + Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt); + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); +#ifdef REVERSE_BITORDER + Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm); +#endif + return 0; +} + +static void +deactivate_bchannel(struct bchannel *bch) +{ + struct hfc_pci *hc = bch->hw; + u_long flags; + + spin_lock_irqsave(&hc->lock, flags); + mISDN_clear_bchannel(bch); + mode_hfcpci(bch, bch->nr, ISDN_P_NONE); + spin_unlock_irqrestore(&hc->lock, flags); +} + +/* + * Layer 1 B-channel hardware access + */ +static int +channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + return mISDN_ctrl_bchannel(bch, cq); +} +static int +hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct hfc_pci *hc = bch->hw; + int ret = -EINVAL; + u_long flags; + + if (bch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg); + switch (cmd) { + case HW_TESTRX_RAW: + spin_lock_irqsave(&hc->lock, flags); + ret = set_hfcpci_rxtest(bch, ISDN_P_B_RAW, (int)(long)arg); + spin_unlock_irqrestore(&hc->lock, flags); + break; + case HW_TESTRX_HDLC: + spin_lock_irqsave(&hc->lock, flags); + ret = set_hfcpci_rxtest(bch, ISDN_P_B_HDLC, (int)(long)arg); + spin_unlock_irqrestore(&hc->lock, flags); + break; + case HW_TESTRX_OFF: + spin_lock_irqsave(&hc->lock, flags); + mode_hfcpci(bch, bch->nr, ISDN_P_NONE); + spin_unlock_irqrestore(&hc->lock, flags); + ret = 0; + break; + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + deactivate_bchannel(bch); + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(THIS_MODULE); + ret = 0; + break; + case CONTROL_CHANNEL: + ret = channel_bctrl(bch, arg); + break; + default: + printk(KERN_WARNING "%s: unknown prim(%x)\n", + __func__, cmd); + } + return ret; +} + +/* + * Layer2 -> Layer 1 Dchannel data + */ +static int +hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct hfc_pci *hc = dch->hw; + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + unsigned int id; + u_long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(&hc->lock, flags); + ret = dchannel_senddata(dch, skb); + if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ + hfcpci_fill_dfifo(dch->hw); + ret = 0; + spin_unlock_irqrestore(&hc->lock, flags); + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&hc->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + spin_lock_irqsave(&hc->lock, flags); + if (hc->hw.protocol == ISDN_P_NT_S0) { + ret = 0; + if (test_bit(HFC_CFG_MASTER, &hc->cfg)) + hc->hw.mst_m |= HFCPCI_MASTER; + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + if (test_bit(FLG_ACTIVE, &dch->Flags)) { + spin_unlock_irqrestore(&hc->lock, flags); + _queue_data(&dch->dev.D, PH_ACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + break; + } + test_and_set_bit(FLG_L2_ACTIVATED, &dch->Flags); + Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE | + HFCPCI_DO_ACTION | 1); + } else + ret = l1_event(dch->l1, hh->prim); + spin_unlock_irqrestore(&hc->lock, flags); + break; + case PH_DEACTIVATE_REQ: + test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); + spin_lock_irqsave(&hc->lock, flags); + if (hc->hw.protocol == ISDN_P_NT_S0) { + /* prepare deactivation */ + Write_hfc(hc, HFCPCI_STATES, 0x40); + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) + del_timer(&dch->timer); +#ifdef FIXME + if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) + dchannel_sched_event(&hc->dch, D_CLEARBUSY); +#endif + hc->hw.mst_m &= ~HFCPCI_MASTER; + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + ret = 0; + } else { + ret = l1_event(dch->l1, hh->prim); + } + spin_unlock_irqrestore(&hc->lock, flags); + break; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +/* + * Layer2 -> Layer 1 Bchannel data + */ +static int +hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct hfc_pci *hc = bch->hw; + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + unsigned long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(&hc->lock, flags); + ret = bchannel_senddata(bch, skb); + if (ret > 0) { /* direct TX */ + hfcpci_fill_fifo(bch); + ret = 0; + } + spin_unlock_irqrestore(&hc->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + spin_lock_irqsave(&hc->lock, flags); + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) + ret = mode_hfcpci(bch, bch->nr, ch->protocol); + else + ret = 0; + spin_unlock_irqrestore(&hc->lock, flags); + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + break; + case PH_DEACTIVATE_REQ: + deactivate_bchannel(bch); + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + ret = 0; + break; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +/* + * called for card init message + */ + +static void +inithfcpci(struct hfc_pci *hc) +{ + printk(KERN_DEBUG "inithfcpci: entered\n"); + hc->dch.timer.function = (void *) hfcpci_dbusy_timer; + hc->dch.timer.data = (long) &hc->dch; + init_timer(&hc->dch.timer); + hc->chanlimit = 2; + mode_hfcpci(&hc->bch[0], 1, -1); + mode_hfcpci(&hc->bch[1], 2, -1); +} + + +static int +init_card(struct hfc_pci *hc) +{ + int cnt = 3; + u_long flags; + + printk(KERN_DEBUG "init_card: entered\n"); + + + spin_lock_irqsave(&hc->lock, flags); + disable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + if (request_irq(hc->irq, hfcpci_int, IRQF_SHARED, "HFC PCI", hc)) { + printk(KERN_WARNING + "mISDN: couldn't get interrupt %d\n", hc->irq); + return -EIO; + } + spin_lock_irqsave(&hc->lock, flags); + reset_hfcpci(hc); + while (cnt) { + inithfcpci(hc); + /* + * Finally enable IRQ output + * this is only allowed, if an IRQ routine is already + * established for this HFC, so don't do that earlier + */ + enable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + /* Timeout 80ms */ + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout((80 * HZ) / 1000); + printk(KERN_INFO "HFC PCI: IRQ %d count %d\n", + hc->irq, hc->irqcnt); + /* now switch timer interrupt off */ + spin_lock_irqsave(&hc->lock, flags); + hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + /* reinit mode reg */ + Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); + if (!hc->irqcnt) { + printk(KERN_WARNING + "HFC PCI: IRQ(%d) getting no interrupts " + "during init %d\n", hc->irq, 4 - cnt); + if (cnt == 1) + break; + else { + reset_hfcpci(hc); + cnt--; + } + } else { + spin_unlock_irqrestore(&hc->lock, flags); + hc->initdone = 1; + return 0; + } + } + disable_hwirq(hc); + spin_unlock_irqrestore(&hc->lock, flags); + free_irq(hc->irq, hc); + return -EIO; +} + +static int +channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + u_char slot; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT | + MISDN_CTRL_DISCONNECT | MISDN_CTRL_L1_TIMER3; + break; + case MISDN_CTRL_LOOP: + /* channel 0 disabled loop */ + if (cq->channel < 0 || cq->channel > 2) { + ret = -EINVAL; + break; + } + if (cq->channel & 1) { + if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) + slot = 0xC0; + else + slot = 0x80; + printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n", + __func__, slot); + Write_hfc(hc, HFCPCI_B1_SSL, slot); + Write_hfc(hc, HFCPCI_B1_RSL, slot); + hc->hw.conn = (hc->hw.conn & ~7) | 6; + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); + } + if (cq->channel & 2) { + if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) + slot = 0xC1; + else + slot = 0x81; + printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n", + __func__, slot); + Write_hfc(hc, HFCPCI_B2_SSL, slot); + Write_hfc(hc, HFCPCI_B2_RSL, slot); + hc->hw.conn = (hc->hw.conn & ~0x38) | 0x30; + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); + } + if (cq->channel & 3) + hc->hw.trm |= 0x80; /* enable IOM-loop */ + else { + hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09; + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); + hc->hw.trm &= 0x7f; /* disable IOM-loop */ + } + Write_hfc(hc, HFCPCI_TRM, hc->hw.trm); + break; + case MISDN_CTRL_CONNECT: + if (cq->channel == cq->p1) { + ret = -EINVAL; + break; + } + if (cq->channel < 1 || cq->channel > 2 || + cq->p1 < 1 || cq->p1 > 2) { + ret = -EINVAL; + break; + } + if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) + slot = 0xC0; + else + slot = 0x80; + printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n", + __func__, slot); + Write_hfc(hc, HFCPCI_B1_SSL, slot); + Write_hfc(hc, HFCPCI_B2_RSL, slot); + if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) + slot = 0xC1; + else + slot = 0x81; + printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n", + __func__, slot); + Write_hfc(hc, HFCPCI_B2_SSL, slot); + Write_hfc(hc, HFCPCI_B1_RSL, slot); + hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x36; + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); + hc->hw.trm |= 0x80; + Write_hfc(hc, HFCPCI_TRM, hc->hw.trm); + break; + case MISDN_CTRL_DISCONNECT: + hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09; + Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn); + hc->hw.trm &= 0x7f; /* disable IOM-loop */ + break; + case MISDN_CTRL_L1_TIMER3: + ret = l1_event(hc->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff)); + break; + default: + printk(KERN_WARNING "%s: unknown Op %x\n", + __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +static int +open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch, + struct channel_req *rq) +{ + int err = 0; + + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__, + hc->dch.dev.id, __builtin_return_address(0)); + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + if (rq->adr.channel == 1) { + /* TODO: E-Channel */ + return -EINVAL; + } + if (!hc->initdone) { + if (rq->protocol == ISDN_P_TE_S0) { + err = create_l1(&hc->dch, hfc_l1callback); + if (err) + return err; + } + hc->hw.protocol = rq->protocol; + ch->protocol = rq->protocol; + err = init_card(hc); + if (err) + return err; + } else { + if (rq->protocol != ch->protocol) { + if (hc->hw.protocol == ISDN_P_TE_S0) + l1_event(hc->dch.l1, CLOSE_CHANNEL); + if (rq->protocol == ISDN_P_TE_S0) { + err = create_l1(&hc->dch, hfc_l1callback); + if (err) + return err; + } + hc->hw.protocol = rq->protocol; + ch->protocol = rq->protocol; + hfcpci_setmode(hc); + } + } + + if (((ch->protocol == ISDN_P_NT_S0) && (hc->dch.state == 3)) || + ((ch->protocol == ISDN_P_TE_S0) && (hc->dch.state == 7))) { + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, + 0, NULL, GFP_KERNEL); + } + rq->ch = ch; + if (!try_module_get(THIS_MODULE)) + printk(KERN_WARNING "%s:cannot get module\n", __func__); + return 0; +} + +static int +open_bchannel(struct hfc_pci *hc, struct channel_req *rq) +{ + struct bchannel *bch; + + if (rq->adr.channel == 0 || rq->adr.channel > 2) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + bch = &hc->bch[rq->adr.channel - 1]; + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + bch->ch.protocol = rq->protocol; + rq->ch = &bch->ch; /* TODO: E-channel */ + if (!try_module_get(THIS_MODULE)) + printk(KERN_WARNING "%s:cannot get module\n", __func__); + return 0; +} + +/* + * device control function + */ +static int +hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct hfc_pci *hc = dch->hw; + struct channel_req *rq; + int err = 0; + + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: cmd:%x %p\n", + __func__, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + if ((rq->protocol == ISDN_P_TE_S0) || + (rq->protocol == ISDN_P_NT_S0)) + err = open_dchannel(hc, ch, rq); + else + err = open_bchannel(hc, rq); + break; + case CLOSE_CHANNEL: + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG "%s: dev(%d) close from %p\n", + __func__, hc->dch.dev.id, + __builtin_return_address(0)); + module_put(THIS_MODULE); + break; + case CONTROL_CHANNEL: + err = channel_ctrl(hc, arg); + break; + default: + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: unknown command %x\n", + __func__, cmd); + return -EINVAL; + } + return err; +} + +static int +setup_hw(struct hfc_pci *hc) +{ + void *buffer; + + printk(KERN_INFO "mISDN: HFC-PCI driver %s\n", hfcpci_revision); + hc->hw.cirm = 0; + hc->dch.state = 0; + pci_set_master(hc->pdev); + if (!hc->irq) { + printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); + return 1; + } + hc->hw.pci_io = + (char __iomem *)(unsigned long)hc->pdev->resource[1].start; + + if (!hc->hw.pci_io) { + printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); + return 1; + } + /* Allocate memory for FIFOS */ + /* the memory needs to be on a 32k boundary within the first 4G */ + pci_set_dma_mask(hc->pdev, 0xFFFF8000); + buffer = pci_alloc_consistent(hc->pdev, 0x8000, &hc->hw.dmahandle); + /* We silently assume the address is okay if nonzero */ + if (!buffer) { + printk(KERN_WARNING + "HFC-PCI: Error allocating memory for FIFO!\n"); + return 1; + } + hc->hw.fifos = buffer; + pci_write_config_dword(hc->pdev, 0x80, hc->hw.dmahandle); + hc->hw.pci_io = ioremap((ulong) hc->hw.pci_io, 256); + printk(KERN_INFO + "HFC-PCI: defined at mem %#lx fifo %#lx(%#lx) IRQ %d HZ %d\n", + (u_long) hc->hw.pci_io, (u_long) hc->hw.fifos, + (u_long) hc->hw.dmahandle, hc->irq, HZ); + /* enable memory mapped ports, disable busmaster */ + pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO); + hc->hw.int_m2 = 0; + disable_hwirq(hc); + hc->hw.int_m1 = 0; + Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); + /* At this point the needed PCI config is done */ + /* fifos are still not enabled */ + hc->hw.timer.function = (void *) hfcpci_Timer; + hc->hw.timer.data = (long) hc; + init_timer(&hc->hw.timer); + /* default PCM master */ + test_and_set_bit(HFC_CFG_MASTER, &hc->cfg); + return 0; +} + +static void +release_card(struct hfc_pci *hc) { + u_long flags; + + spin_lock_irqsave(&hc->lock, flags); + hc->hw.int_m2 = 0; /* interrupt output off ! */ + disable_hwirq(hc); + mode_hfcpci(&hc->bch[0], 1, ISDN_P_NONE); + mode_hfcpci(&hc->bch[1], 2, ISDN_P_NONE); + if (hc->dch.timer.function != NULL) { + del_timer(&hc->dch.timer); + hc->dch.timer.function = NULL; + } + spin_unlock_irqrestore(&hc->lock, flags); + if (hc->hw.protocol == ISDN_P_TE_S0) + l1_event(hc->dch.l1, CLOSE_CHANNEL); + if (hc->initdone) + free_irq(hc->irq, hc); + release_io_hfcpci(hc); /* must release after free_irq! */ + mISDN_unregister_device(&hc->dch.dev); + mISDN_freebchannel(&hc->bch[1]); + mISDN_freebchannel(&hc->bch[0]); + mISDN_freedchannel(&hc->dch); + pci_set_drvdata(hc->pdev, NULL); + kfree(hc); +} + +static int +setup_card(struct hfc_pci *card) +{ + int err = -EINVAL; + u_int i; + char name[MISDN_MAX_IDLEN]; + + card->dch.debug = debug; + spin_lock_init(&card->lock); + mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, ph_state); + card->dch.hw = card; + card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0); + card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + card->dch.dev.D.send = hfcpci_l2l1D; + card->dch.dev.D.ctrl = hfc_dctrl; + card->dch.dev.nrbchan = 2; + for (i = 0; i < 2; i++) { + card->bch[i].nr = i + 1; + set_channelmap(i + 1, card->dch.dev.channelmap); + card->bch[i].debug = debug; + mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1); + card->bch[i].hw = card; + card->bch[i].ch.send = hfcpci_l2l1B; + card->bch[i].ch.ctrl = hfc_bctrl; + card->bch[i].ch.nr = i + 1; + list_add(&card->bch[i].ch.list, &card->dch.dev.bchannels); + } + err = setup_hw(card); + if (err) + goto error; + snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1); + err = mISDN_register_device(&card->dch.dev, &card->pdev->dev, name); + if (err) + goto error; + HFC_cnt++; + printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt); + return 0; +error: + mISDN_freebchannel(&card->bch[1]); + mISDN_freebchannel(&card->bch[0]); + mISDN_freedchannel(&card->dch); + kfree(card); + return err; +} + +/* private data in the PCI devices list */ +struct _hfc_map { + u_int subtype; + u_int flag; + char *name; +}; + +static const struct _hfc_map hfc_map[] = +{ + {HFC_CCD_2BD0, 0, "CCD/Billion/Asuscom 2BD0"}, + {HFC_CCD_B000, 0, "Billion B000"}, + {HFC_CCD_B006, 0, "Billion B006"}, + {HFC_CCD_B007, 0, "Billion B007"}, + {HFC_CCD_B008, 0, "Billion B008"}, + {HFC_CCD_B009, 0, "Billion B009"}, + {HFC_CCD_B00A, 0, "Billion B00A"}, + {HFC_CCD_B00B, 0, "Billion B00B"}, + {HFC_CCD_B00C, 0, "Billion B00C"}, + {HFC_CCD_B100, 0, "Seyeon B100"}, + {HFC_CCD_B700, 0, "Primux II S0 B700"}, + {HFC_CCD_B701, 0, "Primux II S0 NT B701"}, + {HFC_ABOCOM_2BD1, 0, "Abocom/Magitek 2BD1"}, + {HFC_ASUS_0675, 0, "Asuscom/Askey 675"}, + {HFC_BERKOM_TCONCEPT, 0, "German telekom T-Concept"}, + {HFC_BERKOM_A1T, 0, "German telekom A1T"}, + {HFC_ANIGMA_MC145575, 0, "Motorola MC145575"}, + {HFC_ZOLTRIX_2BD0, 0, "Zoltrix 2BD0"}, + {HFC_DIGI_DF_M_IOM2_E, 0, + "Digi International DataFire Micro V IOM2 (Europe)"}, + {HFC_DIGI_DF_M_E, 0, + "Digi International DataFire Micro V (Europe)"}, + {HFC_DIGI_DF_M_IOM2_A, 0, + "Digi International DataFire Micro V IOM2 (North America)"}, + {HFC_DIGI_DF_M_A, 0, + "Digi International DataFire Micro V (North America)"}, + {HFC_SITECOM_DC105V2, 0, "Sitecom Connectivity DC-105 ISDN TA"}, + {}, +}; + +static struct pci_device_id hfc_ids[] = +{ + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_2BD0), + (unsigned long) &hfc_map[0] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B000), + (unsigned long) &hfc_map[1] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B006), + (unsigned long) &hfc_map[2] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B007), + (unsigned long) &hfc_map[3] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B008), + (unsigned long) &hfc_map[4] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B009), + (unsigned long) &hfc_map[5] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00A), + (unsigned long) &hfc_map[6] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00B), + (unsigned long) &hfc_map[7] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00C), + (unsigned long) &hfc_map[8] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B100), + (unsigned long) &hfc_map[9] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B700), + (unsigned long) &hfc_map[10] }, + { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B701), + (unsigned long) &hfc_map[11] }, + { PCI_VDEVICE(ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1), + (unsigned long) &hfc_map[12] }, + { PCI_VDEVICE(ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675), + (unsigned long) &hfc_map[13] }, + { PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT), + (unsigned long) &hfc_map[14] }, + { PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_A1T), + (unsigned long) &hfc_map[15] }, + { PCI_VDEVICE(ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575), + (unsigned long) &hfc_map[16] }, + { PCI_VDEVICE(ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0), + (unsigned long) &hfc_map[17] }, + { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E), + (unsigned long) &hfc_map[18] }, + { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_E), + (unsigned long) &hfc_map[19] }, + { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A), + (unsigned long) &hfc_map[20] }, + { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_A), + (unsigned long) &hfc_map[21] }, + { PCI_VDEVICE(SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2), + (unsigned long) &hfc_map[22] }, + {}, +}; + +static int +hfc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = -ENOMEM; + struct hfc_pci *card; + struct _hfc_map *m = (struct _hfc_map *)ent->driver_data; + + card = kzalloc(sizeof(struct hfc_pci), GFP_ATOMIC); + if (!card) { + printk(KERN_ERR "No kmem for HFC card\n"); + return err; + } + card->pdev = pdev; + card->subtype = m->subtype; + err = pci_enable_device(pdev); + if (err) { + kfree(card); + return err; + } + + printk(KERN_INFO "mISDN_hfcpci: found adapter %s at %s\n", + m->name, pci_name(pdev)); + + card->irq = pdev->irq; + pci_set_drvdata(pdev, card); + err = setup_card(card); + if (err) + pci_set_drvdata(pdev, NULL); + return err; +} + +static void +hfc_remove_pci(struct pci_dev *pdev) +{ + struct hfc_pci *card = pci_get_drvdata(pdev); + + if (card) + release_card(card); + else + if (debug) + printk(KERN_DEBUG "%s: drvdata already removed\n", + __func__); +} + + +static struct pci_driver hfc_driver = { + .name = "hfcpci", + .probe = hfc_probe, + .remove = hfc_remove_pci, + .id_table = hfc_ids, +}; + +static int +_hfcpci_softirq(struct device *dev, void *arg) +{ + struct hfc_pci *hc = dev_get_drvdata(dev); + struct bchannel *bch; + if (hc == NULL) + return 0; + + if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { + spin_lock(&hc->lock); + bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); + if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ + main_rec_hfcpci(bch); + tx_birq(bch); + } + bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2); + if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */ + main_rec_hfcpci(bch); + tx_birq(bch); + } + spin_unlock(&hc->lock); + } + return 0; +} + +static void +hfcpci_softirq(void *arg) +{ + WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, arg, + _hfcpci_softirq) != 0); + + /* if next event would be in the past ... */ + if ((s32)(hfc_jiffies + tics - jiffies) <= 0) + hfc_jiffies = jiffies + 1; + else + hfc_jiffies += tics; + hfc_tl.expires = hfc_jiffies; + add_timer(&hfc_tl); +} + +static int __init +HFC_init(void) +{ + int err; + + if (!poll) + poll = HFCPCI_BTRANS_THRESHOLD; + + if (poll != HFCPCI_BTRANS_THRESHOLD) { + tics = (poll * HZ) / 8000; + if (tics < 1) + tics = 1; + poll = (tics * 8000) / HZ; + if (poll > 256 || poll < 8) { + printk(KERN_ERR "%s: Wrong poll value %d not in range " + "of 8..256.\n", __func__, poll); + err = -EINVAL; + return err; + } + } + if (poll != HFCPCI_BTRANS_THRESHOLD) { + printk(KERN_INFO "%s: Using alternative poll value of %d\n", + __func__, poll); + hfc_tl.function = (void *)hfcpci_softirq; + hfc_tl.data = 0; + init_timer(&hfc_tl); + hfc_tl.expires = jiffies + tics; + hfc_jiffies = hfc_tl.expires; + add_timer(&hfc_tl); + } else + tics = 0; /* indicate the use of controller's timer */ + + err = pci_register_driver(&hfc_driver); + if (err) { + if (timer_pending(&hfc_tl)) + del_timer(&hfc_tl); + } + + return err; +} + +static void __exit +HFC_cleanup(void) +{ + if (timer_pending(&hfc_tl)) + del_timer(&hfc_tl); + + pci_unregister_driver(&hfc_driver); +} + +module_init(HFC_init); +module_exit(HFC_cleanup); + +MODULE_DEVICE_TABLE(pci, hfc_ids); diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c new file mode 100644 index 00000000000..114f3bcba1b --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -0,0 +1,2140 @@ +/* hfcsusb.c + * mISDN driver for Colognechip HFC-S USB chip + * + * Copyright 2001 by Peter Sprenger (sprenger@moving-bytes.de) + * Copyright 2008 by Martin Bachem (info@bachem-it.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * module params + * debug=<n>, default=0, with n=0xHHHHGGGG + * H - l1 driver flags described in hfcsusb.h + * G - common mISDN debug flags described at mISDNhw.h + * + * poll=<n>, default 128 + * n : burst size of PH_DATA_IND at transparent rx data + * + * Revision: 0.3.3 (socket), 2008-11-05 + */ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/usb.h> +#include <linux/mISDNhw.h> +#include <linux/slab.h> +#include "hfcsusb.h" + +static unsigned int debug; +static int poll = DEFAULT_TRANSP_BURST_SZ; + +static LIST_HEAD(HFClist); +static DEFINE_RWLOCK(HFClock); + + +MODULE_AUTHOR("Martin Bachem"); +MODULE_LICENSE("GPL"); +module_param(debug, uint, S_IRUGO | S_IWUSR); +module_param(poll, int, 0); + +static int hfcsusb_cnt; + +/* some function prototypes */ +static void hfcsusb_ph_command(struct hfcsusb *hw, u_char command); +static void release_hw(struct hfcsusb *hw); +static void reset_hfcsusb(struct hfcsusb *hw); +static void setPortMode(struct hfcsusb *hw); +static void hfcsusb_start_endpoint(struct hfcsusb *hw, int channel); +static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel); +static int hfcsusb_setup_bch(struct bchannel *bch, int protocol); +static void deactivate_bchannel(struct bchannel *bch); +static void hfcsusb_ph_info(struct hfcsusb *hw); + +/* start next background transfer for control channel */ +static void +ctrl_start_transfer(struct hfcsusb *hw) +{ + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); + + if (hw->ctrl_cnt) { + hw->ctrl_urb->pipe = hw->ctrl_out_pipe; + hw->ctrl_urb->setup_packet = (u_char *)&hw->ctrl_write; + hw->ctrl_urb->transfer_buffer = NULL; + hw->ctrl_urb->transfer_buffer_length = 0; + hw->ctrl_write.wIndex = + cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].hfcs_reg); + hw->ctrl_write.wValue = + cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].reg_val); + + usb_submit_urb(hw->ctrl_urb, GFP_ATOMIC); + } +} + +/* + * queue a control transfer request to write HFC-S USB + * chip register using CTRL resuest queue + */ +static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val) +{ + struct ctrl_buf *buf; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s reg(0x%02x) val(0x%02x)\n", + hw->name, __func__, reg, val); + + spin_lock(&hw->ctrl_lock); + if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) { + spin_unlock(&hw->ctrl_lock); + return 1; + } + buf = &hw->ctrl_buff[hw->ctrl_in_idx]; + buf->hfcs_reg = reg; + buf->reg_val = val; + if (++hw->ctrl_in_idx >= HFC_CTRL_BUFSIZE) + hw->ctrl_in_idx = 0; + if (++hw->ctrl_cnt == 1) + ctrl_start_transfer(hw); + spin_unlock(&hw->ctrl_lock); + + return 0; +} + +/* control completion routine handling background control cmds */ +static void +ctrl_complete(struct urb *urb) +{ + struct hfcsusb *hw = (struct hfcsusb *) urb->context; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); + + urb->dev = hw->dev; + if (hw->ctrl_cnt) { + hw->ctrl_cnt--; /* decrement actual count */ + if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE) + hw->ctrl_out_idx = 0; /* pointer wrap */ + + ctrl_start_transfer(hw); /* start next transfer */ + } +} + +/* handle LED bits */ +static void +set_led_bit(struct hfcsusb *hw, signed short led_bits, int set_on) +{ + if (set_on) { + if (led_bits < 0) + hw->led_state &= ~abs(led_bits); + else + hw->led_state |= led_bits; + } else { + if (led_bits < 0) + hw->led_state |= abs(led_bits); + else + hw->led_state &= ~led_bits; + } +} + +/* handle LED requests */ +static void +handle_led(struct hfcsusb *hw, int event) +{ + struct hfcsusb_vdata *driver_info = (struct hfcsusb_vdata *) + hfcsusb_idtab[hw->vend_idx].driver_info; + __u8 tmpled; + + if (driver_info->led_scheme == LED_OFF) + return; + tmpled = hw->led_state; + + switch (event) { + case LED_POWER_ON: + set_led_bit(hw, driver_info->led_bits[0], 1); + set_led_bit(hw, driver_info->led_bits[1], 0); + set_led_bit(hw, driver_info->led_bits[2], 0); + set_led_bit(hw, driver_info->led_bits[3], 0); + break; + case LED_POWER_OFF: + set_led_bit(hw, driver_info->led_bits[0], 0); + set_led_bit(hw, driver_info->led_bits[1], 0); + set_led_bit(hw, driver_info->led_bits[2], 0); + set_led_bit(hw, driver_info->led_bits[3], 0); + break; + case LED_S0_ON: + set_led_bit(hw, driver_info->led_bits[1], 1); + break; + case LED_S0_OFF: + set_led_bit(hw, driver_info->led_bits[1], 0); + break; + case LED_B1_ON: + set_led_bit(hw, driver_info->led_bits[2], 1); + break; + case LED_B1_OFF: + set_led_bit(hw, driver_info->led_bits[2], 0); + break; + case LED_B2_ON: + set_led_bit(hw, driver_info->led_bits[3], 1); + break; + case LED_B2_OFF: + set_led_bit(hw, driver_info->led_bits[3], 0); + break; + } + + if (hw->led_state != tmpled) { + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s reg(0x%02x) val(x%02x)\n", + hw->name, __func__, + HFCUSB_P_DATA, hw->led_state); + + write_reg(hw, HFCUSB_P_DATA, hw->led_state); + } +} + +/* + * Layer2 -> Layer 1 Bchannel data + */ +static int +hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct hfcsusb *hw = bch->hw; + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + u_long flags; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(&hw->lock, flags); + ret = bchannel_senddata(bch, skb); + spin_unlock_irqrestore(&hw->lock, flags); + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n", + hw->name, __func__, ret); + if (ret > 0) + ret = 0; + return ret; + case PH_ACTIVATE_REQ: + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) { + hfcsusb_start_endpoint(hw, bch->nr - 1); + ret = hfcsusb_setup_bch(bch, ch->protocol); + } else + ret = 0; + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, + 0, NULL, GFP_KERNEL); + break; + case PH_DEACTIVATE_REQ: + deactivate_bchannel(bch); + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, + 0, NULL, GFP_KERNEL); + ret = 0; + break; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +/* + * send full D/B channel status information + * as MPH_INFORMATION_IND + */ +static void +hfcsusb_ph_info(struct hfcsusb *hw) +{ + struct ph_info *phi; + struct dchannel *dch = &hw->dch; + int i; + + phi = kzalloc(sizeof(struct ph_info) + + dch->dev.nrbchan * sizeof(struct ph_info_ch), GFP_ATOMIC); + phi->dch.ch.protocol = hw->protocol; + phi->dch.ch.Flags = dch->Flags; + phi->dch.state = dch->state; + phi->dch.num_bch = dch->dev.nrbchan; + for (i = 0; i < dch->dev.nrbchan; i++) { + phi->bch[i].protocol = hw->bch[i].ch.protocol; + phi->bch[i].Flags = hw->bch[i].Flags; + } + _queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY, + sizeof(struct ph_info_dch) + dch->dev.nrbchan * + sizeof(struct ph_info_ch), phi, GFP_ATOMIC); + kfree(phi); +} + +/* + * Layer2 -> Layer 1 Dchannel data + */ +static int +hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct mISDNhead *hh = mISDN_HEAD_P(skb); + struct hfcsusb *hw = dch->hw; + int ret = -EINVAL; + u_long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n", + hw->name, __func__); + + spin_lock_irqsave(&hw->lock, flags); + ret = dchannel_senddata(dch, skb); + spin_unlock_irqrestore(&hw->lock, flags); + if (ret > 0) { + ret = 0; + queue_ch_frame(ch, PH_DATA_CNF, hh->id, NULL); + } + break; + + case PH_ACTIVATE_REQ: + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n", + hw->name, __func__, + (hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE"); + + if (hw->protocol == ISDN_P_NT_S0) { + ret = 0; + if (test_bit(FLG_ACTIVE, &dch->Flags)) { + _queue_data(&dch->dev.D, + PH_ACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_ATOMIC); + } else { + hfcsusb_ph_command(hw, + HFC_L1_ACTIVATE_NT); + test_and_set_bit(FLG_L2_ACTIVATED, + &dch->Flags); + } + } else { + hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE); + ret = l1_event(dch->l1, hh->prim); + } + break; + + case PH_DEACTIVATE_REQ: + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n", + hw->name, __func__); + test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); + + if (hw->protocol == ISDN_P_NT_S0) { + hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT); + spin_lock_irqsave(&hw->lock, flags); + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + spin_unlock_irqrestore(&hw->lock, flags); +#ifdef FIXME + if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) + dchannel_sched_event(&hc->dch, D_CLEARBUSY); +#endif + ret = 0; + } else + ret = l1_event(dch->l1, hh->prim); + break; + case MPH_INFORMATION_REQ: + hfcsusb_ph_info(hw); + ret = 0; + break; + } + + return ret; +} + +/* + * Layer 1 callback function + */ +static int +hfc_l1callback(struct dchannel *dch, u_int cmd) +{ + struct hfcsusb *hw = dch->hw; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s cmd 0x%x\n", + hw->name, __func__, cmd); + + switch (cmd) { + case INFO3_P8: + case INFO3_P10: + case HW_RESET_REQ: + case HW_POWERUP_REQ: + break; + + case HW_DEACT_REQ: + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + break; + case PH_ACTIVATE_IND: + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + case PH_DEACTIVATE_IND: + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + default: + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: unknown cmd %x\n", + hw->name, __func__, cmd); + return -1; + } + hfcsusb_ph_info(hw); + return 0; +} + +static int +open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch, + struct channel_req *rq) +{ + int err = 0; + + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG "%s: %s: dev(%d) open addr(%i) from %p\n", + hw->name, __func__, hw->dch.dev.id, rq->adr.channel, + __builtin_return_address(0)); + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + + test_and_clear_bit(FLG_ACTIVE, &hw->dch.Flags); + test_and_clear_bit(FLG_ACTIVE, &hw->ech.Flags); + hfcsusb_start_endpoint(hw, HFC_CHAN_D); + + /* E-Channel logging */ + if (rq->adr.channel == 1) { + if (hw->fifos[HFCUSB_PCM_RX].pipe) { + hfcsusb_start_endpoint(hw, HFC_CHAN_E); + set_bit(FLG_ACTIVE, &hw->ech.Flags); + _queue_data(&hw->ech.dev.D, PH_ACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + } else + return -EINVAL; + } + + if (!hw->initdone) { + hw->protocol = rq->protocol; + if (rq->protocol == ISDN_P_TE_S0) { + err = create_l1(&hw->dch, hfc_l1callback); + if (err) + return err; + } + setPortMode(hw); + ch->protocol = rq->protocol; + hw->initdone = 1; + } else { + if (rq->protocol != ch->protocol) + return -EPROTONOSUPPORT; + } + + if (((ch->protocol == ISDN_P_NT_S0) && (hw->dch.state == 3)) || + ((ch->protocol == ISDN_P_TE_S0) && (hw->dch.state == 7))) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, + 0, NULL, GFP_KERNEL); + rq->ch = ch; + if (!try_module_get(THIS_MODULE)) + printk(KERN_WARNING "%s: %s: cannot get module\n", + hw->name, __func__); + return 0; +} + +static int +open_bchannel(struct hfcsusb *hw, struct channel_req *rq) +{ + struct bchannel *bch; + + if (rq->adr.channel == 0 || rq->adr.channel > 2) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s B%i\n", + hw->name, __func__, rq->adr.channel); + + bch = &hw->bch[rq->adr.channel - 1]; + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + bch->ch.protocol = rq->protocol; + rq->ch = &bch->ch; + + if (!try_module_get(THIS_MODULE)) + printk(KERN_WARNING "%s: %s:cannot get module\n", + hw->name, __func__); + return 0; +} + +static int +channel_ctrl(struct hfcsusb *hw, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s op(0x%x) channel(0x%x)\n", + hw->name, __func__, (cq->op), (cq->channel)); + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT | + MISDN_CTRL_DISCONNECT; + break; + default: + printk(KERN_WARNING "%s: %s: unknown Op %x\n", + hw->name, __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +/* + * device control function + */ +static int +hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct hfcsusb *hw = dch->hw; + struct channel_req *rq; + int err = 0; + + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: cmd:%x %p\n", + hw->name, __func__, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + if ((rq->protocol == ISDN_P_TE_S0) || + (rq->protocol == ISDN_P_NT_S0)) + err = open_dchannel(hw, ch, rq); + else + err = open_bchannel(hw, rq); + if (!err) + hw->open++; + break; + case CLOSE_CHANNEL: + hw->open--; + if (debug & DEBUG_HW_OPEN) + printk(KERN_DEBUG + "%s: %s: dev(%d) close from %p (open %d)\n", + hw->name, __func__, hw->dch.dev.id, + __builtin_return_address(0), hw->open); + if (!hw->open) { + hfcsusb_stop_endpoint(hw, HFC_CHAN_D); + if (hw->fifos[HFCUSB_PCM_RX].pipe) + hfcsusb_stop_endpoint(hw, HFC_CHAN_E); + handle_led(hw, LED_POWER_ON); + } + module_put(THIS_MODULE); + break; + case CONTROL_CHANNEL: + err = channel_ctrl(hw, arg); + break; + default: + if (dch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: unknown command %x\n", + hw->name, __func__, cmd); + return -EINVAL; + } + return err; +} + +/* + * S0 TE state change event handler + */ +static void +ph_state_te(struct dchannel *dch) +{ + struct hfcsusb *hw = dch->hw; + + if (debug & DEBUG_HW) { + if (dch->state <= HFC_MAX_TE_LAYER1_STATE) + printk(KERN_DEBUG "%s: %s: %s\n", hw->name, __func__, + HFC_TE_LAYER1_STATES[dch->state]); + else + printk(KERN_DEBUG "%s: %s: TE F%d\n", + hw->name, __func__, dch->state); + } + + switch (dch->state) { + case 0: + l1_event(dch->l1, HW_RESET_IND); + break; + case 3: + l1_event(dch->l1, HW_DEACT_IND); + break; + case 5: + case 8: + l1_event(dch->l1, ANYSIGNAL); + break; + case 6: + l1_event(dch->l1, INFO2); + break; + case 7: + l1_event(dch->l1, INFO4_P8); + break; + } + if (dch->state == 7) + handle_led(hw, LED_S0_ON); + else + handle_led(hw, LED_S0_OFF); +} + +/* + * S0 NT state change event handler + */ +static void +ph_state_nt(struct dchannel *dch) +{ + struct hfcsusb *hw = dch->hw; + + if (debug & DEBUG_HW) { + if (dch->state <= HFC_MAX_NT_LAYER1_STATE) + printk(KERN_DEBUG "%s: %s: %s\n", + hw->name, __func__, + HFC_NT_LAYER1_STATES[dch->state]); + + else + printk(KERN_INFO DRIVER_NAME "%s: %s: NT G%d\n", + hw->name, __func__, dch->state); + } + + switch (dch->state) { + case (1): + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); + hw->nt_timer = 0; + hw->timers &= ~NT_ACTIVATION_TIMER; + handle_led(hw, LED_S0_OFF); + break; + + case (2): + if (hw->nt_timer < 0) { + hw->nt_timer = 0; + hw->timers &= ~NT_ACTIVATION_TIMER; + hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT); + } else { + hw->timers |= NT_ACTIVATION_TIMER; + hw->nt_timer = NT_T1_COUNT; + /* allow G2 -> G3 transition */ + write_reg(hw, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3); + } + break; + case (3): + hw->nt_timer = 0; + hw->timers &= ~NT_ACTIVATION_TIMER; + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, PH_ACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + handle_led(hw, LED_S0_ON); + break; + case (4): + hw->nt_timer = 0; + hw->timers &= ~NT_ACTIVATION_TIMER; + break; + default: + break; + } + hfcsusb_ph_info(hw); +} + +static void +ph_state(struct dchannel *dch) +{ + struct hfcsusb *hw = dch->hw; + + if (hw->protocol == ISDN_P_NT_S0) + ph_state_nt(dch); + else if (hw->protocol == ISDN_P_TE_S0) + ph_state_te(dch); +} + +/* + * disable/enable BChannel for desired protocoll + */ +static int +hfcsusb_setup_bch(struct bchannel *bch, int protocol) +{ + struct hfcsusb *hw = bch->hw; + __u8 conhdlc, sctrl, sctrl_r; + + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: protocol %x-->%x B%d\n", + hw->name, __func__, bch->state, protocol, + bch->nr); + + /* setup val for CON_HDLC */ + conhdlc = 0; + if (protocol > ISDN_P_NONE) + conhdlc = 8; /* enable FIFO */ + + switch (protocol) { + case (-1): /* used for init */ + bch->state = -1; + /* fall through */ + case (ISDN_P_NONE): + if (bch->state == ISDN_P_NONE) + return 0; /* already in idle state */ + bch->state = ISDN_P_NONE; + clear_bit(FLG_HDLC, &bch->Flags); + clear_bit(FLG_TRANSPARENT, &bch->Flags); + break; + case (ISDN_P_B_RAW): + conhdlc |= 2; + bch->state = protocol; + set_bit(FLG_TRANSPARENT, &bch->Flags); + break; + case (ISDN_P_B_HDLC): + bch->state = protocol; + set_bit(FLG_HDLC, &bch->Flags); + break; + default: + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: prot not known %x\n", + hw->name, __func__, protocol); + return -ENOPROTOOPT; + } + + if (protocol >= ISDN_P_NONE) { + write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 0 : 2); + write_reg(hw, HFCUSB_CON_HDLC, conhdlc); + write_reg(hw, HFCUSB_INC_RES_F, 2); + write_reg(hw, HFCUSB_FIFO, (bch->nr == 1) ? 1 : 3); + write_reg(hw, HFCUSB_CON_HDLC, conhdlc); + write_reg(hw, HFCUSB_INC_RES_F, 2); + + sctrl = 0x40 + ((hw->protocol == ISDN_P_TE_S0) ? 0x00 : 0x04); + sctrl_r = 0x0; + if (test_bit(FLG_ACTIVE, &hw->bch[0].Flags)) { + sctrl |= 1; + sctrl_r |= 1; + } + if (test_bit(FLG_ACTIVE, &hw->bch[1].Flags)) { + sctrl |= 2; + sctrl_r |= 2; + } + write_reg(hw, HFCUSB_SCTRL, sctrl); + write_reg(hw, HFCUSB_SCTRL_R, sctrl_r); + + if (protocol > ISDN_P_NONE) + handle_led(hw, (bch->nr == 1) ? LED_B1_ON : LED_B2_ON); + else + handle_led(hw, (bch->nr == 1) ? LED_B1_OFF : + LED_B2_OFF); + } + hfcsusb_ph_info(hw); + return 0; +} + +static void +hfcsusb_ph_command(struct hfcsusb *hw, u_char command) +{ + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: %x\n", + hw->name, __func__, command); + + switch (command) { + case HFC_L1_ACTIVATE_TE: + /* force sending sending INFO1 */ + write_reg(hw, HFCUSB_STATES, 0x14); + /* start l1 activation */ + write_reg(hw, HFCUSB_STATES, 0x04); + break; + + case HFC_L1_FORCE_DEACTIVATE_TE: + write_reg(hw, HFCUSB_STATES, 0x10); + write_reg(hw, HFCUSB_STATES, 0x03); + break; + + case HFC_L1_ACTIVATE_NT: + if (hw->dch.state == 3) + _queue_data(&hw->dch.dev.D, PH_ACTIVATE_IND, + MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); + else + write_reg(hw, HFCUSB_STATES, HFCUSB_ACTIVATE | + HFCUSB_DO_ACTION | HFCUSB_NT_G2_G3); + break; + + case HFC_L1_DEACTIVATE_NT: + write_reg(hw, HFCUSB_STATES, + HFCUSB_DO_ACTION); + break; + } +} + +/* + * Layer 1 B-channel hardware access + */ +static int +channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + return mISDN_ctrl_bchannel(bch, cq); +} + +/* collect data from incoming interrupt or isochron USB data */ +static void +hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, + int finish) +{ + struct hfcsusb *hw = fifo->hw; + struct sk_buff *rx_skb = NULL; + int maxlen = 0; + int fifon = fifo->fifonum; + int i; + int hdlc = 0; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) " + "dch(%p) bch(%p) ech(%p)\n", + hw->name, __func__, fifon, len, + fifo->dch, fifo->bch, fifo->ech); + + if (!len) + return; + + if ((!!fifo->dch + !!fifo->bch + !!fifo->ech) != 1) { + printk(KERN_DEBUG "%s: %s: undefined channel\n", + hw->name, __func__); + return; + } + + spin_lock(&hw->lock); + if (fifo->dch) { + rx_skb = fifo->dch->rx_skb; + maxlen = fifo->dch->maxlen; + hdlc = 1; + } + if (fifo->bch) { + if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) { + fifo->bch->dropcnt += len; + spin_unlock(&hw->lock); + return; + } + maxlen = bchannel_get_rxbuf(fifo->bch, len); + rx_skb = fifo->bch->rx_skb; + if (maxlen < 0) { + if (rx_skb) + skb_trim(rx_skb, 0); + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + hw->name, fifo->bch->nr, len); + spin_unlock(&hw->lock); + return; + } + maxlen = fifo->bch->maxlen; + hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags); + } + if (fifo->ech) { + rx_skb = fifo->ech->rx_skb; + maxlen = fifo->ech->maxlen; + hdlc = 1; + } + + if (fifo->dch || fifo->ech) { + if (!rx_skb) { + rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC); + if (rx_skb) { + if (fifo->dch) + fifo->dch->rx_skb = rx_skb; + if (fifo->ech) + fifo->ech->rx_skb = rx_skb; + skb_trim(rx_skb, 0); + } else { + printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n", + hw->name, __func__); + spin_unlock(&hw->lock); + return; + } + } + /* D/E-Channel SKB range check */ + if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) { + printk(KERN_DEBUG "%s: %s: sbk mem exceeded " + "for fifo(%d) HFCUSB_D_RX\n", + hw->name, __func__, fifon); + skb_trim(rx_skb, 0); + spin_unlock(&hw->lock); + return; + } + } + + memcpy(skb_put(rx_skb, len), data, len); + + if (hdlc) { + /* we have a complete hdlc packet */ + if (finish) { + if ((rx_skb->len > 3) && + (!(rx_skb->data[rx_skb->len - 1]))) { + if (debug & DBG_HFC_FIFO_VERBOSE) { + printk(KERN_DEBUG "%s: %s: fifon(%i)" + " new RX len(%i): ", + hw->name, __func__, fifon, + rx_skb->len); + i = 0; + while (i < rx_skb->len) + printk("%02x ", + rx_skb->data[i++]); + printk("\n"); + } + + /* remove CRC & status */ + skb_trim(rx_skb, rx_skb->len - 3); + + if (fifo->dch) + recv_Dchannel(fifo->dch); + if (fifo->bch) + recv_Bchannel(fifo->bch, MISDN_ID_ANY, + 0); + if (fifo->ech) + recv_Echannel(fifo->ech, + &hw->dch); + } else { + if (debug & DBG_HFC_FIFO_VERBOSE) { + printk(KERN_DEBUG + "%s: CRC or minlen ERROR fifon(%i) " + "RX len(%i): ", + hw->name, fifon, rx_skb->len); + i = 0; + while (i < rx_skb->len) + printk("%02x ", + rx_skb->data[i++]); + printk("\n"); + } + skb_trim(rx_skb, 0); + } + } + } else { + /* deliver transparent data to layer2 */ + recv_Bchannel(fifo->bch, MISDN_ID_ANY, false); + } + spin_unlock(&hw->lock); +} + +static void +fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, + void *buf, int num_packets, int packet_size, int interval, + usb_complete_t complete, void *context) +{ + int k; + + usb_fill_bulk_urb(urb, dev, pipe, buf, packet_size * num_packets, + complete, context); + + urb->number_of_packets = num_packets; + urb->transfer_flags = URB_ISO_ASAP; + urb->actual_length = 0; + urb->interval = interval; + + for (k = 0; k < num_packets; k++) { + urb->iso_frame_desc[k].offset = packet_size * k; + urb->iso_frame_desc[k].length = packet_size; + urb->iso_frame_desc[k].actual_length = 0; + } +} + +/* receive completion routine for all ISO tx fifos */ +static void +rx_iso_complete(struct urb *urb) +{ + struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context; + struct usb_fifo *fifo = context_iso_urb->owner_fifo; + struct hfcsusb *hw = fifo->hw; + int k, len, errcode, offset, num_isoc_packets, fifon, maxlen, + status, iso_status, i; + __u8 *buf; + static __u8 eof[8]; + __u8 s0_state; + + fifon = fifo->fifonum; + status = urb->status; + + spin_lock(&hw->lock); + if (fifo->stop_gracefull) { + fifo->stop_gracefull = 0; + fifo->active = 0; + spin_unlock(&hw->lock); + return; + } + spin_unlock(&hw->lock); + + /* + * ISO transfer only partially completed, + * look at individual frame status for details + */ + if (status == -EXDEV) { + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: with -EXDEV " + "urb->status %d, fifonum %d\n", + hw->name, __func__, status, fifon); + + /* clear status, so go on with ISO transfers */ + status = 0; + } + + s0_state = 0; + if (fifo->active && !status) { + num_isoc_packets = iso_packets[fifon]; + maxlen = fifo->usb_packet_maxlen; + + for (k = 0; k < num_isoc_packets; ++k) { + len = urb->iso_frame_desc[k].actual_length; + offset = urb->iso_frame_desc[k].offset; + buf = context_iso_urb->buffer + offset; + iso_status = urb->iso_frame_desc[k].status; + + if (iso_status && (debug & DBG_HFC_FIFO_VERBOSE)) { + printk(KERN_DEBUG "%s: %s: " + "ISO packet %i, status: %i\n", + hw->name, __func__, k, iso_status); + } + + /* USB data log for every D ISO in */ + if ((fifon == HFCUSB_D_RX) && + (debug & DBG_HFC_USB_VERBOSE)) { + printk(KERN_DEBUG + "%s: %s: %d (%d/%d) len(%d) ", + hw->name, __func__, urb->start_frame, + k, num_isoc_packets - 1, + len); + for (i = 0; i < len; i++) + printk("%x ", buf[i]); + printk("\n"); + } + + if (!iso_status) { + if (fifo->last_urblen != maxlen) { + /* + * save fifo fill-level threshold bits + * to use them later in TX ISO URB + * completions + */ + hw->threshold_mask = buf[1]; + + if (fifon == HFCUSB_D_RX) + s0_state = (buf[0] >> 4); + + eof[fifon] = buf[0] & 1; + if (len > 2) + hfcsusb_rx_frame(fifo, buf + 2, + len - 2, (len < maxlen) + ? eof[fifon] : 0); + } else + hfcsusb_rx_frame(fifo, buf, len, + (len < maxlen) ? + eof[fifon] : 0); + fifo->last_urblen = len; + } + } + + /* signal S0 layer1 state change */ + if ((s0_state) && (hw->initdone) && + (s0_state != hw->dch.state)) { + hw->dch.state = s0_state; + schedule_event(&hw->dch, FLG_PHCHANGE); + } + + fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe, + context_iso_urb->buffer, num_isoc_packets, + fifo->usb_packet_maxlen, fifo->intervall, + (usb_complete_t)rx_iso_complete, urb->context); + errcode = usb_submit_urb(urb, GFP_ATOMIC); + if (errcode < 0) { + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: error submitting " + "ISO URB: %d\n", + hw->name, __func__, errcode); + } + } else { + if (status && (debug & DBG_HFC_URB_INFO)) + printk(KERN_DEBUG "%s: %s: rx_iso_complete : " + "urb->status %d, fifonum %d\n", + hw->name, __func__, status, fifon); + } +} + +/* receive completion routine for all interrupt rx fifos */ +static void +rx_int_complete(struct urb *urb) +{ + int len, status, i; + __u8 *buf, maxlen, fifon; + struct usb_fifo *fifo = (struct usb_fifo *) urb->context; + struct hfcsusb *hw = fifo->hw; + static __u8 eof[8]; + + spin_lock(&hw->lock); + if (fifo->stop_gracefull) { + fifo->stop_gracefull = 0; + fifo->active = 0; + spin_unlock(&hw->lock); + return; + } + spin_unlock(&hw->lock); + + fifon = fifo->fifonum; + if ((!fifo->active) || (urb->status)) { + if (debug & DBG_HFC_URB_ERROR) + printk(KERN_DEBUG + "%s: %s: RX-Fifo %i is going down (%i)\n", + hw->name, __func__, fifon, urb->status); + + fifo->urb->interval = 0; /* cancel automatic rescheduling */ + return; + } + len = urb->actual_length; + buf = fifo->buffer; + maxlen = fifo->usb_packet_maxlen; + + /* USB data log for every D INT in */ + if ((fifon == HFCUSB_D_RX) && (debug & DBG_HFC_USB_VERBOSE)) { + printk(KERN_DEBUG "%s: %s: D RX INT len(%d) ", + hw->name, __func__, len); + for (i = 0; i < len; i++) + printk("%02x ", buf[i]); + printk("\n"); + } + + if (fifo->last_urblen != fifo->usb_packet_maxlen) { + /* the threshold mask is in the 2nd status byte */ + hw->threshold_mask = buf[1]; + + /* signal S0 layer1 state change */ + if (hw->initdone && ((buf[0] >> 4) != hw->dch.state)) { + hw->dch.state = (buf[0] >> 4); + schedule_event(&hw->dch, FLG_PHCHANGE); + } + + eof[fifon] = buf[0] & 1; + /* if we have more than the 2 status bytes -> collect data */ + if (len > 2) + hfcsusb_rx_frame(fifo, buf + 2, + urb->actual_length - 2, + (len < maxlen) ? eof[fifon] : 0); + } else { + hfcsusb_rx_frame(fifo, buf, urb->actual_length, + (len < maxlen) ? eof[fifon] : 0); + } + fifo->last_urblen = urb->actual_length; + + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) { + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: error resubmitting USB\n", + hw->name, __func__); + } +} + +/* transmit completion routine for all ISO tx fifos */ +static void +tx_iso_complete(struct urb *urb) +{ + struct iso_urb *context_iso_urb = (struct iso_urb *) urb->context; + struct usb_fifo *fifo = context_iso_urb->owner_fifo; + struct hfcsusb *hw = fifo->hw; + struct sk_buff *tx_skb; + int k, tx_offset, num_isoc_packets, sink, remain, current_len, + errcode, hdlc, i; + int *tx_idx; + int frame_complete, fifon, status, fillempty = 0; + __u8 threshbit, *p; + + spin_lock(&hw->lock); + if (fifo->stop_gracefull) { + fifo->stop_gracefull = 0; + fifo->active = 0; + spin_unlock(&hw->lock); + return; + } + + if (fifo->dch) { + tx_skb = fifo->dch->tx_skb; + tx_idx = &fifo->dch->tx_idx; + hdlc = 1; + } else if (fifo->bch) { + tx_skb = fifo->bch->tx_skb; + tx_idx = &fifo->bch->tx_idx; + hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags); + if (!tx_skb && !hdlc && + test_bit(FLG_FILLEMPTY, &fifo->bch->Flags)) + fillempty = 1; + } else { + printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n", + hw->name, __func__); + spin_unlock(&hw->lock); + return; + } + + fifon = fifo->fifonum; + status = urb->status; + + tx_offset = 0; + + /* + * ISO transfer only partially completed, + * look at individual frame status for details + */ + if (status == -EXDEV) { + if (debug & DBG_HFC_URB_ERROR) + printk(KERN_DEBUG "%s: %s: " + "-EXDEV (%i) fifon (%d)\n", + hw->name, __func__, status, fifon); + + /* clear status, so go on with ISO transfers */ + status = 0; + } + + if (fifo->active && !status) { + /* is FifoFull-threshold set for our channel? */ + threshbit = (hw->threshold_mask & (1 << fifon)); + num_isoc_packets = iso_packets[fifon]; + + /* predict dataflow to avoid fifo overflow */ + if (fifon >= HFCUSB_D_TX) + sink = (threshbit) ? SINK_DMIN : SINK_DMAX; + else + sink = (threshbit) ? SINK_MIN : SINK_MAX; + fill_isoc_urb(urb, fifo->hw->dev, fifo->pipe, + context_iso_urb->buffer, num_isoc_packets, + fifo->usb_packet_maxlen, fifo->intervall, + (usb_complete_t)tx_iso_complete, urb->context); + memset(context_iso_urb->buffer, 0, + sizeof(context_iso_urb->buffer)); + frame_complete = 0; + + for (k = 0; k < num_isoc_packets; ++k) { + /* analyze tx success of previous ISO packets */ + if (debug & DBG_HFC_URB_ERROR) { + errcode = urb->iso_frame_desc[k].status; + if (errcode) { + printk(KERN_DEBUG "%s: %s: " + "ISO packet %i, status: %i\n", + hw->name, __func__, k, errcode); + } + } + + /* Generate next ISO Packets */ + if (tx_skb) + remain = tx_skb->len - *tx_idx; + else if (fillempty) + remain = 15; /* > not complete */ + else + remain = 0; + + if (remain > 0) { + fifo->bit_line -= sink; + current_len = (0 - fifo->bit_line) / 8; + if (current_len > 14) + current_len = 14; + if (current_len < 0) + current_len = 0; + if (remain < current_len) + current_len = remain; + + /* how much bit do we put on the line? */ + fifo->bit_line += current_len * 8; + + context_iso_urb->buffer[tx_offset] = 0; + if (current_len == remain) { + if (hdlc) { + /* signal frame completion */ + context_iso_urb-> + buffer[tx_offset] = 1; + /* add 2 byte flags and 16bit + * CRC at end of ISDN frame */ + fifo->bit_line += 32; + } + frame_complete = 1; + } + + /* copy tx data to iso-urb buffer */ + p = context_iso_urb->buffer + tx_offset + 1; + if (fillempty) { + memset(p, fifo->bch->fill[0], + current_len); + } else { + memcpy(p, (tx_skb->data + *tx_idx), + current_len); + *tx_idx += current_len; + } + urb->iso_frame_desc[k].offset = tx_offset; + urb->iso_frame_desc[k].length = current_len + 1; + + /* USB data log for every D ISO out */ + if ((fifon == HFCUSB_D_RX) && !fillempty && + (debug & DBG_HFC_USB_VERBOSE)) { + printk(KERN_DEBUG + "%s: %s (%d/%d) offs(%d) len(%d) ", + hw->name, __func__, + k, num_isoc_packets - 1, + urb->iso_frame_desc[k].offset, + urb->iso_frame_desc[k].length); + + for (i = urb->iso_frame_desc[k].offset; + i < (urb->iso_frame_desc[k].offset + + urb->iso_frame_desc[k].length); + i++) + printk("%x ", + context_iso_urb->buffer[i]); + + printk(" skb->len(%i) tx-idx(%d)\n", + tx_skb->len, *tx_idx); + } + + tx_offset += (current_len + 1); + } else { + urb->iso_frame_desc[k].offset = tx_offset++; + urb->iso_frame_desc[k].length = 1; + /* we lower data margin every msec */ + fifo->bit_line -= sink; + if (fifo->bit_line < BITLINE_INF) + fifo->bit_line = BITLINE_INF; + } + + if (frame_complete) { + frame_complete = 0; + + if (debug & DBG_HFC_FIFO_VERBOSE) { + printk(KERN_DEBUG "%s: %s: " + "fifon(%i) new TX len(%i): ", + hw->name, __func__, + fifon, tx_skb->len); + i = 0; + while (i < tx_skb->len) + printk("%02x ", + tx_skb->data[i++]); + printk("\n"); + } + + dev_kfree_skb(tx_skb); + tx_skb = NULL; + if (fifo->dch && get_next_dframe(fifo->dch)) + tx_skb = fifo->dch->tx_skb; + else if (fifo->bch && + get_next_bframe(fifo->bch)) + tx_skb = fifo->bch->tx_skb; + } + } + errcode = usb_submit_urb(urb, GFP_ATOMIC); + if (errcode < 0) { + if (debug & DEBUG_HW) + printk(KERN_DEBUG + "%s: %s: error submitting ISO URB: %d \n", + hw->name, __func__, errcode); + } + + /* + * abuse DChannel tx iso completion to trigger NT mode state + * changes tx_iso_complete is assumed to be called every + * fifo->intervall (ms) + */ + if ((fifon == HFCUSB_D_TX) && (hw->protocol == ISDN_P_NT_S0) + && (hw->timers & NT_ACTIVATION_TIMER)) { + if ((--hw->nt_timer) < 0) + schedule_event(&hw->dch, FLG_PHCHANGE); + } + + } else { + if (status && (debug & DBG_HFC_URB_ERROR)) + printk(KERN_DEBUG "%s: %s: urb->status %s (%i)" + "fifonum=%d\n", + hw->name, __func__, + symbolic(urb_errlist, status), status, fifon); + } + spin_unlock(&hw->lock); +} + +/* + * allocs urbs and start isoc transfer with two pending urbs to avoid + * gaps in the transfer chain + */ +static int +start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb, + usb_complete_t complete, int packet_size) +{ + struct hfcsusb *hw = fifo->hw; + int i, k, errcode; + + if (debug) + printk(KERN_DEBUG "%s: %s: fifo %i\n", + hw->name, __func__, fifo->fifonum); + + /* allocate Memory for Iso out Urbs */ + for (i = 0; i < 2; i++) { + if (!(fifo->iso[i].urb)) { + fifo->iso[i].urb = + usb_alloc_urb(num_packets_per_urb, GFP_KERNEL); + if (!(fifo->iso[i].urb)) { + printk(KERN_DEBUG + "%s: %s: alloc urb for fifo %i failed", + hw->name, __func__, fifo->fifonum); + } + fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo; + fifo->iso[i].indx = i; + + /* Init the first iso */ + if (ISO_BUFFER_SIZE >= + (fifo->usb_packet_maxlen * + num_packets_per_urb)) { + fill_isoc_urb(fifo->iso[i].urb, + fifo->hw->dev, fifo->pipe, + fifo->iso[i].buffer, + num_packets_per_urb, + fifo->usb_packet_maxlen, + fifo->intervall, complete, + &fifo->iso[i]); + memset(fifo->iso[i].buffer, 0, + sizeof(fifo->iso[i].buffer)); + + for (k = 0; k < num_packets_per_urb; k++) { + fifo->iso[i].urb-> + iso_frame_desc[k].offset = + k * packet_size; + fifo->iso[i].urb-> + iso_frame_desc[k].length = + packet_size; + } + } else { + printk(KERN_DEBUG + "%s: %s: ISO Buffer size to small!\n", + hw->name, __func__); + } + } + fifo->bit_line = BITLINE_INF; + + errcode = usb_submit_urb(fifo->iso[i].urb, GFP_KERNEL); + fifo->active = (errcode >= 0) ? 1 : 0; + fifo->stop_gracefull = 0; + if (errcode < 0) { + printk(KERN_DEBUG "%s: %s: %s URB nr:%d\n", + hw->name, __func__, + symbolic(urb_errlist, errcode), i); + } + } + return fifo->active; +} + +static void +stop_iso_gracefull(struct usb_fifo *fifo) +{ + struct hfcsusb *hw = fifo->hw; + int i, timeout; + u_long flags; + + for (i = 0; i < 2; i++) { + spin_lock_irqsave(&hw->lock, flags); + if (debug) + printk(KERN_DEBUG "%s: %s for fifo %i.%i\n", + hw->name, __func__, fifo->fifonum, i); + fifo->stop_gracefull = 1; + spin_unlock_irqrestore(&hw->lock, flags); + } + + for (i = 0; i < 2; i++) { + timeout = 3; + while (fifo->stop_gracefull && timeout--) + schedule_timeout_interruptible((HZ / 1000) * 16); + if (debug && fifo->stop_gracefull) + printk(KERN_DEBUG "%s: ERROR %s for fifo %i.%i\n", + hw->name, __func__, fifo->fifonum, i); + } +} + +static void +stop_int_gracefull(struct usb_fifo *fifo) +{ + struct hfcsusb *hw = fifo->hw; + int timeout; + u_long flags; + + spin_lock_irqsave(&hw->lock, flags); + if (debug) + printk(KERN_DEBUG "%s: %s for fifo %i\n", + hw->name, __func__, fifo->fifonum); + fifo->stop_gracefull = 1; + spin_unlock_irqrestore(&hw->lock, flags); + + timeout = 3; + while (fifo->stop_gracefull && timeout--) + schedule_timeout_interruptible((HZ / 1000) * 3); + if (debug && fifo->stop_gracefull) + printk(KERN_DEBUG "%s: ERROR %s for fifo %i\n", + hw->name, __func__, fifo->fifonum); +} + +/* start the interrupt transfer for the given fifo */ +static void +start_int_fifo(struct usb_fifo *fifo) +{ + struct hfcsusb *hw = fifo->hw; + int errcode; + + if (debug) + printk(KERN_DEBUG "%s: %s: INT IN fifo:%d\n", + hw->name, __func__, fifo->fifonum); + + if (!fifo->urb) { + fifo->urb = usb_alloc_urb(0, GFP_KERNEL); + if (!fifo->urb) + return; + } + usb_fill_int_urb(fifo->urb, fifo->hw->dev, fifo->pipe, + fifo->buffer, fifo->usb_packet_maxlen, + (usb_complete_t)rx_int_complete, fifo, fifo->intervall); + fifo->active = 1; + fifo->stop_gracefull = 0; + errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); + if (errcode) { + printk(KERN_DEBUG "%s: %s: submit URB: status:%i\n", + hw->name, __func__, errcode); + fifo->active = 0; + } +} + +static void +setPortMode(struct hfcsusb *hw) +{ + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s %s\n", hw->name, __func__, + (hw->protocol == ISDN_P_TE_S0) ? "TE" : "NT"); + + if (hw->protocol == ISDN_P_TE_S0) { + write_reg(hw, HFCUSB_SCTRL, 0x40); + write_reg(hw, HFCUSB_SCTRL_E, 0x00); + write_reg(hw, HFCUSB_CLKDEL, CLKDEL_TE); + write_reg(hw, HFCUSB_STATES, 3 | 0x10); + write_reg(hw, HFCUSB_STATES, 3); + } else { + write_reg(hw, HFCUSB_SCTRL, 0x44); + write_reg(hw, HFCUSB_SCTRL_E, 0x09); + write_reg(hw, HFCUSB_CLKDEL, CLKDEL_NT); + write_reg(hw, HFCUSB_STATES, 1 | 0x10); + write_reg(hw, HFCUSB_STATES, 1); + } +} + +static void +reset_hfcsusb(struct hfcsusb *hw) +{ + struct usb_fifo *fifo; + int i; + + if (debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); + + /* do Chip reset */ + write_reg(hw, HFCUSB_CIRM, 8); + + /* aux = output, reset off */ + write_reg(hw, HFCUSB_CIRM, 0x10); + + /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */ + write_reg(hw, HFCUSB_USB_SIZE, (hw->packet_size / 8) | + ((hw->packet_size / 8) << 4)); + + /* set USB_SIZE_I to match the the wMaxPacketSize for ISO transfers */ + write_reg(hw, HFCUSB_USB_SIZE_I, hw->iso_packet_size); + + /* enable PCM/GCI master mode */ + write_reg(hw, HFCUSB_MST_MODE1, 0); /* set default values */ + write_reg(hw, HFCUSB_MST_MODE0, 1); /* enable master mode */ + + /* init the fifos */ + write_reg(hw, HFCUSB_F_THRES, + (HFCUSB_TX_THRESHOLD / 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4)); + + fifo = hw->fifos; + for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { + write_reg(hw, HFCUSB_FIFO, i); /* select the desired fifo */ + fifo[i].max_size = + (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN; + fifo[i].last_urblen = 0; + + /* set 2 bit for D- & E-channel */ + write_reg(hw, HFCUSB_HDLC_PAR, ((i <= HFCUSB_B2_RX) ? 0 : 2)); + + /* enable all fifos */ + if (i == HFCUSB_D_TX) + write_reg(hw, HFCUSB_CON_HDLC, + (hw->protocol == ISDN_P_NT_S0) ? 0x08 : 0x09); + else + write_reg(hw, HFCUSB_CON_HDLC, 0x08); + write_reg(hw, HFCUSB_INC_RES_F, 2); /* reset the fifo */ + } + + write_reg(hw, HFCUSB_SCTRL_R, 0); /* disable both B receivers */ + handle_led(hw, LED_POWER_ON); +} + +/* start USB data pipes dependand on device's endpoint configuration */ +static void +hfcsusb_start_endpoint(struct hfcsusb *hw, int channel) +{ + /* quick check if endpoint already running */ + if ((channel == HFC_CHAN_D) && (hw->fifos[HFCUSB_D_RX].active)) + return; + if ((channel == HFC_CHAN_B1) && (hw->fifos[HFCUSB_B1_RX].active)) + return; + if ((channel == HFC_CHAN_B2) && (hw->fifos[HFCUSB_B2_RX].active)) + return; + if ((channel == HFC_CHAN_E) && (hw->fifos[HFCUSB_PCM_RX].active)) + return; + + /* start rx endpoints using USB INT IN method */ + if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO) + start_int_fifo(hw->fifos + channel * 2 + 1); + + /* start rx endpoints using USB ISO IN method */ + if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO) { + switch (channel) { + case HFC_CHAN_D: + start_isoc_chain(hw->fifos + HFCUSB_D_RX, + ISOC_PACKETS_D, + (usb_complete_t)rx_iso_complete, + 16); + break; + case HFC_CHAN_E: + start_isoc_chain(hw->fifos + HFCUSB_PCM_RX, + ISOC_PACKETS_D, + (usb_complete_t)rx_iso_complete, + 16); + break; + case HFC_CHAN_B1: + start_isoc_chain(hw->fifos + HFCUSB_B1_RX, + ISOC_PACKETS_B, + (usb_complete_t)rx_iso_complete, + 16); + break; + case HFC_CHAN_B2: + start_isoc_chain(hw->fifos + HFCUSB_B2_RX, + ISOC_PACKETS_B, + (usb_complete_t)rx_iso_complete, + 16); + break; + } + } + + /* start tx endpoints using USB ISO OUT method */ + switch (channel) { + case HFC_CHAN_D: + start_isoc_chain(hw->fifos + HFCUSB_D_TX, + ISOC_PACKETS_B, + (usb_complete_t)tx_iso_complete, 1); + break; + case HFC_CHAN_B1: + start_isoc_chain(hw->fifos + HFCUSB_B1_TX, + ISOC_PACKETS_D, + (usb_complete_t)tx_iso_complete, 1); + break; + case HFC_CHAN_B2: + start_isoc_chain(hw->fifos + HFCUSB_B2_TX, + ISOC_PACKETS_B, + (usb_complete_t)tx_iso_complete, 1); + break; + } +} + +/* stop USB data pipes dependand on device's endpoint configuration */ +static void +hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel) +{ + /* quick check if endpoint currently running */ + if ((channel == HFC_CHAN_D) && (!hw->fifos[HFCUSB_D_RX].active)) + return; + if ((channel == HFC_CHAN_B1) && (!hw->fifos[HFCUSB_B1_RX].active)) + return; + if ((channel == HFC_CHAN_B2) && (!hw->fifos[HFCUSB_B2_RX].active)) + return; + if ((channel == HFC_CHAN_E) && (!hw->fifos[HFCUSB_PCM_RX].active)) + return; + + /* rx endpoints using USB INT IN method */ + if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO) + stop_int_gracefull(hw->fifos + channel * 2 + 1); + + /* rx endpoints using USB ISO IN method */ + if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO) + stop_iso_gracefull(hw->fifos + channel * 2 + 1); + + /* tx endpoints using USB ISO OUT method */ + if (channel != HFC_CHAN_E) + stop_iso_gracefull(hw->fifos + channel * 2); +} + + +/* Hardware Initialization */ +static int +setup_hfcsusb(struct hfcsusb *hw) +{ + u_char b; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); + + /* check the chip id */ + if (read_reg_atomic(hw, HFCUSB_CHIP_ID, &b) != 1) { + printk(KERN_DEBUG "%s: %s: cannot read chip id\n", + hw->name, __func__); + return 1; + } + if (b != HFCUSB_CHIPID) { + printk(KERN_DEBUG "%s: %s: Invalid chip id 0x%02x\n", + hw->name, __func__, b); + return 1; + } + + /* first set the needed config, interface and alternate */ + (void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used); + + hw->led_state = 0; + + /* init the background machinery for control requests */ + hw->ctrl_read.bRequestType = 0xc0; + hw->ctrl_read.bRequest = 1; + hw->ctrl_read.wLength = cpu_to_le16(1); + hw->ctrl_write.bRequestType = 0x40; + hw->ctrl_write.bRequest = 0; + hw->ctrl_write.wLength = 0; + usb_fill_control_urb(hw->ctrl_urb, hw->dev, hw->ctrl_out_pipe, + (u_char *)&hw->ctrl_write, NULL, 0, + (usb_complete_t)ctrl_complete, hw); + + reset_hfcsusb(hw); + return 0; +} + +static void +release_hw(struct hfcsusb *hw) +{ + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); + + /* + * stop all endpoints gracefully + * TODO: mISDN_core should generate CLOSE_CHANNEL + * signals after calling mISDN_unregister_device() + */ + hfcsusb_stop_endpoint(hw, HFC_CHAN_D); + hfcsusb_stop_endpoint(hw, HFC_CHAN_B1); + hfcsusb_stop_endpoint(hw, HFC_CHAN_B2); + if (hw->fifos[HFCUSB_PCM_RX].pipe) + hfcsusb_stop_endpoint(hw, HFC_CHAN_E); + if (hw->protocol == ISDN_P_TE_S0) + l1_event(hw->dch.l1, CLOSE_CHANNEL); + + mISDN_unregister_device(&hw->dch.dev); + mISDN_freebchannel(&hw->bch[1]); + mISDN_freebchannel(&hw->bch[0]); + mISDN_freedchannel(&hw->dch); + + if (hw->ctrl_urb) { + usb_kill_urb(hw->ctrl_urb); + usb_free_urb(hw->ctrl_urb); + hw->ctrl_urb = NULL; + } + + if (hw->intf) + usb_set_intfdata(hw->intf, NULL); + list_del(&hw->list); + kfree(hw); + hw = NULL; +} + +static void +deactivate_bchannel(struct bchannel *bch) +{ + struct hfcsusb *hw = bch->hw; + u_long flags; + + if (bch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: %s: bch->nr(%i)\n", + hw->name, __func__, bch->nr); + + spin_lock_irqsave(&hw->lock, flags); + mISDN_clear_bchannel(bch); + spin_unlock_irqrestore(&hw->lock, flags); + hfcsusb_setup_bch(bch, ISDN_P_NONE); + hfcsusb_stop_endpoint(hw, bch->nr - 1); +} + +/* + * Layer 1 B-channel hardware access + */ +static int +hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + int ret = -EINVAL; + + if (bch->debug & DEBUG_HW) + printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg); + + switch (cmd) { + case HW_TESTRX_RAW: + case HW_TESTRX_HDLC: + case HW_TESTRX_OFF: + ret = -EINVAL; + break; + + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + deactivate_bchannel(bch); + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(THIS_MODULE); + ret = 0; + break; + case CONTROL_CHANNEL: + ret = channel_bctrl(bch, arg); + break; + default: + printk(KERN_WARNING "%s: unknown prim(%x)\n", + __func__, cmd); + } + return ret; +} + +static int +setup_instance(struct hfcsusb *hw, struct device *parent) +{ + u_long flags; + int err, i; + + if (debug & DBG_HFC_CALL_TRACE) + printk(KERN_DEBUG "%s: %s\n", hw->name, __func__); + + spin_lock_init(&hw->ctrl_lock); + spin_lock_init(&hw->lock); + + mISDN_initdchannel(&hw->dch, MAX_DFRAME_LEN_L1, ph_state); + hw->dch.debug = debug & 0xFFFF; + hw->dch.hw = hw; + hw->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0); + hw->dch.dev.D.send = hfcusb_l2l1D; + hw->dch.dev.D.ctrl = hfc_dctrl; + + /* enable E-Channel logging */ + if (hw->fifos[HFCUSB_PCM_RX].pipe) + mISDN_initdchannel(&hw->ech, MAX_DFRAME_LEN_L1, NULL); + + hw->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + hw->dch.dev.nrbchan = 2; + for (i = 0; i < 2; i++) { + hw->bch[i].nr = i + 1; + set_channelmap(i + 1, hw->dch.dev.channelmap); + hw->bch[i].debug = debug; + mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1); + hw->bch[i].hw = hw; + hw->bch[i].ch.send = hfcusb_l2l1B; + hw->bch[i].ch.ctrl = hfc_bctrl; + hw->bch[i].ch.nr = i + 1; + list_add(&hw->bch[i].ch.list, &hw->dch.dev.bchannels); + } + + hw->fifos[HFCUSB_B1_TX].bch = &hw->bch[0]; + hw->fifos[HFCUSB_B1_RX].bch = &hw->bch[0]; + hw->fifos[HFCUSB_B2_TX].bch = &hw->bch[1]; + hw->fifos[HFCUSB_B2_RX].bch = &hw->bch[1]; + hw->fifos[HFCUSB_D_TX].dch = &hw->dch; + hw->fifos[HFCUSB_D_RX].dch = &hw->dch; + hw->fifos[HFCUSB_PCM_RX].ech = &hw->ech; + hw->fifos[HFCUSB_PCM_TX].ech = &hw->ech; + + err = setup_hfcsusb(hw); + if (err) + goto out; + + snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s.%d", DRIVER_NAME, + hfcsusb_cnt + 1); + printk(KERN_INFO "%s: registered as '%s'\n", + DRIVER_NAME, hw->name); + + err = mISDN_register_device(&hw->dch.dev, parent, hw->name); + if (err) + goto out; + + hfcsusb_cnt++; + write_lock_irqsave(&HFClock, flags); + list_add_tail(&hw->list, &HFClist); + write_unlock_irqrestore(&HFClock, flags); + return 0; + +out: + mISDN_freebchannel(&hw->bch[1]); + mISDN_freebchannel(&hw->bch[0]); + mISDN_freedchannel(&hw->dch); + kfree(hw); + return err; +} + +static int +hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct hfcsusb *hw; + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *iface = intf->cur_altsetting; + struct usb_host_interface *iface_used = NULL; + struct usb_host_endpoint *ep; + struct hfcsusb_vdata *driver_info; + int ifnum = iface->desc.bInterfaceNumber, i, idx, alt_idx, + probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found, + ep_addr, cmptbl[16], small_match, iso_packet_size, packet_size, + alt_used = 0; + + vend_idx = 0xffff; + for (i = 0; hfcsusb_idtab[i].idVendor; i++) { + if ((le16_to_cpu(dev->descriptor.idVendor) + == hfcsusb_idtab[i].idVendor) && + (le16_to_cpu(dev->descriptor.idProduct) + == hfcsusb_idtab[i].idProduct)) { + vend_idx = i; + continue; + } + } + + printk(KERN_DEBUG + "%s: interface(%d) actalt(%d) minor(%d) vend_idx(%d)\n", + __func__, ifnum, iface->desc.bAlternateSetting, + intf->minor, vend_idx); + + if (vend_idx == 0xffff) { + printk(KERN_WARNING + "%s: no valid vendor found in USB descriptor\n", + __func__); + return -EIO; + } + /* if vendor and product ID is OK, start probing alternate settings */ + alt_idx = 0; + small_match = -1; + + /* default settings */ + iso_packet_size = 16; + packet_size = 64; + + while (alt_idx < intf->num_altsetting) { + iface = intf->altsetting + alt_idx; + probe_alt_setting = iface->desc.bAlternateSetting; + cfg_used = 0; + + while (validconf[cfg_used][0]) { + cfg_found = 1; + vcf = validconf[cfg_used]; + ep = iface->endpoint; + memcpy(cmptbl, vcf, 16 * sizeof(int)); + + /* check for all endpoints in this alternate setting */ + for (i = 0; i < iface->desc.bNumEndpoints; i++) { + ep_addr = ep->desc.bEndpointAddress; + + /* get endpoint base */ + idx = ((ep_addr & 0x7f) - 1) * 2; + if (ep_addr & 0x80) + idx++; + attr = ep->desc.bmAttributes; + + if (cmptbl[idx] != EP_NOP) { + if (cmptbl[idx] == EP_NUL) + cfg_found = 0; + if (attr == USB_ENDPOINT_XFER_INT + && cmptbl[idx] == EP_INT) + cmptbl[idx] = EP_NUL; + if (attr == USB_ENDPOINT_XFER_BULK + && cmptbl[idx] == EP_BLK) + cmptbl[idx] = EP_NUL; + if (attr == USB_ENDPOINT_XFER_ISOC + && cmptbl[idx] == EP_ISO) + cmptbl[idx] = EP_NUL; + + if (attr == USB_ENDPOINT_XFER_INT && + ep->desc.bInterval < vcf[17]) { + cfg_found = 0; + } + } + ep++; + } + + for (i = 0; i < 16; i++) + if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL) + cfg_found = 0; + + if (cfg_found) { + if (small_match < cfg_used) { + small_match = cfg_used; + alt_used = probe_alt_setting; + iface_used = iface; + } + } + cfg_used++; + } + alt_idx++; + } /* (alt_idx < intf->num_altsetting) */ + + /* not found a valid USB Ta Endpoint config */ + if (small_match == -1) + return -EIO; + + iface = iface_used; + hw = kzalloc(sizeof(struct hfcsusb), GFP_KERNEL); + if (!hw) + return -ENOMEM; /* got no mem */ + snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s", DRIVER_NAME); + + ep = iface->endpoint; + vcf = validconf[small_match]; + + for (i = 0; i < iface->desc.bNumEndpoints; i++) { + struct usb_fifo *f; + + ep_addr = ep->desc.bEndpointAddress; + /* get endpoint base */ + idx = ((ep_addr & 0x7f) - 1) * 2; + if (ep_addr & 0x80) + idx++; + f = &hw->fifos[idx & 7]; + + /* init Endpoints */ + if (vcf[idx] == EP_NOP || vcf[idx] == EP_NUL) { + ep++; + continue; + } + switch (ep->desc.bmAttributes) { + case USB_ENDPOINT_XFER_INT: + f->pipe = usb_rcvintpipe(dev, + ep->desc.bEndpointAddress); + f->usb_transfer_mode = USB_INT; + packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); + break; + case USB_ENDPOINT_XFER_BULK: + if (ep_addr & 0x80) + f->pipe = usb_rcvbulkpipe(dev, + ep->desc.bEndpointAddress); + else + f->pipe = usb_sndbulkpipe(dev, + ep->desc.bEndpointAddress); + f->usb_transfer_mode = USB_BULK; + packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); + break; + case USB_ENDPOINT_XFER_ISOC: + if (ep_addr & 0x80) + f->pipe = usb_rcvisocpipe(dev, + ep->desc.bEndpointAddress); + else + f->pipe = usb_sndisocpipe(dev, + ep->desc.bEndpointAddress); + f->usb_transfer_mode = USB_ISOC; + iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize); + break; + default: + f->pipe = 0; + } + + if (f->pipe) { + f->fifonum = idx & 7; + f->hw = hw; + f->usb_packet_maxlen = + le16_to_cpu(ep->desc.wMaxPacketSize); + f->intervall = ep->desc.bInterval; + } + ep++; + } + hw->dev = dev; /* save device */ + hw->if_used = ifnum; /* save used interface */ + hw->alt_used = alt_used; /* and alternate config */ + hw->ctrl_paksize = dev->descriptor.bMaxPacketSize0; /* control size */ + hw->cfg_used = vcf[16]; /* store used config */ + hw->vend_idx = vend_idx; /* store found vendor */ + hw->packet_size = packet_size; + hw->iso_packet_size = iso_packet_size; + + /* create the control pipes needed for register access */ + hw->ctrl_in_pipe = usb_rcvctrlpipe(hw->dev, 0); + hw->ctrl_out_pipe = usb_sndctrlpipe(hw->dev, 0); + + driver_info = (struct hfcsusb_vdata *) + hfcsusb_idtab[vend_idx].driver_info; + + hw->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!hw->ctrl_urb) { + pr_warn("%s: No memory for control urb\n", + driver_info->vend_name); + kfree(hw); + return -ENOMEM; + } + + pr_info("%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n", + hw->name, __func__, driver_info->vend_name, + conf_str[small_match], ifnum, alt_used); + + if (setup_instance(hw, dev->dev.parent)) + return -EIO; + + hw->intf = intf; + usb_set_intfdata(hw->intf, hw); + return 0; +} + +/* function called when an active device is removed */ +static void +hfcsusb_disconnect(struct usb_interface *intf) +{ + struct hfcsusb *hw = usb_get_intfdata(intf); + struct hfcsusb *next; + int cnt = 0; + + printk(KERN_INFO "%s: device disconnected\n", hw->name); + + handle_led(hw, LED_POWER_OFF); + release_hw(hw); + + list_for_each_entry_safe(hw, next, &HFClist, list) + cnt++; + if (!cnt) + hfcsusb_cnt = 0; + + usb_set_intfdata(intf, NULL); +} + +static struct usb_driver hfcsusb_drv = { + .name = DRIVER_NAME, + .id_table = hfcsusb_idtab, + .probe = hfcsusb_probe, + .disconnect = hfcsusb_disconnect, + .disable_hub_initiated_lpm = 1, +}; + +module_usb_driver(hfcsusb_drv); diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h new file mode 100644 index 00000000000..4157311d569 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfcsusb.h @@ -0,0 +1,424 @@ +/* + * hfcsusb.h, HFC-S USB mISDN driver + */ + +#ifndef __HFCSUSB_H__ +#define __HFCSUSB_H__ + + +#define DRIVER_NAME "HFC-S_USB" + +#define DBG_HFC_CALL_TRACE 0x00010000 +#define DBG_HFC_FIFO_VERBOSE 0x00020000 +#define DBG_HFC_USB_VERBOSE 0x00100000 +#define DBG_HFC_URB_INFO 0x00200000 +#define DBG_HFC_URB_ERROR 0x00400000 + +#define DEFAULT_TRANSP_BURST_SZ 128 + +#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ +#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */ +#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */ + +/* hfcsusb Layer1 commands */ +#define HFC_L1_ACTIVATE_TE 1 +#define HFC_L1_ACTIVATE_NT 2 +#define HFC_L1_DEACTIVATE_NT 3 +#define HFC_L1_FORCE_DEACTIVATE_TE 4 + +/* cmd FLAGS in HFCUSB_STATES register */ +#define HFCUSB_LOAD_STATE 0x10 +#define HFCUSB_ACTIVATE 0x20 +#define HFCUSB_DO_ACTION 0x40 +#define HFCUSB_NT_G2_G3 0x80 + +/* timers */ +#define NT_ACTIVATION_TIMER 0x01 /* enables NT mode activation Timer */ +#define NT_T1_COUNT 10 + +#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ + +#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ +#define HFCUSB_TX_THRESHOLD 96 /* threshold for fifo report bit tx */ + +#define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ +#define HFCUSB_CIRM 0x00 /* cirm register index */ +#define HFCUSB_USB_SIZE 0x07 /* int length register */ +#define HFCUSB_USB_SIZE_I 0x06 /* iso length register */ +#define HFCUSB_F_CROSS 0x0b /* bit order register */ +#define HFCUSB_CLKDEL 0x37 /* bit delay register */ +#define HFCUSB_CON_HDLC 0xfa /* channel connect register */ +#define HFCUSB_HDLC_PAR 0xfb +#define HFCUSB_SCTRL 0x31 /* S-bus control register (tx) */ +#define HFCUSB_SCTRL_E 0x32 /* same for E and special funcs */ +#define HFCUSB_SCTRL_R 0x33 /* S-bus control register (rx) */ +#define HFCUSB_F_THRES 0x0c /* threshold register */ +#define HFCUSB_FIFO 0x0f /* fifo select register */ +#define HFCUSB_F_USAGE 0x1a /* fifo usage register */ +#define HFCUSB_MST_MODE0 0x14 +#define HFCUSB_MST_MODE1 0x15 +#define HFCUSB_P_DATA 0x1f +#define HFCUSB_INC_RES_F 0x0e +#define HFCUSB_B1_SSL 0x20 +#define HFCUSB_B2_SSL 0x21 +#define HFCUSB_B1_RSL 0x24 +#define HFCUSB_B2_RSL 0x25 +#define HFCUSB_STATES 0x30 + + +#define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ + +/* fifo registers */ +#define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ +#define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ +#define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ +#define HFCUSB_B2_TX 2 +#define HFCUSB_B2_RX 3 +#define HFCUSB_D_TX 4 +#define HFCUSB_D_RX 5 +#define HFCUSB_PCM_TX 6 +#define HFCUSB_PCM_RX 7 + + +#define USB_INT 0 +#define USB_BULK 1 +#define USB_ISOC 2 + +#define ISOC_PACKETS_D 8 +#define ISOC_PACKETS_B 8 +#define ISO_BUFFER_SIZE 128 + +/* defines how much ISO packets are handled in one URB */ +static int iso_packets[8] = +{ ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, + ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D +}; + + +/* Fifo flow Control for TX ISO */ +#define SINK_MAX 68 +#define SINK_MIN 48 +#define SINK_DMIN 12 +#define SINK_DMAX 18 +#define BITLINE_INF (-96 * 8) + +/* HFC-S USB register access by Control-URSs */ +#define write_reg_atomic(a, b, c) \ + usb_control_msg((a)->dev, (a)->ctrl_out_pipe, 0, 0x40, (c), (b), \ + 0, 0, HFC_CTRL_TIMEOUT) +#define read_reg_atomic(a, b, c) \ + usb_control_msg((a)->dev, (a)->ctrl_in_pipe, 1, 0xC0, 0, (b), (c), \ + 1, HFC_CTRL_TIMEOUT) +#define HFC_CTRL_BUFSIZE 64 + +struct ctrl_buf { + __u8 hfcs_reg; /* register number */ + __u8 reg_val; /* value to be written (or read) */ +}; + +/* + * URB error codes + * Used to represent a list of values and their respective symbolic names + */ +struct hfcusb_symbolic_list { + const int num; + const char *name; +}; + +static struct hfcusb_symbolic_list urb_errlist[] = { + {-ENOMEM, "No memory for allocation of internal structures"}, + {-ENOSPC, "The host controller's bandwidth is already consumed"}, + {-ENOENT, "URB was canceled by unlink_urb"}, + {-EXDEV, "ISO transfer only partially completed"}, + {-EAGAIN, "Too match scheduled for the future"}, + {-ENXIO, "URB already queued"}, + {-EFBIG, "Too much ISO frames requested"}, + {-ENOSR, "Buffer error (overrun)"}, + {-EPIPE, "Specified endpoint is stalled (device not responding)"}, + {-EOVERFLOW, "Babble (bad cable?)"}, + {-EPROTO, "Bit-stuff error (bad cable?)"}, + {-EILSEQ, "CRC/Timeout"}, + {-ETIMEDOUT, "NAK (device does not respond)"}, + {-ESHUTDOWN, "Device unplugged"}, + {-1, NULL} +}; + +static inline const char * +symbolic(struct hfcusb_symbolic_list list[], const int num) +{ + int i; + for (i = 0; list[i].name != NULL; i++) + if (list[i].num == num) + return list[i].name; + return "<unknown USB Error>"; +} + +/* USB descriptor need to contain one of the following EndPoint combination: */ +#define CNF_4INT3ISO 1 /* 4 INT IN, 3 ISO OUT */ +#define CNF_3INT3ISO 2 /* 3 INT IN, 3 ISO OUT */ +#define CNF_4ISO3ISO 3 /* 4 ISO IN, 3 ISO OUT */ +#define CNF_3ISO3ISO 4 /* 3 ISO IN, 3 ISO OUT */ + +#define EP_NUL 1 /* Endpoint at this position not allowed */ +#define EP_NOP 2 /* all type of endpoints allowed at this position */ +#define EP_ISO 3 /* Isochron endpoint mandatory at this position */ +#define EP_BLK 4 /* Bulk endpoint mandatory at this position */ +#define EP_INT 5 /* Interrupt endpoint mandatory at this position */ + +#define HFC_CHAN_B1 0 +#define HFC_CHAN_B2 1 +#define HFC_CHAN_D 2 +#define HFC_CHAN_E 3 + + +/* + * List of all supported enpoints configiration sets, used to find the + * best matching endpoint configuration within a devices' USB descriptor. + * We need at least 3 RX endpoints, and 3 TX endpoints, either + * INT-in and ISO-out, or ISO-in and ISO-out) + * with 4 RX endpoints even E-Channel logging is possible + */ +static int +validconf[][19] = { + /* INT in, ISO out config */ + {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, + EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, + CNF_4INT3ISO, 2, 1}, + {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_NUL, + EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL, + CNF_3INT3ISO, 2, 0}, + /* ISO in, ISO out config */ + {EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, EP_NOP, + EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NOP, EP_ISO, + CNF_4ISO3ISO, 2, 1}, + {EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, EP_NUL, + EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_ISO, EP_NUL, EP_NUL, + CNF_3ISO3ISO, 2, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* EOL element */ +}; + +/* string description of chosen config */ +static char *conf_str[] = { + "4 Interrupt IN + 3 Isochron OUT", + "3 Interrupt IN + 3 Isochron OUT", + "4 Isochron IN + 3 Isochron OUT", + "3 Isochron IN + 3 Isochron OUT" +}; + + +#define LED_OFF 0 /* no LED support */ +#define LED_SCHEME1 1 /* LED standard scheme */ +#define LED_SCHEME2 2 /* not used yet... */ + +#define LED_POWER_ON 1 +#define LED_POWER_OFF 2 +#define LED_S0_ON 3 +#define LED_S0_OFF 4 +#define LED_B1_ON 5 +#define LED_B1_OFF 6 +#define LED_B1_DATA 7 +#define LED_B2_ON 8 +#define LED_B2_OFF 9 +#define LED_B2_DATA 10 + +#define LED_NORMAL 0 /* LEDs are normal */ +#define LED_INVERTED 1 /* LEDs are inverted */ + +/* time in ms to perform a Flashing LED when B-Channel has traffic */ +#define LED_TIME 250 + + + +struct hfcsusb; +struct usb_fifo; + +/* structure defining input+output fifos (interrupt/bulk mode) */ +struct iso_urb { + struct urb *urb; + __u8 buffer[ISO_BUFFER_SIZE]; /* buffer rx/tx USB URB data */ + struct usb_fifo *owner_fifo; /* pointer to owner fifo */ + __u8 indx; /* Fifos's ISO double buffer 0 or 1 ? */ +#ifdef ISO_FRAME_START_DEBUG + int start_frames[ISO_FRAME_START_RING_COUNT]; + __u8 iso_frm_strt_pos; /* index in start_frame[] */ +#endif +}; + +struct usb_fifo { + int fifonum; /* fifo index attached to this structure */ + int active; /* fifo is currently active */ + struct hfcsusb *hw; /* pointer to main structure */ + int pipe; /* address of endpoint */ + __u8 usb_packet_maxlen; /* maximum length for usb transfer */ + unsigned int max_size; /* maximum size of receive/send packet */ + __u8 intervall; /* interrupt interval */ + struct urb *urb; /* transfer structure for usb routines */ + __u8 buffer[128]; /* buffer USB INT OUT URB data */ + int bit_line; /* how much bits are in the fifo? */ + + __u8 usb_transfer_mode; /* switched between ISO and INT */ + struct iso_urb iso[2]; /* two urbs to have one always + one pending */ + + struct dchannel *dch; /* link to hfcsusb_t->dch */ + struct bchannel *bch; /* link to hfcsusb_t->bch */ + struct dchannel *ech; /* link to hfcsusb_t->ech, TODO: E-CHANNEL */ + int last_urblen; /* remember length of last packet */ + __u8 stop_gracefull; /* stops URB retransmission */ +}; + +struct hfcsusb { + struct list_head list; + struct dchannel dch; + struct bchannel bch[2]; + struct dchannel ech; /* TODO : wait for struct echannel ;) */ + + struct usb_device *dev; /* our device */ + struct usb_interface *intf; /* used interface */ + int if_used; /* used interface number */ + int alt_used; /* used alternate config */ + int cfg_used; /* configuration index used */ + int vend_idx; /* index in hfcsusb_idtab */ + int packet_size; + int iso_packet_size; + struct usb_fifo fifos[HFCUSB_NUM_FIFOS]; + + /* control pipe background handling */ + struct ctrl_buf ctrl_buff[HFC_CTRL_BUFSIZE]; + int ctrl_in_idx, ctrl_out_idx, ctrl_cnt; + struct urb *ctrl_urb; + struct usb_ctrlrequest ctrl_write; + struct usb_ctrlrequest ctrl_read; + int ctrl_paksize; + int ctrl_in_pipe, ctrl_out_pipe; + spinlock_t ctrl_lock; /* lock for ctrl */ + spinlock_t lock; + + __u8 threshold_mask; + __u8 led_state; + + __u8 protocol; + int nt_timer; + int open; + __u8 timers; + __u8 initdone; + char name[MISDN_MAX_IDLEN]; +}; + +/* private vendor specific data */ +struct hfcsusb_vdata { + __u8 led_scheme; /* led display scheme */ + signed short led_bits[8]; /* array of 8 possible LED bitmask */ + char *vend_name; /* device name */ +}; + + +#define HFC_MAX_TE_LAYER1_STATE 8 +#define HFC_MAX_NT_LAYER1_STATE 4 + +static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = { + "TE F0 - Reset", + "TE F1 - Reset", + "TE F2 - Sensing", + "TE F3 - Deactivated", + "TE F4 - Awaiting signal", + "TE F5 - Identifying input", + "TE F6 - Synchronized", + "TE F7 - Activated", + "TE F8 - Lost framing", +}; + +static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = { + "NT G0 - Reset", + "NT G1 - Deactive", + "NT G2 - Pending activation", + "NT G3 - Active", + "NT G4 - Pending deactivation", +}; + +/* supported devices */ +static struct usb_device_id hfcsusb_idtab[] = { + { + USB_DEVICE(0x0959, 0x2bd0), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_OFF, {4, 0, 2, 1}, + "ISDN USB TA (Cologne Chip HFC-S USB based)"}), + }, + { + USB_DEVICE(0x0675, 0x1688), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {1, 2, 0, 0}, + "DrayTek miniVigor 128 USB ISDN TA"}), + }, + { + USB_DEVICE(0x07b0, 0x0007), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {0x80, -64, -32, -16}, + "Billion tiny USB ISDN TA 128"}), + }, + { + USB_DEVICE(0x0742, 0x2008), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {4, 0, 2, 1}, + "Stollmann USB TA"}), + }, + { + USB_DEVICE(0x0742, 0x2009), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {4, 0, 2, 1}, + "Aceex USB ISDN TA"}), + }, + { + USB_DEVICE(0x0742, 0x200A), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {4, 0, 2, 1}, + "OEM USB ISDN TA"}), + }, + { + USB_DEVICE(0x08e3, 0x0301), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {2, 0, 1, 4}, + "Olitec USB RNIS"}), + }, + { + USB_DEVICE(0x07fa, 0x0846), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {0x80, -64, -32, -16}, + "Bewan Modem RNIS USB"}), + }, + { + USB_DEVICE(0x07fa, 0x0847), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {0x80, -64, -32, -16}, + "Djinn Numeris USB"}), + }, + { + USB_DEVICE(0x07b0, 0x0006), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {0x80, -64, -32, -16}, + "Twister ISDN TA"}), + }, + { + USB_DEVICE(0x071d, 0x1005), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {0x02, 0, 0x01, 0x04}, + "Eicon DIVA USB 4.0"}), + }, + { + USB_DEVICE(0x0586, 0x0102), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {0x88, -64, -32, -16}, + "ZyXEL OMNI.NET USB II"}), + }, + { + USB_DEVICE(0x1ae7, 0x0525), + .driver_info = (unsigned long) &((struct hfcsusb_vdata) + {LED_SCHEME1, {0x88, -64, -32, -16}, + "X-Tensions USB ISDN TA XC-525"}), + }, + { } +}; + +MODULE_DEVICE_TABLE(usb, hfcsusb_idtab); + +#endif /* __HFCSUSB_H__ */ diff --git a/drivers/isdn/hardware/mISDN/iohelper.h b/drivers/isdn/hardware/mISDN/iohelper.h new file mode 100644 index 00000000000..c3e7bb1daa2 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/iohelper.h @@ -0,0 +1,109 @@ +/* + * iohelper.h + * helper for define functions to access ISDN hardware + * supported are memory mapped IO + * indirect port IO (one port for address, one for data) + * + * Author Karsten Keil <keil@isdn4linux.de> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _IOHELPER_H +#define _IOHELPER_H + +typedef u8 (read_reg_func)(void *hwp, u8 offset); + typedef void (write_reg_func)(void *hwp, u8 offset, u8 value); + typedef void (fifo_func)(void *hwp, u8 offset, u8 *datap, int size); + + struct _ioport { + u32 port; + u32 ale; + }; + +#define IOFUNC_IO(name, hws, ap) \ + static u8 Read##name##_IO(void *p, u8 off) { \ + struct hws *hw = p; \ + return inb(hw->ap.port + off); \ + } \ + static void Write##name##_IO(void *p, u8 off, u8 val) { \ + struct hws *hw = p; \ + outb(val, hw->ap.port + off); \ + } \ + static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \ + struct hws *hw = p; \ + insb(hw->ap.port + off, dp, size); \ + } \ + static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \ + struct hws *hw = p; \ + outsb(hw->ap.port + off, dp, size); \ + } + +#define IOFUNC_IND(name, hws, ap) \ + static u8 Read##name##_IND(void *p, u8 off) { \ + struct hws *hw = p; \ + outb(off, hw->ap.ale); \ + return inb(hw->ap.port); \ + } \ + static void Write##name##_IND(void *p, u8 off, u8 val) { \ + struct hws *hw = p; \ + outb(off, hw->ap.ale); \ + outb(val, hw->ap.port); \ + } \ + static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \ + struct hws *hw = p; \ + outb(off, hw->ap.ale); \ + insb(hw->ap.port, dp, size); \ + } \ + static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \ + struct hws *hw = p; \ + outb(off, hw->ap.ale); \ + outsb(hw->ap.port, dp, size); \ + } + +#define IOFUNC_MEMIO(name, hws, typ, adr) \ + static u8 Read##name##_MIO(void *p, u8 off) { \ + struct hws *hw = p; \ + return readb(((typ *)hw->adr) + off); \ + } \ + static void Write##name##_MIO(void *p, u8 off, u8 val) { \ + struct hws *hw = p; \ + writeb(val, ((typ *)hw->adr) + off); \ + } \ + static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \ + struct hws *hw = p; \ + while (size--) \ + *dp++ = readb(((typ *)hw->adr) + off); \ + } \ + static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \ + struct hws *hw = p; \ + while (size--) \ + writeb(*dp++, ((typ *)hw->adr) + off); \ + } + +#define ASSIGN_FUNC(typ, name, dest) do { \ + dest.read_reg = &Read##name##_##typ; \ + dest.write_reg = &Write##name##_##typ; \ + dest.read_fifo = &ReadFiFo##name##_##typ; \ + dest.write_fifo = &WriteFiFo##name##_##typ; \ + } while (0) +#define ASSIGN_FUNC_IPAC(typ, target) do { \ + ASSIGN_FUNC(typ, ISAC, target.isac); \ + ASSIGN_FUNC(typ, IPAC, target); \ + } while (0) + +#endif diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h new file mode 100644 index 00000000000..8121e046b73 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/ipac.h @@ -0,0 +1,405 @@ +/* + * + * ipac.h Defines for the Infineon (former Siemens) ISDN + * chip series + * + * Author Karsten Keil <keil@isdn4linux.de> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "iohelper.h" + +struct isac_hw { + struct dchannel dch; + u32 type; + u32 off; /* offset to isac regs */ + char *name; + spinlock_t *hwlock; /* lock HW access */ + read_reg_func *read_reg; + write_reg_func *write_reg; + fifo_func *read_fifo; + fifo_func *write_fifo; + int (*monitor)(void *, u32, u8 *, int); + void (*release)(struct isac_hw *); + int (*init)(struct isac_hw *); + int (*ctrl)(struct isac_hw *, u32, u_long); + int (*open)(struct isac_hw *, struct channel_req *); + u8 *mon_tx; + u8 *mon_rx; + int mon_txp; + int mon_txc; + int mon_rxp; + struct arcofi_msg *arcofi_list; + struct timer_list arcofitimer; + wait_queue_head_t arcofi_wait; + u8 arcofi_bc; + u8 arcofi_state; + u8 mocr; + u8 adf2; + u8 state; +}; + +struct ipac_hw; + +struct hscx_hw { + struct bchannel bch; + struct ipac_hw *ip; + u8 fifo_size; + u8 off; /* offset to ICA or ICB */ + u8 slot; + char log[64]; +}; + +struct ipac_hw { + struct isac_hw isac; + struct hscx_hw hscx[2]; + char *name; + void *hw; + spinlock_t *hwlock; /* lock HW access */ + struct module *owner; + u32 type; + read_reg_func *read_reg; + write_reg_func *write_reg; + fifo_func *read_fifo; + fifo_func *write_fifo; + void (*release)(struct ipac_hw *); + int (*init)(struct ipac_hw *); + int (*ctrl)(struct ipac_hw *, u32, u_long); + u8 conf; +}; + +#define IPAC_TYPE_ISAC 0x0010 +#define IPAC_TYPE_IPAC 0x0020 +#define IPAC_TYPE_ISACX 0x0040 +#define IPAC_TYPE_IPACX 0x0080 +#define IPAC_TYPE_HSCX 0x0100 + +#define ISAC_USE_ARCOFI 0x1000 + +/* Monitor functions */ +#define MONITOR_RX_0 0x1000 +#define MONITOR_RX_1 0x1001 +#define MONITOR_TX_0 0x2000 +#define MONITOR_TX_1 0x2001 + +/* All registers original Siemens Spec */ +/* IPAC/ISAC registers */ +#define ISAC_MASK 0x20 +#define ISAC_ISTA 0x20 +#define ISAC_STAR 0x21 +#define ISAC_CMDR 0x21 +#define ISAC_EXIR 0x24 +#define ISAC_ADF2 0x39 +#define ISAC_SPCR 0x30 +#define ISAC_ADF1 0x38 +#define ISAC_CIR0 0x31 +#define ISAC_CIX0 0x31 +#define ISAC_CIR1 0x33 +#define ISAC_CIX1 0x33 +#define ISAC_STCR 0x37 +#define ISAC_MODE 0x22 +#define ISAC_RSTA 0x27 +#define ISAC_RBCL 0x25 +#define ISAC_RBCH 0x2A +#define ISAC_TIMR 0x23 +#define ISAC_SQXR 0x3b +#define ISAC_SQRR 0x3b +#define ISAC_MOSR 0x3a +#define ISAC_MOCR 0x3a +#define ISAC_MOR0 0x32 +#define ISAC_MOX0 0x32 +#define ISAC_MOR1 0x34 +#define ISAC_MOX1 0x34 + +#define ISAC_RBCH_XAC 0x80 + +#define IPAC_D_TIN2 0x01 + +/* IPAC/HSCX */ +#define IPAC_ISTAB 0x20 /* RD */ +#define IPAC_MASKB 0x20 /* WR */ +#define IPAC_STARB 0x21 /* RD */ +#define IPAC_CMDRB 0x21 /* WR */ +#define IPAC_MODEB 0x22 /* R/W */ +#define IPAC_EXIRB 0x24 /* RD */ +#define IPAC_RBCLB 0x25 /* RD */ +#define IPAC_RAH1 0x26 /* WR */ +#define IPAC_RAH2 0x27 /* WR */ +#define IPAC_RSTAB 0x27 /* RD */ +#define IPAC_RAL1 0x28 /* R/W */ +#define IPAC_RAL2 0x29 /* WR */ +#define IPAC_RHCRB 0x29 /* RD */ +#define IPAC_XBCL 0x2A /* WR */ +#define IPAC_CCR2 0x2C /* R/W */ +#define IPAC_RBCHB 0x2D /* RD */ +#define IPAC_XBCH 0x2D /* WR */ +#define HSCX_VSTR 0x2E /* RD */ +#define IPAC_RLCR 0x2E /* WR */ +#define IPAC_CCR1 0x2F /* R/W */ +#define IPAC_TSAX 0x30 /* WR */ +#define IPAC_TSAR 0x31 /* WR */ +#define IPAC_XCCR 0x32 /* WR */ +#define IPAC_RCCR 0x33 /* WR */ + +/* IPAC_ISTAB/IPAC_MASKB bits */ +#define IPAC_B_XPR 0x10 +#define IPAC_B_RPF 0x40 +#define IPAC_B_RME 0x80 +#define IPAC_B_ON 0x2F + +/* IPAC_EXIRB bits */ +#define IPAC_B_RFS 0x04 +#define IPAC_B_RFO 0x10 +#define IPAC_B_XDU 0x40 +#define IPAC_B_XMR 0x80 + +/* IPAC special registers */ +#define IPAC_CONF 0xC0 /* R/W */ +#define IPAC_ISTA 0xC1 /* RD */ +#define IPAC_MASK 0xC1 /* WR */ +#define IPAC_ID 0xC2 /* RD */ +#define IPAC_ACFG 0xC3 /* R/W */ +#define IPAC_AOE 0xC4 /* R/W */ +#define IPAC_ARX 0xC5 /* RD */ +#define IPAC_ATX 0xC5 /* WR */ +#define IPAC_PITA1 0xC6 /* R/W */ +#define IPAC_PITA2 0xC7 /* R/W */ +#define IPAC_POTA1 0xC8 /* R/W */ +#define IPAC_POTA2 0xC9 /* R/W */ +#define IPAC_PCFG 0xCA /* R/W */ +#define IPAC_SCFG 0xCB /* R/W */ +#define IPAC_TIMR2 0xCC /* R/W */ + +/* IPAC_ISTA/_MASK bits */ +#define IPAC__EXB 0x01 +#define IPAC__ICB 0x02 +#define IPAC__EXA 0x04 +#define IPAC__ICA 0x08 +#define IPAC__EXD 0x10 +#define IPAC__ICD 0x20 +#define IPAC__INT0 0x40 +#define IPAC__INT1 0x80 +#define IPAC__ON 0xC0 + +/* HSCX ISTA/MASK bits */ +#define HSCX__EXB 0x01 +#define HSCX__EXA 0x02 +#define HSCX__ICA 0x04 + +/* ISAC/ISACX/IPAC/IPACX L1 commands */ +#define ISAC_CMD_TIM 0x0 +#define ISAC_CMD_RS 0x1 +#define ISAC_CMD_SCZ 0x4 +#define ISAC_CMD_SSZ 0x2 +#define ISAC_CMD_AR8 0x8 +#define ISAC_CMD_AR10 0x9 +#define ISAC_CMD_ARL 0xA +#define ISAC_CMD_DUI 0xF + +/* ISAC/ISACX/IPAC/IPACX L1 indications */ +#define ISAC_IND_RS 0x1 +#define ISAC_IND_PU 0x7 +#define ISAC_IND_DR 0x0 +#define ISAC_IND_SD 0x2 +#define ISAC_IND_DIS 0x3 +#define ISAC_IND_EI 0x6 +#define ISAC_IND_RSY 0x4 +#define ISAC_IND_ARD 0x8 +#define ISAC_IND_TI 0xA +#define ISAC_IND_ATI 0xB +#define ISAC_IND_AI8 0xC +#define ISAC_IND_AI10 0xD +#define ISAC_IND_DID 0xF + +/* the new ISACX / IPACX */ +/* D-channel registers */ +#define ISACX_RFIFOD 0x00 /* RD */ +#define ISACX_XFIFOD 0x00 /* WR */ +#define ISACX_ISTAD 0x20 /* RD */ +#define ISACX_MASKD 0x20 /* WR */ +#define ISACX_STARD 0x21 /* RD */ +#define ISACX_CMDRD 0x21 /* WR */ +#define ISACX_MODED 0x22 /* R/W */ +#define ISACX_EXMD1 0x23 /* R/W */ +#define ISACX_TIMR1 0x24 /* R/W */ +#define ISACX_SAP1 0x25 /* WR */ +#define ISACX_SAP2 0x26 /* WR */ +#define ISACX_RBCLD 0x26 /* RD */ +#define ISACX_RBCHD 0x27 /* RD */ +#define ISACX_TEI1 0x27 /* WR */ +#define ISACX_TEI2 0x28 /* WR */ +#define ISACX_RSTAD 0x28 /* RD */ +#define ISACX_TMD 0x29 /* R/W */ +#define ISACX_CIR0 0x2E /* RD */ +#define ISACX_CIX0 0x2E /* WR */ +#define ISACX_CIR1 0x2F /* RD */ +#define ISACX_CIX1 0x2F /* WR */ + +/* Transceiver registers */ +#define ISACX_TR_CONF0 0x30 /* R/W */ +#define ISACX_TR_CONF1 0x31 /* R/W */ +#define ISACX_TR_CONF2 0x32 /* R/W */ +#define ISACX_TR_STA 0x33 /* RD */ +#define ISACX_TR_CMD 0x34 /* R/W */ +#define ISACX_SQRR1 0x35 /* RD */ +#define ISACX_SQXR1 0x35 /* WR */ +#define ISACX_SQRR2 0x36 /* RD */ +#define ISACX_SQXR2 0x36 /* WR */ +#define ISACX_SQRR3 0x37 /* RD */ +#define ISACX_SQXR3 0x37 /* WR */ +#define ISACX_ISTATR 0x38 /* RD */ +#define ISACX_MASKTR 0x39 /* R/W */ +#define ISACX_TR_MODE 0x3A /* R/W */ +#define ISACX_ACFG1 0x3C /* R/W */ +#define ISACX_ACFG2 0x3D /* R/W */ +#define ISACX_AOE 0x3E /* R/W */ +#define ISACX_ARX 0x3F /* RD */ +#define ISACX_ATX 0x3F /* WR */ + +/* IOM: Timeslot, DPS, CDA */ +#define ISACX_CDA10 0x40 /* R/W */ +#define ISACX_CDA11 0x41 /* R/W */ +#define ISACX_CDA20 0x42 /* R/W */ +#define ISACX_CDA21 0x43 /* R/W */ +#define ISACX_CDA_TSDP10 0x44 /* R/W */ +#define ISACX_CDA_TSDP11 0x45 /* R/W */ +#define ISACX_CDA_TSDP20 0x46 /* R/W */ +#define ISACX_CDA_TSDP21 0x47 /* R/W */ +#define ISACX_BCHA_TSDP_BC1 0x48 /* R/W */ +#define ISACX_BCHA_TSDP_BC2 0x49 /* R/W */ +#define ISACX_BCHB_TSDP_BC1 0x4A /* R/W */ +#define ISACX_BCHB_TSDP_BC2 0x4B /* R/W */ +#define ISACX_TR_TSDP_BC1 0x4C /* R/W */ +#define ISACX_TR_TSDP_BC2 0x4D /* R/W */ +#define ISACX_CDA1_CR 0x4E /* R/W */ +#define ISACX_CDA2_CR 0x4F /* R/W */ + +/* IOM: Contol, Sync transfer, Monitor */ +#define ISACX_TR_CR 0x50 /* R/W */ +#define ISACX_TRC_CR 0x50 /* R/W */ +#define ISACX_BCHA_CR 0x51 /* R/W */ +#define ISACX_BCHB_CR 0x52 /* R/W */ +#define ISACX_DCI_CR 0x53 /* R/W */ +#define ISACX_DCIC_CR 0x53 /* R/W */ +#define ISACX_MON_CR 0x54 /* R/W */ +#define ISACX_SDS1_CR 0x55 /* R/W */ +#define ISACX_SDS2_CR 0x56 /* R/W */ +#define ISACX_IOM_CR 0x57 /* R/W */ +#define ISACX_STI 0x58 /* RD */ +#define ISACX_ASTI 0x58 /* WR */ +#define ISACX_MSTI 0x59 /* R/W */ +#define ISACX_SDS_CONF 0x5A /* R/W */ +#define ISACX_MCDA 0x5B /* RD */ +#define ISACX_MOR 0x5C /* RD */ +#define ISACX_MOX 0x5C /* WR */ +#define ISACX_MOSR 0x5D /* RD */ +#define ISACX_MOCR 0x5E /* R/W */ +#define ISACX_MSTA 0x5F /* RD */ +#define ISACX_MCONF 0x5F /* WR */ + +/* Interrupt and general registers */ +#define ISACX_ISTA 0x60 /* RD */ +#define ISACX_MASK 0x60 /* WR */ +#define ISACX_AUXI 0x61 /* RD */ +#define ISACX_AUXM 0x61 /* WR */ +#define ISACX_MODE1 0x62 /* R/W */ +#define ISACX_MODE2 0x63 /* R/W */ +#define ISACX_ID 0x64 /* RD */ +#define ISACX_SRES 0x64 /* WR */ +#define ISACX_TIMR2 0x65 /* R/W */ + +/* Register Bits */ +/* ISACX/IPACX _ISTAD (R) and _MASKD (W) */ +#define ISACX_D_XDU 0x04 +#define ISACX_D_XMR 0x08 +#define ISACX_D_XPR 0x10 +#define ISACX_D_RFO 0x20 +#define ISACX_D_RPF 0x40 +#define ISACX_D_RME 0x80 + +/* ISACX/IPACX _ISTA (R) and _MASK (W) */ +#define ISACX__ICD 0x01 +#define ISACX__MOS 0x02 +#define ISACX__TRAN 0x04 +#define ISACX__AUX 0x08 +#define ISACX__CIC 0x10 +#define ISACX__ST 0x20 +#define IPACX__ICB 0x40 +#define IPACX__ICA 0x80 +#define IPACX__ON 0x2C + +/* ISACX/IPACX _CMDRD (W) */ +#define ISACX_CMDRD_XRES 0x01 +#define ISACX_CMDRD_XME 0x02 +#define ISACX_CMDRD_XTF 0x08 +#define ISACX_CMDRD_STI 0x10 +#define ISACX_CMDRD_RRES 0x40 +#define ISACX_CMDRD_RMC 0x80 + +/* ISACX/IPACX _RSTAD (R) */ +#define ISACX_RSTAD_TA 0x01 +#define ISACX_RSTAD_CR 0x02 +#define ISACX_RSTAD_SA0 0x04 +#define ISACX_RSTAD_SA1 0x08 +#define ISACX_RSTAD_RAB 0x10 +#define ISACX_RSTAD_CRC 0x20 +#define ISACX_RSTAD_RDO 0x40 +#define ISACX_RSTAD_VFR 0x80 + +/* ISACX/IPACX _CIR0 (R) */ +#define ISACX_CIR0_BAS 0x01 +#define ISACX_CIR0_SG 0x08 +#define ISACX_CIR0_CIC1 0x08 +#define ISACX_CIR0_CIC0 0x08 + +/* B-channel registers */ +#define IPACX_OFF_ICA 0x70 +#define IPACX_OFF_ICB 0x80 + +/* ICA: IPACX_OFF_ICA + Reg ICB: IPACX_OFF_ICB + Reg */ + +#define IPACX_ISTAB 0x00 /* RD */ +#define IPACX_MASKB 0x00 /* WR */ +#define IPACX_STARB 0x01 /* RD */ +#define IPACX_CMDRB 0x01 /* WR */ +#define IPACX_MODEB 0x02 /* R/W */ +#define IPACX_EXMB 0x03 /* R/W */ +#define IPACX_RAH1 0x05 /* WR */ +#define IPACX_RAH2 0x06 /* WR */ +#define IPACX_RBCLB 0x06 /* RD */ +#define IPACX_RBCHB 0x07 /* RD */ +#define IPACX_RAL1 0x07 /* WR */ +#define IPACX_RAL2 0x08 /* WR */ +#define IPACX_RSTAB 0x08 /* RD */ +#define IPACX_TMB 0x09 /* R/W */ +#define IPACX_RFIFOB 0x0A /* RD */ +#define IPACX_XFIFOB 0x0A /* WR */ + +/* IPACX_ISTAB / IPACX_MASKB bits */ +#define IPACX_B_XDU 0x04 +#define IPACX_B_XPR 0x10 +#define IPACX_B_RFO 0x20 +#define IPACX_B_RPF 0x40 +#define IPACX_B_RME 0x80 + +#define IPACX_B_ON 0x0B + +extern int mISDNisac_init(struct isac_hw *, void *); +extern irqreturn_t mISDNisac_irq(struct isac_hw *, u8); +extern u32 mISDNipac_init(struct ipac_hw *, void *); +extern irqreturn_t mISDNipac_irq(struct ipac_hw *, int); diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h new file mode 100644 index 00000000000..cadfc49c920 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/isar.h @@ -0,0 +1,269 @@ +/* + * + * isar.h ISAR (Siemens PSB 7110) specific defines + * + * Author Karsten Keil (keil@isdn4linux.de) + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "iohelper.h" + +struct isar_hw; + +struct isar_ch { + struct bchannel bch; + struct isar_hw *is; + struct timer_list ftimer; + u8 nr; + u8 dpath; + u8 mml; + u8 state; + u8 cmd; + u8 mod; + u8 newcmd; + u8 newmod; + u8 try_mod; + u8 conmsg[16]; +}; + +struct isar_hw { + struct isar_ch ch[2]; + void *hw; + spinlock_t *hwlock; /* lock HW access */ + char *name; + struct module *owner; + read_reg_func *read_reg; + write_reg_func *write_reg; + fifo_func *read_fifo; + fifo_func *write_fifo; + int (*ctrl)(void *, u32, u_long); + void (*release)(struct isar_hw *); + int (*init)(struct isar_hw *); + int (*open)(struct isar_hw *, struct channel_req *); + int (*firmware)(struct isar_hw *, const u8 *, int); + unsigned long Flags; + int version; + u8 bstat; + u8 iis; + u8 cmsb; + u8 clsb; + u8 buf[256]; + u8 log[256]; +}; + +#define ISAR_IRQMSK 0x04 +#define ISAR_IRQSTA 0x04 +#define ISAR_IRQBIT 0x75 +#define ISAR_CTRL_H 0x61 +#define ISAR_CTRL_L 0x60 +#define ISAR_IIS 0x58 +#define ISAR_IIA 0x58 +#define ISAR_HIS 0x50 +#define ISAR_HIA 0x50 +#define ISAR_MBOX 0x4c +#define ISAR_WADR 0x4a +#define ISAR_RADR 0x48 + +#define ISAR_HIS_VNR 0x14 +#define ISAR_HIS_DKEY 0x02 +#define ISAR_HIS_FIRM 0x1e +#define ISAR_HIS_STDSP 0x08 +#define ISAR_HIS_DIAG 0x05 +#define ISAR_HIS_P0CFG 0x3c +#define ISAR_HIS_P12CFG 0x24 +#define ISAR_HIS_SARTCFG 0x25 +#define ISAR_HIS_PUMPCFG 0x26 +#define ISAR_HIS_PUMPCTRL 0x2a +#define ISAR_HIS_IOM2CFG 0x27 +#define ISAR_HIS_IOM2REQ 0x07 +#define ISAR_HIS_IOM2CTRL 0x2b +#define ISAR_HIS_BSTREQ 0x0c +#define ISAR_HIS_PSTREQ 0x0e +#define ISAR_HIS_SDATA 0x20 +#define ISAR_HIS_DPS1 0x40 +#define ISAR_HIS_DPS2 0x80 +#define SET_DPS(x) ((x << 6) & 0xc0) + +#define ISAR_IIS_MSCMSD 0x3f +#define ISAR_IIS_VNR 0x15 +#define ISAR_IIS_DKEY 0x03 +#define ISAR_IIS_FIRM 0x1f +#define ISAR_IIS_STDSP 0x09 +#define ISAR_IIS_DIAG 0x25 +#define ISAR_IIS_GSTEV 0x00 +#define ISAR_IIS_BSTEV 0x28 +#define ISAR_IIS_BSTRSP 0x2c +#define ISAR_IIS_PSTRSP 0x2e +#define ISAR_IIS_PSTEV 0x2a +#define ISAR_IIS_IOM2RSP 0x27 +#define ISAR_IIS_RDATA 0x20 +#define ISAR_IIS_INVMSG 0x3f + +#define ISAR_CTRL_SWVER 0x10 +#define ISAR_CTRL_STST 0x40 + +#define ISAR_MSG_HWVER 0x20 + +#define ISAR_DP1_USE 1 +#define ISAR_DP2_USE 2 +#define ISAR_RATE_REQ 3 + +#define PMOD_DISABLE 0 +#define PMOD_FAX 1 +#define PMOD_DATAMODEM 2 +#define PMOD_HALFDUPLEX 3 +#define PMOD_V110 4 +#define PMOD_DTMF 5 +#define PMOD_DTMF_TRANS 6 +#define PMOD_BYPASS 7 + +#define PCTRL_ORIG 0x80 +#define PV32P2_V23R 0x40 +#define PV32P2_V22A 0x20 +#define PV32P2_V22B 0x10 +#define PV32P2_V22C 0x08 +#define PV32P2_V21 0x02 +#define PV32P2_BEL 0x01 + +/* LSB MSB in ISAR doc wrong !!! Arghhh */ +#define PV32P3_AMOD 0x80 +#define PV32P3_V32B 0x02 +#define PV32P3_V23B 0x01 +#define PV32P4_48 0x11 +#define PV32P5_48 0x05 +#define PV32P4_UT48 0x11 +#define PV32P5_UT48 0x0d +#define PV32P4_96 0x11 +#define PV32P5_96 0x03 +#define PV32P4_UT96 0x11 +#define PV32P5_UT96 0x0f +#define PV32P4_B96 0x91 +#define PV32P5_B96 0x0b +#define PV32P4_UTB96 0xd1 +#define PV32P5_UTB96 0x0f +#define PV32P4_120 0xb1 +#define PV32P5_120 0x09 +#define PV32P4_UT120 0xf1 +#define PV32P5_UT120 0x0f +#define PV32P4_144 0x99 +#define PV32P5_144 0x09 +#define PV32P4_UT144 0xf9 +#define PV32P5_UT144 0x0f +#define PV32P6_CTN 0x01 +#define PV32P6_ATN 0x02 + +#define PFAXP2_CTN 0x01 +#define PFAXP2_ATN 0x04 + +#define PSEV_10MS_TIMER 0x02 +#define PSEV_CON_ON 0x18 +#define PSEV_CON_OFF 0x19 +#define PSEV_V24_OFF 0x20 +#define PSEV_CTS_ON 0x21 +#define PSEV_CTS_OFF 0x22 +#define PSEV_DCD_ON 0x23 +#define PSEV_DCD_OFF 0x24 +#define PSEV_DSR_ON 0x25 +#define PSEV_DSR_OFF 0x26 +#define PSEV_REM_RET 0xcc +#define PSEV_REM_REN 0xcd +#define PSEV_GSTN_CLR 0xd4 + +#define PSEV_RSP_READY 0xbc +#define PSEV_LINE_TX_H 0xb3 +#define PSEV_LINE_TX_B 0xb2 +#define PSEV_LINE_RX_H 0xb1 +#define PSEV_LINE_RX_B 0xb0 +#define PSEV_RSP_CONN 0xb5 +#define PSEV_RSP_DISC 0xb7 +#define PSEV_RSP_FCERR 0xb9 +#define PSEV_RSP_SILDET 0xbe +#define PSEV_RSP_SILOFF 0xab +#define PSEV_FLAGS_DET 0xba + +#define PCTRL_CMD_TDTMF 0x5a + +#define PCTRL_CMD_FTH 0xa7 +#define PCTRL_CMD_FRH 0xa5 +#define PCTRL_CMD_FTM 0xa8 +#define PCTRL_CMD_FRM 0xa6 +#define PCTRL_CMD_SILON 0xac +#define PCTRL_CMD_CONT 0xa2 +#define PCTRL_CMD_ESC 0xa4 +#define PCTRL_CMD_SILOFF 0xab +#define PCTRL_CMD_HALT 0xa9 + +#define PCTRL_LOC_RET 0xcf +#define PCTRL_LOC_REN 0xce + +#define SMODE_DISABLE 0 +#define SMODE_V14 2 +#define SMODE_HDLC 3 +#define SMODE_BINARY 4 +#define SMODE_FSK_V14 5 + +#define SCTRL_HDMC_BOTH 0x00 +#define SCTRL_HDMC_DTX 0x80 +#define SCTRL_HDMC_DRX 0x40 +#define S_P1_OVSP 0x40 +#define S_P1_SNP 0x20 +#define S_P1_EOP 0x10 +#define S_P1_EDP 0x08 +#define S_P1_NSB 0x04 +#define S_P1_CHS_8 0x03 +#define S_P1_CHS_7 0x02 +#define S_P1_CHS_6 0x01 +#define S_P1_CHS_5 0x00 + +#define S_P2_BFT_DEF 0x10 + +#define IOM_CTRL_ENA 0x80 +#define IOM_CTRL_NOPCM 0x00 +#define IOM_CTRL_ALAW 0x02 +#define IOM_CTRL_ULAW 0x04 +#define IOM_CTRL_RCV 0x01 + +#define IOM_P1_TXD 0x10 + +#define HDLC_FED 0x40 +#define HDLC_FSD 0x20 +#define HDLC_FST 0x20 +#define HDLC_ERROR 0x1c +#define HDLC_ERR_FAD 0x10 +#define HDLC_ERR_RER 0x08 +#define HDLC_ERR_CER 0x04 +#define SART_NMD 0x01 + +#define BSTAT_RDM0 0x1 +#define BSTAT_RDM1 0x2 +#define BSTAT_RDM2 0x4 +#define BSTAT_RDM3 0x8 +#define BSTEV_TBO 0x1f +#define BSTEV_RBO 0x2f + +/* FAX State Machine */ +#define STFAX_NULL 0 +#define STFAX_READY 1 +#define STFAX_LINE 2 +#define STFAX_CONT 3 +#define STFAX_ACTIV 4 +#define STFAX_ESCAPE 5 +#define STFAX_SILDET 6 + +extern u32 mISDNisar_init(struct isar_hw *, void *); +extern void mISDNisar_irq(struct isar_hw *); diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c new file mode 100644 index 00000000000..c1493f4162f --- /dev/null +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -0,0 +1,1173 @@ +/* + * mISDNinfineon.c + * Support for cards based on following Infineon ISDN chipsets + * - ISAC + HSCX + * - IPAC and IPAC-X + * - ISAC-SX + HSCX + * + * Supported cards: + * - Dialogic Diva 2.0 + * - Dialogic Diva 2.0U + * - Dialogic Diva 2.01 + * - Dialogic Diva 2.02 + * - Sedlbauer Speedwin + * - HST Saphir3 + * - Develo (former ELSA) Microlink PCI (Quickstep 1000) + * - Develo (former ELSA) Quickstep 3000 + * - Berkom Scitel BRIX Quadro + * - Dr.Neuhaus (Sagem) Niccy + * + * + * + * Author Karsten Keil <keil@isdn4linux.de> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/mISDNhw.h> +#include <linux/slab.h> +#include "ipac.h" + +#define INFINEON_REV "1.0" + +static int inf_cnt; +static u32 debug; +static u32 irqloops = 4; + +enum inf_types { + INF_NONE, + INF_DIVA20, + INF_DIVA20U, + INF_DIVA201, + INF_DIVA202, + INF_SPEEDWIN, + INF_SAPHIR3, + INF_QS1000, + INF_QS3000, + INF_NICCY, + INF_SCT_1, + INF_SCT_2, + INF_SCT_3, + INF_SCT_4, + INF_GAZEL_R685, + INF_GAZEL_R753 +}; + +enum addr_mode { + AM_NONE = 0, + AM_IO, + AM_MEMIO, + AM_IND_IO, +}; + +struct inf_cinfo { + enum inf_types typ; + const char *full; + const char *name; + enum addr_mode cfg_mode; + enum addr_mode addr_mode; + u8 cfg_bar; + u8 addr_bar; + void *irqfunc; +}; + +struct _ioaddr { + enum addr_mode mode; + union { + void __iomem *p; + struct _ioport io; + } a; +}; + +struct _iohandle { + enum addr_mode mode; + resource_size_t size; + resource_size_t start; + void __iomem *p; +}; + +struct inf_hw { + struct list_head list; + struct pci_dev *pdev; + const struct inf_cinfo *ci; + char name[MISDN_MAX_IDLEN]; + u32 irq; + u32 irqcnt; + struct _iohandle cfg; + struct _iohandle addr; + struct _ioaddr isac; + struct _ioaddr hscx; + spinlock_t lock; /* HW access lock */ + struct ipac_hw ipac; + struct inf_hw *sc[3]; /* slave cards */ +}; + + +#define PCI_SUBVENDOR_HST_SAPHIR3 0x52 +#define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53 +#define PCI_SUB_ID_SEDLBAUER 0x01 + +static struct pci_device_id infineon_ids[] = { + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), INF_DIVA20 }, + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), INF_DIVA20U }, + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), INF_DIVA201 }, + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), INF_DIVA202 }, + { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, + PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0, + INF_SPEEDWIN }, + { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, + PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3 }, + { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_MICROLINK), INF_QS1000 }, + { PCI_VDEVICE(ELSA, PCI_DEVICE_ID_ELSA_QS3000), INF_QS3000 }, + { PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY), INF_NICCY }, + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, + PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0, + INF_SCT_1 }, + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685), INF_GAZEL_R685 }, + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753), INF_GAZEL_R753 }, + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO), INF_GAZEL_R753 }, + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC), INF_GAZEL_R753 }, + { } +}; +MODULE_DEVICE_TABLE(pci, infineon_ids); + +/* PCI interface specific defines */ +/* Diva 2.0/2.0U */ +#define DIVA_HSCX_PORT 0x00 +#define DIVA_HSCX_ALE 0x04 +#define DIVA_ISAC_PORT 0x08 +#define DIVA_ISAC_ALE 0x0C +#define DIVA_PCI_CTRL 0x10 + +/* DIVA_PCI_CTRL bits */ +#define DIVA_IRQ_BIT 0x01 +#define DIVA_RESET_BIT 0x08 +#define DIVA_EEPROM_CLK 0x40 +#define DIVA_LED_A 0x10 +#define DIVA_LED_B 0x20 +#define DIVA_IRQ_CLR 0x80 + +/* Diva 2.01/2.02 */ +/* Siemens PITA */ +#define PITA_ICR_REG 0x00 +#define PITA_INT0_STATUS 0x02 + +#define PITA_MISC_REG 0x1c +#define PITA_PARA_SOFTRESET 0x01000000 +#define PITA_SER_SOFTRESET 0x02000000 +#define PITA_PARA_MPX_MODE 0x04000000 +#define PITA_INT0_ENABLE 0x00020000 + +/* TIGER 100 Registers */ +#define TIGER_RESET_ADDR 0x00 +#define TIGER_EXTERN_RESET 0x01 +#define TIGER_AUX_CTRL 0x02 +#define TIGER_AUX_DATA 0x03 +#define TIGER_AUX_IRQMASK 0x05 +#define TIGER_AUX_STATUS 0x07 + +/* Tiger AUX BITs */ +#define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */ +#define TIGER_IRQ_BIT 0x02 + +#define TIGER_IPAC_ALE 0xC0 +#define TIGER_IPAC_PORT 0xC8 + +/* ELSA (now Develo) PCI cards */ +#define ELSA_IRQ_ADDR 0x4c +#define ELSA_IRQ_MASK 0x04 +#define QS1000_IRQ_OFF 0x01 +#define QS3000_IRQ_OFF 0x03 +#define QS1000_IRQ_ON 0x41 +#define QS3000_IRQ_ON 0x43 + +/* Dr Neuhaus/Sagem Niccy */ +#define NICCY_ISAC_PORT 0x00 +#define NICCY_HSCX_PORT 0x01 +#define NICCY_ISAC_ALE 0x02 +#define NICCY_HSCX_ALE 0x03 + +#define NICCY_IRQ_CTRL_REG 0x38 +#define NICCY_IRQ_ENABLE 0x001f00 +#define NICCY_IRQ_DISABLE 0xff0000 +#define NICCY_IRQ_BIT 0x800000 + + +/* Scitel PLX */ +#define SCT_PLX_IRQ_ADDR 0x4c +#define SCT_PLX_RESET_ADDR 0x50 +#define SCT_PLX_IRQ_ENABLE 0x41 +#define SCT_PLX_RESET_BIT 0x04 + +/* Gazel */ +#define GAZEL_IPAC_DATA_PORT 0x04 +/* Gazel PLX */ +#define GAZEL_CNTRL 0x50 +#define GAZEL_RESET 0x04 +#define GAZEL_RESET_9050 0x40000000 +#define GAZEL_INCSR 0x4C +#define GAZEL_ISAC_EN 0x08 +#define GAZEL_INT_ISAC 0x20 +#define GAZEL_HSCX_EN 0x01 +#define GAZEL_INT_HSCX 0x04 +#define GAZEL_PCI_EN 0x40 +#define GAZEL_IPAC_EN 0x03 + + +static LIST_HEAD(Cards); +static DEFINE_RWLOCK(card_lock); /* protect Cards */ + +static void +_set_debug(struct inf_hw *card) +{ + card->ipac.isac.dch.debug = debug; + card->ipac.hscx[0].bch.debug = debug; + card->ipac.hscx[1].bch.debug = debug; +} + +static int +set_debug(const char *val, struct kernel_param *kp) +{ + int ret; + struct inf_hw *card; + + ret = param_set_uint(val, kp); + if (!ret) { + read_lock(&card_lock); + list_for_each_entry(card, &Cards, list) + _set_debug(card); + read_unlock(&card_lock); + } + return ret; +} + +MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(INFINEON_REV); +module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "infineon debug mask"); +module_param(irqloops, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)"); + +/* Interface functions */ + +IOFUNC_IO(ISAC, inf_hw, isac.a.io) +IOFUNC_IO(IPAC, inf_hw, hscx.a.io) +IOFUNC_IND(ISAC, inf_hw, isac.a.io) +IOFUNC_IND(IPAC, inf_hw, hscx.a.io) +IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p) +IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p) + +static irqreturn_t +diva_irq(int intno, void *dev_id) +{ + struct inf_hw *hw = dev_id; + u8 val; + + spin_lock(&hw->lock); + val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL); + if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */ + spin_unlock(&hw->lock); + return IRQ_NONE; /* shared */ + } + hw->irqcnt++; + mISDNipac_irq(&hw->ipac, irqloops); + spin_unlock(&hw->lock); + return IRQ_HANDLED; +} + +static irqreturn_t +diva20x_irq(int intno, void *dev_id) +{ + struct inf_hw *hw = dev_id; + u8 val; + + spin_lock(&hw->lock); + val = readb(hw->cfg.p); + if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */ + spin_unlock(&hw->lock); + return IRQ_NONE; /* shared */ + } + hw->irqcnt++; + mISDNipac_irq(&hw->ipac, irqloops); + writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */ + spin_unlock(&hw->lock); + return IRQ_HANDLED; +} + +static irqreturn_t +tiger_irq(int intno, void *dev_id) +{ + struct inf_hw *hw = dev_id; + u8 val; + + spin_lock(&hw->lock); + val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS); + if (val & TIGER_IRQ_BIT) { /* for us or shared ? */ + spin_unlock(&hw->lock); + return IRQ_NONE; /* shared */ + } + hw->irqcnt++; + mISDNipac_irq(&hw->ipac, irqloops); + spin_unlock(&hw->lock); + return IRQ_HANDLED; +} + +static irqreturn_t +elsa_irq(int intno, void *dev_id) +{ + struct inf_hw *hw = dev_id; + u8 val; + + spin_lock(&hw->lock); + val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR); + if (!(val & ELSA_IRQ_MASK)) { + spin_unlock(&hw->lock); + return IRQ_NONE; /* shared */ + } + hw->irqcnt++; + mISDNipac_irq(&hw->ipac, irqloops); + spin_unlock(&hw->lock); + return IRQ_HANDLED; +} + +static irqreturn_t +niccy_irq(int intno, void *dev_id) +{ + struct inf_hw *hw = dev_id; + u32 val; + + spin_lock(&hw->lock); + val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); + if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */ + spin_unlock(&hw->lock); + return IRQ_NONE; /* shared */ + } + outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); + hw->irqcnt++; + mISDNipac_irq(&hw->ipac, irqloops); + spin_unlock(&hw->lock); + return IRQ_HANDLED; +} + +static irqreturn_t +gazel_irq(int intno, void *dev_id) +{ + struct inf_hw *hw = dev_id; + irqreturn_t ret; + + spin_lock(&hw->lock); + ret = mISDNipac_irq(&hw->ipac, irqloops); + spin_unlock(&hw->lock); + return ret; +} + +static irqreturn_t +ipac_irq(int intno, void *dev_id) +{ + struct inf_hw *hw = dev_id; + u8 val; + + spin_lock(&hw->lock); + val = hw->ipac.read_reg(hw, IPAC_ISTA); + if (!(val & 0x3f)) { + spin_unlock(&hw->lock); + return IRQ_NONE; /* shared */ + } + hw->irqcnt++; + mISDNipac_irq(&hw->ipac, irqloops); + spin_unlock(&hw->lock); + return IRQ_HANDLED; +} + +static void +enable_hwirq(struct inf_hw *hw) +{ + u16 w; + u32 val; + + switch (hw->ci->typ) { + case INF_DIVA201: + case INF_DIVA202: + writel(PITA_INT0_ENABLE, hw->cfg.p); + break; + case INF_SPEEDWIN: + case INF_SAPHIR3: + outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK); + break; + case INF_QS1000: + outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR); + break; + case INF_QS3000: + outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR); + break; + case INF_NICCY: + val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); + val |= NICCY_IRQ_ENABLE; + outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); + break; + case INF_SCT_1: + w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR); + w |= SCT_PLX_IRQ_ENABLE; + outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR); + break; + case INF_GAZEL_R685: + outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN, + (u32)hw->cfg.start + GAZEL_INCSR); + break; + case INF_GAZEL_R753: + outb(GAZEL_IPAC_EN + GAZEL_PCI_EN, + (u32)hw->cfg.start + GAZEL_INCSR); + break; + default: + break; + } +} + +static void +disable_hwirq(struct inf_hw *hw) +{ + u16 w; + u32 val; + + switch (hw->ci->typ) { + case INF_DIVA201: + case INF_DIVA202: + writel(0, hw->cfg.p); + break; + case INF_SPEEDWIN: + case INF_SAPHIR3: + outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK); + break; + case INF_QS1000: + outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR); + break; + case INF_QS3000: + outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR); + break; + case INF_NICCY: + val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); + val &= NICCY_IRQ_DISABLE; + outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); + break; + case INF_SCT_1: + w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR); + w &= (~SCT_PLX_IRQ_ENABLE); + outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR); + break; + case INF_GAZEL_R685: + case INF_GAZEL_R753: + outb(0, (u32)hw->cfg.start + GAZEL_INCSR); + break; + default: + break; + } +} + +static void +ipac_chip_reset(struct inf_hw *hw) +{ + hw->ipac.write_reg(hw, IPAC_POTA2, 0x20); + mdelay(5); + hw->ipac.write_reg(hw, IPAC_POTA2, 0x00); + mdelay(5); + hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf); + hw->ipac.write_reg(hw, IPAC_MASK, 0xc0); +} + +static void +reset_inf(struct inf_hw *hw) +{ + u16 w; + u32 val; + + if (debug & DEBUG_HW) + pr_notice("%s: resetting card\n", hw->name); + switch (hw->ci->typ) { + case INF_DIVA20: + case INF_DIVA20U: + outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL); + mdelay(10); + outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL); + mdelay(10); + /* Workaround PCI9060 */ + outb(9, (u32)hw->cfg.start + 0x69); + outb(DIVA_RESET_BIT | DIVA_LED_A, + (u32)hw->cfg.start + DIVA_PCI_CTRL); + break; + case INF_DIVA201: + writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE, + hw->cfg.p + PITA_MISC_REG); + mdelay(1); + writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG); + mdelay(10); + break; + case INF_DIVA202: + writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE, + hw->cfg.p + PITA_MISC_REG); + mdelay(1); + writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET, + hw->cfg.p + PITA_MISC_REG); + mdelay(10); + break; + case INF_SPEEDWIN: + case INF_SAPHIR3: + ipac_chip_reset(hw); + hw->ipac.write_reg(hw, IPAC_ACFG, 0xff); + hw->ipac.write_reg(hw, IPAC_AOE, 0x00); + hw->ipac.write_reg(hw, IPAC_PCFG, 0x12); + break; + case INF_QS1000: + case INF_QS3000: + ipac_chip_reset(hw); + hw->ipac.write_reg(hw, IPAC_ACFG, 0x00); + hw->ipac.write_reg(hw, IPAC_AOE, 0x3c); + hw->ipac.write_reg(hw, IPAC_ATX, 0xff); + break; + case INF_NICCY: + break; + case INF_SCT_1: + w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR); + w &= (~SCT_PLX_RESET_BIT); + outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR); + mdelay(10); + w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR); + w |= SCT_PLX_RESET_BIT; + outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR); + mdelay(10); + break; + case INF_GAZEL_R685: + val = inl((u32)hw->cfg.start + GAZEL_CNTRL); + val |= (GAZEL_RESET_9050 + GAZEL_RESET); + outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); + val &= ~(GAZEL_RESET_9050 + GAZEL_RESET); + mdelay(4); + outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); + mdelay(10); + hw->ipac.isac.adf2 = 0x87; + hw->ipac.hscx[0].slot = 0x1f; + hw->ipac.hscx[1].slot = 0x23; + break; + case INF_GAZEL_R753: + val = inl((u32)hw->cfg.start + GAZEL_CNTRL); + val |= (GAZEL_RESET_9050 + GAZEL_RESET); + outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); + val &= ~(GAZEL_RESET_9050 + GAZEL_RESET); + mdelay(4); + outl(val, (u32)hw->cfg.start + GAZEL_CNTRL); + mdelay(10); + ipac_chip_reset(hw); + hw->ipac.write_reg(hw, IPAC_ACFG, 0xff); + hw->ipac.write_reg(hw, IPAC_AOE, 0x00); + hw->ipac.conf = 0x01; /* IOM off */ + break; + default: + return; + } + enable_hwirq(hw); +} + +static int +inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg) +{ + int ret = 0; + + switch (cmd) { + case HW_RESET_REQ: + reset_inf(hw); + break; + default: + pr_info("%s: %s unknown command %x %lx\n", + hw->name, __func__, cmd, arg); + ret = -EINVAL; + break; + } + return ret; +} + +static int +init_irq(struct inf_hw *hw) +{ + int ret, cnt = 3; + u_long flags; + + if (!hw->ci->irqfunc) + return -EINVAL; + ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw); + if (ret) { + pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq); + return ret; + } + while (cnt--) { + spin_lock_irqsave(&hw->lock, flags); + reset_inf(hw); + ret = hw->ipac.init(&hw->ipac); + if (ret) { + spin_unlock_irqrestore(&hw->lock, flags); + pr_info("%s: ISAC init failed with %d\n", + hw->name, ret); + break; + } + spin_unlock_irqrestore(&hw->lock, flags); + msleep_interruptible(10); + if (debug & DEBUG_HW) + pr_notice("%s: IRQ %d count %d\n", hw->name, + hw->irq, hw->irqcnt); + if (!hw->irqcnt) { + pr_info("%s: IRQ(%d) got no requests during init %d\n", + hw->name, hw->irq, 3 - cnt); + } else + return 0; + } + free_irq(hw->irq, hw); + return -EIO; +} + +static void +release_io(struct inf_hw *hw) +{ + if (hw->cfg.mode) { + if (hw->cfg.p) { + release_mem_region(hw->cfg.start, hw->cfg.size); + iounmap(hw->cfg.p); + } else + release_region(hw->cfg.start, hw->cfg.size); + hw->cfg.mode = AM_NONE; + } + if (hw->addr.mode) { + if (hw->addr.p) { + release_mem_region(hw->addr.start, hw->addr.size); + iounmap(hw->addr.p); + } else + release_region(hw->addr.start, hw->addr.size); + hw->addr.mode = AM_NONE; + } +} + +static int +setup_io(struct inf_hw *hw) +{ + int err = 0; + + if (hw->ci->cfg_mode) { + hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar); + hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar); + if (hw->ci->cfg_mode == AM_MEMIO) { + if (!request_mem_region(hw->cfg.start, hw->cfg.size, + hw->name)) + err = -EBUSY; + } else { + if (!request_region(hw->cfg.start, hw->cfg.size, + hw->name)) + err = -EBUSY; + } + if (err) { + pr_info("mISDN: %s config port %lx (%lu bytes)" + "already in use\n", hw->name, + (ulong)hw->cfg.start, (ulong)hw->cfg.size); + return err; + } + if (hw->ci->cfg_mode == AM_MEMIO) + hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); + hw->cfg.mode = hw->ci->cfg_mode; + if (debug & DEBUG_HW) + pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n", + hw->name, (ulong)hw->cfg.start, + (ulong)hw->cfg.size, hw->ci->cfg_mode); + + } + if (hw->ci->addr_mode) { + hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar); + hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar); + if (hw->ci->addr_mode == AM_MEMIO) { + if (!request_mem_region(hw->addr.start, hw->addr.size, + hw->name)) + err = -EBUSY; + } else { + if (!request_region(hw->addr.start, hw->addr.size, + hw->name)) + err = -EBUSY; + } + if (err) { + pr_info("mISDN: %s address port %lx (%lu bytes)" + "already in use\n", hw->name, + (ulong)hw->addr.start, (ulong)hw->addr.size); + return err; + } + if (hw->ci->addr_mode == AM_MEMIO) + hw->addr.p = ioremap(hw->addr.start, hw->addr.size); + hw->addr.mode = hw->ci->addr_mode; + if (debug & DEBUG_HW) + pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n", + hw->name, (ulong)hw->addr.start, + (ulong)hw->addr.size, hw->ci->addr_mode); + + } + + switch (hw->ci->typ) { + case INF_DIVA20: + case INF_DIVA20U: + hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; + hw->isac.mode = hw->cfg.mode; + hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE; + hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT; + hw->hscx.mode = hw->cfg.mode; + hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE; + hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT; + break; + case INF_DIVA201: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.mode = hw->addr.mode; + hw->isac.a.p = hw->addr.p; + hw->hscx.mode = hw->addr.mode; + hw->hscx.a.p = hw->addr.p; + break; + case INF_DIVA202: + hw->ipac.type = IPAC_TYPE_IPACX; + hw->isac.mode = hw->addr.mode; + hw->isac.a.p = hw->addr.p; + hw->hscx.mode = hw->addr.mode; + hw->hscx.a.p = hw->addr.p; + break; + case INF_SPEEDWIN: + case INF_SAPHIR3: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.mode = hw->cfg.mode; + hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE; + hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT; + hw->hscx.mode = hw->cfg.mode; + hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE; + hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT; + outb(0xff, (ulong)hw->cfg.start); + mdelay(1); + outb(0x00, (ulong)hw->cfg.start); + mdelay(1); + outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL); + break; + case INF_QS1000: + case INF_QS3000: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.a.io.ale = (u32)hw->addr.start; + hw->isac.a.io.port = (u32)hw->addr.start + 1; + hw->isac.mode = hw->addr.mode; + hw->hscx.a.io.ale = (u32)hw->addr.start; + hw->hscx.a.io.port = (u32)hw->addr.start + 1; + hw->hscx.mode = hw->addr.mode; + break; + case INF_NICCY: + hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; + hw->isac.mode = hw->addr.mode; + hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE; + hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT; + hw->hscx.mode = hw->addr.mode; + hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE; + hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT; + break; + case INF_SCT_1: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.a.io.ale = (u32)hw->addr.start; + hw->isac.a.io.port = hw->isac.a.io.ale + 4; + hw->isac.mode = hw->addr.mode; + hw->hscx.a.io.ale = hw->isac.a.io.ale; + hw->hscx.a.io.port = hw->isac.a.io.port; + hw->hscx.mode = hw->addr.mode; + break; + case INF_SCT_2: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.a.io.ale = (u32)hw->addr.start + 0x08; + hw->isac.a.io.port = hw->isac.a.io.ale + 4; + hw->isac.mode = hw->addr.mode; + hw->hscx.a.io.ale = hw->isac.a.io.ale; + hw->hscx.a.io.port = hw->isac.a.io.port; + hw->hscx.mode = hw->addr.mode; + break; + case INF_SCT_3: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.a.io.ale = (u32)hw->addr.start + 0x10; + hw->isac.a.io.port = hw->isac.a.io.ale + 4; + hw->isac.mode = hw->addr.mode; + hw->hscx.a.io.ale = hw->isac.a.io.ale; + hw->hscx.a.io.port = hw->isac.a.io.port; + hw->hscx.mode = hw->addr.mode; + break; + case INF_SCT_4: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.a.io.ale = (u32)hw->addr.start + 0x20; + hw->isac.a.io.port = hw->isac.a.io.ale + 4; + hw->isac.mode = hw->addr.mode; + hw->hscx.a.io.ale = hw->isac.a.io.ale; + hw->hscx.a.io.port = hw->isac.a.io.port; + hw->hscx.mode = hw->addr.mode; + break; + case INF_GAZEL_R685: + hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX; + hw->ipac.isac.off = 0x80; + hw->isac.mode = hw->addr.mode; + hw->isac.a.io.port = (u32)hw->addr.start; + hw->hscx.mode = hw->addr.mode; + hw->hscx.a.io.port = hw->isac.a.io.port; + break; + case INF_GAZEL_R753: + hw->ipac.type = IPAC_TYPE_IPAC; + hw->ipac.isac.off = 0x80; + hw->isac.mode = hw->addr.mode; + hw->isac.a.io.ale = (u32)hw->addr.start; + hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT; + hw->hscx.mode = hw->addr.mode; + hw->hscx.a.io.ale = hw->isac.a.io.ale; + hw->hscx.a.io.port = hw->isac.a.io.port; + break; + default: + return -EINVAL; + } + switch (hw->isac.mode) { + case AM_MEMIO: + ASSIGN_FUNC_IPAC(MIO, hw->ipac); + break; + case AM_IND_IO: + ASSIGN_FUNC_IPAC(IND, hw->ipac); + break; + case AM_IO: + ASSIGN_FUNC_IPAC(IO, hw->ipac); + break; + default: + return -EINVAL; + } + return 0; +} + +static void +release_card(struct inf_hw *card) { + ulong flags; + int i; + + spin_lock_irqsave(&card->lock, flags); + disable_hwirq(card); + spin_unlock_irqrestore(&card->lock, flags); + card->ipac.isac.release(&card->ipac.isac); + free_irq(card->irq, card); + mISDN_unregister_device(&card->ipac.isac.dch.dev); + release_io(card); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + switch (card->ci->typ) { + case INF_SCT_2: + case INF_SCT_3: + case INF_SCT_4: + break; + case INF_SCT_1: + for (i = 0; i < 3; i++) { + if (card->sc[i]) + release_card(card->sc[i]); + card->sc[i] = NULL; + } + default: + pci_disable_device(card->pdev); + pci_set_drvdata(card->pdev, NULL); + break; + } + kfree(card); + inf_cnt--; +} + +static int +setup_instance(struct inf_hw *card) +{ + int err; + ulong flags; + + snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name, + inf_cnt + 1); + write_lock_irqsave(&card_lock, flags); + list_add_tail(&card->list, &Cards); + write_unlock_irqrestore(&card_lock, flags); + + _set_debug(card); + card->ipac.isac.name = card->name; + card->ipac.name = card->name; + card->ipac.owner = THIS_MODULE; + spin_lock_init(&card->lock); + card->ipac.isac.hwlock = &card->lock; + card->ipac.hwlock = &card->lock; + card->ipac.ctrl = (void *)&inf_ctrl; + + err = setup_io(card); + if (err) + goto error_setup; + + card->ipac.isac.dch.dev.Bprotocols = + mISDNipac_init(&card->ipac, card); + + if (card->ipac.isac.dch.dev.Bprotocols == 0) + goto error_setup; + + err = mISDN_register_device(&card->ipac.isac.dch.dev, + &card->pdev->dev, card->name); + if (err) + goto error; + + err = init_irq(card); + if (!err) { + inf_cnt++; + pr_notice("Infineon %d cards installed\n", inf_cnt); + return 0; + } + mISDN_unregister_device(&card->ipac.isac.dch.dev); +error: + card->ipac.release(&card->ipac); +error_setup: + release_io(card); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + return err; +} + +static const struct inf_cinfo inf_card_info[] = { + { + INF_DIVA20, + "Dialogic Diva 2.0", + "diva20", + AM_IND_IO, AM_NONE, 2, 0, + &diva_irq + }, + { + INF_DIVA20U, + "Dialogic Diva 2.0U", + "diva20U", + AM_IND_IO, AM_NONE, 2, 0, + &diva_irq + }, + { + INF_DIVA201, + "Dialogic Diva 2.01", + "diva201", + AM_MEMIO, AM_MEMIO, 0, 1, + &diva20x_irq + }, + { + INF_DIVA202, + "Dialogic Diva 2.02", + "diva202", + AM_MEMIO, AM_MEMIO, 0, 1, + &diva20x_irq + }, + { + INF_SPEEDWIN, + "Sedlbauer SpeedWin PCI", + "speedwin", + AM_IND_IO, AM_NONE, 0, 0, + &tiger_irq + }, + { + INF_SAPHIR3, + "HST Saphir 3", + "saphir", + AM_IND_IO, AM_NONE, 0, 0, + &tiger_irq + }, + { + INF_QS1000, + "Develo Microlink PCI", + "qs1000", + AM_IO, AM_IND_IO, 1, 3, + &elsa_irq + }, + { + INF_QS3000, + "Develo QuickStep 3000", + "qs3000", + AM_IO, AM_IND_IO, 1, 3, + &elsa_irq + }, + { + INF_NICCY, + "Sagem NICCY", + "niccy", + AM_IO, AM_IND_IO, 0, 1, + &niccy_irq + }, + { + INF_SCT_1, + "SciTel Quadro", + "p1_scitel", + AM_IO, AM_IND_IO, 1, 5, + &ipac_irq + }, + { + INF_SCT_2, + "SciTel Quadro", + "p2_scitel", + AM_NONE, AM_IND_IO, 0, 4, + &ipac_irq + }, + { + INF_SCT_3, + "SciTel Quadro", + "p3_scitel", + AM_NONE, AM_IND_IO, 0, 3, + &ipac_irq + }, + { + INF_SCT_4, + "SciTel Quadro", + "p4_scitel", + AM_NONE, AM_IND_IO, 0, 2, + &ipac_irq + }, + { + INF_GAZEL_R685, + "Gazel R685", + "gazel685", + AM_IO, AM_IO, 1, 2, + &gazel_irq + }, + { + INF_GAZEL_R753, + "Gazel R753", + "gazel753", + AM_IO, AM_IND_IO, 1, 2, + &ipac_irq + }, + { + INF_NONE, + } +}; + +static const struct inf_cinfo * +get_card_info(enum inf_types typ) +{ + const struct inf_cinfo *ci = inf_card_info; + + while (ci->typ != INF_NONE) { + if (ci->typ == typ) + return ci; + ci++; + } + return NULL; +} + +static int +inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = -ENOMEM; + struct inf_hw *card; + + card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); + if (!card) { + pr_info("No memory for Infineon ISDN card\n"); + return err; + } + card->pdev = pdev; + err = pci_enable_device(pdev); + if (err) { + kfree(card); + return err; + } + card->ci = get_card_info(ent->driver_data); + if (!card->ci) { + pr_info("mISDN: do not have informations about adapter at %s\n", + pci_name(pdev)); + kfree(card); + pci_disable_device(pdev); + return -EINVAL; + } else + pr_notice("mISDN: found adapter %s at %s\n", + card->ci->full, pci_name(pdev)); + + card->irq = pdev->irq; + pci_set_drvdata(pdev, card); + err = setup_instance(card); + if (err) { + pci_disable_device(pdev); + kfree(card); + pci_set_drvdata(pdev, NULL); + } else if (ent->driver_data == INF_SCT_1) { + int i; + struct inf_hw *sc; + + for (i = 1; i < 4; i++) { + sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); + if (!sc) { + release_card(card); + pci_disable_device(pdev); + return -ENOMEM; + } + sc->irq = card->irq; + sc->pdev = card->pdev; + sc->ci = card->ci + i; + err = setup_instance(sc); + if (err) { + pci_disable_device(pdev); + kfree(sc); + release_card(card); + break; + } else + card->sc[i - 1] = sc; + } + } + return err; +} + +static void +inf_remove(struct pci_dev *pdev) +{ + struct inf_hw *card = pci_get_drvdata(pdev); + + if (card) + release_card(card); + else + pr_debug("%s: drvdata already removed\n", __func__); +} + +static struct pci_driver infineon_driver = { + .name = "ISDN Infineon pci", + .probe = inf_probe, + .remove = inf_remove, + .id_table = infineon_ids, +}; + +static int __init +infineon_init(void) +{ + int err; + + pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV); + err = pci_register_driver(&infineon_driver); + return err; +} + +static void __exit +infineon_cleanup(void) +{ + pci_unregister_driver(&infineon_driver); +} + +module_init(infineon_init); +module_exit(infineon_cleanup); diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c new file mode 100644 index 00000000000..ccd7d851be2 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -0,0 +1,1647 @@ +/* + * isac.c ISAC specific routines + * + * Author Karsten Keil <keil@isdn4linux.de> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/irqreturn.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/mISDNhw.h> +#include "ipac.h" + + +#define DBUSY_TIMER_VALUE 80 +#define ARCOFI_USE 1 + +#define ISAC_REV "2.0" + +MODULE_AUTHOR("Karsten Keil"); +MODULE_VERSION(ISAC_REV); +MODULE_LICENSE("GPL v2"); + +#define ReadISAC(is, o) (is->read_reg(is->dch.hw, o + is->off)) +#define WriteISAC(is, o, v) (is->write_reg(is->dch.hw, o + is->off, v)) +#define ReadHSCX(h, o) (h->ip->read_reg(h->ip->hw, h->off + o)) +#define WriteHSCX(h, o, v) (h->ip->write_reg(h->ip->hw, h->off + o, v)) +#define ReadIPAC(ip, o) (ip->read_reg(ip->hw, o)) +#define WriteIPAC(ip, o, v) (ip->write_reg(ip->hw, o, v)) + +static inline void +ph_command(struct isac_hw *isac, u8 command) +{ + pr_debug("%s: ph_command %x\n", isac->name, command); + if (isac->type & IPAC_TYPE_ISACX) + WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE); + else + WriteISAC(isac, ISAC_CIX0, (command << 2) | 3); +} + +static void +isac_ph_state_change(struct isac_hw *isac) +{ + switch (isac->state) { + case (ISAC_IND_RS): + case (ISAC_IND_EI): + ph_command(isac, ISAC_CMD_DUI); + } + schedule_event(&isac->dch, FLG_PHCHANGE); +} + +static void +isac_ph_state_bh(struct dchannel *dch) +{ + struct isac_hw *isac = container_of(dch, struct isac_hw, dch); + + switch (isac->state) { + case ISAC_IND_RS: + case ISAC_IND_EI: + dch->state = 0; + l1_event(dch->l1, HW_RESET_IND); + break; + case ISAC_IND_DID: + dch->state = 3; + l1_event(dch->l1, HW_DEACT_CNF); + break; + case ISAC_IND_DR: + dch->state = 3; + l1_event(dch->l1, HW_DEACT_IND); + break; + case ISAC_IND_PU: + dch->state = 4; + l1_event(dch->l1, HW_POWERUP_IND); + break; + case ISAC_IND_RSY: + if (dch->state <= 5) { + dch->state = 5; + l1_event(dch->l1, ANYSIGNAL); + } else { + dch->state = 8; + l1_event(dch->l1, LOSTFRAMING); + } + break; + case ISAC_IND_ARD: + dch->state = 6; + l1_event(dch->l1, INFO2); + break; + case ISAC_IND_AI8: + dch->state = 7; + l1_event(dch->l1, INFO4_P8); + break; + case ISAC_IND_AI10: + dch->state = 7; + l1_event(dch->l1, INFO4_P10); + break; + } + pr_debug("%s: TE newstate %x\n", isac->name, dch->state); +} + +void +isac_empty_fifo(struct isac_hw *isac, int count) +{ + u8 *ptr; + + pr_debug("%s: %s %d\n", isac->name, __func__, count); + + if (!isac->dch.rx_skb) { + isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC); + if (!isac->dch.rx_skb) { + pr_info("%s: D receive out of memory\n", isac->name); + WriteISAC(isac, ISAC_CMDR, 0x80); + return; + } + } + if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) { + pr_debug("%s: %s overrun %d\n", isac->name, __func__, + isac->dch.rx_skb->len + count); + WriteISAC(isac, ISAC_CMDR, 0x80); + return; + } + ptr = skb_put(isac->dch.rx_skb, count); + isac->read_fifo(isac->dch.hw, isac->off, ptr, count); + WriteISAC(isac, ISAC_CMDR, 0x80); + if (isac->dch.debug & DEBUG_HW_DFIFO) { + char pfx[MISDN_MAX_IDLEN + 16]; + + snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ", + isac->name, count); + print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count); + } +} + +static void +isac_fill_fifo(struct isac_hw *isac) +{ + int count, more; + u8 *ptr; + + if (!isac->dch.tx_skb) + return; + count = isac->dch.tx_skb->len - isac->dch.tx_idx; + if (count <= 0) + return; + + more = 0; + if (count > 32) { + more = !0; + count = 32; + } + pr_debug("%s: %s %d\n", isac->name, __func__, count); + ptr = isac->dch.tx_skb->data + isac->dch.tx_idx; + isac->dch.tx_idx += count; + isac->write_fifo(isac->dch.hw, isac->off, ptr, count); + WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa); + if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) { + pr_debug("%s: %s dbusytimer running\n", isac->name, __func__); + del_timer(&isac->dch.timer); + } + init_timer(&isac->dch.timer); + isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); + add_timer(&isac->dch.timer); + if (isac->dch.debug & DEBUG_HW_DFIFO) { + char pfx[MISDN_MAX_IDLEN + 16]; + + snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ", + isac->name, count); + print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count); + } +} + +static void +isac_rme_irq(struct isac_hw *isac) +{ + u8 val, count; + + val = ReadISAC(isac, ISAC_RSTA); + if ((val & 0x70) != 0x20) { + if (val & 0x40) { + pr_debug("%s: ISAC RDO\n", isac->name); +#ifdef ERROR_STATISTIC + isac->dch.err_rx++; +#endif + } + if (!(val & 0x20)) { + pr_debug("%s: ISAC CRC error\n", isac->name); +#ifdef ERROR_STATISTIC + isac->dch.err_crc++; +#endif + } + WriteISAC(isac, ISAC_CMDR, 0x80); + if (isac->dch.rx_skb) + dev_kfree_skb(isac->dch.rx_skb); + isac->dch.rx_skb = NULL; + } else { + count = ReadISAC(isac, ISAC_RBCL) & 0x1f; + if (count == 0) + count = 32; + isac_empty_fifo(isac, count); + recv_Dchannel(&isac->dch); + } +} + +static void +isac_xpr_irq(struct isac_hw *isac) +{ + if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) + del_timer(&isac->dch.timer); + if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) { + isac_fill_fifo(isac); + } else { + if (isac->dch.tx_skb) + dev_kfree_skb(isac->dch.tx_skb); + if (get_next_dframe(&isac->dch)) + isac_fill_fifo(isac); + } +} + +static void +isac_retransmit(struct isac_hw *isac) +{ + if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) + del_timer(&isac->dch.timer); + if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) { + /* Restart frame */ + isac->dch.tx_idx = 0; + isac_fill_fifo(isac); + } else if (isac->dch.tx_skb) { /* should not happen */ + pr_info("%s: tx_skb exist but not busy\n", isac->name); + test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags); + isac->dch.tx_idx = 0; + isac_fill_fifo(isac); + } else { + pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name); + if (get_next_dframe(&isac->dch)) + isac_fill_fifo(isac); + } +} + +static void +isac_mos_irq(struct isac_hw *isac) +{ + u8 val; + int ret; + + val = ReadISAC(isac, ISAC_MOSR); + pr_debug("%s: ISAC MOSR %02x\n", isac->name, val); +#if ARCOFI_USE + if (val & 0x08) { + if (!isac->mon_rx) { + isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); + if (!isac->mon_rx) { + pr_info("%s: ISAC MON RX out of memory!\n", + isac->name); + isac->mocr &= 0xf0; + isac->mocr |= 0x0a; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + goto afterMONR0; + } else + isac->mon_rxp = 0; + } + if (isac->mon_rxp >= MAX_MON_FRAME) { + isac->mocr &= 0xf0; + isac->mocr |= 0x0a; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + isac->mon_rxp = 0; + pr_debug("%s: ISAC MON RX overflow!\n", isac->name); + goto afterMONR0; + } + isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0); + pr_debug("%s: ISAC MOR0 %02x\n", isac->name, + isac->mon_rx[isac->mon_rxp - 1]); + if (isac->mon_rxp == 1) { + isac->mocr |= 0x04; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + } + } +afterMONR0: + if (val & 0x80) { + if (!isac->mon_rx) { + isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); + if (!isac->mon_rx) { + pr_info("%s: ISAC MON RX out of memory!\n", + isac->name); + isac->mocr &= 0x0f; + isac->mocr |= 0xa0; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + goto afterMONR1; + } else + isac->mon_rxp = 0; + } + if (isac->mon_rxp >= MAX_MON_FRAME) { + isac->mocr &= 0x0f; + isac->mocr |= 0xa0; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + isac->mon_rxp = 0; + pr_debug("%s: ISAC MON RX overflow!\n", isac->name); + goto afterMONR1; + } + isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1); + pr_debug("%s: ISAC MOR1 %02x\n", isac->name, + isac->mon_rx[isac->mon_rxp - 1]); + isac->mocr |= 0x40; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + } +afterMONR1: + if (val & 0x04) { + isac->mocr &= 0xf0; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + isac->mocr |= 0x0a; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + if (isac->monitor) { + ret = isac->monitor(isac->dch.hw, MONITOR_RX_0, + isac->mon_rx, isac->mon_rxp); + if (ret) + kfree(isac->mon_rx); + } else { + pr_info("%s: MONITOR 0 received %d but no user\n", + isac->name, isac->mon_rxp); + kfree(isac->mon_rx); + } + isac->mon_rx = NULL; + isac->mon_rxp = 0; + } + if (val & 0x40) { + isac->mocr &= 0x0f; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + isac->mocr |= 0xa0; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + if (isac->monitor) { + ret = isac->monitor(isac->dch.hw, MONITOR_RX_1, + isac->mon_rx, isac->mon_rxp); + if (ret) + kfree(isac->mon_rx); + } else { + pr_info("%s: MONITOR 1 received %d but no user\n", + isac->name, isac->mon_rxp); + kfree(isac->mon_rx); + } + isac->mon_rx = NULL; + isac->mon_rxp = 0; + } + if (val & 0x02) { + if ((!isac->mon_tx) || (isac->mon_txc && + (isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) { + isac->mocr &= 0xf0; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + isac->mocr |= 0x0a; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { + if (isac->monitor) + ret = isac->monitor(isac->dch.hw, + MONITOR_TX_0, NULL, 0); + } + kfree(isac->mon_tx); + isac->mon_tx = NULL; + isac->mon_txc = 0; + isac->mon_txp = 0; + goto AfterMOX0; + } + if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { + if (isac->monitor) + ret = isac->monitor(isac->dch.hw, + MONITOR_TX_0, NULL, 0); + kfree(isac->mon_tx); + isac->mon_tx = NULL; + isac->mon_txc = 0; + isac->mon_txp = 0; + goto AfterMOX0; + } + WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]); + pr_debug("%s: ISAC %02x -> MOX0\n", isac->name, + isac->mon_tx[isac->mon_txp - 1]); + } +AfterMOX0: + if (val & 0x20) { + if ((!isac->mon_tx) || (isac->mon_txc && + (isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) { + isac->mocr &= 0x0f; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + isac->mocr |= 0xa0; + WriteISAC(isac, ISAC_MOCR, isac->mocr); + if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { + if (isac->monitor) + ret = isac->monitor(isac->dch.hw, + MONITOR_TX_1, NULL, 0); + } + kfree(isac->mon_tx); + isac->mon_tx = NULL; + isac->mon_txc = 0; + isac->mon_txp = 0; + goto AfterMOX1; + } + if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { + if (isac->monitor) + ret = isac->monitor(isac->dch.hw, + MONITOR_TX_1, NULL, 0); + kfree(isac->mon_tx); + isac->mon_tx = NULL; + isac->mon_txc = 0; + isac->mon_txp = 0; + goto AfterMOX1; + } + WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]); + pr_debug("%s: ISAC %02x -> MOX1\n", isac->name, + isac->mon_tx[isac->mon_txp - 1]); + } +AfterMOX1: + val = 0; /* dummy to avoid warning */ +#endif +} + +static void +isac_cisq_irq(struct isac_hw *isac) { + u8 val; + + val = ReadISAC(isac, ISAC_CIR0); + pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val); + if (val & 2) { + pr_debug("%s: ph_state change %x->%x\n", isac->name, + isac->state, (val >> 2) & 0xf); + isac->state = (val >> 2) & 0xf; + isac_ph_state_change(isac); + } + if (val & 1) { + val = ReadISAC(isac, ISAC_CIR1); + pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val); + } +} + +static void +isacsx_cic_irq(struct isac_hw *isac) +{ + u8 val; + + val = ReadISAC(isac, ISACX_CIR0); + pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val); + if (val & ISACX_CIR0_CIC0) { + pr_debug("%s: ph_state change %x->%x\n", isac->name, + isac->state, val >> 4); + isac->state = val >> 4; + isac_ph_state_change(isac); + } +} + +static void +isacsx_rme_irq(struct isac_hw *isac) +{ + int count; + u8 val; + + val = ReadISAC(isac, ISACX_RSTAD); + if ((val & (ISACX_RSTAD_VFR | + ISACX_RSTAD_RDO | + ISACX_RSTAD_CRC | + ISACX_RSTAD_RAB)) + != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) { + pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val); +#ifdef ERROR_STATISTIC + if (val & ISACX_RSTAD_CRC) + isac->dch.err_rx++; + else + isac->dch.err_crc++; +#endif + WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC); + if (isac->dch.rx_skb) + dev_kfree_skb(isac->dch.rx_skb); + isac->dch.rx_skb = NULL; + } else { + count = ReadISAC(isac, ISACX_RBCLD) & 0x1f; + if (count == 0) + count = 32; + isac_empty_fifo(isac, count); + if (isac->dch.rx_skb) { + skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1); + pr_debug("%s: dchannel received %d\n", isac->name, + isac->dch.rx_skb->len); + recv_Dchannel(&isac->dch); + } + } +} + +irqreturn_t +mISDNisac_irq(struct isac_hw *isac, u8 val) +{ + if (unlikely(!val)) + return IRQ_NONE; + pr_debug("%s: ISAC interrupt %02x\n", isac->name, val); + if (isac->type & IPAC_TYPE_ISACX) { + if (val & ISACX__CIC) + isacsx_cic_irq(isac); + if (val & ISACX__ICD) { + val = ReadISAC(isac, ISACX_ISTAD); + pr_debug("%s: ISTAD %02x\n", isac->name, val); + if (val & ISACX_D_XDU) { + pr_debug("%s: ISAC XDU\n", isac->name); +#ifdef ERROR_STATISTIC + isac->dch.err_tx++; +#endif + isac_retransmit(isac); + } + if (val & ISACX_D_XMR) { + pr_debug("%s: ISAC XMR\n", isac->name); +#ifdef ERROR_STATISTIC + isac->dch.err_tx++; +#endif + isac_retransmit(isac); + } + if (val & ISACX_D_XPR) + isac_xpr_irq(isac); + if (val & ISACX_D_RFO) { + pr_debug("%s: ISAC RFO\n", isac->name); + WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC); + } + if (val & ISACX_D_RME) + isacsx_rme_irq(isac); + if (val & ISACX_D_RPF) + isac_empty_fifo(isac, 0x20); + } + } else { + if (val & 0x80) /* RME */ + isac_rme_irq(isac); + if (val & 0x40) /* RPF */ + isac_empty_fifo(isac, 32); + if (val & 0x10) /* XPR */ + isac_xpr_irq(isac); + if (val & 0x04) /* CISQ */ + isac_cisq_irq(isac); + if (val & 0x20) /* RSC - never */ + pr_debug("%s: ISAC RSC interrupt\n", isac->name); + if (val & 0x02) /* SIN - never */ + pr_debug("%s: ISAC SIN interrupt\n", isac->name); + if (val & 0x01) { /* EXI */ + val = ReadISAC(isac, ISAC_EXIR); + pr_debug("%s: ISAC EXIR %02x\n", isac->name, val); + if (val & 0x80) /* XMR */ + pr_debug("%s: ISAC XMR\n", isac->name); + if (val & 0x40) { /* XDU */ + pr_debug("%s: ISAC XDU\n", isac->name); +#ifdef ERROR_STATISTIC + isac->dch.err_tx++; +#endif + isac_retransmit(isac); + } + if (val & 0x04) /* MOS */ + isac_mos_irq(isac); + } + } + return IRQ_HANDLED; +} +EXPORT_SYMBOL(mISDNisac_irq); + +static int +isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct isac_hw *isac = container_of(dch, struct isac_hw, dch); + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + u32 id; + u_long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(isac->hwlock, flags); + ret = dchannel_senddata(dch, skb); + if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ + isac_fill_fifo(isac); + ret = 0; + spin_unlock_irqrestore(isac->hwlock, flags); + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(isac->hwlock, flags); + return ret; + case PH_ACTIVATE_REQ: + ret = l1_event(dch->l1, hh->prim); + break; + case PH_DEACTIVATE_REQ: + test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); + ret = l1_event(dch->l1, hh->prim); + break; + } + + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static int +isac_ctrl(struct isac_hw *isac, u32 cmd, unsigned long para) +{ + u8 tl = 0; + unsigned long flags; + int ret = 0; + + switch (cmd) { + case HW_TESTLOOP: + spin_lock_irqsave(isac->hwlock, flags); + if (!(isac->type & IPAC_TYPE_ISACX)) { + /* TODO: implement for IPAC_TYPE_ISACX */ + if (para & 1) /* B1 */ + tl |= 0x0c; + else if (para & 2) /* B2 */ + tl |= 0x3; + /* we only support IOM2 mode */ + WriteISAC(isac, ISAC_SPCR, tl); + if (tl) + WriteISAC(isac, ISAC_ADF1, 0x8); + else + WriteISAC(isac, ISAC_ADF1, 0x0); + } + spin_unlock_irqrestore(isac->hwlock, flags); + break; + case HW_TIMER3_VALUE: + ret = l1_event(isac->dch.l1, HW_TIMER3_VALUE | (para & 0xff)); + break; + default: + pr_debug("%s: %s unknown command %x %lx\n", isac->name, + __func__, cmd, para); + ret = -1; + } + return ret; +} + +static int +isac_l1cmd(struct dchannel *dch, u32 cmd) +{ + struct isac_hw *isac = container_of(dch, struct isac_hw, dch); + u_long flags; + + pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state); + switch (cmd) { + case INFO3_P8: + spin_lock_irqsave(isac->hwlock, flags); + ph_command(isac, ISAC_CMD_AR8); + spin_unlock_irqrestore(isac->hwlock, flags); + break; + case INFO3_P10: + spin_lock_irqsave(isac->hwlock, flags); + ph_command(isac, ISAC_CMD_AR10); + spin_unlock_irqrestore(isac->hwlock, flags); + break; + case HW_RESET_REQ: + spin_lock_irqsave(isac->hwlock, flags); + if ((isac->state == ISAC_IND_EI) || + (isac->state == ISAC_IND_DR) || + (isac->state == ISAC_IND_RS)) + ph_command(isac, ISAC_CMD_TIM); + else + ph_command(isac, ISAC_CMD_RS); + spin_unlock_irqrestore(isac->hwlock, flags); + break; + case HW_DEACT_REQ: + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) + del_timer(&dch->timer); + break; + case HW_POWERUP_REQ: + spin_lock_irqsave(isac->hwlock, flags); + ph_command(isac, ISAC_CMD_TIM); + spin_unlock_irqrestore(isac->hwlock, flags); + break; + case PH_ACTIVATE_IND: + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + case PH_DEACTIVATE_IND: + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + default: + pr_debug("%s: %s unknown command %x\n", isac->name, + __func__, cmd); + return -1; + } + return 0; +} + +static void +isac_release(struct isac_hw *isac) +{ + if (isac->type & IPAC_TYPE_ISACX) + WriteISAC(isac, ISACX_MASK, 0xff); + else + WriteISAC(isac, ISAC_MASK, 0xff); + if (isac->dch.timer.function != NULL) { + del_timer(&isac->dch.timer); + isac->dch.timer.function = NULL; + } + kfree(isac->mon_rx); + isac->mon_rx = NULL; + kfree(isac->mon_tx); + isac->mon_tx = NULL; + if (isac->dch.l1) + l1_event(isac->dch.l1, CLOSE_CHANNEL); + mISDN_freedchannel(&isac->dch); +} + +static void +dbusy_timer_handler(struct isac_hw *isac) +{ + int rbch, star; + u_long flags; + + if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) { + spin_lock_irqsave(isac->hwlock, flags); + rbch = ReadISAC(isac, ISAC_RBCH); + star = ReadISAC(isac, ISAC_STAR); + pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n", + isac->name, rbch, star); + if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */ + test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags); + else { + /* discard frame; reset transceiver */ + test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags); + if (isac->dch.tx_idx) + isac->dch.tx_idx = 0; + else + pr_info("%s: ISAC D-Channel Busy no tx_idx\n", + isac->name); + /* Transmitter reset */ + WriteISAC(isac, ISAC_CMDR, 0x01); + } + spin_unlock_irqrestore(isac->hwlock, flags); + } +} + +static int +open_dchannel(struct isac_hw *isac, struct channel_req *rq) +{ + pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__, + isac->dch.dev.id, __builtin_return_address(1)); + if (rq->protocol != ISDN_P_TE_S0) + return -EINVAL; + if (rq->adr.channel == 1) + /* E-Channel not supported */ + return -EINVAL; + rq->ch = &isac->dch.dev.D; + rq->ch->protocol = rq->protocol; + if (isac->dch.state == 7) + _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY, + 0, NULL, GFP_KERNEL); + return 0; +} + +static const char *ISACVer[] = +{"2086/2186 V1.1", "2085 B1", "2085 B2", + "2085 V2.3"}; + +static int +isac_init(struct isac_hw *isac) +{ + u8 val; + int err = 0; + + if (!isac->dch.l1) { + err = create_l1(&isac->dch, isac_l1cmd); + if (err) + return err; + } + isac->mon_tx = NULL; + isac->mon_rx = NULL; + isac->dch.timer.function = (void *) dbusy_timer_handler; + isac->dch.timer.data = (long)isac; + init_timer(&isac->dch.timer); + isac->mocr = 0xaa; + if (isac->type & IPAC_TYPE_ISACX) { + /* Disable all IRQ */ + WriteISAC(isac, ISACX_MASK, 0xff); + val = ReadISAC(isac, ISACX_STARD); + pr_debug("%s: ISACX STARD %x\n", isac->name, val); + val = ReadISAC(isac, ISACX_ISTAD); + pr_debug("%s: ISACX ISTAD %x\n", isac->name, val); + val = ReadISAC(isac, ISACX_ISTA); + pr_debug("%s: ISACX ISTA %x\n", isac->name, val); + /* clear LDD */ + WriteISAC(isac, ISACX_TR_CONF0, 0x00); + /* enable transmitter */ + WriteISAC(isac, ISACX_TR_CONF2, 0x00); + /* transparent mode 0, RAC, stop/go */ + WriteISAC(isac, ISACX_MODED, 0xc9); + /* all HDLC IRQ unmasked */ + val = ReadISAC(isac, ISACX_ID); + if (isac->dch.debug & DEBUG_HW) + pr_notice("%s: ISACX Design ID %x\n", + isac->name, val & 0x3f); + val = ReadISAC(isac, ISACX_CIR0); + pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val); + isac->state = val >> 4; + isac_ph_state_change(isac); + ph_command(isac, ISAC_CMD_RS); + WriteISAC(isac, ISACX_MASK, IPACX__ON); + WriteISAC(isac, ISACX_MASKD, 0x00); + } else { /* old isac */ + WriteISAC(isac, ISAC_MASK, 0xff); + val = ReadISAC(isac, ISAC_STAR); + pr_debug("%s: ISAC STAR %x\n", isac->name, val); + val = ReadISAC(isac, ISAC_MODE); + pr_debug("%s: ISAC MODE %x\n", isac->name, val); + val = ReadISAC(isac, ISAC_ADF2); + pr_debug("%s: ISAC ADF2 %x\n", isac->name, val); + val = ReadISAC(isac, ISAC_ISTA); + pr_debug("%s: ISAC ISTA %x\n", isac->name, val); + if (val & 0x01) { + val = ReadISAC(isac, ISAC_EXIR); + pr_debug("%s: ISAC EXIR %x\n", isac->name, val); + } + val = ReadISAC(isac, ISAC_RBCH); + if (isac->dch.debug & DEBUG_HW) + pr_notice("%s: ISAC version (%x): %s\n", isac->name, + val, ISACVer[(val >> 5) & 3]); + isac->type |= ((val >> 5) & 3); + if (!isac->adf2) + isac->adf2 = 0x80; + if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */ + pr_info("%s: only support IOM2 mode but adf2=%02x\n", + isac->name, isac->adf2); + isac_release(isac); + return -EINVAL; + } + WriteISAC(isac, ISAC_ADF2, isac->adf2); + WriteISAC(isac, ISAC_SQXR, 0x2f); + WriteISAC(isac, ISAC_SPCR, 0x00); + WriteISAC(isac, ISAC_STCR, 0x70); + WriteISAC(isac, ISAC_MODE, 0xc9); + WriteISAC(isac, ISAC_TIMR, 0x00); + WriteISAC(isac, ISAC_ADF1, 0x00); + val = ReadISAC(isac, ISAC_CIR0); + pr_debug("%s: ISAC CIR0 %x\n", isac->name, val); + isac->state = (val >> 2) & 0xf; + isac_ph_state_change(isac); + ph_command(isac, ISAC_CMD_RS); + WriteISAC(isac, ISAC_MASK, 0); + } + return err; +} + +int +mISDNisac_init(struct isac_hw *isac, void *hw) +{ + mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh); + isac->dch.hw = hw; + isac->dch.dev.D.send = isac_l1hw; + isac->init = isac_init; + isac->release = isac_release; + isac->ctrl = isac_ctrl; + isac->open = open_dchannel; + isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0); + isac->dch.dev.nrbchan = 2; + return 0; +} +EXPORT_SYMBOL(mISDNisac_init); + +static void +waitforCEC(struct hscx_hw *hx) +{ + u8 starb, to = 50; + + while (to) { + starb = ReadHSCX(hx, IPAC_STARB); + if (!(starb & 0x04)) + break; + udelay(1); + to--; + } + if (to < 50) + pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr, + 50 - to); + if (!to) + pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr); +} + + +static void +waitforXFW(struct hscx_hw *hx) +{ + u8 starb, to = 50; + + while (to) { + starb = ReadHSCX(hx, IPAC_STARB); + if ((starb & 0x44) == 0x40) + break; + udelay(1); + to--; + } + if (to < 50) + pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr, + 50 - to); + if (!to) + pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr); +} + +static void +hscx_cmdr(struct hscx_hw *hx, u8 cmd) +{ + if (hx->ip->type & IPAC_TYPE_IPACX) + WriteHSCX(hx, IPACX_CMDRB, cmd); + else { + waitforCEC(hx); + WriteHSCX(hx, IPAC_CMDRB, cmd); + } +} + +static void +hscx_empty_fifo(struct hscx_hw *hscx, u8 count) +{ + u8 *p; + int maxlen; + + pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count); + if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) { + hscx->bch.dropcnt += count; + hscx_cmdr(hscx, 0x80); /* RMC */ + return; + } + maxlen = bchannel_get_rxbuf(&hscx->bch, count); + if (maxlen < 0) { + hscx_cmdr(hscx, 0x80); /* RMC */ + if (hscx->bch.rx_skb) + skb_trim(hscx->bch.rx_skb, 0); + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + hscx->ip->name, hscx->bch.nr, count); + return; + } + p = skb_put(hscx->bch.rx_skb, count); + + if (hscx->ip->type & IPAC_TYPE_IPACX) + hscx->ip->read_fifo(hscx->ip->hw, + hscx->off + IPACX_RFIFOB, p, count); + else + hscx->ip->read_fifo(hscx->ip->hw, + hscx->off, p, count); + + hscx_cmdr(hscx, 0x80); /* RMC */ + + if (hscx->bch.debug & DEBUG_HW_BFIFO) { + snprintf(hscx->log, 64, "B%1d-recv %s %d ", + hscx->bch.nr, hscx->ip->name, count); + print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); + } +} + +static void +hscx_fill_fifo(struct hscx_hw *hscx) +{ + int count, more; + u8 *p; + + if (!hscx->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags)) + return; + count = hscx->fifo_size; + more = 1; + p = hscx->log; + memset(p, hscx->bch.fill[0], count); + } else { + count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; + if (count <= 0) + return; + p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; + + more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; + if (count > hscx->fifo_size) { + count = hscx->fifo_size; + more = 1; + } + pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, + count, hscx->bch.tx_idx, hscx->bch.tx_skb->len); + hscx->bch.tx_idx += count; + } + if (hscx->ip->type & IPAC_TYPE_IPACX) + hscx->ip->write_fifo(hscx->ip->hw, + hscx->off + IPACX_XFIFOB, p, count); + else { + waitforXFW(hscx); + hscx->ip->write_fifo(hscx->ip->hw, + hscx->off, p, count); + } + hscx_cmdr(hscx, more ? 0x08 : 0x0a); + + if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) { + snprintf(hscx->log, 64, "B%1d-send %s %d ", + hscx->bch.nr, hscx->ip->name, count); + print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); + } +} + +static void +hscx_xpr(struct hscx_hw *hx) +{ + if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) { + hscx_fill_fifo(hx); + } else { + if (hx->bch.tx_skb) + dev_kfree_skb(hx->bch.tx_skb); + if (get_next_bframe(&hx->bch)) { + hscx_fill_fifo(hx); + test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) { + hscx_fill_fifo(hx); + } + } +} + +static void +ipac_rme(struct hscx_hw *hx) +{ + int count; + u8 rstab; + + if (hx->ip->type & IPAC_TYPE_IPACX) + rstab = ReadHSCX(hx, IPACX_RSTAB); + else + rstab = ReadHSCX(hx, IPAC_RSTAB); + pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab); + if ((rstab & 0xf0) != 0xa0) { + /* !(VFR && !RDO && CRC && !RAB) */ + if (!(rstab & 0x80)) { + if (hx->bch.debug & DEBUG_HW_BCHANNEL) + pr_notice("%s: B%1d invalid frame\n", + hx->ip->name, hx->bch.nr); + } + if (rstab & 0x40) { + if (hx->bch.debug & DEBUG_HW_BCHANNEL) + pr_notice("%s: B%1d RDO proto=%x\n", + hx->ip->name, hx->bch.nr, + hx->bch.state); + } + if (!(rstab & 0x20)) { + if (hx->bch.debug & DEBUG_HW_BCHANNEL) + pr_notice("%s: B%1d CRC error\n", + hx->ip->name, hx->bch.nr); + } + hscx_cmdr(hx, 0x80); /* Do RMC */ + return; + } + if (hx->ip->type & IPAC_TYPE_IPACX) + count = ReadHSCX(hx, IPACX_RBCLB); + else + count = ReadHSCX(hx, IPAC_RBCLB); + count &= (hx->fifo_size - 1); + if (count == 0) + count = hx->fifo_size; + hscx_empty_fifo(hx, count); + if (!hx->bch.rx_skb) + return; + if (hx->bch.rx_skb->len < 2) { + pr_debug("%s: B%1d frame to short %d\n", + hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len); + skb_trim(hx->bch.rx_skb, 0); + } else { + skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1); + recv_Bchannel(&hx->bch, 0, false); + } +} + +static void +ipac_irq(struct hscx_hw *hx, u8 ista) +{ + u8 istab, m, exirb = 0; + + if (hx->ip->type & IPAC_TYPE_IPACX) + istab = ReadHSCX(hx, IPACX_ISTAB); + else if (hx->ip->type & IPAC_TYPE_IPAC) { + istab = ReadHSCX(hx, IPAC_ISTAB); + m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB; + if (m & ista) { + exirb = ReadHSCX(hx, IPAC_EXIRB); + pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name, + hx->bch.nr, exirb); + } + } else if (hx->bch.nr & 2) { /* HSCX B */ + if (ista & (HSCX__EXA | HSCX__ICA)) + ipac_irq(&hx->ip->hscx[0], ista); + if (ista & HSCX__EXB) { + exirb = ReadHSCX(hx, IPAC_EXIRB); + pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name, + hx->bch.nr, exirb); + } + istab = ista & 0xF8; + } else { /* HSCX A */ + istab = ReadHSCX(hx, IPAC_ISTAB); + if (ista & HSCX__EXA) { + exirb = ReadHSCX(hx, IPAC_EXIRB); + pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name, + hx->bch.nr, exirb); + } + istab = istab & 0xF8; + } + if (exirb & IPAC_B_XDU) + istab |= IPACX_B_XDU; + if (exirb & IPAC_B_RFO) + istab |= IPACX_B_RFO; + pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab); + + if (!test_bit(FLG_ACTIVE, &hx->bch.Flags)) + return; + + if (istab & IPACX_B_RME) + ipac_rme(hx); + + if (istab & IPACX_B_RPF) { + hscx_empty_fifo(hx, hx->fifo_size); + if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) + recv_Bchannel(&hx->bch, 0, false); + } + + if (istab & IPACX_B_RFO) { + pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr); + hscx_cmdr(hx, 0x40); /* RRES */ + } + + if (istab & IPACX_B_XPR) + hscx_xpr(hx); + + if (istab & IPACX_B_XDU) { + if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { + if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags)) + test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags); + hscx_xpr(hx); + return; + } + pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name, + hx->bch.nr, hx->bch.tx_idx); + hx->bch.tx_idx = 0; + hscx_cmdr(hx, 0x01); /* XRES */ + } +} + +irqreturn_t +mISDNipac_irq(struct ipac_hw *ipac, int maxloop) +{ + int cnt = maxloop + 1; + u8 ista, istad; + struct isac_hw *isac = &ipac->isac; + + if (ipac->type & IPAC_TYPE_IPACX) { + ista = ReadIPAC(ipac, ISACX_ISTA); + while (ista && cnt--) { + pr_debug("%s: ISTA %02x\n", ipac->name, ista); + if (ista & IPACX__ICA) + ipac_irq(&ipac->hscx[0], ista); + if (ista & IPACX__ICB) + ipac_irq(&ipac->hscx[1], ista); + if (ista & (ISACX__ICD | ISACX__CIC)) + mISDNisac_irq(&ipac->isac, ista); + ista = ReadIPAC(ipac, ISACX_ISTA); + } + } else if (ipac->type & IPAC_TYPE_IPAC) { + ista = ReadIPAC(ipac, IPAC_ISTA); + while (ista && cnt--) { + pr_debug("%s: ISTA %02x\n", ipac->name, ista); + if (ista & (IPAC__ICD | IPAC__EXD)) { + istad = ReadISAC(isac, ISAC_ISTA); + pr_debug("%s: ISTAD %02x\n", ipac->name, istad); + if (istad & IPAC_D_TIN2) + pr_debug("%s TIN2 irq\n", ipac->name); + if (ista & IPAC__EXD) + istad |= 1; /* ISAC EXI */ + mISDNisac_irq(isac, istad); + } + if (ista & (IPAC__ICA | IPAC__EXA)) + ipac_irq(&ipac->hscx[0], ista); + if (ista & (IPAC__ICB | IPAC__EXB)) + ipac_irq(&ipac->hscx[1], ista); + ista = ReadIPAC(ipac, IPAC_ISTA); + } + } else if (ipac->type & IPAC_TYPE_HSCX) { + while (cnt) { + ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off); + pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista); + if (ista) + ipac_irq(&ipac->hscx[1], ista); + istad = ReadISAC(isac, ISAC_ISTA); + pr_debug("%s: ISTAD %02x\n", ipac->name, istad); + if (istad) + mISDNisac_irq(isac, istad); + if (0 == (ista | istad)) + break; + cnt--; + } + } + if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */ + return IRQ_NONE; + if (cnt < maxloop) + pr_debug("%s: %d irqloops cpu%d\n", ipac->name, + maxloop - cnt, smp_processor_id()); + if (maxloop && !cnt) + pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name, + maxloop, smp_processor_id()); + return IRQ_HANDLED; +} +EXPORT_SYMBOL(mISDNipac_irq); + +static int +hscx_mode(struct hscx_hw *hscx, u32 bprotocol) +{ + pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name, + '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr); + if (hscx->ip->type & IPAC_TYPE_IPACX) { + if (hscx->bch.nr & 1) { /* B1 and ICA */ + WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80); + WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88); + } else { /* B2 and ICB */ + WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81); + WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88); + } + switch (bprotocol) { + case ISDN_P_NONE: /* init */ + WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* rec off */ + WriteHSCX(hscx, IPACX_EXMB, 0x30); /* std adj. */ + WriteHSCX(hscx, IPACX_MASKB, 0xFF); /* ints off */ + hscx_cmdr(hscx, 0x41); + test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags); + test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags); + break; + case ISDN_P_B_RAW: + WriteHSCX(hscx, IPACX_MODEB, 0x88); /* ex trans */ + WriteHSCX(hscx, IPACX_EXMB, 0x00); /* trans */ + hscx_cmdr(hscx, 0x41); + WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON); + test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags); + break; + case ISDN_P_B_HDLC: + WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* trans */ + WriteHSCX(hscx, IPACX_EXMB, 0x00); /* hdlc,crc */ + hscx_cmdr(hscx, 0x41); + WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON); + test_and_set_bit(FLG_HDLC, &hscx->bch.Flags); + break; + default: + pr_info("%s: protocol not known %x\n", hscx->ip->name, + bprotocol); + return -ENOPROTOOPT; + } + } else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */ + WriteHSCX(hscx, IPAC_CCR1, 0x82); + WriteHSCX(hscx, IPAC_CCR2, 0x30); + WriteHSCX(hscx, IPAC_XCCR, 0x07); + WriteHSCX(hscx, IPAC_RCCR, 0x07); + WriteHSCX(hscx, IPAC_TSAX, hscx->slot); + WriteHSCX(hscx, IPAC_TSAR, hscx->slot); + switch (bprotocol) { + case ISDN_P_NONE: + WriteHSCX(hscx, IPAC_TSAX, 0x1F); + WriteHSCX(hscx, IPAC_TSAR, 0x1F); + WriteHSCX(hscx, IPAC_MODEB, 0x84); + WriteHSCX(hscx, IPAC_CCR1, 0x82); + WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */ + test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags); + test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags); + break; + case ISDN_P_B_RAW: + WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */ + WriteHSCX(hscx, IPAC_CCR1, 0x82); + hscx_cmdr(hscx, 0x41); + WriteHSCX(hscx, IPAC_MASKB, 0); + test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags); + break; + case ISDN_P_B_HDLC: + WriteHSCX(hscx, IPAC_MODEB, 0x8c); + WriteHSCX(hscx, IPAC_CCR1, 0x8a); + hscx_cmdr(hscx, 0x41); + WriteHSCX(hscx, IPAC_MASKB, 0); + test_and_set_bit(FLG_HDLC, &hscx->bch.Flags); + break; + default: + pr_info("%s: protocol not known %x\n", hscx->ip->name, + bprotocol); + return -ENOPROTOOPT; + } + } else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */ + WriteHSCX(hscx, IPAC_CCR1, 0x85); + WriteHSCX(hscx, IPAC_CCR2, 0x30); + WriteHSCX(hscx, IPAC_XCCR, 0x07); + WriteHSCX(hscx, IPAC_RCCR, 0x07); + WriteHSCX(hscx, IPAC_TSAX, hscx->slot); + WriteHSCX(hscx, IPAC_TSAR, hscx->slot); + switch (bprotocol) { + case ISDN_P_NONE: + WriteHSCX(hscx, IPAC_TSAX, 0x1F); + WriteHSCX(hscx, IPAC_TSAR, 0x1F); + WriteHSCX(hscx, IPAC_MODEB, 0x84); + WriteHSCX(hscx, IPAC_CCR1, 0x85); + WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */ + test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags); + test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags); + break; + case ISDN_P_B_RAW: + WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */ + WriteHSCX(hscx, IPAC_CCR1, 0x85); + hscx_cmdr(hscx, 0x41); + WriteHSCX(hscx, IPAC_MASKB, 0); + test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags); + break; + case ISDN_P_B_HDLC: + WriteHSCX(hscx, IPAC_MODEB, 0x8c); + WriteHSCX(hscx, IPAC_CCR1, 0x8d); + hscx_cmdr(hscx, 0x41); + WriteHSCX(hscx, IPAC_MASKB, 0); + test_and_set_bit(FLG_HDLC, &hscx->bch.Flags); + break; + default: + pr_info("%s: protocol not known %x\n", hscx->ip->name, + bprotocol); + return -ENOPROTOOPT; + } + } else + return -EINVAL; + hscx->bch.state = bprotocol; + return 0; +} + +static int +hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch); + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + unsigned long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(hx->ip->hwlock, flags); + ret = bchannel_senddata(bch, skb); + if (ret > 0) { /* direct TX */ + ret = 0; + hscx_fill_fifo(hx); + } + spin_unlock_irqrestore(hx->ip->hwlock, flags); + return ret; + case PH_ACTIVATE_REQ: + spin_lock_irqsave(hx->ip->hwlock, flags); + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) + ret = hscx_mode(hx, ch->protocol); + else + ret = 0; + spin_unlock_irqrestore(hx->ip->hwlock, flags); + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + break; + case PH_DEACTIVATE_REQ: + spin_lock_irqsave(hx->ip->hwlock, flags); + mISDN_clear_bchannel(bch); + hscx_mode(hx, ISDN_P_NONE); + spin_unlock_irqrestore(hx->ip->hwlock, flags); + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + ret = 0; + break; + default: + pr_info("%s: %s unknown prim(%x,%x)\n", + hx->ip->name, __func__, hh->prim, hh->id); + ret = -EINVAL; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static int +channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + return mISDN_ctrl_bchannel(bch, cq); +} + +static int +hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch); + int ret = -EINVAL; + u_long flags; + + pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg); + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + cancel_work_sync(&bch->workq); + spin_lock_irqsave(hx->ip->hwlock, flags); + mISDN_clear_bchannel(bch); + hscx_mode(hx, ISDN_P_NONE); + spin_unlock_irqrestore(hx->ip->hwlock, flags); + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(hx->ip->owner); + ret = 0; + break; + case CONTROL_CHANNEL: + ret = channel_bctrl(bch, arg); + break; + default: + pr_info("%s: %s unknown prim(%x)\n", + hx->ip->name, __func__, cmd); + } + return ret; +} + +static void +free_ipac(struct ipac_hw *ipac) +{ + isac_release(&ipac->isac); +} + +static const char *HSCXVer[] = +{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7", + "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"}; + + + +static void +hscx_init(struct hscx_hw *hx) +{ + u8 val; + + WriteHSCX(hx, IPAC_RAH2, 0xFF); + WriteHSCX(hx, IPAC_XBCH, 0x00); + WriteHSCX(hx, IPAC_RLCR, 0x00); + + if (hx->ip->type & IPAC_TYPE_HSCX) { + WriteHSCX(hx, IPAC_CCR1, 0x85); + val = ReadHSCX(hx, HSCX_VSTR); + pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val); + if (hx->bch.debug & DEBUG_HW) + pr_notice("%s: HSCX version %s\n", hx->ip->name, + HSCXVer[val & 0x0f]); + } else + WriteHSCX(hx, IPAC_CCR1, 0x82); + WriteHSCX(hx, IPAC_CCR2, 0x30); + WriteHSCX(hx, IPAC_XCCR, 0x07); + WriteHSCX(hx, IPAC_RCCR, 0x07); +} + +static int +ipac_init(struct ipac_hw *ipac) +{ + u8 val; + + if (ipac->type & IPAC_TYPE_HSCX) { + hscx_init(&ipac->hscx[0]); + hscx_init(&ipac->hscx[1]); + val = ReadIPAC(ipac, IPAC_ID); + } else if (ipac->type & IPAC_TYPE_IPAC) { + hscx_init(&ipac->hscx[0]); + hscx_init(&ipac->hscx[1]); + WriteIPAC(ipac, IPAC_MASK, IPAC__ON); + val = ReadIPAC(ipac, IPAC_CONF); + /* conf is default 0, but can be overwritten by card setup */ + pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name, + val, ipac->conf); + WriteIPAC(ipac, IPAC_CONF, ipac->conf); + val = ReadIPAC(ipac, IPAC_ID); + if (ipac->hscx[0].bch.debug & DEBUG_HW) + pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val); + } + /* nothing special for IPACX to do here */ + return isac_init(&ipac->isac); +} + +static int +open_bchannel(struct ipac_hw *ipac, struct channel_req *rq) +{ + struct bchannel *bch; + + if (rq->adr.channel == 0 || rq->adr.channel > 2) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + bch = &ipac->hscx[rq->adr.channel - 1].bch; + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); + bch->ch.protocol = rq->protocol; + rq->ch = &bch->ch; + return 0; +} + +static int +channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3; + break; + case MISDN_CTRL_LOOP: + /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */ + if (cq->channel < 0 || cq->channel > 3) { + ret = -EINVAL; + break; + } + ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel); + break; + case MISDN_CTRL_L1_TIMER3: + ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1); + break; + default: + pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +static int +ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct isac_hw *isac = container_of(dch, struct isac_hw, dch); + struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac); + struct channel_req *rq; + int err = 0; + + pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + if (rq->protocol == ISDN_P_TE_S0) + err = open_dchannel(isac, rq); + else + err = open_bchannel(ipac, rq); + if (err) + break; + if (!try_module_get(ipac->owner)) + pr_info("%s: cannot get module\n", ipac->name); + break; + case CLOSE_CHANNEL: + pr_debug("%s: dev(%d) close from %p\n", ipac->name, + dch->dev.id, __builtin_return_address(0)); + module_put(ipac->owner); + break; + case CONTROL_CHANNEL: + err = channel_ctrl(ipac, arg); + break; + default: + pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd); + return -EINVAL; + } + return err; +} + +u32 +mISDNipac_init(struct ipac_hw *ipac, void *hw) +{ + u32 ret; + u8 i; + + ipac->hw = hw; + if (ipac->isac.dch.debug & DEBUG_HW) + pr_notice("%s: ipac type %x\n", ipac->name, ipac->type); + if (ipac->type & IPAC_TYPE_HSCX) { + ipac->isac.type = IPAC_TYPE_ISAC; + ipac->hscx[0].off = 0; + ipac->hscx[1].off = 0x40; + ipac->hscx[0].fifo_size = 32; + ipac->hscx[1].fifo_size = 32; + } else if (ipac->type & IPAC_TYPE_IPAC) { + ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC; + ipac->hscx[0].off = 0; + ipac->hscx[1].off = 0x40; + ipac->hscx[0].fifo_size = 64; + ipac->hscx[1].fifo_size = 64; + } else if (ipac->type & IPAC_TYPE_IPACX) { + ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX; + ipac->hscx[0].off = IPACX_OFF_ICA; + ipac->hscx[1].off = IPACX_OFF_ICB; + ipac->hscx[0].fifo_size = 64; + ipac->hscx[1].fifo_size = 64; + } else + return 0; + + mISDNisac_init(&ipac->isac, hw); + + ipac->isac.dch.dev.D.ctrl = ipac_dctrl; + + for (i = 0; i < 2; i++) { + ipac->hscx[i].bch.nr = i + 1; + set_channelmap(i + 1, ipac->isac.dch.dev.channelmap); + list_add(&ipac->hscx[i].bch.ch.list, + &ipac->isac.dch.dev.bchannels); + mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM, + ipac->hscx[i].fifo_size); + ipac->hscx[i].bch.ch.nr = i + 1; + ipac->hscx[i].bch.ch.send = &hscx_l2l1; + ipac->hscx[i].bch.ch.ctrl = hscx_bctrl; + ipac->hscx[i].bch.hw = hw; + ipac->hscx[i].ip = ipac; + /* default values for IOM time slots + * can be overwriten by card */ + ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03; + } + + ipac->init = ipac_init; + ipac->release = free_ipac; + + ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + return ret; +} +EXPORT_SYMBOL(mISDNipac_init); + +static int __init +isac_mod_init(void) +{ + pr_notice("mISDNipac module version %s\n", ISAC_REV); + return 0; +} + +static void __exit +isac_mod_cleanup(void) +{ + pr_notice("mISDNipac module unloaded\n"); +} +module_init(isac_mod_init); +module_exit(isac_mod_cleanup); diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c new file mode 100644 index 00000000000..feafa91c2ed --- /dev/null +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -0,0 +1,1708 @@ +/* + * mISDNisar.c ISAR (Siemens PSB 7110) specific functions + * + * Author Karsten Keil (keil@isdn4linux.de) + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* define this to enable static debug messages, if you kernel supports + * dynamic debugging, you should use debugfs for this + */ +/* #define DEBUG */ + +#include <linux/gfp.h> +#include <linux/delay.h> +#include <linux/vmalloc.h> +#include <linux/mISDNhw.h> +#include <linux/module.h> +#include "isar.h" + +#define ISAR_REV "2.1" + +MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(ISAR_REV); + +#define DEBUG_HW_FIRMWARE_FIFO 0x10000 + +static const u8 faxmodulation_s[] = "3,24,48,72,73,74,96,97,98,121,122,145,146"; +static const u8 faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121, + 122, 145, 146}; +#define FAXMODCNT 13 + +static void isar_setup(struct isar_hw *); + +static inline int +waitforHIA(struct isar_hw *isar, int timeout) +{ + int t = timeout; + u8 val = isar->read_reg(isar->hw, ISAR_HIA); + + while ((val & 1) && t) { + udelay(1); + t--; + val = isar->read_reg(isar->hw, ISAR_HIA); + } + pr_debug("%s: HIA after %dus\n", isar->name, timeout - t); + return timeout; +} + +/* + * send msg to ISAR mailbox + * if msg is NULL use isar->buf + */ +static int +send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 *msg) +{ + if (!waitforHIA(isar, 1000)) + return 0; + pr_debug("send_mbox(%02x,%02x,%d)\n", his, creg, len); + isar->write_reg(isar->hw, ISAR_CTRL_H, creg); + isar->write_reg(isar->hw, ISAR_CTRL_L, len); + isar->write_reg(isar->hw, ISAR_WADR, 0); + if (!msg) + msg = isar->buf; + if (msg && len) { + isar->write_fifo(isar->hw, ISAR_MBOX, msg, len); + if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) { + int l = 0; + + while (l < (int)len) { + hex_dump_to_buffer(msg + l, len - l, 32, 1, + isar->log, 256, 1); + pr_debug("%s: %s %02x: %s\n", isar->name, + __func__, l, isar->log); + l += 32; + } + } + } + isar->write_reg(isar->hw, ISAR_HIS, his); + waitforHIA(isar, 1000); + return 1; +} + +/* + * receive message from ISAR mailbox + * if msg is NULL use isar->buf + */ +static void +rcv_mbox(struct isar_hw *isar, u8 *msg) +{ + if (!msg) + msg = isar->buf; + isar->write_reg(isar->hw, ISAR_RADR, 0); + if (msg && isar->clsb) { + isar->read_fifo(isar->hw, ISAR_MBOX, msg, isar->clsb); + if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) { + int l = 0; + + while (l < (int)isar->clsb) { + hex_dump_to_buffer(msg + l, isar->clsb - l, 32, + 1, isar->log, 256, 1); + pr_debug("%s: %s %02x: %s\n", isar->name, + __func__, l, isar->log); + l += 32; + } + } + } + isar->write_reg(isar->hw, ISAR_IIA, 0); +} + +static inline void +get_irq_infos(struct isar_hw *isar) +{ + isar->iis = isar->read_reg(isar->hw, ISAR_IIS); + isar->cmsb = isar->read_reg(isar->hw, ISAR_CTRL_H); + isar->clsb = isar->read_reg(isar->hw, ISAR_CTRL_L); + pr_debug("%s: rcv_mbox(%02x,%02x,%d)\n", isar->name, + isar->iis, isar->cmsb, isar->clsb); +} + +/* + * poll answer message from ISAR mailbox + * should be used only with ISAR IRQs disabled before DSP was started + * + */ +static int +poll_mbox(struct isar_hw *isar, int maxdelay) +{ + int t = maxdelay; + u8 irq; + + irq = isar->read_reg(isar->hw, ISAR_IRQBIT); + while (t && !(irq & ISAR_IRQSTA)) { + udelay(1); + t--; + } + if (t) { + get_irq_infos(isar); + rcv_mbox(isar, NULL); + } + pr_debug("%s: pulled %d bytes after %d us\n", + isar->name, isar->clsb, maxdelay - t); + return t; +} + +static int +ISARVersion(struct isar_hw *isar) +{ + int ver; + + /* disable ISAR IRQ */ + isar->write_reg(isar->hw, ISAR_IRQBIT, 0); + isar->buf[0] = ISAR_MSG_HWVER; + isar->buf[1] = 0; + isar->buf[2] = 1; + if (!send_mbox(isar, ISAR_HIS_VNR, 0, 3, NULL)) + return -1; + if (!poll_mbox(isar, 1000)) + return -2; + if (isar->iis == ISAR_IIS_VNR) { + if (isar->clsb == 1) { + ver = isar->buf[0] & 0xf; + return ver; + } + return -3; + } + return -4; +} + +static int +load_firmware(struct isar_hw *isar, const u8 *buf, int size) +{ + u32 saved_debug = isar->ch[0].bch.debug; + int ret, cnt; + u8 nom, noc; + u16 left, val, *sp = (u16 *)buf; + u8 *mp; + u_long flags; + + struct { + u16 sadr; + u16 len; + u16 d_key; + } blk_head; + + if (1 != isar->version) { + pr_err("%s: ISAR wrong version %d firmware download aborted\n", + isar->name, isar->version); + return -EINVAL; + } + if (!(saved_debug & DEBUG_HW_FIRMWARE_FIFO)) + isar->ch[0].bch.debug &= ~DEBUG_HW_BFIFO; + pr_debug("%s: load firmware %d words (%d bytes)\n", + isar->name, size / 2, size); + cnt = 0; + size /= 2; + /* disable ISAR IRQ */ + spin_lock_irqsave(isar->hwlock, flags); + isar->write_reg(isar->hw, ISAR_IRQBIT, 0); + spin_unlock_irqrestore(isar->hwlock, flags); + while (cnt < size) { + blk_head.sadr = le16_to_cpu(*sp++); + blk_head.len = le16_to_cpu(*sp++); + blk_head.d_key = le16_to_cpu(*sp++); + cnt += 3; + pr_debug("ISAR firmware block (%#x,%d,%#x)\n", + blk_head.sadr, blk_head.len, blk_head.d_key & 0xff); + left = blk_head.len; + if (cnt + left > size) { + pr_info("%s: firmware error have %d need %d words\n", + isar->name, size, cnt + left); + ret = -EINVAL; + goto reterrflg; + } + spin_lock_irqsave(isar->hwlock, flags); + if (!send_mbox(isar, ISAR_HIS_DKEY, blk_head.d_key & 0xff, + 0, NULL)) { + pr_info("ISAR send_mbox dkey failed\n"); + ret = -ETIME; + goto reterror; + } + if (!poll_mbox(isar, 1000)) { + pr_warning("ISAR poll_mbox dkey failed\n"); + ret = -ETIME; + goto reterror; + } + spin_unlock_irqrestore(isar->hwlock, flags); + if ((isar->iis != ISAR_IIS_DKEY) || isar->cmsb || isar->clsb) { + pr_info("ISAR wrong dkey response (%x,%x,%x)\n", + isar->iis, isar->cmsb, isar->clsb); + ret = 1; + goto reterrflg; + } + while (left > 0) { + if (left > 126) + noc = 126; + else + noc = left; + nom = (2 * noc) + 3; + mp = isar->buf; + /* the ISAR is big endian */ + *mp++ = blk_head.sadr >> 8; + *mp++ = blk_head.sadr & 0xFF; + left -= noc; + cnt += noc; + *mp++ = noc; + pr_debug("%s: load %3d words at %04x\n", isar->name, + noc, blk_head.sadr); + blk_head.sadr += noc; + while (noc) { + val = le16_to_cpu(*sp++); + *mp++ = val >> 8; + *mp++ = val & 0xFF; + noc--; + } + spin_lock_irqsave(isar->hwlock, flags); + if (!send_mbox(isar, ISAR_HIS_FIRM, 0, nom, NULL)) { + pr_info("ISAR send_mbox prog failed\n"); + ret = -ETIME; + goto reterror; + } + if (!poll_mbox(isar, 1000)) { + pr_info("ISAR poll_mbox prog failed\n"); + ret = -ETIME; + goto reterror; + } + spin_unlock_irqrestore(isar->hwlock, flags); + if ((isar->iis != ISAR_IIS_FIRM) || + isar->cmsb || isar->clsb) { + pr_info("ISAR wrong prog response (%x,%x,%x)\n", + isar->iis, isar->cmsb, isar->clsb); + ret = -EIO; + goto reterrflg; + } + } + pr_debug("%s: ISAR firmware block %d words loaded\n", + isar->name, blk_head.len); + } + isar->ch[0].bch.debug = saved_debug; + /* 10ms delay */ + cnt = 10; + while (cnt--) + mdelay(1); + isar->buf[0] = 0xff; + isar->buf[1] = 0xfe; + isar->bstat = 0; + spin_lock_irqsave(isar->hwlock, flags); + if (!send_mbox(isar, ISAR_HIS_STDSP, 0, 2, NULL)) { + pr_info("ISAR send_mbox start dsp failed\n"); + ret = -ETIME; + goto reterror; + } + if (!poll_mbox(isar, 1000)) { + pr_info("ISAR poll_mbox start dsp failed\n"); + ret = -ETIME; + goto reterror; + } + if ((isar->iis != ISAR_IIS_STDSP) || isar->cmsb || isar->clsb) { + pr_info("ISAR wrong start dsp response (%x,%x,%x)\n", + isar->iis, isar->cmsb, isar->clsb); + ret = -EIO; + goto reterror; + } else + pr_debug("%s: ISAR start dsp success\n", isar->name); + + /* NORMAL mode entered */ + /* Enable IRQs of ISAR */ + isar->write_reg(isar->hw, ISAR_IRQBIT, ISAR_IRQSTA); + spin_unlock_irqrestore(isar->hwlock, flags); + cnt = 1000; /* max 1s */ + while ((!isar->bstat) && cnt) { + mdelay(1); + cnt--; + } + if (!cnt) { + pr_info("ISAR no general status event received\n"); + ret = -ETIME; + goto reterrflg; + } else + pr_debug("%s: ISAR general status event %x\n", + isar->name, isar->bstat); + /* 10ms delay */ + cnt = 10; + while (cnt--) + mdelay(1); + isar->iis = 0; + spin_lock_irqsave(isar->hwlock, flags); + if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) { + pr_info("ISAR send_mbox self tst failed\n"); + ret = -ETIME; + goto reterror; + } + spin_unlock_irqrestore(isar->hwlock, flags); + cnt = 10000; /* max 100 ms */ + while ((isar->iis != ISAR_IIS_DIAG) && cnt) { + udelay(10); + cnt--; + } + mdelay(1); + if (!cnt) { + pr_info("ISAR no self tst response\n"); + ret = -ETIME; + goto reterrflg; + } + if ((isar->cmsb == ISAR_CTRL_STST) && (isar->clsb == 1) + && (isar->buf[0] == 0)) + pr_debug("%s: ISAR selftest OK\n", isar->name); + else { + pr_info("ISAR selftest not OK %x/%x/%x\n", + isar->cmsb, isar->clsb, isar->buf[0]); + ret = -EIO; + goto reterrflg; + } + spin_lock_irqsave(isar->hwlock, flags); + isar->iis = 0; + if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) { + pr_info("ISAR RQST SVN failed\n"); + ret = -ETIME; + goto reterror; + } + spin_unlock_irqrestore(isar->hwlock, flags); + cnt = 30000; /* max 300 ms */ + while ((isar->iis != ISAR_IIS_DIAG) && cnt) { + udelay(10); + cnt--; + } + mdelay(1); + if (!cnt) { + pr_info("ISAR no SVN response\n"); + ret = -ETIME; + goto reterrflg; + } else { + if ((isar->cmsb == ISAR_CTRL_SWVER) && (isar->clsb == 1)) { + pr_notice("%s: ISAR software version %#x\n", + isar->name, isar->buf[0]); + } else { + pr_info("%s: ISAR wrong swver response (%x,%x)" + " cnt(%d)\n", isar->name, isar->cmsb, + isar->clsb, cnt); + ret = -EIO; + goto reterrflg; + } + } + spin_lock_irqsave(isar->hwlock, flags); + isar_setup(isar); + spin_unlock_irqrestore(isar->hwlock, flags); + ret = 0; +reterrflg: + spin_lock_irqsave(isar->hwlock, flags); +reterror: + isar->ch[0].bch.debug = saved_debug; + if (ret) + /* disable ISAR IRQ */ + isar->write_reg(isar->hw, ISAR_IRQBIT, 0); + spin_unlock_irqrestore(isar->hwlock, flags); + return ret; +} + +static inline void +deliver_status(struct isar_ch *ch, int status) +{ + pr_debug("%s: HL->LL FAXIND %x\n", ch->is->name, status); + _queue_data(&ch->bch.ch, PH_CONTROL_IND, status, 0, NULL, GFP_ATOMIC); +} + +static inline void +isar_rcv_frame(struct isar_ch *ch) +{ + u8 *ptr; + int maxlen; + + if (!ch->is->clsb) { + pr_debug("%s; ISAR zero len frame\n", ch->is->name); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + return; + } + if (test_bit(FLG_RX_OFF, &ch->bch.Flags)) { + ch->bch.dropcnt += ch->is->clsb; + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + return; + } + switch (ch->bch.state) { + case ISDN_P_NONE: + pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n", + ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + case ISDN_P_B_RAW: + case ISDN_P_B_L2DTMF: + case ISDN_P_B_MODEM_ASYNC: + maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb); + if (maxlen < 0) { + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + ch->is->name, ch->bch.nr, ch->is->clsb); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } + rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb)); + recv_Bchannel(&ch->bch, 0, false); + break; + case ISDN_P_B_HDLC: + maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb); + if (maxlen < 0) { + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + ch->is->name, ch->bch.nr, ch->is->clsb); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } + if (ch->is->cmsb & HDLC_ERROR) { + pr_debug("%s: ISAR frame error %x len %d\n", + ch->is->name, ch->is->cmsb, ch->is->clsb); +#ifdef ERROR_STATISTIC + if (ch->is->cmsb & HDLC_ERR_RER) + ch->bch.err_inv++; + if (ch->is->cmsb & HDLC_ERR_CER) + ch->bch.err_crc++; +#endif + skb_trim(ch->bch.rx_skb, 0); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } + if (ch->is->cmsb & HDLC_FSD) + skb_trim(ch->bch.rx_skb, 0); + ptr = skb_put(ch->bch.rx_skb, ch->is->clsb); + rcv_mbox(ch->is, ptr); + if (ch->is->cmsb & HDLC_FED) { + if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */ + pr_debug("%s: ISAR frame to short %d\n", + ch->is->name, ch->bch.rx_skb->len); + skb_trim(ch->bch.rx_skb, 0); + break; + } + skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); + recv_Bchannel(&ch->bch, 0, false); + } + break; + case ISDN_P_B_T30_FAX: + if (ch->state != STFAX_ACTIV) { + pr_debug("%s: isar_rcv_frame: not ACTIV\n", + ch->is->name); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + if (ch->bch.rx_skb) + skb_trim(ch->bch.rx_skb, 0); + break; + } + if (!ch->bch.rx_skb) { + ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen, + GFP_ATOMIC); + if (unlikely(!ch->bch.rx_skb)) { + pr_info("%s: B receive out of memory\n", + __func__); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } + } + if (ch->cmd == PCTRL_CMD_FRM) { + rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb)); + pr_debug("%s: isar_rcv_frame: %d\n", + ch->is->name, ch->bch.rx_skb->len); + if (ch->is->cmsb & SART_NMD) { /* ABORT */ + pr_debug("%s: isar_rcv_frame: no more data\n", + ch->is->name); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + send_mbox(ch->is, SET_DPS(ch->dpath) | + ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, + 0, NULL); + ch->state = STFAX_ESCAPE; + /* set_skb_flag(skb, DF_NOMOREDATA); */ + } + recv_Bchannel(&ch->bch, 0, false); + if (ch->is->cmsb & SART_NMD) + deliver_status(ch, HW_MOD_NOCARR); + break; + } + if (ch->cmd != PCTRL_CMD_FRH) { + pr_debug("%s: isar_rcv_frame: unknown fax mode %x\n", + ch->is->name, ch->cmd); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + if (ch->bch.rx_skb) + skb_trim(ch->bch.rx_skb, 0); + break; + } + /* PCTRL_CMD_FRH */ + if ((ch->bch.rx_skb->len + ch->is->clsb) > + (ch->bch.maxlen + 2)) { + pr_info("%s: %s incoming packet too large\n", + ch->is->name, __func__); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + skb_trim(ch->bch.rx_skb, 0); + break; + } else if (ch->is->cmsb & HDLC_ERROR) { + pr_info("%s: ISAR frame error %x len %d\n", + ch->is->name, ch->is->cmsb, ch->is->clsb); + skb_trim(ch->bch.rx_skb, 0); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } + if (ch->is->cmsb & HDLC_FSD) + skb_trim(ch->bch.rx_skb, 0); + ptr = skb_put(ch->bch.rx_skb, ch->is->clsb); + rcv_mbox(ch->is, ptr); + if (ch->is->cmsb & HDLC_FED) { + if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */ + pr_info("%s: ISAR frame to short %d\n", + ch->is->name, ch->bch.rx_skb->len); + skb_trim(ch->bch.rx_skb, 0); + break; + } + skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); + recv_Bchannel(&ch->bch, 0, false); + } + if (ch->is->cmsb & SART_NMD) { /* ABORT */ + pr_debug("%s: isar_rcv_frame: no more data\n", + ch->is->name); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + if (ch->bch.rx_skb) + skb_trim(ch->bch.rx_skb, 0); + send_mbox(ch->is, SET_DPS(ch->dpath) | + ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL); + ch->state = STFAX_ESCAPE; + deliver_status(ch, HW_MOD_NOCARR); + } + break; + default: + pr_info("isar_rcv_frame protocol (%x)error\n", ch->bch.state); + ch->is->write_reg(ch->is->hw, ISAR_IIA, 0); + break; + } +} + +static void +isar_fill_fifo(struct isar_ch *ch) +{ + int count; + u8 msb; + u8 *ptr; + + pr_debug("%s: ch%d tx_skb %d tx_idx %d\n", ch->is->name, ch->bch.nr, + ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, ch->bch.tx_idx); + if (!(ch->is->bstat & + (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2))) + return; + if (!ch->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &ch->bch.Flags) || + (ch->bch.state != ISDN_P_B_RAW)) + return; + count = ch->mml; + /* use the card buffer */ + memset(ch->is->buf, ch->bch.fill[0], count); + send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA, + 0, count, ch->is->buf); + return; + } + count = ch->bch.tx_skb->len - ch->bch.tx_idx; + if (count <= 0) + return; + if (count > ch->mml) { + msb = 0; + count = ch->mml; + } else { + msb = HDLC_FED; + } + ptr = ch->bch.tx_skb->data + ch->bch.tx_idx; + if (!ch->bch.tx_idx) { + pr_debug("%s: frame start\n", ch->is->name); + if ((ch->bch.state == ISDN_P_B_T30_FAX) && + (ch->cmd == PCTRL_CMD_FTH)) { + if (count > 1) { + if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) { + /* last frame */ + test_and_set_bit(FLG_LASTDATA, + &ch->bch.Flags); + pr_debug("%s: set LASTDATA\n", + ch->is->name); + if (msb == HDLC_FED) + test_and_set_bit(FLG_DLEETX, + &ch->bch.Flags); + } + } + } + msb |= HDLC_FST; + } + ch->bch.tx_idx += count; + switch (ch->bch.state) { + case ISDN_P_NONE: + pr_info("%s: wrong protocol 0\n", __func__); + break; + case ISDN_P_B_RAW: + case ISDN_P_B_L2DTMF: + case ISDN_P_B_MODEM_ASYNC: + send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA, + 0, count, ptr); + break; + case ISDN_P_B_HDLC: + send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA, + msb, count, ptr); + break; + case ISDN_P_B_T30_FAX: + if (ch->state != STFAX_ACTIV) + pr_debug("%s: not ACTIV\n", ch->is->name); + else if (ch->cmd == PCTRL_CMD_FTH) + send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA, + msb, count, ptr); + else if (ch->cmd == PCTRL_CMD_FTM) + send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA, + 0, count, ptr); + else + pr_debug("%s: not FTH/FTM\n", ch->is->name); + break; + default: + pr_info("%s: protocol(%x) error\n", + __func__, ch->bch.state); + break; + } +} + +static inline struct isar_ch * +sel_bch_isar(struct isar_hw *isar, u8 dpath) +{ + struct isar_ch *base = &isar->ch[0]; + + if ((!dpath) || (dpath > 2)) + return NULL; + if (base->dpath == dpath) + return base; + base++; + if (base->dpath == dpath) + return base; + return NULL; +} + +static void +send_next(struct isar_ch *ch) +{ + pr_debug("%s: %s ch%d tx_skb %d tx_idx %d\n", ch->is->name, __func__, + ch->bch.nr, ch->bch.tx_skb ? ch->bch.tx_skb->len : -1, + ch->bch.tx_idx); + if (ch->bch.state == ISDN_P_B_T30_FAX) { + if (ch->cmd == PCTRL_CMD_FTH) { + if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) { + pr_debug("set NMD_DATA\n"); + test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags); + } + } else if (ch->cmd == PCTRL_CMD_FTM) { + if (test_bit(FLG_DLEETX, &ch->bch.Flags)) { + test_and_set_bit(FLG_LASTDATA, &ch->bch.Flags); + test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags); + } + } + } + if (ch->bch.tx_skb) + dev_kfree_skb(ch->bch.tx_skb); + if (get_next_bframe(&ch->bch)) { + isar_fill_fifo(ch); + test_and_clear_bit(FLG_TX_EMPTY, &ch->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &ch->bch.Flags)) { + isar_fill_fifo(ch); + } else { + if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) { + if (test_and_clear_bit(FLG_LASTDATA, + &ch->bch.Flags)) { + if (test_and_clear_bit(FLG_NMD_DATA, + &ch->bch.Flags)) { + u8 zd = 0; + send_mbox(ch->is, SET_DPS(ch->dpath) | + ISAR_HIS_SDATA, 0x01, 1, &zd); + } + test_and_set_bit(FLG_LL_OK, &ch->bch.Flags); + } else { + deliver_status(ch, HW_MOD_CONNECT); + } + } else if (test_bit(FLG_FILLEMPTY, &ch->bch.Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &ch->bch.Flags); + } + } +} + +static void +check_send(struct isar_hw *isar, u8 rdm) +{ + struct isar_ch *ch; + + pr_debug("%s: rdm %x\n", isar->name, rdm); + if (rdm & BSTAT_RDM1) { + ch = sel_bch_isar(isar, 1); + if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) { + if (ch->bch.tx_skb && (ch->bch.tx_skb->len > + ch->bch.tx_idx)) + isar_fill_fifo(ch); + else + send_next(ch); + } + } + if (rdm & BSTAT_RDM2) { + ch = sel_bch_isar(isar, 2); + if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) { + if (ch->bch.tx_skb && (ch->bch.tx_skb->len > + ch->bch.tx_idx)) + isar_fill_fifo(ch); + else + send_next(ch); + } + } +} + +const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4", + "300", "600", "1200", "2400", "4800", "7200", + "9600nt", "9600t", "12000", "14400", "WRONG"}; +const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21", + "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"}; + +static void +isar_pump_status_rsp(struct isar_ch *ch) { + u8 ril = ch->is->buf[0]; + u8 rim; + + if (!test_and_clear_bit(ISAR_RATE_REQ, &ch->is->Flags)) + return; + if (ril > 14) { + pr_info("%s: wrong pstrsp ril=%d\n", ch->is->name, ril); + ril = 15; + } + switch (ch->is->buf[1]) { + case 0: + rim = 0; + break; + case 0x20: + rim = 2; + break; + case 0x40: + rim = 3; + break; + case 0x41: + rim = 4; + break; + case 0x51: + rim = 5; + break; + case 0x61: + rim = 6; + break; + case 0x71: + rim = 7; + break; + case 0x82: + rim = 8; + break; + case 0x92: + rim = 9; + break; + case 0xa2: + rim = 10; + break; + default: + rim = 1; + break; + } + sprintf(ch->conmsg, "%s %s", dmril[ril], dmrim[rim]); + pr_debug("%s: pump strsp %s\n", ch->is->name, ch->conmsg); +} + +static void +isar_pump_statev_modem(struct isar_ch *ch, u8 devt) { + u8 dps = SET_DPS(ch->dpath); + + switch (devt) { + case PSEV_10MS_TIMER: + pr_debug("%s: pump stev TIMER\n", ch->is->name); + break; + case PSEV_CON_ON: + pr_debug("%s: pump stev CONNECT\n", ch->is->name); + deliver_status(ch, HW_MOD_CONNECT); + break; + case PSEV_CON_OFF: + pr_debug("%s: pump stev NO CONNECT\n", ch->is->name); + send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); + deliver_status(ch, HW_MOD_NOCARR); + break; + case PSEV_V24_OFF: + pr_debug("%s: pump stev V24 OFF\n", ch->is->name); + break; + case PSEV_CTS_ON: + pr_debug("%s: pump stev CTS ON\n", ch->is->name); + break; + case PSEV_CTS_OFF: + pr_debug("%s pump stev CTS OFF\n", ch->is->name); + break; + case PSEV_DCD_ON: + pr_debug("%s: pump stev CARRIER ON\n", ch->is->name); + test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags); + send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); + break; + case PSEV_DCD_OFF: + pr_debug("%s: pump stev CARRIER OFF\n", ch->is->name); + break; + case PSEV_DSR_ON: + pr_debug("%s: pump stev DSR ON\n", ch->is->name); + break; + case PSEV_DSR_OFF: + pr_debug("%s: pump stev DSR_OFF\n", ch->is->name); + break; + case PSEV_REM_RET: + pr_debug("%s: pump stev REMOTE RETRAIN\n", ch->is->name); + break; + case PSEV_REM_REN: + pr_debug("%s: pump stev REMOTE RENEGOTIATE\n", ch->is->name); + break; + case PSEV_GSTN_CLR: + pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name); + break; + default: + pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt); + break; + } +} + +static void +isar_pump_statev_fax(struct isar_ch *ch, u8 devt) { + u8 dps = SET_DPS(ch->dpath); + u8 p1; + + switch (devt) { + case PSEV_10MS_TIMER: + pr_debug("%s: pump stev TIMER\n", ch->is->name); + break; + case PSEV_RSP_READY: + pr_debug("%s: pump stev RSP_READY\n", ch->is->name); + ch->state = STFAX_READY; + deliver_status(ch, HW_MOD_READY); +#ifdef AUTOCON + if (test_bit(BC_FLG_ORIG, &ch->bch.Flags)) + isar_pump_cmd(bch, HW_MOD_FRH, 3); + else + isar_pump_cmd(bch, HW_MOD_FTH, 3); +#endif + break; + case PSEV_LINE_TX_H: + if (ch->state == STFAX_LINE) { + pr_debug("%s: pump stev LINE_TX_H\n", ch->is->name); + ch->state = STFAX_CONT; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + PCTRL_CMD_CONT, 0, NULL); + } else { + pr_debug("%s: pump stev LINE_TX_H wrong st %x\n", + ch->is->name, ch->state); + } + break; + case PSEV_LINE_RX_H: + if (ch->state == STFAX_LINE) { + pr_debug("%s: pump stev LINE_RX_H\n", ch->is->name); + ch->state = STFAX_CONT; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + PCTRL_CMD_CONT, 0, NULL); + } else { + pr_debug("%s: pump stev LINE_RX_H wrong st %x\n", + ch->is->name, ch->state); + } + break; + case PSEV_LINE_TX_B: + if (ch->state == STFAX_LINE) { + pr_debug("%s: pump stev LINE_TX_B\n", ch->is->name); + ch->state = STFAX_CONT; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + PCTRL_CMD_CONT, 0, NULL); + } else { + pr_debug("%s: pump stev LINE_TX_B wrong st %x\n", + ch->is->name, ch->state); + } + break; + case PSEV_LINE_RX_B: + if (ch->state == STFAX_LINE) { + pr_debug("%s: pump stev LINE_RX_B\n", ch->is->name); + ch->state = STFAX_CONT; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + PCTRL_CMD_CONT, 0, NULL); + } else { + pr_debug("%s: pump stev LINE_RX_B wrong st %x\n", + ch->is->name, ch->state); + } + break; + case PSEV_RSP_CONN: + if (ch->state == STFAX_CONT) { + pr_debug("%s: pump stev RSP_CONN\n", ch->is->name); + ch->state = STFAX_ACTIV; + test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags); + send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); + if (ch->cmd == PCTRL_CMD_FTH) { + int delay = (ch->mod == 3) ? 1000 : 200; + /* 1s (200 ms) Flags before data */ + if (test_and_set_bit(FLG_FTI_RUN, + &ch->bch.Flags)) + del_timer(&ch->ftimer); + ch->ftimer.expires = + jiffies + ((delay * HZ) / 1000); + test_and_set_bit(FLG_LL_CONN, + &ch->bch.Flags); + add_timer(&ch->ftimer); + } else { + deliver_status(ch, HW_MOD_CONNECT); + } + } else { + pr_debug("%s: pump stev RSP_CONN wrong st %x\n", + ch->is->name, ch->state); + } + break; + case PSEV_FLAGS_DET: + pr_debug("%s: pump stev FLAGS_DET\n", ch->is->name); + break; + case PSEV_RSP_DISC: + pr_debug("%s: pump stev RSP_DISC state(%d)\n", + ch->is->name, ch->state); + if (ch->state == STFAX_ESCAPE) { + p1 = 5; + switch (ch->newcmd) { + case 0: + ch->state = STFAX_READY; + break; + case PCTRL_CMD_FTM: + p1 = 2; + case PCTRL_CMD_FTH: + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + PCTRL_CMD_SILON, 1, &p1); + ch->state = STFAX_SILDET; + break; + case PCTRL_CMD_FRH: + case PCTRL_CMD_FRM: + ch->mod = ch->newmod; + p1 = ch->newmod; + ch->newmod = 0; + ch->cmd = ch->newcmd; + ch->newcmd = 0; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + ch->cmd, 1, &p1); + ch->state = STFAX_LINE; + ch->try_mod = 3; + break; + default: + pr_debug("%s: RSP_DISC unknown newcmd %x\n", + ch->is->name, ch->newcmd); + break; + } + } else if (ch->state == STFAX_ACTIV) { + if (test_and_clear_bit(FLG_LL_OK, &ch->bch.Flags)) + deliver_status(ch, HW_MOD_OK); + else if (ch->cmd == PCTRL_CMD_FRM) + deliver_status(ch, HW_MOD_NOCARR); + else + deliver_status(ch, HW_MOD_FCERROR); + ch->state = STFAX_READY; + } else if (ch->state != STFAX_SILDET) { + /* ignore in STFAX_SILDET */ + ch->state = STFAX_READY; + deliver_status(ch, HW_MOD_FCERROR); + } + break; + case PSEV_RSP_SILDET: + pr_debug("%s: pump stev RSP_SILDET\n", ch->is->name); + if (ch->state == STFAX_SILDET) { + ch->mod = ch->newmod; + p1 = ch->newmod; + ch->newmod = 0; + ch->cmd = ch->newcmd; + ch->newcmd = 0; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + ch->cmd, 1, &p1); + ch->state = STFAX_LINE; + ch->try_mod = 3; + } + break; + case PSEV_RSP_SILOFF: + pr_debug("%s: pump stev RSP_SILOFF\n", ch->is->name); + break; + case PSEV_RSP_FCERR: + if (ch->state == STFAX_LINE) { + pr_debug("%s: pump stev RSP_FCERR try %d\n", + ch->is->name, ch->try_mod); + if (ch->try_mod--) { + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, + ch->cmd, 1, &ch->mod); + break; + } + } + pr_debug("%s: pump stev RSP_FCERR\n", ch->is->name); + ch->state = STFAX_ESCAPE; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, + 0, NULL); + deliver_status(ch, HW_MOD_FCERROR); + break; + default: + break; + } +} + +void +mISDNisar_irq(struct isar_hw *isar) +{ + struct isar_ch *ch; + + get_irq_infos(isar); + switch (isar->iis & ISAR_IIS_MSCMSD) { + case ISAR_IIS_RDATA: + ch = sel_bch_isar(isar, isar->iis >> 6); + if (ch) + isar_rcv_frame(ch); + else { + pr_debug("%s: ISAR spurious IIS_RDATA %x/%x/%x\n", + isar->name, isar->iis, isar->cmsb, + isar->clsb); + isar->write_reg(isar->hw, ISAR_IIA, 0); + } + break; + case ISAR_IIS_GSTEV: + isar->write_reg(isar->hw, ISAR_IIA, 0); + isar->bstat |= isar->cmsb; + check_send(isar, isar->cmsb); + break; + case ISAR_IIS_BSTEV: +#ifdef ERROR_STATISTIC + ch = sel_bch_isar(isar, isar->iis >> 6); + if (ch) { + if (isar->cmsb == BSTEV_TBO) + ch->bch.err_tx++; + if (isar->cmsb == BSTEV_RBO) + ch->bch.err_rdo++; + } +#endif + pr_debug("%s: Buffer STEV dpath%d msb(%x)\n", + isar->name, isar->iis >> 6, isar->cmsb); + isar->write_reg(isar->hw, ISAR_IIA, 0); + break; + case ISAR_IIS_PSTEV: + ch = sel_bch_isar(isar, isar->iis >> 6); + if (ch) { + rcv_mbox(isar, NULL); + if (ch->bch.state == ISDN_P_B_MODEM_ASYNC) + isar_pump_statev_modem(ch, isar->cmsb); + else if (ch->bch.state == ISDN_P_B_T30_FAX) + isar_pump_statev_fax(ch, isar->cmsb); + else if (ch->bch.state == ISDN_P_B_RAW) { + int tt; + tt = isar->cmsb | 0x30; + if (tt == 0x3e) + tt = '*'; + else if (tt == 0x3f) + tt = '#'; + else if (tt > '9') + tt += 7; + tt |= DTMF_TONE_VAL; + _queue_data(&ch->bch.ch, PH_CONTROL_IND, + MISDN_ID_ANY, sizeof(tt), &tt, + GFP_ATOMIC); + } else + pr_debug("%s: ISAR IIS_PSTEV pm %d sta %x\n", + isar->name, ch->bch.state, + isar->cmsb); + } else { + pr_debug("%s: ISAR spurious IIS_PSTEV %x/%x/%x\n", + isar->name, isar->iis, isar->cmsb, + isar->clsb); + isar->write_reg(isar->hw, ISAR_IIA, 0); + } + break; + case ISAR_IIS_PSTRSP: + ch = sel_bch_isar(isar, isar->iis >> 6); + if (ch) { + rcv_mbox(isar, NULL); + isar_pump_status_rsp(ch); + } else { + pr_debug("%s: ISAR spurious IIS_PSTRSP %x/%x/%x\n", + isar->name, isar->iis, isar->cmsb, + isar->clsb); + isar->write_reg(isar->hw, ISAR_IIA, 0); + } + break; + case ISAR_IIS_DIAG: + case ISAR_IIS_BSTRSP: + case ISAR_IIS_IOM2RSP: + rcv_mbox(isar, NULL); + break; + case ISAR_IIS_INVMSG: + rcv_mbox(isar, NULL); + pr_debug("%s: invalid msg his:%x\n", isar->name, isar->cmsb); + break; + default: + rcv_mbox(isar, NULL); + pr_debug("%s: unhandled msg iis(%x) ctrl(%x/%x)\n", + isar->name, isar->iis, isar->cmsb, isar->clsb); + break; + } +} +EXPORT_SYMBOL(mISDNisar_irq); + +static void +ftimer_handler(unsigned long data) +{ + struct isar_ch *ch = (struct isar_ch *)data; + + pr_debug("%s: ftimer flags %lx\n", ch->is->name, ch->bch.Flags); + test_and_clear_bit(FLG_FTI_RUN, &ch->bch.Flags); + if (test_and_clear_bit(FLG_LL_CONN, &ch->bch.Flags)) + deliver_status(ch, HW_MOD_CONNECT); +} + +static void +setup_pump(struct isar_ch *ch) { + u8 dps = SET_DPS(ch->dpath); + u8 ctrl, param[6]; + + switch (ch->bch.state) { + case ISDN_P_NONE: + case ISDN_P_B_RAW: + case ISDN_P_B_HDLC: + send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL); + break; + case ISDN_P_B_L2DTMF: + if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) { + param[0] = 5; /* TOA 5 db */ + send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, + PMOD_DTMF_TRANS, 1, param); + } else { + param[0] = 40; /* REL -46 dbm */ + send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, + PMOD_DTMF, 1, param); + } + case ISDN_P_B_MODEM_ASYNC: + ctrl = PMOD_DATAMODEM; + if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) { + ctrl |= PCTRL_ORIG; + param[5] = PV32P6_CTN; + } else { + param[5] = PV32P6_ATN; + } + param[0] = 6; /* 6 db */ + param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B | + PV32P2_V22C | PV32P2_V21 | PV32P2_BEL; + param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B; + param[3] = PV32P4_UT144; + param[4] = PV32P5_UT144; + send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param); + break; + case ISDN_P_B_T30_FAX: + ctrl = PMOD_FAX; + if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) { + ctrl |= PCTRL_ORIG; + param[1] = PFAXP2_CTN; + } else { + param[1] = PFAXP2_ATN; + } + param[0] = 6; /* 6 db */ + send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param); + ch->state = STFAX_NULL; + ch->newcmd = 0; + ch->newmod = 0; + test_and_set_bit(FLG_FTI_RUN, &ch->bch.Flags); + break; + } + udelay(1000); + send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); + udelay(1000); +} + +static void +setup_sart(struct isar_ch *ch) { + u8 dps = SET_DPS(ch->dpath); + u8 ctrl, param[2] = {0, 0}; + + switch (ch->bch.state) { + case ISDN_P_NONE: + send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, + 0, NULL); + break; + case ISDN_P_B_RAW: + case ISDN_P_B_L2DTMF: + send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, + 2, param); + break; + case ISDN_P_B_HDLC: + case ISDN_P_B_T30_FAX: + send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, + 1, param); + break; + case ISDN_P_B_MODEM_ASYNC: + ctrl = SMODE_V14 | SCTRL_HDMC_BOTH; + param[0] = S_P1_CHS_8; + param[1] = S_P2_BFT_DEF; + send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, ctrl, 2, param); + break; + } + udelay(1000); + send_mbox(ch->is, dps | ISAR_HIS_BSTREQ, 0, 0, NULL); + udelay(1000); +} + +static void +setup_iom2(struct isar_ch *ch) { + u8 dps = SET_DPS(ch->dpath); + u8 cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0}; + + if (ch->bch.nr == 2) { + msg[1] = 1; + msg[3] = 1; + } + switch (ch->bch.state) { + case ISDN_P_NONE: + cmsb = 0; + /* dummy slot */ + msg[1] = ch->dpath + 2; + msg[3] = ch->dpath + 2; + break; + case ISDN_P_B_RAW: + case ISDN_P_B_HDLC: + break; + case ISDN_P_B_MODEM_ASYNC: + case ISDN_P_B_T30_FAX: + cmsb |= IOM_CTRL_RCV; + case ISDN_P_B_L2DTMF: + if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) + cmsb |= IOM_CTRL_RCV; + cmsb |= IOM_CTRL_ALAW; + break; + } + send_mbox(ch->is, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg); + udelay(1000); + send_mbox(ch->is, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL); + udelay(1000); +} + +static int +modeisar(struct isar_ch *ch, u32 bprotocol) +{ + /* Here we are selecting the best datapath for requested protocol */ + if (ch->bch.state == ISDN_P_NONE) { /* New Setup */ + switch (bprotocol) { + case ISDN_P_NONE: /* init */ + if (!ch->dpath) + /* no init for dpath 0 */ + return 0; + test_and_clear_bit(FLG_HDLC, &ch->bch.Flags); + test_and_clear_bit(FLG_TRANSPARENT, &ch->bch.Flags); + break; + case ISDN_P_B_RAW: + case ISDN_P_B_HDLC: + /* best is datapath 2 */ + if (!test_and_set_bit(ISAR_DP2_USE, &ch->is->Flags)) + ch->dpath = 2; + else if (!test_and_set_bit(ISAR_DP1_USE, + &ch->is->Flags)) + ch->dpath = 1; + else { + pr_info("modeisar both paths in use\n"); + return -EBUSY; + } + if (bprotocol == ISDN_P_B_HDLC) + test_and_set_bit(FLG_HDLC, &ch->bch.Flags); + else + test_and_set_bit(FLG_TRANSPARENT, + &ch->bch.Flags); + break; + case ISDN_P_B_MODEM_ASYNC: + case ISDN_P_B_T30_FAX: + case ISDN_P_B_L2DTMF: + /* only datapath 1 */ + if (!test_and_set_bit(ISAR_DP1_USE, &ch->is->Flags)) + ch->dpath = 1; + else { + pr_info("%s: ISAR modeisar analog functions" + "only with DP1\n", ch->is->name); + return -EBUSY; + } + break; + default: + pr_info("%s: protocol not known %x\n", ch->is->name, + bprotocol); + return -ENOPROTOOPT; + } + } + pr_debug("%s: ISAR ch%d dp%d protocol %x->%x\n", ch->is->name, + ch->bch.nr, ch->dpath, ch->bch.state, bprotocol); + ch->bch.state = bprotocol; + setup_pump(ch); + setup_iom2(ch); + setup_sart(ch); + if (ch->bch.state == ISDN_P_NONE) { + /* Clear resources */ + if (ch->dpath == 1) + test_and_clear_bit(ISAR_DP1_USE, &ch->is->Flags); + else if (ch->dpath == 2) + test_and_clear_bit(ISAR_DP2_USE, &ch->is->Flags); + ch->dpath = 0; + ch->is->ctrl(ch->is->hw, HW_DEACT_IND, ch->bch.nr); + } else + ch->is->ctrl(ch->is->hw, HW_ACTIVATE_IND, ch->bch.nr); + return 0; +} + +static void +isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para) +{ + u8 dps = SET_DPS(ch->dpath); + u8 ctrl = 0, nom = 0, p1 = 0; + + pr_debug("%s: isar_pump_cmd %x/%x state(%x)\n", + ch->is->name, cmd, para, ch->bch.state); + switch (cmd) { + case HW_MOD_FTM: + if (ch->state == STFAX_READY) { + p1 = para; + ctrl = PCTRL_CMD_FTM; + nom = 1; + ch->state = STFAX_LINE; + ch->cmd = ctrl; + ch->mod = para; + ch->newmod = 0; + ch->newcmd = 0; + ch->try_mod = 3; + } else if ((ch->state == STFAX_ACTIV) && + (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para)) + deliver_status(ch, HW_MOD_CONNECT); + else { + ch->newmod = para; + ch->newcmd = PCTRL_CMD_FTM; + nom = 0; + ctrl = PCTRL_CMD_ESC; + ch->state = STFAX_ESCAPE; + } + break; + case HW_MOD_FTH: + if (ch->state == STFAX_READY) { + p1 = para; + ctrl = PCTRL_CMD_FTH; + nom = 1; + ch->state = STFAX_LINE; + ch->cmd = ctrl; + ch->mod = para; + ch->newmod = 0; + ch->newcmd = 0; + ch->try_mod = 3; + } else if ((ch->state == STFAX_ACTIV) && + (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para)) + deliver_status(ch, HW_MOD_CONNECT); + else { + ch->newmod = para; + ch->newcmd = PCTRL_CMD_FTH; + nom = 0; + ctrl = PCTRL_CMD_ESC; + ch->state = STFAX_ESCAPE; + } + break; + case HW_MOD_FRM: + if (ch->state == STFAX_READY) { + p1 = para; + ctrl = PCTRL_CMD_FRM; + nom = 1; + ch->state = STFAX_LINE; + ch->cmd = ctrl; + ch->mod = para; + ch->newmod = 0; + ch->newcmd = 0; + ch->try_mod = 3; + } else if ((ch->state == STFAX_ACTIV) && + (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para)) + deliver_status(ch, HW_MOD_CONNECT); + else { + ch->newmod = para; + ch->newcmd = PCTRL_CMD_FRM; + nom = 0; + ctrl = PCTRL_CMD_ESC; + ch->state = STFAX_ESCAPE; + } + break; + case HW_MOD_FRH: + if (ch->state == STFAX_READY) { + p1 = para; + ctrl = PCTRL_CMD_FRH; + nom = 1; + ch->state = STFAX_LINE; + ch->cmd = ctrl; + ch->mod = para; + ch->newmod = 0; + ch->newcmd = 0; + ch->try_mod = 3; + } else if ((ch->state == STFAX_ACTIV) && + (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para)) + deliver_status(ch, HW_MOD_CONNECT); + else { + ch->newmod = para; + ch->newcmd = PCTRL_CMD_FRH; + nom = 0; + ctrl = PCTRL_CMD_ESC; + ch->state = STFAX_ESCAPE; + } + break; + case PCTRL_CMD_TDTMF: + p1 = para; + nom = 1; + ctrl = PCTRL_CMD_TDTMF; + break; + } + if (ctrl) + send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1); +} + +static void +isar_setup(struct isar_hw *isar) +{ + u8 msg; + int i; + + /* Dpath 1, 2 */ + msg = 61; + for (i = 0; i < 2; i++) { + /* Buffer Config */ + send_mbox(isar, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) | + ISAR_HIS_P12CFG, 4, 1, &msg); + isar->ch[i].mml = msg; + isar->ch[i].bch.state = 0; + isar->ch[i].dpath = i + 1; + modeisar(&isar->ch[i], ISDN_P_NONE); + } +} + +static int +isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct isar_ch *ich = container_of(bch, struct isar_ch, bch); + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + u32 id, *val; + u_long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(ich->is->hwlock, flags); + ret = bchannel_senddata(bch, skb); + if (ret > 0) { /* direct TX */ + ret = 0; + isar_fill_fifo(ich); + } + spin_unlock_irqrestore(ich->is->hwlock, flags); + return ret; + case PH_ACTIVATE_REQ: + spin_lock_irqsave(ich->is->hwlock, flags); + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) + ret = modeisar(ich, ch->protocol); + else + ret = 0; + spin_unlock_irqrestore(ich->is->hwlock, flags); + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + break; + case PH_DEACTIVATE_REQ: + spin_lock_irqsave(ich->is->hwlock, flags); + mISDN_clear_bchannel(bch); + modeisar(ich, ISDN_P_NONE); + spin_unlock_irqrestore(ich->is->hwlock, flags); + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + ret = 0; + break; + case PH_CONTROL_REQ: + val = (u32 *)skb->data; + pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name, + hh->id, *val); + if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) == + DTMF_TONE_VAL)) { + if (bch->state == ISDN_P_B_L2DTMF) { + char tt = *val & DTMF_TONE_MASK; + + if (tt == '*') + tt = 0x1e; + else if (tt == '#') + tt = 0x1f; + else if (tt > '9') + tt -= 7; + tt &= 0x1f; + spin_lock_irqsave(ich->is->hwlock, flags); + isar_pump_cmd(ich, PCTRL_CMD_TDTMF, tt); + spin_unlock_irqrestore(ich->is->hwlock, flags); + } else { + pr_info("%s: DTMF send wrong protocol %x\n", + __func__, bch->state); + return -EINVAL; + } + } else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) || + (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) { + for (id = 0; id < FAXMODCNT; id++) + if (faxmodulation[id] == *val) + break; + if ((FAXMODCNT > id) && + test_bit(FLG_INITIALIZED, &bch->Flags)) { + pr_debug("%s: isar: new mod\n", ich->is->name); + isar_pump_cmd(ich, hh->id, *val); + ret = 0; + } else { + pr_info("%s: wrong modulation\n", + ich->is->name); + ret = -EINVAL; + } + } else if (hh->id == HW_MOD_LASTDATA) + test_and_set_bit(FLG_DLEETX, &bch->Flags); + else { + pr_info("%s: unknown PH_CONTROL_REQ %x\n", + ich->is->name, hh->id); + ret = -EINVAL; + } + default: + pr_info("%s: %s unknown prim(%x,%x)\n", + ich->is->name, __func__, hh->prim, hh->id); + ret = -EINVAL; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static int +channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + return mISDN_ctrl_bchannel(bch, cq); +} + +static int +isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct isar_ch *ich = container_of(bch, struct isar_ch, bch); + int ret = -EINVAL; + u_long flags; + + pr_debug("%s: %s cmd:%x %p\n", ich->is->name, __func__, cmd, arg); + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + cancel_work_sync(&bch->workq); + spin_lock_irqsave(ich->is->hwlock, flags); + mISDN_clear_bchannel(bch); + modeisar(ich, ISDN_P_NONE); + spin_unlock_irqrestore(ich->is->hwlock, flags); + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(ich->is->owner); + ret = 0; + break; + case CONTROL_CHANNEL: + ret = channel_bctrl(bch, arg); + break; + default: + pr_info("%s: %s unknown prim(%x)\n", + ich->is->name, __func__, cmd); + } + return ret; +} + +static void +free_isar(struct isar_hw *isar) +{ + modeisar(&isar->ch[0], ISDN_P_NONE); + modeisar(&isar->ch[1], ISDN_P_NONE); + del_timer(&isar->ch[0].ftimer); + del_timer(&isar->ch[1].ftimer); + test_and_clear_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags); + test_and_clear_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags); +} + +static int +init_isar(struct isar_hw *isar) +{ + int cnt = 3; + + while (cnt--) { + isar->version = ISARVersion(isar); + if (isar->ch[0].bch.debug & DEBUG_HW) + pr_notice("%s: Testing version %d (%d time)\n", + isar->name, isar->version, 3 - cnt); + if (isar->version == 1) + break; + isar->ctrl(isar->hw, HW_RESET_REQ, 0); + } + if (isar->version != 1) + return -EINVAL; + isar->ch[0].ftimer.function = &ftimer_handler; + isar->ch[0].ftimer.data = (long)&isar->ch[0]; + init_timer(&isar->ch[0].ftimer); + test_and_set_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags); + isar->ch[1].ftimer.function = &ftimer_handler; + isar->ch[1].ftimer.data = (long)&isar->ch[1]; + init_timer(&isar->ch[1].ftimer); + test_and_set_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags); + return 0; +} + +static int +isar_open(struct isar_hw *isar, struct channel_req *rq) +{ + struct bchannel *bch; + + if (rq->adr.channel == 0 || rq->adr.channel > 2) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + bch = &isar->ch[rq->adr.channel - 1].bch; + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + bch->ch.protocol = rq->protocol; + rq->ch = &bch->ch; + return 0; +} + +u32 +mISDNisar_init(struct isar_hw *isar, void *hw) +{ + u32 ret, i; + + isar->hw = hw; + for (i = 0; i < 2; i++) { + isar->ch[i].bch.nr = i + 1; + mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32); + isar->ch[i].bch.ch.nr = i + 1; + isar->ch[i].bch.ch.send = &isar_l2l1; + isar->ch[i].bch.ch.ctrl = isar_bctrl; + isar->ch[i].bch.hw = hw; + isar->ch[i].is = isar; + } + + isar->init = &init_isar; + isar->release = &free_isar; + isar->firmware = &load_firmware; + isar->open = &isar_open; + + ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK)); + + return ret; +} +EXPORT_SYMBOL(mISDNisar_init); + +static int __init isar_mod_init(void) +{ + pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV); + return 0; +} + +static void __exit isar_mod_cleanup(void) +{ + pr_notice("mISDN: ISAR module unloaded\n"); +} +module_init(isar_mod_init); +module_exit(isar_mod_cleanup); diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c new file mode 100644 index 00000000000..8e2944784e0 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -0,0 +1,1169 @@ +/* + * NETJet mISDN driver + * + * Author Karsten Keil <keil@isdn4linux.de> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/mISDNhw.h> +#include <linux/slab.h> +#include "ipac.h" +#include "iohelper.h" +#include "netjet.h" +#include <linux/isdn/hdlc.h> + +#define NETJET_REV "2.0" + +enum nj_types { + NETJET_S_TJ300, + NETJET_S_TJ320, + ENTERNOW__TJ320, +}; + +struct tiger_dma { + size_t size; + u32 *start; + int idx; + u32 dmastart; + u32 dmairq; + u32 dmaend; + u32 dmacur; +}; + +struct tiger_hw; + +struct tiger_ch { + struct bchannel bch; + struct tiger_hw *nj; + int idx; + int free; + int lastrx; + u16 rxstate; + u16 txstate; + struct isdnhdlc_vars hsend; + struct isdnhdlc_vars hrecv; + u8 *hsbuf; + u8 *hrbuf; +}; + +#define TX_INIT 0x0001 +#define TX_IDLE 0x0002 +#define TX_RUN 0x0004 +#define TX_UNDERRUN 0x0100 +#define RX_OVERRUN 0x0100 + +#define LOG_SIZE 64 + +struct tiger_hw { + struct list_head list; + struct pci_dev *pdev; + char name[MISDN_MAX_IDLEN]; + enum nj_types typ; + int irq; + u32 irqcnt; + u32 base; + size_t base_s; + dma_addr_t dma; + void *dma_p; + spinlock_t lock; /* lock HW */ + struct isac_hw isac; + struct tiger_dma send; + struct tiger_dma recv; + struct tiger_ch bc[2]; + u8 ctrlreg; + u8 dmactrl; + u8 auxd; + u8 last_is0; + u8 irqmask0; + char log[LOG_SIZE]; +}; + +static LIST_HEAD(Cards); +static DEFINE_RWLOCK(card_lock); /* protect Cards */ +static u32 debug; +static int nj_cnt; + +static void +_set_debug(struct tiger_hw *card) +{ + card->isac.dch.debug = debug; + card->bc[0].bch.debug = debug; + card->bc[1].bch.debug = debug; +} + +static int +set_debug(const char *val, struct kernel_param *kp) +{ + int ret; + struct tiger_hw *card; + + ret = param_set_uint(val, kp); + if (!ret) { + read_lock(&card_lock); + list_for_each_entry(card, &Cards, list) + _set_debug(card); + read_unlock(&card_lock); + } + return ret; +} + +MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(NETJET_REV); +module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Netjet debug mask"); + +static void +nj_disable_hwirq(struct tiger_hw *card) +{ + outb(0, card->base + NJ_IRQMASK0); + outb(0, card->base + NJ_IRQMASK1); +} + + +static u8 +ReadISAC_nj(void *p, u8 offset) +{ + struct tiger_hw *card = p; + u8 ret; + + card->auxd &= 0xfc; + card->auxd |= (offset >> 4) & 3; + outb(card->auxd, card->base + NJ_AUXDATA); + ret = inb(card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2)); + return ret; +} + +static void +WriteISAC_nj(void *p, u8 offset, u8 value) +{ + struct tiger_hw *card = p; + + card->auxd &= 0xfc; + card->auxd |= (offset >> 4) & 3; + outb(card->auxd, card->base + NJ_AUXDATA); + outb(value, card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2)); +} + +static void +ReadFiFoISAC_nj(void *p, u8 offset, u8 *data, int size) +{ + struct tiger_hw *card = p; + + card->auxd &= 0xfc; + outb(card->auxd, card->base + NJ_AUXDATA); + insb(card->base + NJ_ISAC_OFF, data, size); +} + +static void +WriteFiFoISAC_nj(void *p, u8 offset, u8 *data, int size) +{ + struct tiger_hw *card = p; + + card->auxd &= 0xfc; + outb(card->auxd, card->base + NJ_AUXDATA); + outsb(card->base + NJ_ISAC_OFF, data, size); +} + +static void +fill_mem(struct tiger_ch *bc, u32 idx, u32 cnt, u32 fill) +{ + struct tiger_hw *card = bc->bch.hw; + u32 mask = 0xff, val; + + pr_debug("%s: B%1d fill %02x len %d idx %d/%d\n", card->name, + bc->bch.nr, fill, cnt, idx, card->send.idx); + if (bc->bch.nr & 2) { + fill <<= 8; + mask <<= 8; + } + mask ^= 0xffffffff; + while (cnt--) { + val = card->send.start[idx]; + val &= mask; + val |= fill; + card->send.start[idx++] = val; + if (idx >= card->send.size) + idx = 0; + } +} + +static int +mode_tiger(struct tiger_ch *bc, u32 protocol) +{ + struct tiger_hw *card = bc->bch.hw; + + pr_debug("%s: B%1d protocol %x-->%x\n", card->name, + bc->bch.nr, bc->bch.state, protocol); + switch (protocol) { + case ISDN_P_NONE: + if (bc->bch.state == ISDN_P_NONE) + break; + fill_mem(bc, 0, card->send.size, 0xff); + bc->bch.state = protocol; + /* only stop dma and interrupts if both channels NULL */ + if ((card->bc[0].bch.state == ISDN_P_NONE) && + (card->bc[1].bch.state == ISDN_P_NONE)) { + card->dmactrl = 0; + outb(card->dmactrl, card->base + NJ_DMACTRL); + outb(0, card->base + NJ_IRQMASK0); + } + test_and_clear_bit(FLG_HDLC, &bc->bch.Flags); + test_and_clear_bit(FLG_TRANSPARENT, &bc->bch.Flags); + bc->txstate = 0; + bc->rxstate = 0; + bc->lastrx = -1; + break; + case ISDN_P_B_RAW: + test_and_set_bit(FLG_TRANSPARENT, &bc->bch.Flags); + bc->bch.state = protocol; + bc->idx = 0; + bc->free = card->send.size / 2; + bc->rxstate = 0; + bc->txstate = TX_INIT | TX_IDLE; + bc->lastrx = -1; + if (!card->dmactrl) { + card->dmactrl = 1; + outb(card->dmactrl, card->base + NJ_DMACTRL); + outb(0x0f, card->base + NJ_IRQMASK0); + } + break; + case ISDN_P_B_HDLC: + test_and_set_bit(FLG_HDLC, &bc->bch.Flags); + bc->bch.state = protocol; + bc->idx = 0; + bc->free = card->send.size / 2; + bc->rxstate = 0; + bc->txstate = TX_INIT | TX_IDLE; + isdnhdlc_rcv_init(&bc->hrecv, 0); + isdnhdlc_out_init(&bc->hsend, 0); + bc->lastrx = -1; + if (!card->dmactrl) { + card->dmactrl = 1; + outb(card->dmactrl, card->base + NJ_DMACTRL); + outb(0x0f, card->base + NJ_IRQMASK0); + } + break; + default: + pr_info("%s: %s protocol %x not handled\n", card->name, + __func__, protocol); + return -ENOPROTOOPT; + } + card->send.dmacur = inl(card->base + NJ_DMA_READ_ADR); + card->recv.dmacur = inl(card->base + NJ_DMA_WRITE_ADR); + card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2; + card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2; + pr_debug("%s: %s ctrl %x irq %02x/%02x idx %d/%d\n", + card->name, __func__, + inb(card->base + NJ_DMACTRL), + inb(card->base + NJ_IRQMASK0), + inb(card->base + NJ_IRQSTAT0), + card->send.idx, + card->recv.idx); + return 0; +} + +static void +nj_reset(struct tiger_hw *card) +{ + outb(0xff, card->base + NJ_CTRL); /* Reset On */ + mdelay(1); + + /* now edge triggered for TJ320 GE 13/07/00 */ + /* see comment in IRQ function */ + if (card->typ == NETJET_S_TJ320) /* TJ320 */ + card->ctrlreg = 0x40; /* Reset Off and status read clear */ + else + card->ctrlreg = 0x00; /* Reset Off and status read clear */ + outb(card->ctrlreg, card->base + NJ_CTRL); + mdelay(10); + + /* configure AUX pins (all output except ISAC IRQ pin) */ + card->auxd = 0; + card->dmactrl = 0; + outb(~NJ_ISACIRQ, card->base + NJ_AUXCTRL); + outb(NJ_ISACIRQ, card->base + NJ_IRQMASK1); + outb(card->auxd, card->base + NJ_AUXDATA); +} + +static int +inittiger(struct tiger_hw *card) +{ + int i; + + card->dma_p = pci_alloc_consistent(card->pdev, NJ_DMA_SIZE, + &card->dma); + if (!card->dma_p) { + pr_info("%s: No DMA memory\n", card->name); + return -ENOMEM; + } + if ((u64)card->dma > 0xffffffff) { + pr_info("%s: DMA outside 32 bit\n", card->name); + return -ENOMEM; + } + for (i = 0; i < 2; i++) { + card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_ATOMIC); + if (!card->bc[i].hsbuf) { + pr_info("%s: no B%d send buffer\n", card->name, i + 1); + return -ENOMEM; + } + card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_ATOMIC); + if (!card->bc[i].hrbuf) { + pr_info("%s: no B%d recv buffer\n", card->name, i + 1); + return -ENOMEM; + } + } + memset(card->dma_p, 0xff, NJ_DMA_SIZE); + + card->send.start = card->dma_p; + card->send.dmastart = (u32)card->dma; + card->send.dmaend = card->send.dmastart + + (4 * (NJ_DMA_TXSIZE - 1)); + card->send.dmairq = card->send.dmastart + + (4 * ((NJ_DMA_TXSIZE / 2) - 1)); + card->send.size = NJ_DMA_TXSIZE; + + if (debug & DEBUG_HW) + pr_notice("%s: send buffer phy %#x - %#x - %#x virt %p" + " size %zu u32\n", card->name, + card->send.dmastart, card->send.dmairq, + card->send.dmaend, card->send.start, card->send.size); + + outl(card->send.dmastart, card->base + NJ_DMA_READ_START); + outl(card->send.dmairq, card->base + NJ_DMA_READ_IRQ); + outl(card->send.dmaend, card->base + NJ_DMA_READ_END); + + card->recv.start = card->dma_p + (NJ_DMA_SIZE / 2); + card->recv.dmastart = (u32)card->dma + (NJ_DMA_SIZE / 2); + card->recv.dmaend = card->recv.dmastart + + (4 * (NJ_DMA_RXSIZE - 1)); + card->recv.dmairq = card->recv.dmastart + + (4 * ((NJ_DMA_RXSIZE / 2) - 1)); + card->recv.size = NJ_DMA_RXSIZE; + + if (debug & DEBUG_HW) + pr_notice("%s: recv buffer phy %#x - %#x - %#x virt %p" + " size %zu u32\n", card->name, + card->recv.dmastart, card->recv.dmairq, + card->recv.dmaend, card->recv.start, card->recv.size); + + outl(card->recv.dmastart, card->base + NJ_DMA_WRITE_START); + outl(card->recv.dmairq, card->base + NJ_DMA_WRITE_IRQ); + outl(card->recv.dmaend, card->base + NJ_DMA_WRITE_END); + return 0; +} + +static void +read_dma(struct tiger_ch *bc, u32 idx, int cnt) +{ + struct tiger_hw *card = bc->bch.hw; + int i, stat; + u32 val; + u8 *p, *pn; + + if (bc->lastrx == idx) { + bc->rxstate |= RX_OVERRUN; + pr_info("%s: B%1d overrun at idx %d\n", card->name, + bc->bch.nr, idx); + } + bc->lastrx = idx; + if (test_bit(FLG_RX_OFF, &bc->bch.Flags)) { + bc->bch.dropcnt += cnt; + return; + } + stat = bchannel_get_rxbuf(&bc->bch, cnt); + /* only transparent use the count here, HDLC overun is detected later */ + if (stat == ENOMEM) { + pr_warning("%s.B%d: No memory for %d bytes\n", + card->name, bc->bch.nr, cnt); + return; + } + if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) + p = skb_put(bc->bch.rx_skb, cnt); + else + p = bc->hrbuf; + + for (i = 0; i < cnt; i++) { + val = card->recv.start[idx++]; + if (bc->bch.nr & 2) + val >>= 8; + if (idx >= card->recv.size) + idx = 0; + p[i] = val & 0xff; + } + + if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) { + recv_Bchannel(&bc->bch, 0, false); + return; + } + + pn = bc->hrbuf; + while (cnt > 0) { + stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i, + bc->bch.rx_skb->data, bc->bch.maxlen); + if (stat > 0) { /* valid frame received */ + p = skb_put(bc->bch.rx_skb, stat); + if (debug & DEBUG_HW_BFIFO) { + snprintf(card->log, LOG_SIZE, + "B%1d-recv %s %d ", bc->bch.nr, + card->name, stat); + print_hex_dump_bytes(card->log, + DUMP_PREFIX_OFFSET, p, + stat); + } + recv_Bchannel(&bc->bch, 0, false); + stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen); + if (stat < 0) { + pr_warning("%s.B%d: No memory for %d bytes\n", + card->name, bc->bch.nr, cnt); + return; + } + } else if (stat == -HDLC_CRC_ERROR) { + pr_info("%s: B%1d receive frame CRC error\n", + card->name, bc->bch.nr); + } else if (stat == -HDLC_FRAMING_ERROR) { + pr_info("%s: B%1d receive framing error\n", + card->name, bc->bch.nr); + } else if (stat == -HDLC_LENGTH_ERROR) { + pr_info("%s: B%1d receive frame too long (> %d)\n", + card->name, bc->bch.nr, bc->bch.maxlen); + } + pn += i; + cnt -= i; + } +} + +static void +recv_tiger(struct tiger_hw *card, u8 irq_stat) +{ + u32 idx; + int cnt = card->recv.size / 2; + + /* Note receive is via the WRITE DMA channel */ + card->last_is0 &= ~NJ_IRQM0_WR_MASK; + card->last_is0 |= (irq_stat & NJ_IRQM0_WR_MASK); + + if (irq_stat & NJ_IRQM0_WR_END) + idx = cnt - 1; + else + idx = card->recv.size - 1; + + if (test_bit(FLG_ACTIVE, &card->bc[0].bch.Flags)) + read_dma(&card->bc[0], idx, cnt); + if (test_bit(FLG_ACTIVE, &card->bc[1].bch.Flags)) + read_dma(&card->bc[1], idx, cnt); +} + +/* sync with current DMA address at start or after exception */ +static void +resync(struct tiger_ch *bc, struct tiger_hw *card) +{ + card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR); + card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2; + if (bc->free > card->send.size / 2) + bc->free = card->send.size / 2; + /* currently we simple sync to the next complete free area + * this hast the advantage that we have always maximum time to + * handle TX irq + */ + if (card->send.idx < ((card->send.size / 2) - 1)) + bc->idx = (card->recv.size / 2) - 1; + else + bc->idx = card->recv.size - 1; + bc->txstate = TX_RUN; + pr_debug("%s: %s B%1d free %d idx %d/%d\n", card->name, + __func__, bc->bch.nr, bc->free, bc->idx, card->send.idx); +} + +static int bc_next_frame(struct tiger_ch *); + +static void +fill_hdlc_flag(struct tiger_ch *bc) +{ + struct tiger_hw *card = bc->bch.hw; + int count, i; + u32 m, v; + u8 *p; + + if (bc->free == 0) + return; + pr_debug("%s: %s B%1d %d state %x idx %d/%d\n", card->name, + __func__, bc->bch.nr, bc->free, bc->txstate, + bc->idx, card->send.idx); + if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN)) + resync(bc, card); + count = isdnhdlc_encode(&bc->hsend, NULL, 0, &i, + bc->hsbuf, bc->free); + pr_debug("%s: B%1d hdlc encoded %d flags\n", card->name, + bc->bch.nr, count); + bc->free -= count; + p = bc->hsbuf; + m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff; + for (i = 0; i < count; i++) { + if (bc->idx >= card->send.size) + bc->idx = 0; + v = card->send.start[bc->idx]; + v &= m; + v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8; + card->send.start[bc->idx++] = v; + } + if (debug & DEBUG_HW_BFIFO) { + snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ", + bc->bch.nr, card->name, count); + print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count); + } +} + +static void +fill_dma(struct tiger_ch *bc) +{ + struct tiger_hw *card = bc->bch.hw; + int count, i, fillempty = 0; + u32 m, v, n = 0; + u8 *p; + + if (bc->free == 0) + return; + if (!bc->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) + return; + fillempty = 1; + count = card->send.size >> 1; + p = bc->bch.fill; + } else { + count = bc->bch.tx_skb->len - bc->bch.tx_idx; + if (count <= 0) + return; + pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", + card->name, __func__, bc->bch.nr, count, bc->free, + bc->bch.tx_idx, bc->bch.tx_skb->len, bc->txstate, + bc->idx, card->send.idx); + p = bc->bch.tx_skb->data + bc->bch.tx_idx; + } + if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN)) + resync(bc, card); + if (test_bit(FLG_HDLC, &bc->bch.Flags) && !fillempty) { + count = isdnhdlc_encode(&bc->hsend, p, count, &i, + bc->hsbuf, bc->free); + pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name, + bc->bch.nr, i, count); + bc->bch.tx_idx += i; + bc->free -= count; + p = bc->hsbuf; + } else { + if (count > bc->free) + count = bc->free; + if (!fillempty) + bc->bch.tx_idx += count; + bc->free -= count; + } + m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff; + if (fillempty) { + n = p[0]; + if (!(bc->bch.nr & 1)) + n <<= 8; + for (i = 0; i < count; i++) { + if (bc->idx >= card->send.size) + bc->idx = 0; + v = card->send.start[bc->idx]; + v &= m; + v |= n; + card->send.start[bc->idx++] = v; + } + } else { + for (i = 0; i < count; i++) { + if (bc->idx >= card->send.size) + bc->idx = 0; + v = card->send.start[bc->idx]; + v &= m; + n = p[i]; + v |= (bc->bch.nr & 1) ? n : n << 8; + card->send.start[bc->idx++] = v; + } + } + if (debug & DEBUG_HW_BFIFO) { + snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ", + bc->bch.nr, card->name, count); + print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count); + } + if (bc->free) + bc_next_frame(bc); +} + + +static int +bc_next_frame(struct tiger_ch *bc) +{ + int ret = 1; + + if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len) { + fill_dma(bc); + } else { + if (bc->bch.tx_skb) + dev_kfree_skb(bc->bch.tx_skb); + if (get_next_bframe(&bc->bch)) { + fill_dma(bc); + test_and_clear_bit(FLG_TX_EMPTY, &bc->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &bc->bch.Flags)) { + fill_dma(bc); + } else if (test_bit(FLG_FILLEMPTY, &bc->bch.Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &bc->bch.Flags); + ret = 0; + } else { + ret = 0; + } + } + return ret; +} + +static void +send_tiger_bc(struct tiger_hw *card, struct tiger_ch *bc) +{ + int ret; + + bc->free += card->send.size / 2; + if (bc->free >= card->send.size) { + if (!(bc->txstate & (TX_UNDERRUN | TX_INIT))) { + pr_info("%s: B%1d TX underrun state %x\n", card->name, + bc->bch.nr, bc->txstate); + bc->txstate |= TX_UNDERRUN; + } + bc->free = card->send.size; + } + ret = bc_next_frame(bc); + if (!ret) { + if (test_bit(FLG_HDLC, &bc->bch.Flags)) { + fill_hdlc_flag(bc); + return; + } + pr_debug("%s: B%1d TX no data free %d idx %d/%d\n", card->name, + bc->bch.nr, bc->free, bc->idx, card->send.idx); + if (!(bc->txstate & (TX_IDLE | TX_INIT))) { + fill_mem(bc, bc->idx, bc->free, 0xff); + if (bc->free == card->send.size) + bc->txstate |= TX_IDLE; + } + } +} + +static void +send_tiger(struct tiger_hw *card, u8 irq_stat) +{ + int i; + + /* Note send is via the READ DMA channel */ + if ((irq_stat & card->last_is0) & NJ_IRQM0_RD_MASK) { + pr_info("%s: tiger warn write double dma %x/%x\n", + card->name, irq_stat, card->last_is0); + return; + } else { + card->last_is0 &= ~NJ_IRQM0_RD_MASK; + card->last_is0 |= (irq_stat & NJ_IRQM0_RD_MASK); + } + for (i = 0; i < 2; i++) { + if (test_bit(FLG_ACTIVE, &card->bc[i].bch.Flags)) + send_tiger_bc(card, &card->bc[i]); + } +} + +static irqreturn_t +nj_irq(int intno, void *dev_id) +{ + struct tiger_hw *card = dev_id; + u8 val, s1val, s0val; + + spin_lock(&card->lock); + s0val = inb(card->base | NJ_IRQSTAT0); + s1val = inb(card->base | NJ_IRQSTAT1); + if ((s1val & NJ_ISACIRQ) && (s0val == 0)) { + /* shared IRQ */ + spin_unlock(&card->lock); + return IRQ_NONE; + } + pr_debug("%s: IRQSTAT0 %02x IRQSTAT1 %02x\n", card->name, s0val, s1val); + card->irqcnt++; + if (!(s1val & NJ_ISACIRQ)) { + val = ReadISAC_nj(card, ISAC_ISTA); + if (val) + mISDNisac_irq(&card->isac, val); + } + + if (s0val) + /* write to clear */ + outb(s0val, card->base | NJ_IRQSTAT0); + else + goto end; + s1val = s0val; + /* set bits in sval to indicate which page is free */ + card->recv.dmacur = inl(card->base | NJ_DMA_WRITE_ADR); + card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2; + if (card->recv.dmacur < card->recv.dmairq) + s0val = 0x08; /* the 2nd write area is free */ + else + s0val = 0x04; /* the 1st write area is free */ + + card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR); + card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2; + if (card->send.dmacur < card->send.dmairq) + s0val |= 0x02; /* the 2nd read area is free */ + else + s0val |= 0x01; /* the 1st read area is free */ + + pr_debug("%s: DMA Status %02x/%02x/%02x %d/%d\n", card->name, + s1val, s0val, card->last_is0, + card->recv.idx, card->send.idx); + /* test if we have a DMA interrupt */ + if (s0val != card->last_is0) { + if ((s0val & NJ_IRQM0_RD_MASK) != + (card->last_is0 & NJ_IRQM0_RD_MASK)) + /* got a write dma int */ + send_tiger(card, s0val); + if ((s0val & NJ_IRQM0_WR_MASK) != + (card->last_is0 & NJ_IRQM0_WR_MASK)) + /* got a read dma int */ + recv_tiger(card, s0val); + } +end: + spin_unlock(&card->lock); + return IRQ_HANDLED; +} + +static int +nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) +{ + int ret = -EINVAL; + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch); + struct tiger_hw *card = bch->hw; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + unsigned long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(&card->lock, flags); + ret = bchannel_senddata(bch, skb); + if (ret > 0) { /* direct TX */ + fill_dma(bc); + ret = 0; + } + spin_unlock_irqrestore(&card->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + spin_lock_irqsave(&card->lock, flags); + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) + ret = mode_tiger(bc, ch->protocol); + else + ret = 0; + spin_unlock_irqrestore(&card->lock, flags); + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + break; + case PH_DEACTIVATE_REQ: + spin_lock_irqsave(&card->lock, flags); + mISDN_clear_bchannel(bch); + mode_tiger(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + ret = 0; + break; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static int +channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq) +{ + return mISDN_ctrl_bchannel(&bc->bch, cq); +} + +static int +nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch); + struct tiger_hw *card = bch->hw; + int ret = -EINVAL; + u_long flags; + + pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg); + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + cancel_work_sync(&bch->workq); + spin_lock_irqsave(&card->lock, flags); + mISDN_clear_bchannel(bch); + mode_tiger(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(THIS_MODULE); + ret = 0; + break; + case CONTROL_CHANNEL: + ret = channel_bctrl(bc, arg); + break; + default: + pr_info("%s: %s unknown prim(%x)\n", card->name, __func__, cmd); + } + return ret; +} + +static int +channel_ctrl(struct tiger_hw *card, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3; + break; + case MISDN_CTRL_LOOP: + /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */ + if (cq->channel < 0 || cq->channel > 3) { + ret = -EINVAL; + break; + } + ret = card->isac.ctrl(&card->isac, HW_TESTLOOP, cq->channel); + break; + case MISDN_CTRL_L1_TIMER3: + ret = card->isac.ctrl(&card->isac, HW_TIMER3_VALUE, cq->p1); + break; + default: + pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +static int +open_bchannel(struct tiger_hw *card, struct channel_req *rq) +{ + struct bchannel *bch; + + if (rq->adr.channel == 0 || rq->adr.channel > 2) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + bch = &card->bc[rq->adr.channel - 1].bch; + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); + bch->ch.protocol = rq->protocol; + rq->ch = &bch->ch; + return 0; +} + +/* + * device control function + */ +static int +nj_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct tiger_hw *card = dch->hw; + struct channel_req *rq; + int err = 0; + + pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + if (rq->protocol == ISDN_P_TE_S0) + err = card->isac.open(&card->isac, rq); + else + err = open_bchannel(card, rq); + if (err) + break; + if (!try_module_get(THIS_MODULE)) + pr_info("%s: cannot get module\n", card->name); + break; + case CLOSE_CHANNEL: + pr_debug("%s: dev(%d) close from %p\n", card->name, dch->dev.id, + __builtin_return_address(0)); + module_put(THIS_MODULE); + break; + case CONTROL_CHANNEL: + err = channel_ctrl(card, arg); + break; + default: + pr_debug("%s: %s unknown command %x\n", + card->name, __func__, cmd); + return -EINVAL; + } + return err; +} + +static int +nj_init_card(struct tiger_hw *card) +{ + u_long flags; + int ret; + + spin_lock_irqsave(&card->lock, flags); + nj_disable_hwirq(card); + spin_unlock_irqrestore(&card->lock, flags); + + card->irq = card->pdev->irq; + if (request_irq(card->irq, nj_irq, IRQF_SHARED, card->name, card)) { + pr_info("%s: couldn't get interrupt %d\n", + card->name, card->irq); + card->irq = -1; + return -EIO; + } + + spin_lock_irqsave(&card->lock, flags); + nj_reset(card); + ret = card->isac.init(&card->isac); + if (ret) + goto error; + ret = inittiger(card); + if (ret) + goto error; + mode_tiger(&card->bc[0], ISDN_P_NONE); + mode_tiger(&card->bc[1], ISDN_P_NONE); +error: + spin_unlock_irqrestore(&card->lock, flags); + return ret; +} + + +static void +nj_release(struct tiger_hw *card) +{ + u_long flags; + int i; + + if (card->base_s) { + spin_lock_irqsave(&card->lock, flags); + nj_disable_hwirq(card); + mode_tiger(&card->bc[0], ISDN_P_NONE); + mode_tiger(&card->bc[1], ISDN_P_NONE); + card->isac.release(&card->isac); + spin_unlock_irqrestore(&card->lock, flags); + release_region(card->base, card->base_s); + card->base_s = 0; + } + if (card->irq > 0) + free_irq(card->irq, card); + if (card->isac.dch.dev.dev.class) + mISDN_unregister_device(&card->isac.dch.dev); + + for (i = 0; i < 2; i++) { + mISDN_freebchannel(&card->bc[i].bch); + kfree(card->bc[i].hsbuf); + kfree(card->bc[i].hrbuf); + } + if (card->dma_p) + pci_free_consistent(card->pdev, NJ_DMA_SIZE, + card->dma_p, card->dma); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + pci_clear_master(card->pdev); + pci_disable_device(card->pdev); + pci_set_drvdata(card->pdev, NULL); + kfree(card); +} + + +static int +nj_setup(struct tiger_hw *card) +{ + card->base = pci_resource_start(card->pdev, 0); + card->base_s = pci_resource_len(card->pdev, 0); + if (!request_region(card->base, card->base_s, card->name)) { + pr_info("%s: NETjet config port %#x-%#x already in use\n", + card->name, card->base, + (u32)(card->base + card->base_s - 1)); + card->base_s = 0; + return -EIO; + } + ASSIGN_FUNC(nj, ISAC, card->isac); + return 0; +} + + +static int +setup_instance(struct tiger_hw *card) +{ + int i, err; + u_long flags; + + snprintf(card->name, MISDN_MAX_IDLEN - 1, "netjet.%d", nj_cnt + 1); + write_lock_irqsave(&card_lock, flags); + list_add_tail(&card->list, &Cards); + write_unlock_irqrestore(&card_lock, flags); + + _set_debug(card); + card->isac.name = card->name; + spin_lock_init(&card->lock); + card->isac.hwlock = &card->lock; + mISDNisac_init(&card->isac, card); + + card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + card->isac.dch.dev.D.ctrl = nj_dctrl; + for (i = 0; i < 2; i++) { + card->bc[i].bch.nr = i + 1; + set_channelmap(i + 1, card->isac.dch.dev.channelmap); + mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM, + NJ_DMA_RXSIZE >> 1); + card->bc[i].bch.hw = card; + card->bc[i].bch.ch.send = nj_l2l1B; + card->bc[i].bch.ch.ctrl = nj_bctrl; + card->bc[i].bch.ch.nr = i + 1; + list_add(&card->bc[i].bch.ch.list, + &card->isac.dch.dev.bchannels); + card->bc[i].bch.hw = card; + } + err = nj_setup(card); + if (err) + goto error; + err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev, + card->name); + if (err) + goto error; + err = nj_init_card(card); + if (!err) { + nj_cnt++; + pr_notice("Netjet %d cards installed\n", nj_cnt); + return 0; + } +error: + nj_release(card); + return err; +} + +static int +nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = -ENOMEM; + int cfg; + struct tiger_hw *card; + + if (pdev->subsystem_vendor == 0x8086 && + pdev->subsystem_device == 0x0003) { + pr_notice("Netjet: Digium X100P/X101P not handled\n"); + return -ENODEV; + } + + if (pdev->subsystem_vendor == 0x55 && + pdev->subsystem_device == 0x02) { + pr_notice("Netjet: Enter!Now not handled yet\n"); + return -ENODEV; + } + + if (pdev->subsystem_vendor == 0xb100 && + pdev->subsystem_device == 0x0003) { + pr_notice("Netjet: Digium TDM400P not handled yet\n"); + return -ENODEV; + } + + card = kzalloc(sizeof(struct tiger_hw), GFP_ATOMIC); + if (!card) { + pr_info("No kmem for Netjet\n"); + return err; + } + + card->pdev = pdev; + + err = pci_enable_device(pdev); + if (err) { + kfree(card); + return err; + } + + printk(KERN_INFO "nj_probe(mISDN): found adapter at %s\n", + pci_name(pdev)); + + pci_set_master(pdev); + + /* the TJ300 and TJ320 must be detected, the IRQ handling is different + * unfortunately the chips use the same device ID, but the TJ320 has + * the bit20 in status PCI cfg register set + */ + pci_read_config_dword(pdev, 0x04, &cfg); + if (cfg & 0x00100000) + card->typ = NETJET_S_TJ320; + else + card->typ = NETJET_S_TJ300; + + card->base = pci_resource_start(pdev, 0); + card->irq = pdev->irq; + pci_set_drvdata(pdev, card); + err = setup_instance(card); + if (err) + pci_set_drvdata(pdev, NULL); + + return err; +} + + +static void nj_remove(struct pci_dev *pdev) +{ + struct tiger_hw *card = pci_get_drvdata(pdev); + + if (card) + nj_release(card); + else + pr_info("%s drvdata already removed\n", __func__); +} + +/* We cannot select cards with PCI_SUB... IDs, since here are cards with + * SUB IDs set to PCI_ANY_ID, so we need to match all and reject + * known other cards which not work with this driver - see probe function */ +static struct pci_device_id nj_pci_ids[] = { + { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { } +}; +MODULE_DEVICE_TABLE(pci, nj_pci_ids); + +static struct pci_driver nj_driver = { + .name = "netjet", + .probe = nj_probe, + .remove = nj_remove, + .id_table = nj_pci_ids, +}; + +static int __init nj_init(void) +{ + int err; + + pr_notice("Netjet PCI driver Rev. %s\n", NETJET_REV); + err = pci_register_driver(&nj_driver); + return err; +} + +static void __exit nj_cleanup(void) +{ + pci_unregister_driver(&nj_driver); +} + +module_init(nj_init); +module_exit(nj_cleanup); diff --git a/drivers/isdn/hardware/mISDN/netjet.h b/drivers/isdn/hardware/mISDN/netjet.h new file mode 100644 index 00000000000..ddd41ef1a70 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/netjet.h @@ -0,0 +1,57 @@ +/* + * NETjet common header file + * + * Author Karsten Keil + * based on work of Matt Henderson and Daniel Potts, + * Traverse Technologies P/L www.traverse.com.au + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#define NJ_CTRL 0x00 +#define NJ_DMACTRL 0x01 +#define NJ_AUXCTRL 0x02 +#define NJ_AUXDATA 0x03 +#define NJ_IRQMASK0 0x04 +#define NJ_IRQMASK1 0x05 +#define NJ_IRQSTAT0 0x06 +#define NJ_IRQSTAT1 0x07 +#define NJ_DMA_READ_START 0x08 +#define NJ_DMA_READ_IRQ 0x0c +#define NJ_DMA_READ_END 0x10 +#define NJ_DMA_READ_ADR 0x14 +#define NJ_DMA_WRITE_START 0x18 +#define NJ_DMA_WRITE_IRQ 0x1c +#define NJ_DMA_WRITE_END 0x20 +#define NJ_DMA_WRITE_ADR 0x24 +#define NJ_PULSE_CNT 0x28 + +#define NJ_ISAC_OFF 0xc0 +#define NJ_ISACIRQ 0x10 + +#define NJ_IRQM0_RD_MASK 0x03 +#define NJ_IRQM0_RD_IRQ 0x01 +#define NJ_IRQM0_RD_END 0x02 +#define NJ_IRQM0_WR_MASK 0x0c +#define NJ_IRQM0_WR_IRQ 0x04 +#define NJ_IRQM0_WR_END 0x08 + +/* one page here is no need to be smaller */ +#define NJ_DMA_SIZE 4096 +/* 2 * 64 byte is a compromise between IRQ count and latency */ +#define NJ_DMA_RXSIZE 128 /* 2 * 64 */ +#define NJ_DMA_TXSIZE 128 /* 2 * 64 */ diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c new file mode 100644 index 00000000000..9815bb4eec9 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/speedfax.c @@ -0,0 +1,532 @@ +/* + * speedfax.c low level stuff for Sedlbauer Speedfax+ cards + * based on the ISAR DSP + * Thanks to Sedlbauer AG for informations and HW + * + * Author Karsten Keil <keil@isdn4linux.de> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/mISDNhw.h> +#include <linux/firmware.h> +#include "ipac.h" +#include "isar.h" + +#define SPEEDFAX_REV "2.0" + +#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51 +#define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54 +#define PCI_SUB_ID_SEDLBAUER 0x01 + +#define SFAX_PCI_ADDR 0xc8 +#define SFAX_PCI_ISAC 0xd0 +#define SFAX_PCI_ISAR 0xe0 + +/* TIGER 100 Registers */ + +#define TIGER_RESET_ADDR 0x00 +#define TIGER_EXTERN_RESET_ON 0x01 +#define TIGER_EXTERN_RESET_OFF 0x00 +#define TIGER_AUX_CTRL 0x02 +#define TIGER_AUX_DATA 0x03 +#define TIGER_AUX_IRQMASK 0x05 +#define TIGER_AUX_STATUS 0x07 + +/* Tiger AUX BITs */ +#define SFAX_AUX_IOMASK 0xdd /* 1 and 5 are inputs */ +#define SFAX_ISAR_RESET_BIT_OFF 0x00 +#define SFAX_ISAR_RESET_BIT_ON 0x01 +#define SFAX_TIGER_IRQ_BIT 0x02 +#define SFAX_LED1_BIT 0x08 +#define SFAX_LED2_BIT 0x10 + +#define SFAX_PCI_RESET_ON (SFAX_ISAR_RESET_BIT_ON) +#define SFAX_PCI_RESET_OFF (SFAX_LED1_BIT | SFAX_LED2_BIT) + +static int sfax_cnt; +static u32 debug; +static u32 irqloops = 4; + +struct sfax_hw { + struct list_head list; + struct pci_dev *pdev; + char name[MISDN_MAX_IDLEN]; + u32 irq; + u32 irqcnt; + u32 cfg; + struct _ioport p_isac; + struct _ioport p_isar; + u8 aux_data; + spinlock_t lock; /* HW access lock */ + struct isac_hw isac; + struct isar_hw isar; +}; + +static LIST_HEAD(Cards); +static DEFINE_RWLOCK(card_lock); /* protect Cards */ + +static void +_set_debug(struct sfax_hw *card) +{ + card->isac.dch.debug = debug; + card->isar.ch[0].bch.debug = debug; + card->isar.ch[1].bch.debug = debug; +} + +static int +set_debug(const char *val, struct kernel_param *kp) +{ + int ret; + struct sfax_hw *card; + + ret = param_set_uint(val, kp); + if (!ret) { + read_lock(&card_lock); + list_for_each_entry(card, &Cards, list) + _set_debug(card); + read_unlock(&card_lock); + } + return ret; +} + +MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(SPEEDFAX_REV); +MODULE_FIRMWARE("isdn/ISAR.BIN"); +module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Speedfax debug mask"); +module_param(irqloops, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)"); + +IOFUNC_IND(ISAC, sfax_hw, p_isac) +IOFUNC_IND(ISAR, sfax_hw, p_isar) + +static irqreturn_t +speedfax_irq(int intno, void *dev_id) +{ + struct sfax_hw *sf = dev_id; + u8 val; + int cnt = irqloops; + + spin_lock(&sf->lock); + val = inb(sf->cfg + TIGER_AUX_STATUS); + if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */ + spin_unlock(&sf->lock); + return IRQ_NONE; /* shared */ + } + sf->irqcnt++; + val = ReadISAR_IND(sf, ISAR_IRQBIT); +Start_ISAR: + if (val & ISAR_IRQSTA) + mISDNisar_irq(&sf->isar); + val = ReadISAC_IND(sf, ISAC_ISTA); + if (val) + mISDNisac_irq(&sf->isac, val); + val = ReadISAR_IND(sf, ISAR_IRQBIT); + if ((val & ISAR_IRQSTA) && cnt--) + goto Start_ISAR; + if (cnt < irqloops) + pr_debug("%s: %d irqloops cpu%d\n", sf->name, + irqloops - cnt, smp_processor_id()); + if (irqloops && !cnt) + pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name, + irqloops, smp_processor_id()); + spin_unlock(&sf->lock); + return IRQ_HANDLED; +} + +static void +enable_hwirq(struct sfax_hw *sf) +{ + WriteISAC_IND(sf, ISAC_MASK, 0); + WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK); + outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK); +} + +static void +disable_hwirq(struct sfax_hw *sf) +{ + WriteISAC_IND(sf, ISAC_MASK, 0xFF); + WriteISAR_IND(sf, ISAR_IRQBIT, 0); + outb(0, sf->cfg + TIGER_AUX_IRQMASK); +} + +static void +reset_speedfax(struct sfax_hw *sf) +{ + + pr_debug("%s: resetting card\n", sf->name); + outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR); + outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA); + mdelay(1); + outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR); + sf->aux_data = SFAX_PCI_RESET_OFF; + outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA); + mdelay(1); +} + +static int +sfax_ctrl(struct sfax_hw *sf, u32 cmd, u_long arg) +{ + int ret = 0; + + switch (cmd) { + case HW_RESET_REQ: + reset_speedfax(sf); + break; + case HW_ACTIVATE_IND: + if (arg & 1) + sf->aux_data &= ~SFAX_LED1_BIT; + if (arg & 2) + sf->aux_data &= ~SFAX_LED2_BIT; + outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA); + break; + case HW_DEACT_IND: + if (arg & 1) + sf->aux_data |= SFAX_LED1_BIT; + if (arg & 2) + sf->aux_data |= SFAX_LED2_BIT; + outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA); + break; + default: + pr_info("%s: %s unknown command %x %lx\n", + sf->name, __func__, cmd, arg); + ret = -EINVAL; + break; + } + return ret; +} + +static int +channel_ctrl(struct sfax_hw *sf, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3; + break; + case MISDN_CTRL_LOOP: + /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */ + if (cq->channel < 0 || cq->channel > 3) { + ret = -EINVAL; + break; + } + ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel); + break; + case MISDN_CTRL_L1_TIMER3: + ret = sf->isac.ctrl(&sf->isac, HW_TIMER3_VALUE, cq->p1); + break; + default: + pr_info("%s: unknown Op %x\n", sf->name, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +static int +sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct sfax_hw *sf = dch->hw; + struct channel_req *rq; + int err = 0; + + pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + if (rq->protocol == ISDN_P_TE_S0) + err = sf->isac.open(&sf->isac, rq); + else + err = sf->isar.open(&sf->isar, rq); + if (err) + break; + if (!try_module_get(THIS_MODULE)) + pr_info("%s: cannot get module\n", sf->name); + break; + case CLOSE_CHANNEL: + pr_debug("%s: dev(%d) close from %p\n", sf->name, + dch->dev.id, __builtin_return_address(0)); + module_put(THIS_MODULE); + break; + case CONTROL_CHANNEL: + err = channel_ctrl(sf, arg); + break; + default: + pr_debug("%s: unknown command %x\n", sf->name, cmd); + return -EINVAL; + } + return err; +} + +static int +init_card(struct sfax_hw *sf) +{ + int ret, cnt = 3; + u_long flags; + + ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf); + if (ret) { + pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq); + return ret; + } + while (cnt--) { + spin_lock_irqsave(&sf->lock, flags); + ret = sf->isac.init(&sf->isac); + if (ret) { + spin_unlock_irqrestore(&sf->lock, flags); + pr_info("%s: ISAC init failed with %d\n", + sf->name, ret); + break; + } + enable_hwirq(sf); + /* RESET Receiver and Transmitter */ + WriteISAC_IND(sf, ISAC_CMDR, 0x41); + spin_unlock_irqrestore(&sf->lock, flags); + msleep_interruptible(10); + if (debug & DEBUG_HW) + pr_notice("%s: IRQ %d count %d\n", sf->name, + sf->irq, sf->irqcnt); + if (!sf->irqcnt) { + pr_info("%s: IRQ(%d) got no requests during init %d\n", + sf->name, sf->irq, 3 - cnt); + } else + return 0; + } + free_irq(sf->irq, sf); + return -EIO; +} + + +static int +setup_speedfax(struct sfax_hw *sf) +{ + u_long flags; + + if (!request_region(sf->cfg, 256, sf->name)) { + pr_info("mISDN: %s config port %x-%x already in use\n", + sf->name, sf->cfg, sf->cfg + 255); + return -EIO; + } + outb(0xff, sf->cfg); + outb(0, sf->cfg); + outb(0xdd, sf->cfg + TIGER_AUX_CTRL); + outb(0, sf->cfg + TIGER_AUX_IRQMASK); + + sf->isac.type = IPAC_TYPE_ISAC; + sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR; + sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC; + sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR; + sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR; + ASSIGN_FUNC(IND, ISAC, sf->isac); + ASSIGN_FUNC(IND, ISAR, sf->isar); + spin_lock_irqsave(&sf->lock, flags); + reset_speedfax(sf); + disable_hwirq(sf); + spin_unlock_irqrestore(&sf->lock, flags); + return 0; +} + +static void +release_card(struct sfax_hw *card) { + u_long flags; + + spin_lock_irqsave(&card->lock, flags); + disable_hwirq(card); + spin_unlock_irqrestore(&card->lock, flags); + card->isac.release(&card->isac); + free_irq(card->irq, card); + card->isar.release(&card->isar); + mISDN_unregister_device(&card->isac.dch.dev); + release_region(card->cfg, 256); + pci_disable_device(card->pdev); + pci_set_drvdata(card->pdev, NULL); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + kfree(card); + sfax_cnt--; +} + +static int +setup_instance(struct sfax_hw *card) +{ + const struct firmware *firmware; + int i, err; + u_long flags; + + snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1); + write_lock_irqsave(&card_lock, flags); + list_add_tail(&card->list, &Cards); + write_unlock_irqrestore(&card_lock, flags); + _set_debug(card); + spin_lock_init(&card->lock); + card->isac.hwlock = &card->lock; + card->isar.hwlock = &card->lock; + card->isar.ctrl = (void *)&sfax_ctrl; + card->isac.name = card->name; + card->isar.name = card->name; + card->isar.owner = THIS_MODULE; + + err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev); + if (err < 0) { + pr_info("%s: firmware request failed %d\n", + card->name, err); + goto error_fw; + } + if (debug & DEBUG_HW) + pr_notice("%s: got firmware %zu bytes\n", + card->name, firmware->size); + + mISDNisac_init(&card->isac, card); + + card->isac.dch.dev.D.ctrl = sfax_dctrl; + card->isac.dch.dev.Bprotocols = + mISDNisar_init(&card->isar, card); + for (i = 0; i < 2; i++) { + set_channelmap(i + 1, card->isac.dch.dev.channelmap); + list_add(&card->isar.ch[i].bch.ch.list, + &card->isac.dch.dev.bchannels); + } + + err = setup_speedfax(card); + if (err) + goto error_setup; + err = card->isar.init(&card->isar); + if (err) + goto error; + err = mISDN_register_device(&card->isac.dch.dev, + &card->pdev->dev, card->name); + if (err) + goto error; + err = init_card(card); + if (err) + goto error_init; + err = card->isar.firmware(&card->isar, firmware->data, firmware->size); + if (!err) { + release_firmware(firmware); + sfax_cnt++; + pr_notice("SpeedFax %d cards installed\n", sfax_cnt); + return 0; + } + disable_hwirq(card); + free_irq(card->irq, card); +error_init: + mISDN_unregister_device(&card->isac.dch.dev); +error: + release_region(card->cfg, 256); +error_setup: + card->isac.release(&card->isac); + card->isar.release(&card->isar); + release_firmware(firmware); +error_fw: + pci_disable_device(card->pdev); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + kfree(card); + return err; +} + +static int +sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = -ENOMEM; + struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL); + + if (!card) { + pr_info("No memory for Speedfax+ PCI\n"); + return err; + } + card->pdev = pdev; + err = pci_enable_device(pdev); + if (err) { + kfree(card); + return err; + } + + pr_notice("mISDN: Speedfax found adapter %s at %s\n", + (char *)ent->driver_data, pci_name(pdev)); + + card->cfg = pci_resource_start(pdev, 0); + card->irq = pdev->irq; + pci_set_drvdata(pdev, card); + err = setup_instance(card); + if (err) + pci_set_drvdata(pdev, NULL); + return err; +} + +static void +sfax_remove_pci(struct pci_dev *pdev) +{ + struct sfax_hw *card = pci_get_drvdata(pdev); + + if (card) + release_card(card); + else + pr_debug("%s: drvdata already removed\n", __func__); +} + +static struct pci_device_id sfaxpci_ids[] = { + { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, + PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER, + 0, 0, (unsigned long) "Pyramid Speedfax + PCI" + }, + { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, + PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER, + 0, 0, (unsigned long) "Sedlbauer Speedfax + PCI" + }, + { } +}; +MODULE_DEVICE_TABLE(pci, sfaxpci_ids); + +static struct pci_driver sfaxpci_driver = { + .name = "speedfax+ pci", + .probe = sfaxpci_probe, + .remove = sfax_remove_pci, + .id_table = sfaxpci_ids, +}; + +static int __init +Speedfax_init(void) +{ + int err; + + pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n", + SPEEDFAX_REV); + err = pci_register_driver(&sfaxpci_driver); + return err; +} + +static void __exit +Speedfax_cleanup(void) +{ + pci_unregister_driver(&sfaxpci_driver); +} + +module_init(Speedfax_init); +module_exit(Speedfax_cleanup); diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c new file mode 100644 index 00000000000..de69f6828c7 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/w6692.c @@ -0,0 +1,1437 @@ +/* + * w6692.c mISDN driver for Winbond w6692 based cards + * + * Author Karsten Keil <kkeil@suse.de> + * based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/mISDNhw.h> +#include <linux/slab.h> +#include "w6692.h" + +#define W6692_REV "2.0" + +#define DBUSY_TIMER_VALUE 80 + +enum { + W6692_ASUS, + W6692_WINBOND, + W6692_USR +}; + +/* private data in the PCI devices list */ +struct w6692map { + u_int subtype; + char *name; +}; + +static const struct w6692map w6692_map[] = +{ + {W6692_ASUS, "Dynalink/AsusCom IS64PH"}, + {W6692_WINBOND, "Winbond W6692"}, + {W6692_USR, "USR W6692"} +}; + +#ifndef PCI_VENDOR_ID_USR +#define PCI_VENDOR_ID_USR 0x16ec +#define PCI_DEVICE_ID_USR_6692 0x3409 +#endif + +struct w6692_ch { + struct bchannel bch; + u32 addr; + struct timer_list timer; + u8 b_mode; +}; + +struct w6692_hw { + struct list_head list; + struct pci_dev *pdev; + char name[MISDN_MAX_IDLEN]; + u32 irq; + u32 irqcnt; + u32 addr; + u32 fmask; /* feature mask - bit set per card nr */ + int subtype; + spinlock_t lock; /* hw lock */ + u8 imask; + u8 pctl; + u8 xaddr; + u8 xdata; + u8 state; + struct w6692_ch bc[2]; + struct dchannel dch; + char log[64]; +}; + +static LIST_HEAD(Cards); +static DEFINE_RWLOCK(card_lock); /* protect Cards */ + +static int w6692_cnt; +static int debug; +static u32 led; +static u32 pots; + +static void +_set_debug(struct w6692_hw *card) +{ + card->dch.debug = debug; + card->bc[0].bch.debug = debug; + card->bc[1].bch.debug = debug; +} + +static int +set_debug(const char *val, struct kernel_param *kp) +{ + int ret; + struct w6692_hw *card; + + ret = param_set_uint(val, kp); + if (!ret) { + read_lock(&card_lock); + list_for_each_entry(card, &Cards, list) + _set_debug(card); + read_unlock(&card_lock); + } + return ret; +} + +MODULE_AUTHOR("Karsten Keil"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(W6692_REV); +module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "W6692 debug mask"); +module_param(led, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(led, "W6692 LED support bitmask (one bit per card)"); +module_param(pots, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(pots, "W6692 POTS support bitmask (one bit per card)"); + +static inline u8 +ReadW6692(struct w6692_hw *card, u8 offset) +{ + return inb(card->addr + offset); +} + +static inline void +WriteW6692(struct w6692_hw *card, u8 offset, u8 value) +{ + outb(value, card->addr + offset); +} + +static inline u8 +ReadW6692B(struct w6692_ch *bc, u8 offset) +{ + return inb(bc->addr + offset); +} + +static inline void +WriteW6692B(struct w6692_ch *bc, u8 offset, u8 value) +{ + outb(value, bc->addr + offset); +} + +static void +enable_hwirq(struct w6692_hw *card) +{ + WriteW6692(card, W_IMASK, card->imask); +} + +static void +disable_hwirq(struct w6692_hw *card) +{ + WriteW6692(card, W_IMASK, 0xff); +} + +static const char *W6692Ver[] = {"V00", "V01", "V10", "V11"}; + +static void +W6692Version(struct w6692_hw *card) +{ + int val; + + val = ReadW6692(card, W_D_RBCH); + pr_notice("%s: Winbond W6692 version: %s\n", card->name, + W6692Ver[(val >> 6) & 3]); +} + +static void +w6692_led_handler(struct w6692_hw *card, int on) +{ + if ((!(card->fmask & led)) || card->subtype == W6692_USR) + return; + if (on) { + card->xdata &= 0xfb; /* LED ON */ + WriteW6692(card, W_XDATA, card->xdata); + } else { + card->xdata |= 0x04; /* LED OFF */ + WriteW6692(card, W_XDATA, card->xdata); + } +} + +static void +ph_command(struct w6692_hw *card, u8 cmd) +{ + pr_debug("%s: ph_command %x\n", card->name, cmd); + WriteW6692(card, W_CIX, cmd); +} + +static void +W6692_new_ph(struct w6692_hw *card) +{ + if (card->state == W_L1CMD_RST) + ph_command(card, W_L1CMD_DRC); + schedule_event(&card->dch, FLG_PHCHANGE); +} + +static void +W6692_ph_bh(struct dchannel *dch) +{ + struct w6692_hw *card = dch->hw; + + switch (card->state) { + case W_L1CMD_RST: + dch->state = 0; + l1_event(dch->l1, HW_RESET_IND); + break; + case W_L1IND_CD: + dch->state = 3; + l1_event(dch->l1, HW_DEACT_CNF); + break; + case W_L1IND_DRD: + dch->state = 3; + l1_event(dch->l1, HW_DEACT_IND); + break; + case W_L1IND_CE: + dch->state = 4; + l1_event(dch->l1, HW_POWERUP_IND); + break; + case W_L1IND_LD: + if (dch->state <= 5) { + dch->state = 5; + l1_event(dch->l1, ANYSIGNAL); + } else { + dch->state = 8; + l1_event(dch->l1, LOSTFRAMING); + } + break; + case W_L1IND_ARD: + dch->state = 6; + l1_event(dch->l1, INFO2); + break; + case W_L1IND_AI8: + dch->state = 7; + l1_event(dch->l1, INFO4_P8); + break; + case W_L1IND_AI10: + dch->state = 7; + l1_event(dch->l1, INFO4_P10); + break; + default: + pr_debug("%s: TE unknown state %02x dch state %02x\n", + card->name, card->state, dch->state); + break; + } + pr_debug("%s: TE newstate %02x\n", card->name, dch->state); +} + +static void +W6692_empty_Dfifo(struct w6692_hw *card, int count) +{ + struct dchannel *dch = &card->dch; + u8 *ptr; + + pr_debug("%s: empty_Dfifo %d\n", card->name, count); + if (!dch->rx_skb) { + dch->rx_skb = mI_alloc_skb(card->dch.maxlen, GFP_ATOMIC); + if (!dch->rx_skb) { + pr_info("%s: D receive out of memory\n", card->name); + WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK); + return; + } + } + if ((dch->rx_skb->len + count) >= dch->maxlen) { + pr_debug("%s: empty_Dfifo overrun %d\n", card->name, + dch->rx_skb->len + count); + WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK); + return; + } + ptr = skb_put(dch->rx_skb, count); + insb(card->addr + W_D_RFIFO, ptr, count); + WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK); + if (debug & DEBUG_HW_DFIFO) { + snprintf(card->log, 63, "D-recv %s %d ", + card->name, count); + print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count); + } +} + +static void +W6692_fill_Dfifo(struct w6692_hw *card) +{ + struct dchannel *dch = &card->dch; + int count; + u8 *ptr; + u8 cmd = W_D_CMDR_XMS; + + pr_debug("%s: fill_Dfifo\n", card->name); + if (!dch->tx_skb) + return; + count = dch->tx_skb->len - dch->tx_idx; + if (count <= 0) + return; + if (count > W_D_FIFO_THRESH) + count = W_D_FIFO_THRESH; + else + cmd |= W_D_CMDR_XME; + ptr = dch->tx_skb->data + dch->tx_idx; + dch->tx_idx += count; + outsb(card->addr + W_D_XFIFO, ptr, count); + WriteW6692(card, W_D_CMDR, cmd); + if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) { + pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name); + del_timer(&dch->timer); + } + init_timer(&dch->timer); + dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000); + add_timer(&dch->timer); + if (debug & DEBUG_HW_DFIFO) { + snprintf(card->log, 63, "D-send %s %d ", + card->name, count); + print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count); + } +} + +static void +d_retransmit(struct w6692_hw *card) +{ + struct dchannel *dch = &card->dch; + + if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) + del_timer(&dch->timer); +#ifdef FIXME + if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) + dchannel_sched_event(dch, D_CLEARBUSY); +#endif + if (test_bit(FLG_TX_BUSY, &dch->Flags)) { + /* Restart frame */ + dch->tx_idx = 0; + W6692_fill_Dfifo(card); + } else if (dch->tx_skb) { /* should not happen */ + pr_info("%s: %s without TX_BUSY\n", card->name, __func__); + test_and_set_bit(FLG_TX_BUSY, &dch->Flags); + dch->tx_idx = 0; + W6692_fill_Dfifo(card); + } else { + pr_info("%s: XDU no TX_BUSY\n", card->name); + if (get_next_dframe(dch)) + W6692_fill_Dfifo(card); + } +} + +static void +handle_rxD(struct w6692_hw *card) { + u8 stat; + int count; + + stat = ReadW6692(card, W_D_RSTA); + if (stat & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) { + if (stat & W_D_RSTA_RDOV) { + pr_debug("%s: D-channel RDOV\n", card->name); +#ifdef ERROR_STATISTIC + card->dch.err_rx++; +#endif + } + if (stat & W_D_RSTA_CRCE) { + pr_debug("%s: D-channel CRC error\n", card->name); +#ifdef ERROR_STATISTIC + card->dch.err_crc++; +#endif + } + if (stat & W_D_RSTA_RMB) { + pr_debug("%s: D-channel ABORT\n", card->name); +#ifdef ERROR_STATISTIC + card->dch.err_rx++; +#endif + } + if (card->dch.rx_skb) + dev_kfree_skb(card->dch.rx_skb); + card->dch.rx_skb = NULL; + WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST); + } else { + count = ReadW6692(card, W_D_RBCL) & (W_D_FIFO_THRESH - 1); + if (count == 0) + count = W_D_FIFO_THRESH; + W6692_empty_Dfifo(card, count); + recv_Dchannel(&card->dch); + } +} + +static void +handle_txD(struct w6692_hw *card) { + if (test_and_clear_bit(FLG_BUSY_TIMER, &card->dch.Flags)) + del_timer(&card->dch.timer); + if (card->dch.tx_skb && card->dch.tx_idx < card->dch.tx_skb->len) { + W6692_fill_Dfifo(card); + } else { + if (card->dch.tx_skb) + dev_kfree_skb(card->dch.tx_skb); + if (get_next_dframe(&card->dch)) + W6692_fill_Dfifo(card); + } +} + +static void +handle_statusD(struct w6692_hw *card) +{ + struct dchannel *dch = &card->dch; + u8 exval, v1, cir; + + exval = ReadW6692(card, W_D_EXIR); + + pr_debug("%s: D_EXIR %02x\n", card->name, exval); + if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) { + /* Transmit underrun/collision */ + pr_debug("%s: D-channel underrun/collision\n", card->name); +#ifdef ERROR_STATISTIC + dch->err_tx++; +#endif + d_retransmit(card); + } + if (exval & W_D_EXI_RDOV) { /* RDOV */ + pr_debug("%s: D-channel RDOV\n", card->name); + WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST); + } + if (exval & W_D_EXI_TIN2) /* TIN2 - never */ + pr_debug("%s: spurious TIN2 interrupt\n", card->name); + if (exval & W_D_EXI_MOC) { /* MOC - not supported */ + v1 = ReadW6692(card, W_MOSR); + pr_debug("%s: spurious MOC interrupt MOSR %02x\n", + card->name, v1); + } + if (exval & W_D_EXI_ISC) { /* ISC - Level1 change */ + cir = ReadW6692(card, W_CIR); + pr_debug("%s: ISC CIR %02X\n", card->name, cir); + if (cir & W_CIR_ICC) { + v1 = cir & W_CIR_COD_MASK; + pr_debug("%s: ph_state_change %x -> %x\n", card->name, + dch->state, v1); + card->state = v1; + if (card->fmask & led) { + switch (v1) { + case W_L1IND_AI8: + case W_L1IND_AI10: + w6692_led_handler(card, 1); + break; + default: + w6692_led_handler(card, 0); + break; + } + } + W6692_new_ph(card); + } + if (cir & W_CIR_SCC) { + v1 = ReadW6692(card, W_SQR); + pr_debug("%s: SCC SQR %02X\n", card->name, v1); + } + } + if (exval & W_D_EXI_WEXP) + pr_debug("%s: spurious WEXP interrupt!\n", card->name); + if (exval & W_D_EXI_TEXP) + pr_debug("%s: spurious TEXP interrupt!\n", card->name); +} + +static void +W6692_empty_Bfifo(struct w6692_ch *wch, int count) +{ + struct w6692_hw *card = wch->bch.hw; + u8 *ptr; + int maxlen; + + pr_debug("%s: empty_Bfifo %d\n", card->name, count); + if (unlikely(wch->bch.state == ISDN_P_NONE)) { + pr_debug("%s: empty_Bfifo ISDN_P_NONE\n", card->name); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); + if (wch->bch.rx_skb) + skb_trim(wch->bch.rx_skb, 0); + return; + } + if (test_bit(FLG_RX_OFF, &wch->bch.Flags)) { + wch->bch.dropcnt += count; + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); + return; + } + maxlen = bchannel_get_rxbuf(&wch->bch, count); + if (maxlen < 0) { + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); + if (wch->bch.rx_skb) + skb_trim(wch->bch.rx_skb, 0); + pr_warning("%s.B%d: No bufferspace for %d bytes\n", + card->name, wch->bch.nr, count); + return; + } + ptr = skb_put(wch->bch.rx_skb, count); + insb(wch->addr + W_B_RFIFO, ptr, count); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); + if (debug & DEBUG_HW_DFIFO) { + snprintf(card->log, 63, "B%1d-recv %s %d ", + wch->bch.nr, card->name, count); + print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count); + } +} + +static void +W6692_fill_Bfifo(struct w6692_ch *wch) +{ + struct w6692_hw *card = wch->bch.hw; + int count, fillempty = 0; + u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS; + + pr_debug("%s: fill Bfifo\n", card->name); + if (!wch->bch.tx_skb) { + if (!test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) + return; + ptr = wch->bch.fill; + count = W_B_FIFO_THRESH; + fillempty = 1; + } else { + count = wch->bch.tx_skb->len - wch->bch.tx_idx; + if (count <= 0) + return; + ptr = wch->bch.tx_skb->data + wch->bch.tx_idx; + } + if (count > W_B_FIFO_THRESH) + count = W_B_FIFO_THRESH; + else if (test_bit(FLG_HDLC, &wch->bch.Flags)) + cmd |= W_B_CMDR_XME; + + pr_debug("%s: fill Bfifo%d/%d\n", card->name, + count, wch->bch.tx_idx); + wch->bch.tx_idx += count; + if (fillempty) { + while (count > 0) { + outsb(wch->addr + W_B_XFIFO, ptr, MISDN_BCH_FILL_SIZE); + count -= MISDN_BCH_FILL_SIZE; + } + } else { + outsb(wch->addr + W_B_XFIFO, ptr, count); + } + WriteW6692B(wch, W_B_CMDR, cmd); + if ((debug & DEBUG_HW_BFIFO) && !fillempty) { + snprintf(card->log, 63, "B%1d-send %s %d ", + wch->bch.nr, card->name, count); + print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count); + } +} + +#if 0 +static int +setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb) +{ + struct w6692_hw *card = wch->bch.hw; + u16 *vol = (u16 *)skb->data; + u8 val; + + if ((!(card->fmask & pots)) || + !test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) + return -ENODEV; + if (skb->len < 2) + return -EINVAL; + if (*vol > 7) + return -EINVAL; + val = *vol & 7; + val = 7 - val; + if (mic) { + val <<= 3; + card->xaddr &= 0xc7; + } else { + card->xaddr &= 0xf8; + } + card->xaddr |= val; + WriteW6692(card, W_XADDR, card->xaddr); + return 0; +} + +static int +enable_pots(struct w6692_ch *wch) +{ + struct w6692_hw *card = wch->bch.hw; + + if ((!(card->fmask & pots)) || + !test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) + return -ENODEV; + wch->b_mode |= W_B_MODE_EPCM | W_B_MODE_BSW0; + WriteW6692B(wch, W_B_MODE, wch->b_mode); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); + card->pctl |= ((wch->bch.nr & 2) ? W_PCTL_PCX : 0); + WriteW6692(card, W_PCTL, card->pctl); + return 0; +} +#endif + +static int +disable_pots(struct w6692_ch *wch) +{ + struct w6692_hw *card = wch->bch.hw; + + if (!(card->fmask & pots)) + return -ENODEV; + wch->b_mode &= ~(W_B_MODE_EPCM | W_B_MODE_BSW0); + WriteW6692B(wch, W_B_MODE, wch->b_mode); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT | + W_B_CMDR_XRST); + return 0; +} + +static int +w6692_mode(struct w6692_ch *wch, u32 pr) +{ + struct w6692_hw *card; + + card = wch->bch.hw; + pr_debug("%s: B%d protocol %x-->%x\n", card->name, + wch->bch.nr, wch->bch.state, pr); + switch (pr) { + case ISDN_P_NONE: + if ((card->fmask & pots) && (wch->b_mode & W_B_MODE_EPCM)) + disable_pots(wch); + wch->b_mode = 0; + mISDN_clear_bchannel(&wch->bch); + WriteW6692B(wch, W_B_MODE, wch->b_mode); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); + test_and_clear_bit(FLG_HDLC, &wch->bch.Flags); + test_and_clear_bit(FLG_TRANSPARENT, &wch->bch.Flags); + break; + case ISDN_P_B_RAW: + wch->b_mode = W_B_MODE_MMS; + WriteW6692B(wch, W_B_MODE, wch->b_mode); + WriteW6692B(wch, W_B_EXIM, 0); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT | + W_B_CMDR_XRST); + test_and_set_bit(FLG_TRANSPARENT, &wch->bch.Flags); + break; + case ISDN_P_B_HDLC: + wch->b_mode = W_B_MODE_ITF; + WriteW6692B(wch, W_B_MODE, wch->b_mode); + WriteW6692B(wch, W_B_ADM1, 0xff); + WriteW6692B(wch, W_B_ADM2, 0xff); + WriteW6692B(wch, W_B_EXIM, 0); + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT | + W_B_CMDR_XRST); + test_and_set_bit(FLG_HDLC, &wch->bch.Flags); + break; + default: + pr_info("%s: protocol %x not known\n", card->name, pr); + return -ENOPROTOOPT; + } + wch->bch.state = pr; + return 0; +} + +static void +send_next(struct w6692_ch *wch) +{ + if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len) { + W6692_fill_Bfifo(wch); + } else { + if (wch->bch.tx_skb) + dev_kfree_skb(wch->bch.tx_skb); + if (get_next_bframe(&wch->bch)) { + W6692_fill_Bfifo(wch); + test_and_clear_bit(FLG_TX_EMPTY, &wch->bch.Flags); + } else if (test_bit(FLG_TX_EMPTY, &wch->bch.Flags)) { + W6692_fill_Bfifo(wch); + } + } +} + +static void +W6692B_interrupt(struct w6692_hw *card, int ch) +{ + struct w6692_ch *wch = &card->bc[ch]; + int count; + u8 stat, star = 0; + + stat = ReadW6692B(wch, W_B_EXIR); + pr_debug("%s: B%d EXIR %02x\n", card->name, wch->bch.nr, stat); + if (stat & W_B_EXI_RME) { + star = ReadW6692B(wch, W_B_STAR); + if (star & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) { + if ((star & W_B_STAR_RDOV) && + test_bit(FLG_ACTIVE, &wch->bch.Flags)) { + pr_debug("%s: B%d RDOV proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); +#ifdef ERROR_STATISTIC + wch->bch.err_rdo++; +#endif + } + if (test_bit(FLG_HDLC, &wch->bch.Flags)) { + if (star & W_B_STAR_CRCE) { + pr_debug("%s: B%d CRC error\n", + card->name, wch->bch.nr); +#ifdef ERROR_STATISTIC + wch->bch.err_crc++; +#endif + } + if (star & W_B_STAR_RMB) { + pr_debug("%s: B%d message abort\n", + card->name, wch->bch.nr); +#ifdef ERROR_STATISTIC + wch->bch.err_inv++; +#endif + } + } + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | + W_B_CMDR_RRST | W_B_CMDR_RACT); + if (wch->bch.rx_skb) + skb_trim(wch->bch.rx_skb, 0); + } else { + count = ReadW6692B(wch, W_B_RBCL) & + (W_B_FIFO_THRESH - 1); + if (count == 0) + count = W_B_FIFO_THRESH; + W6692_empty_Bfifo(wch, count); + recv_Bchannel(&wch->bch, 0, false); + } + } + if (stat & W_B_EXI_RMR) { + if (!(stat & W_B_EXI_RME)) + star = ReadW6692B(wch, W_B_STAR); + if (star & W_B_STAR_RDOV) { + pr_debug("%s: B%d RDOV proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); +#ifdef ERROR_STATISTIC + wch->bch.err_rdo++; +#endif + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | + W_B_CMDR_RRST | W_B_CMDR_RACT); + } else { + W6692_empty_Bfifo(wch, W_B_FIFO_THRESH); + if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) + recv_Bchannel(&wch->bch, 0, false); + } + } + if (stat & W_B_EXI_RDOV) { + /* only if it is not handled yet */ + if (!(star & W_B_STAR_RDOV)) { + pr_debug("%s: B%d RDOV IRQ proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); +#ifdef ERROR_STATISTIC + wch->bch.err_rdo++; +#endif + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | + W_B_CMDR_RRST | W_B_CMDR_RACT); + } + } + if (stat & W_B_EXI_XFR) { + if (!(stat & (W_B_EXI_RME | W_B_EXI_RMR))) { + star = ReadW6692B(wch, W_B_STAR); + pr_debug("%s: B%d star %02x\n", card->name, + wch->bch.nr, star); + } + if (star & W_B_STAR_XDOW) { + pr_warning("%s: B%d XDOW proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); +#ifdef ERROR_STATISTIC + wch->bch.err_xdu++; +#endif + WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST | + W_B_CMDR_RACT); + /* resend */ + if (wch->bch.tx_skb) { + if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) + wch->bch.tx_idx = 0; + } + } + send_next(wch); + if (star & W_B_STAR_XDOW) + return; /* handle XDOW only once */ + } + if (stat & W_B_EXI_XDUN) { + pr_warning("%s: B%d XDUN proto=%x\n", card->name, + wch->bch.nr, wch->bch.state); +#ifdef ERROR_STATISTIC + wch->bch.err_xdu++; +#endif + /* resend - no XRST needed */ + if (wch->bch.tx_skb) { + if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags)) + wch->bch.tx_idx = 0; + } else if (test_bit(FLG_FILLEMPTY, &wch->bch.Flags)) { + test_and_set_bit(FLG_TX_EMPTY, &wch->bch.Flags); + } + send_next(wch); + } +} + +static irqreturn_t +w6692_irq(int intno, void *dev_id) +{ + struct w6692_hw *card = dev_id; + u8 ista; + + spin_lock(&card->lock); + ista = ReadW6692(card, W_ISTA); + if ((ista | card->imask) == card->imask) { + /* possible a shared IRQ reqest */ + spin_unlock(&card->lock); + return IRQ_NONE; + } + card->irqcnt++; + pr_debug("%s: ista %02x\n", card->name, ista); + ista &= ~card->imask; + if (ista & W_INT_B1_EXI) + W6692B_interrupt(card, 0); + if (ista & W_INT_B2_EXI) + W6692B_interrupt(card, 1); + if (ista & W_INT_D_RME) + handle_rxD(card); + if (ista & W_INT_D_RMR) + W6692_empty_Dfifo(card, W_D_FIFO_THRESH); + if (ista & W_INT_D_XFR) + handle_txD(card); + if (ista & W_INT_D_EXI) + handle_statusD(card); + if (ista & (W_INT_XINT0 | W_INT_XINT1)) /* XINT0/1 - never */ + pr_debug("%s: W6692 spurious XINT!\n", card->name); +/* End IRQ Handler */ + spin_unlock(&card->lock); + return IRQ_HANDLED; +} + +static void +dbusy_timer_handler(struct dchannel *dch) +{ + struct w6692_hw *card = dch->hw; + int rbch, star; + u_long flags; + + if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) { + spin_lock_irqsave(&card->lock, flags); + rbch = ReadW6692(card, W_D_RBCH); + star = ReadW6692(card, W_D_STAR); + pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n", + card->name, rbch, star); + if (star & W_D_STAR_XBZ) /* D-Channel Busy */ + test_and_set_bit(FLG_L1_BUSY, &dch->Flags); + else { + /* discard frame; reset transceiver */ + test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags); + if (dch->tx_idx) + dch->tx_idx = 0; + else + pr_info("%s: W6692 D-Channel Busy no tx_idx\n", + card->name); + /* Transmitter reset */ + WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST); + } + spin_unlock_irqrestore(&card->lock, flags); + } +} + +void initW6692(struct w6692_hw *card) +{ + u8 val; + + card->dch.timer.function = (void *)dbusy_timer_handler; + card->dch.timer.data = (u_long)&card->dch; + init_timer(&card->dch.timer); + w6692_mode(&card->bc[0], ISDN_P_NONE); + w6692_mode(&card->bc[1], ISDN_P_NONE); + WriteW6692(card, W_D_CTL, 0x00); + disable_hwirq(card); + WriteW6692(card, W_D_SAM, 0xff); + WriteW6692(card, W_D_TAM, 0xff); + WriteW6692(card, W_D_MODE, W_D_MODE_RACT); + card->state = W_L1CMD_RST; + ph_command(card, W_L1CMD_RST); + ph_command(card, W_L1CMD_ECK); + /* enable all IRQ but extern */ + card->imask = 0x18; + WriteW6692(card, W_D_EXIM, 0x00); + WriteW6692B(&card->bc[0], W_B_EXIM, 0); + WriteW6692B(&card->bc[1], W_B_EXIM, 0); + /* Reset D-chan receiver and transmitter */ + WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST); + /* Reset B-chan receiver and transmitter */ + WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); + WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST); + /* enable peripheral */ + if (card->subtype == W6692_USR) { + /* seems that USR implemented some power control features + * Pin 79 is connected to the oscilator circuit so we + * have to handle it here + */ + card->pctl = 0x80; + card->xdata = 0; + WriteW6692(card, W_PCTL, card->pctl); + WriteW6692(card, W_XDATA, card->xdata); + } else { + card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 | + W_PCTL_OE1 | W_PCTL_OE0; + card->xaddr = 0x00;/* all sw off */ + if (card->fmask & pots) + card->xdata |= 0x06; /* POWER UP/ LED OFF / ALAW */ + if (card->fmask & led) + card->xdata |= 0x04; /* LED OFF */ + if ((card->fmask & pots) || (card->fmask & led)) { + WriteW6692(card, W_PCTL, card->pctl); + WriteW6692(card, W_XADDR, card->xaddr); + WriteW6692(card, W_XDATA, card->xdata); + val = ReadW6692(card, W_XADDR); + if (debug & DEBUG_HW) + pr_notice("%s: W_XADDR=%02x\n", + card->name, val); + } + } +} + +static void +reset_w6692(struct w6692_hw *card) +{ + WriteW6692(card, W_D_CTL, W_D_CTL_SRST); + mdelay(10); + WriteW6692(card, W_D_CTL, 0); +} + +static int +init_card(struct w6692_hw *card) +{ + int cnt = 3; + u_long flags; + + spin_lock_irqsave(&card->lock, flags); + disable_hwirq(card); + spin_unlock_irqrestore(&card->lock, flags); + if (request_irq(card->irq, w6692_irq, IRQF_SHARED, card->name, card)) { + pr_info("%s: couldn't get interrupt %d\n", card->name, + card->irq); + return -EIO; + } + while (cnt--) { + spin_lock_irqsave(&card->lock, flags); + initW6692(card); + enable_hwirq(card); + spin_unlock_irqrestore(&card->lock, flags); + /* Timeout 10ms */ + msleep_interruptible(10); + if (debug & DEBUG_HW) + pr_notice("%s: IRQ %d count %d\n", card->name, + card->irq, card->irqcnt); + if (!card->irqcnt) { + pr_info("%s: IRQ(%d) getting no IRQs during init %d\n", + card->name, card->irq, 3 - cnt); + reset_w6692(card); + } else + return 0; + } + free_irq(card->irq, card); + return -EIO; +} + +static int +w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch); + struct w6692_hw *card = bch->hw; + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + unsigned long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(&card->lock, flags); + ret = bchannel_senddata(bch, skb); + if (ret > 0) { /* direct TX */ + ret = 0; + W6692_fill_Bfifo(bc); + } + spin_unlock_irqrestore(&card->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + spin_lock_irqsave(&card->lock, flags); + if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) + ret = w6692_mode(bc, ch->protocol); + else + ret = 0; + spin_unlock_irqrestore(&card->lock, flags); + if (!ret) + _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + break; + case PH_DEACTIVATE_REQ: + spin_lock_irqsave(&card->lock, flags); + mISDN_clear_bchannel(bch); + w6692_mode(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, + NULL, GFP_KERNEL); + ret = 0; + break; + default: + pr_info("%s: %s unknown prim(%x,%x)\n", + card->name, __func__, hh->prim, hh->id); + ret = -EINVAL; + } + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static int +channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) +{ + return mISDN_ctrl_bchannel(bch, cq); +} + +static int +open_bchannel(struct w6692_hw *card, struct channel_req *rq) +{ + struct bchannel *bch; + + if (rq->adr.channel == 0 || rq->adr.channel > 2) + return -EINVAL; + if (rq->protocol == ISDN_P_NONE) + return -EINVAL; + bch = &card->bc[rq->adr.channel - 1].bch; + if (test_and_set_bit(FLG_OPEN, &bch->Flags)) + return -EBUSY; /* b-channel can be only open once */ + bch->ch.protocol = rq->protocol; + rq->ch = &bch->ch; + return 0; +} + +static int +channel_ctrl(struct w6692_hw *card, struct mISDN_ctrl_req *cq) +{ + int ret = 0; + + switch (cq->op) { + case MISDN_CTRL_GETOP: + cq->op = MISDN_CTRL_L1_TIMER3; + break; + case MISDN_CTRL_L1_TIMER3: + ret = l1_event(card->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff)); + break; + default: + pr_info("%s: unknown CTRL OP %x\n", card->name, cq->op); + ret = -EINVAL; + break; + } + return ret; +} + +static int +w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct bchannel *bch = container_of(ch, struct bchannel, ch); + struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch); + struct w6692_hw *card = bch->hw; + int ret = -EINVAL; + u_long flags; + + pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg); + switch (cmd) { + case CLOSE_CHANNEL: + test_and_clear_bit(FLG_OPEN, &bch->Flags); + cancel_work_sync(&bch->workq); + spin_lock_irqsave(&card->lock, flags); + mISDN_clear_bchannel(bch); + w6692_mode(bc, ISDN_P_NONE); + spin_unlock_irqrestore(&card->lock, flags); + ch->protocol = ISDN_P_NONE; + ch->peer = NULL; + module_put(THIS_MODULE); + ret = 0; + break; + case CONTROL_CHANNEL: + ret = channel_bctrl(bch, arg); + break; + default: + pr_info("%s: %s unknown prim(%x)\n", + card->name, __func__, cmd); + } + return ret; +} + +static int +w6692_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct w6692_hw *card = container_of(dch, struct w6692_hw, dch); + int ret = -EINVAL; + struct mISDNhead *hh = mISDN_HEAD_P(skb); + u32 id; + u_long flags; + + switch (hh->prim) { + case PH_DATA_REQ: + spin_lock_irqsave(&card->lock, flags); + ret = dchannel_senddata(dch, skb); + if (ret > 0) { /* direct TX */ + id = hh->id; /* skb can be freed */ + W6692_fill_Dfifo(card); + ret = 0; + spin_unlock_irqrestore(&card->lock, flags); + queue_ch_frame(ch, PH_DATA_CNF, id, NULL); + } else + spin_unlock_irqrestore(&card->lock, flags); + return ret; + case PH_ACTIVATE_REQ: + ret = l1_event(dch->l1, hh->prim); + break; + case PH_DEACTIVATE_REQ: + test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); + ret = l1_event(dch->l1, hh->prim); + break; + } + + if (!ret) + dev_kfree_skb(skb); + return ret; +} + +static int +w6692_l1callback(struct dchannel *dch, u32 cmd) +{ + struct w6692_hw *card = container_of(dch, struct w6692_hw, dch); + u_long flags; + + pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state); + switch (cmd) { + case INFO3_P8: + spin_lock_irqsave(&card->lock, flags); + ph_command(card, W_L1CMD_AR8); + spin_unlock_irqrestore(&card->lock, flags); + break; + case INFO3_P10: + spin_lock_irqsave(&card->lock, flags); + ph_command(card, W_L1CMD_AR10); + spin_unlock_irqrestore(&card->lock, flags); + break; + case HW_RESET_REQ: + spin_lock_irqsave(&card->lock, flags); + if (card->state != W_L1IND_DRD) + ph_command(card, W_L1CMD_RST); + ph_command(card, W_L1CMD_ECK); + spin_unlock_irqrestore(&card->lock, flags); + break; + case HW_DEACT_REQ: + skb_queue_purge(&dch->squeue); + if (dch->tx_skb) { + dev_kfree_skb(dch->tx_skb); + dch->tx_skb = NULL; + } + dch->tx_idx = 0; + if (dch->rx_skb) { + dev_kfree_skb(dch->rx_skb); + dch->rx_skb = NULL; + } + test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); + if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) + del_timer(&dch->timer); + break; + case HW_POWERUP_REQ: + spin_lock_irqsave(&card->lock, flags); + ph_command(card, W_L1CMD_ECK); + spin_unlock_irqrestore(&card->lock, flags); + break; + case PH_ACTIVATE_IND: + test_and_set_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + case PH_DEACTIVATE_IND: + test_and_clear_bit(FLG_ACTIVE, &dch->Flags); + _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, + GFP_ATOMIC); + break; + default: + pr_debug("%s: %s unknown command %x\n", card->name, + __func__, cmd); + return -1; + } + return 0; +} + +static int +open_dchannel(struct w6692_hw *card, struct channel_req *rq) +{ + pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__, + card->dch.dev.id, __builtin_return_address(1)); + if (rq->protocol != ISDN_P_TE_S0) + return -EINVAL; + if (rq->adr.channel == 1) + /* E-Channel not supported */ + return -EINVAL; + rq->ch = &card->dch.dev.D; + rq->ch->protocol = rq->protocol; + if (card->dch.state == 7) + _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY, + 0, NULL, GFP_KERNEL); + return 0; +} + +static int +w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg) +{ + struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); + struct dchannel *dch = container_of(dev, struct dchannel, dev); + struct w6692_hw *card = container_of(dch, struct w6692_hw, dch); + struct channel_req *rq; + int err = 0; + + pr_debug("%s: DCTRL: %x %p\n", card->name, cmd, arg); + switch (cmd) { + case OPEN_CHANNEL: + rq = arg; + if (rq->protocol == ISDN_P_TE_S0) + err = open_dchannel(card, rq); + else + err = open_bchannel(card, rq); + if (err) + break; + if (!try_module_get(THIS_MODULE)) + pr_info("%s: cannot get module\n", card->name); + break; + case CLOSE_CHANNEL: + pr_debug("%s: dev(%d) close from %p\n", card->name, + dch->dev.id, __builtin_return_address(0)); + module_put(THIS_MODULE); + break; + case CONTROL_CHANNEL: + err = channel_ctrl(card, arg); + break; + default: + pr_debug("%s: unknown DCTRL command %x\n", card->name, cmd); + return -EINVAL; + } + return err; +} + +static int +setup_w6692(struct w6692_hw *card) +{ + u32 val; + + if (!request_region(card->addr, 256, card->name)) { + pr_info("%s: config port %x-%x already in use\n", card->name, + card->addr, card->addr + 255); + return -EIO; + } + W6692Version(card); + card->bc[0].addr = card->addr; + card->bc[1].addr = card->addr + 0x40; + val = ReadW6692(card, W_ISTA); + if (debug & DEBUG_HW) + pr_notice("%s ISTA=%02x\n", card->name, val); + val = ReadW6692(card, W_IMASK); + if (debug & DEBUG_HW) + pr_notice("%s IMASK=%02x\n", card->name, val); + val = ReadW6692(card, W_D_EXIR); + if (debug & DEBUG_HW) + pr_notice("%s D_EXIR=%02x\n", card->name, val); + val = ReadW6692(card, W_D_EXIM); + if (debug & DEBUG_HW) + pr_notice("%s D_EXIM=%02x\n", card->name, val); + val = ReadW6692(card, W_D_RSTA); + if (debug & DEBUG_HW) + pr_notice("%s D_RSTA=%02x\n", card->name, val); + return 0; +} + +static void +release_card(struct w6692_hw *card) +{ + u_long flags; + + spin_lock_irqsave(&card->lock, flags); + disable_hwirq(card); + w6692_mode(&card->bc[0], ISDN_P_NONE); + w6692_mode(&card->bc[1], ISDN_P_NONE); + if ((card->fmask & led) || card->subtype == W6692_USR) { + card->xdata |= 0x04; /* LED OFF */ + WriteW6692(card, W_XDATA, card->xdata); + } + spin_unlock_irqrestore(&card->lock, flags); + free_irq(card->irq, card); + l1_event(card->dch.l1, CLOSE_CHANNEL); + mISDN_unregister_device(&card->dch.dev); + release_region(card->addr, 256); + mISDN_freebchannel(&card->bc[1].bch); + mISDN_freebchannel(&card->bc[0].bch); + mISDN_freedchannel(&card->dch); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + pci_disable_device(card->pdev); + pci_set_drvdata(card->pdev, NULL); + kfree(card); +} + +static int +setup_instance(struct w6692_hw *card) +{ + int i, err; + u_long flags; + + snprintf(card->name, MISDN_MAX_IDLEN - 1, "w6692.%d", w6692_cnt + 1); + write_lock_irqsave(&card_lock, flags); + list_add_tail(&card->list, &Cards); + write_unlock_irqrestore(&card_lock, flags); + card->fmask = (1 << w6692_cnt); + _set_debug(card); + spin_lock_init(&card->lock); + mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, W6692_ph_bh); + card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0); + card->dch.dev.D.send = w6692_l2l1D; + card->dch.dev.D.ctrl = w6692_dctrl; + card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | + (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); + card->dch.hw = card; + card->dch.dev.nrbchan = 2; + for (i = 0; i < 2; i++) { + mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM, + W_B_FIFO_THRESH); + card->bc[i].bch.hw = card; + card->bc[i].bch.nr = i + 1; + card->bc[i].bch.ch.nr = i + 1; + card->bc[i].bch.ch.send = w6692_l2l1B; + card->bc[i].bch.ch.ctrl = w6692_bctrl; + set_channelmap(i + 1, card->dch.dev.channelmap); + list_add(&card->bc[i].bch.ch.list, &card->dch.dev.bchannels); + } + err = setup_w6692(card); + if (err) + goto error_setup; + err = mISDN_register_device(&card->dch.dev, &card->pdev->dev, + card->name); + if (err) + goto error_reg; + err = init_card(card); + if (err) + goto error_init; + err = create_l1(&card->dch, w6692_l1callback); + if (!err) { + w6692_cnt++; + pr_notice("W6692 %d cards installed\n", w6692_cnt); + return 0; + } + + free_irq(card->irq, card); +error_init: + mISDN_unregister_device(&card->dch.dev); +error_reg: + release_region(card->addr, 256); +error_setup: + mISDN_freebchannel(&card->bc[1].bch); + mISDN_freebchannel(&card->bc[0].bch); + mISDN_freedchannel(&card->dch); + write_lock_irqsave(&card_lock, flags); + list_del(&card->list); + write_unlock_irqrestore(&card_lock, flags); + kfree(card); + return err; +} + +static int +w6692_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = -ENOMEM; + struct w6692_hw *card; + struct w6692map *m = (struct w6692map *)ent->driver_data; + + card = kzalloc(sizeof(struct w6692_hw), GFP_KERNEL); + if (!card) { + pr_info("No kmem for w6692 card\n"); + return err; + } + card->pdev = pdev; + card->subtype = m->subtype; + err = pci_enable_device(pdev); + if (err) { + kfree(card); + return err; + } + + printk(KERN_INFO "mISDN_w6692: found adapter %s at %s\n", + m->name, pci_name(pdev)); + + card->addr = pci_resource_start(pdev, 1); + card->irq = pdev->irq; + pci_set_drvdata(pdev, card); + err = setup_instance(card); + if (err) + pci_set_drvdata(pdev, NULL); + return err; +} + +static void +w6692_remove_pci(struct pci_dev *pdev) +{ + struct w6692_hw *card = pci_get_drvdata(pdev); + + if (card) + release_card(card); + else + if (debug) + pr_notice("%s: drvdata already removed\n", __func__); +} + +static struct pci_device_id w6692_ids[] = { + { PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[0]}, + { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, + PCI_VENDOR_ID_USR, PCI_DEVICE_ID_USR_6692, 0, 0, + (ulong)&w6692_map[2]}, + { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[1]}, + { } +}; +MODULE_DEVICE_TABLE(pci, w6692_ids); + +static struct pci_driver w6692_driver = { + .name = "w6692", + .probe = w6692_probe, + .remove = w6692_remove_pci, + .id_table = w6692_ids, +}; + +static int __init w6692_init(void) +{ + int err; + + pr_notice("Winbond W6692 PCI driver Rev. %s\n", W6692_REV); + + err = pci_register_driver(&w6692_driver); + return err; +} + +static void __exit w6692_cleanup(void) +{ + pci_unregister_driver(&w6692_driver); +} + +module_init(w6692_init); +module_exit(w6692_cleanup); diff --git a/drivers/isdn/hardware/mISDN/w6692.h b/drivers/isdn/hardware/mISDN/w6692.h new file mode 100644 index 00000000000..f95697757fd --- /dev/null +++ b/drivers/isdn/hardware/mISDN/w6692.h @@ -0,0 +1,190 @@ +/* + * Winbond W6692 specific defines + * + * Author Karsten Keil <keil@isdn4linux.de> + * based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz> + * + * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* Specifications of W6692 registers */ + +#define W_D_RFIFO 0x00 /* R */ +#define W_D_XFIFO 0x04 /* W */ +#define W_D_CMDR 0x08 /* W */ +#define W_D_MODE 0x0c /* R/W */ +#define W_D_TIMR 0x10 /* R/W */ +#define W_ISTA 0x14 /* R_clr */ +#define W_IMASK 0x18 /* R/W */ +#define W_D_EXIR 0x1c /* R_clr */ +#define W_D_EXIM 0x20 /* R/W */ +#define W_D_STAR 0x24 /* R */ +#define W_D_RSTA 0x28 /* R */ +#define W_D_SAM 0x2c /* R/W */ +#define W_D_SAP1 0x30 /* R/W */ +#define W_D_SAP2 0x34 /* R/W */ +#define W_D_TAM 0x38 /* R/W */ +#define W_D_TEI1 0x3c /* R/W */ +#define W_D_TEI2 0x40 /* R/W */ +#define W_D_RBCH 0x44 /* R */ +#define W_D_RBCL 0x48 /* R */ +#define W_TIMR2 0x4c /* W */ +#define W_L1_RC 0x50 /* R/W */ +#define W_D_CTL 0x54 /* R/W */ +#define W_CIR 0x58 /* R */ +#define W_CIX 0x5c /* W */ +#define W_SQR 0x60 /* R */ +#define W_SQX 0x64 /* W */ +#define W_PCTL 0x68 /* R/W */ +#define W_MOR 0x6c /* R */ +#define W_MOX 0x70 /* R/W */ +#define W_MOSR 0x74 /* R_clr */ +#define W_MOCR 0x78 /* R/W */ +#define W_GCR 0x7c /* R/W */ + +#define W_B_RFIFO 0x80 /* R */ +#define W_B_XFIFO 0x84 /* W */ +#define W_B_CMDR 0x88 /* W */ +#define W_B_MODE 0x8c /* R/W */ +#define W_B_EXIR 0x90 /* R_clr */ +#define W_B_EXIM 0x94 /* R/W */ +#define W_B_STAR 0x98 /* R */ +#define W_B_ADM1 0x9c /* R/W */ +#define W_B_ADM2 0xa0 /* R/W */ +#define W_B_ADR1 0xa4 /* R/W */ +#define W_B_ADR2 0xa8 /* R/W */ +#define W_B_RBCL 0xac /* R */ +#define W_B_RBCH 0xb0 /* R */ + +#define W_XADDR 0xf4 /* R/W */ +#define W_XDATA 0xf8 /* R/W */ +#define W_EPCTL 0xfc /* W */ + +/* W6692 register bits */ + +#define W_D_CMDR_XRST 0x01 +#define W_D_CMDR_XME 0x02 +#define W_D_CMDR_XMS 0x08 +#define W_D_CMDR_STT 0x10 +#define W_D_CMDR_RRST 0x40 +#define W_D_CMDR_RACK 0x80 + +#define W_D_MODE_RLP 0x01 +#define W_D_MODE_DLP 0x02 +#define W_D_MODE_MFD 0x04 +#define W_D_MODE_TEE 0x08 +#define W_D_MODE_TMS 0x10 +#define W_D_MODE_RACT 0x40 +#define W_D_MODE_MMS 0x80 + +#define W_INT_B2_EXI 0x01 +#define W_INT_B1_EXI 0x02 +#define W_INT_D_EXI 0x04 +#define W_INT_XINT0 0x08 +#define W_INT_XINT1 0x10 +#define W_INT_D_XFR 0x20 +#define W_INT_D_RME 0x40 +#define W_INT_D_RMR 0x80 + +#define W_D_EXI_WEXP 0x01 +#define W_D_EXI_TEXP 0x02 +#define W_D_EXI_ISC 0x04 +#define W_D_EXI_MOC 0x08 +#define W_D_EXI_TIN2 0x10 +#define W_D_EXI_XCOL 0x20 +#define W_D_EXI_XDUN 0x40 +#define W_D_EXI_RDOV 0x80 + +#define W_D_STAR_DRDY 0x10 +#define W_D_STAR_XBZ 0x20 +#define W_D_STAR_XDOW 0x80 + +#define W_D_RSTA_RMB 0x10 +#define W_D_RSTA_CRCE 0x20 +#define W_D_RSTA_RDOV 0x40 + +#define W_D_CTL_SRST 0x20 + +#define W_CIR_SCC 0x80 +#define W_CIR_ICC 0x40 +#define W_CIR_COD_MASK 0x0f + +#define W_PCTL_PCX 0x01 +#define W_PCTL_XMODE 0x02 +#define W_PCTL_OE0 0x04 +#define W_PCTL_OE1 0x08 +#define W_PCTL_OE2 0x10 +#define W_PCTL_OE3 0x20 +#define W_PCTL_OE4 0x40 +#define W_PCTL_OE5 0x80 + +#define W_B_CMDR_XRST 0x01 +#define W_B_CMDR_XME 0x02 +#define W_B_CMDR_XMS 0x04 +#define W_B_CMDR_RACT 0x20 +#define W_B_CMDR_RRST 0x40 +#define W_B_CMDR_RACK 0x80 + +#define W_B_MODE_FTS0 0x01 +#define W_B_MODE_FTS1 0x02 +#define W_B_MODE_SW56 0x04 +#define W_B_MODE_BSW0 0x08 +#define W_B_MODE_BSW1 0x10 +#define W_B_MODE_EPCM 0x20 +#define W_B_MODE_ITF 0x40 +#define W_B_MODE_MMS 0x80 + +#define W_B_EXI_XDUN 0x01 +#define W_B_EXI_XFR 0x02 +#define W_B_EXI_RDOV 0x10 +#define W_B_EXI_RME 0x20 +#define W_B_EXI_RMR 0x40 + +#define W_B_STAR_XBZ 0x01 +#define W_B_STAR_XDOW 0x04 +#define W_B_STAR_RMB 0x10 +#define W_B_STAR_CRCE 0x20 +#define W_B_STAR_RDOV 0x40 + +#define W_B_RBCH_LOV 0x20 + +/* W6692 Layer1 commands */ + +#define W_L1CMD_ECK 0x00 +#define W_L1CMD_RST 0x01 +#define W_L1CMD_SCP 0x04 +#define W_L1CMD_SSP 0x02 +#define W_L1CMD_AR8 0x08 +#define W_L1CMD_AR10 0x09 +#define W_L1CMD_EAL 0x0a +#define W_L1CMD_DRC 0x0f + +/* W6692 Layer1 indications */ + +#define W_L1IND_CE 0x07 +#define W_L1IND_DRD 0x00 +#define W_L1IND_LD 0x04 +#define W_L1IND_ARD 0x08 +#define W_L1IND_TI 0x0a +#define W_L1IND_ATI 0x0b +#define W_L1IND_AI8 0x0c +#define W_L1IND_AI10 0x0d +#define W_L1IND_CD 0x0f + +/* FIFO thresholds */ +#define W_D_FIFO_THRESH 64 +#define W_B_FIFO_THRESH 64 |
