rebase on mainstream patchset 2.6.16

This commit is contained in:
Karsten Keil 2006-06-28 13:23:53 +00:00
parent 7a49a4e11a
commit 4b242c7873
29 changed files with 480 additions and 761 deletions

View File

@ -181,17 +181,17 @@ typedef struct act2000_card {
char regname[35]; /* Name used for request_region */ char regname[35]; /* Name used for request_region */
} act2000_card; } act2000_card;
extern __inline__ void act2000_schedule_tx(act2000_card *card) static inline void act2000_schedule_tx(act2000_card *card)
{ {
schedule_work(&card->snd_tq); schedule_work(&card->snd_tq);
} }
extern __inline__ void act2000_schedule_rx(act2000_card *card) static inline void act2000_schedule_rx(act2000_card *card)
{ {
schedule_work(&card->rcv_tq); schedule_work(&card->rcv_tq);
} }
extern __inline__ void act2000_schedule_poll(act2000_card *card) static inline void act2000_schedule_poll(act2000_card *card)
{ {
schedule_work(&card->poll_tq); schedule_work(&card->poll_tq);
} }

View File

@ -78,29 +78,29 @@ typedef union actcapi_infoel { /* info element */
typedef struct actcapi_msn { typedef struct actcapi_msn {
__u8 eaz; __u8 eaz;
__u8 len; /* Length of MSN */ __u8 len; /* Length of MSN */
__u8 msn[15] __attribute__ ((packed)); __u8 msn[15];
} actcapi_msn; } __attribute__((packed)) actcapi_msn;
typedef struct actcapi_dlpd { typedef struct actcapi_dlpd {
__u8 len; /* Length of structure */ __u8 len; /* Length of structure */
__u16 dlen __attribute__ ((packed)); /* Data Length */ __u16 dlen; /* Data Length */
__u8 laa __attribute__ ((packed)); /* Link Address A */ __u8 laa; /* Link Address A */
__u8 lab; /* Link Address B */ __u8 lab; /* Link Address B */
__u8 modulo; /* Modulo Mode */ __u8 modulo; /* Modulo Mode */
__u8 win; /* Window size */ __u8 win; /* Window size */
__u8 xid[100]; /* XID Information */ __u8 xid[100]; /* XID Information */
} actcapi_dlpd; } __attribute__((packed)) actcapi_dlpd;
typedef struct actcapi_ncpd { typedef struct actcapi_ncpd {
__u8 len; /* Length of structure */ __u8 len; /* Length of structure */
__u16 lic __attribute__ ((packed)); __u16 lic;
__u16 hic __attribute__ ((packed)); __u16 hic;
__u16 ltc __attribute__ ((packed)); __u16 ltc;
__u16 htc __attribute__ ((packed)); __u16 htc;
__u16 loc __attribute__ ((packed)); __u16 loc;
__u16 hoc __attribute__ ((packed)); __u16 hoc;
__u8 modulo __attribute__ ((packed)); __u8 modulo;
} actcapi_ncpd; } __attribute__((packed)) actcapi_ncpd;
#define actcapi_ncpi actcapi_ncpd #define actcapi_ncpi actcapi_ncpd
/* /*
@ -168,19 +168,19 @@ typedef struct actcapi_msg {
__u16 manuf_msg; __u16 manuf_msg;
__u16 controller; __u16 controller;
actcapi_msn msnmap; actcapi_msn msnmap;
} manufacturer_req_msn; } __attribute ((packed)) manufacturer_req_msn;
/* TODO: TraceInit-req/conf/ind/resp and /* TODO: TraceInit-req/conf/ind/resp and
* TraceDump-req/conf/ind/resp * TraceDump-req/conf/ind/resp
*/ */
struct connect_req { struct connect_req {
__u8 controller; __u8 controller;
__u8 bchan; __u8 bchan;
__u32 infomask __attribute__ ((packed)); __u32 infomask;
__u8 si1; __u8 si1;
__u8 si2; __u8 si2;
__u8 eaz; __u8 eaz;
actcapi_addr addr; actcapi_addr addr;
} connect_req; } __attribute__ ((packed)) connect_req;
struct connect_conf { struct connect_conf {
__u16 plci; __u16 plci;
__u16 info; __u16 info;
@ -192,7 +192,7 @@ typedef struct actcapi_msg {
__u8 si2; __u8 si2;
__u8 eaz; __u8 eaz;
actcapi_addr addr; actcapi_addr addr;
} connect_ind; } __attribute__ ((packed)) connect_ind;
struct connect_resp { struct connect_resp {
__u16 plci; __u16 plci;
__u8 rejectcause; __u8 rejectcause;
@ -200,14 +200,14 @@ typedef struct actcapi_msg {
struct connect_active_ind { struct connect_active_ind {
__u16 plci; __u16 plci;
actcapi_addr addr; actcapi_addr addr;
} connect_active_ind; } __attribute__ ((packed)) connect_active_ind;
struct connect_active_resp { struct connect_active_resp {
__u16 plci; __u16 plci;
} connect_active_resp; } connect_active_resp;
struct connect_b3_req { struct connect_b3_req {
__u16 plci; __u16 plci;
actcapi_ncpi ncpi; actcapi_ncpi ncpi;
} connect_b3_req; } __attribute__ ((packed)) connect_b3_req;
struct connect_b3_conf { struct connect_b3_conf {
__u16 plci; __u16 plci;
__u16 ncci; __u16 ncci;
@ -217,12 +217,12 @@ typedef struct actcapi_msg {
__u16 ncci; __u16 ncci;
__u16 plci; __u16 plci;
actcapi_ncpi ncpi; actcapi_ncpi ncpi;
} connect_b3_ind; } __attribute__ ((packed)) connect_b3_ind;
struct connect_b3_resp { struct connect_b3_resp {
__u16 ncci; __u16 ncci;
__u8 rejectcause; __u8 rejectcause;
actcapi_ncpi ncpi __attribute__ ((packed)); actcapi_ncpi ncpi;
} connect_b3_resp; } __attribute__ ((packed)) connect_b3_resp;
struct disconnect_req { struct disconnect_req {
__u16 plci; __u16 plci;
__u8 cause; __u8 cause;
@ -241,14 +241,14 @@ typedef struct actcapi_msg {
struct connect_b3_active_ind { struct connect_b3_active_ind {
__u16 ncci; __u16 ncci;
actcapi_ncpi ncpi; actcapi_ncpi ncpi;
} connect_b3_active_ind; } __attribute__ ((packed)) connect_b3_active_ind;
struct connect_b3_active_resp { struct connect_b3_active_resp {
__u16 ncci; __u16 ncci;
} connect_b3_active_resp; } connect_b3_active_resp;
struct disconnect_b3_req { struct disconnect_b3_req {
__u16 ncci; __u16 ncci;
actcapi_ncpi ncpi; actcapi_ncpi ncpi;
} disconnect_b3_req; } __attribute__ ((packed)) disconnect_b3_req;
struct disconnect_b3_conf { struct disconnect_b3_conf {
__u16 ncci; __u16 ncci;
__u16 info; __u16 info;
@ -257,7 +257,7 @@ typedef struct actcapi_msg {
__u16 ncci; __u16 ncci;
__u16 info; __u16 info;
actcapi_ncpi ncpi; actcapi_ncpi ncpi;
} disconnect_b3_ind; } __attribute__ ((packed)) disconnect_b3_ind;
struct disconnect_b3_resp { struct disconnect_b3_resp {
__u16 ncci; __u16 ncci;
} disconnect_b3_resp; } disconnect_b3_resp;
@ -265,7 +265,7 @@ typedef struct actcapi_msg {
__u16 plci; __u16 plci;
actcapi_infonr nr; actcapi_infonr nr;
actcapi_infoel el; actcapi_infoel el;
} info_ind; } __attribute__ ((packed)) info_ind;
struct info_resp { struct info_resp {
__u16 plci; __u16 plci;
} info_resp; } info_resp;
@ -279,8 +279,8 @@ typedef struct actcapi_msg {
struct select_b2_protocol_req { struct select_b2_protocol_req {
__u16 plci; __u16 plci;
__u8 protocol; __u8 protocol;
actcapi_dlpd dlpd __attribute__ ((packed)); actcapi_dlpd dlpd;
} select_b2_protocol_req; } __attribute__ ((packed)) select_b2_protocol_req;
struct select_b2_protocol_conf { struct select_b2_protocol_conf {
__u16 plci; __u16 plci;
__u16 info; __u16 info;
@ -288,49 +288,49 @@ typedef struct actcapi_msg {
struct select_b3_protocol_req { struct select_b3_protocol_req {
__u16 plci; __u16 plci;
__u8 protocol; __u8 protocol;
actcapi_ncpd ncpd __attribute__ ((packed)); actcapi_ncpd ncpd;
} select_b3_protocol_req; } __attribute__ ((packed)) select_b3_protocol_req;
struct select_b3_protocol_conf { struct select_b3_protocol_conf {
__u16 plci; __u16 plci;
__u16 info; __u16 info;
} select_b3_protocol_conf; } select_b3_protocol_conf;
struct listen_req { struct listen_req {
__u8 controller; __u8 controller;
__u32 infomask __attribute__ ((packed)); __u32 infomask;
__u16 eazmask __attribute__ ((packed)); __u16 eazmask;
__u16 simask __attribute__ ((packed)); __u16 simask;
} listen_req; } __attribute__ ((packed)) listen_req;
struct listen_conf { struct listen_conf {
__u8 controller; __u8 controller;
__u16 info __attribute__ ((packed)); __u16 info;
} listen_conf; } __attribute__ ((packed)) listen_conf;
struct data_b3_req { struct data_b3_req {
__u16 fakencci; __u16 fakencci;
__u16 datalen; __u16 datalen;
__u32 unused; __u32 unused;
__u8 blocknr; __u8 blocknr;
__u16 flags __attribute__ ((packed)); __u16 flags;
} data_b3_req; } __attribute ((packed)) data_b3_req;
struct data_b3_ind { struct data_b3_ind {
__u16 fakencci; __u16 fakencci;
__u16 datalen; __u16 datalen;
__u32 unused; __u32 unused;
__u8 blocknr; __u8 blocknr;
__u16 flags __attribute__ ((packed)); __u16 flags;
} data_b3_ind; } __attribute__ ((packed)) data_b3_ind;
struct data_b3_resp { struct data_b3_resp {
__u16 ncci; __u16 ncci;
__u8 blocknr; __u8 blocknr;
} data_b3_resp; } __attribute__ ((packed)) data_b3_resp;
struct data_b3_conf { struct data_b3_conf {
__u16 ncci; __u16 ncci;
__u8 blocknr; __u8 blocknr;
__u16 info __attribute__ ((packed)); __u16 info;
} data_b3_conf; } __attribute__ ((packed)) data_b3_conf;
} msg; } msg;
} actcapi_msg; } __attribute__ ((packed)) actcapi_msg;
extern __inline__ unsigned short static inline unsigned short
actcapi_nextsmsg(act2000_card *card) actcapi_nextsmsg(act2000_card *card)
{ {
unsigned long flags; unsigned long flags;

View File

@ -463,8 +463,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
#endif #endif
goto bad; goto bad;
} }
if (ld->receive_room && if (mp->tty->receive_room < datalen) {
ld->receive_room(mp->tty) < datalen) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: no room in tty\n"); printk(KERN_DEBUG "capi: no room in tty\n");
#endif #endif

View File

@ -17,6 +17,8 @@
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/sched.h> /* current */ #include <linux/sched.h> /* current */
#include "capifs.h"
MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem"); MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
MODULE_AUTHOR("Carsten Paeth"); MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
@ -136,7 +138,7 @@ static struct dentry *get_node(int num)
{ {
char s[10]; char s[10];
struct dentry *root = capifs_root; struct dentry *root = capifs_root;
down(&root->d_inode->i_sem); mutex_lock(&root->d_inode->i_mutex);
return lookup_one_len(s, root, sprintf(s, "%d", num)); return lookup_one_len(s, root, sprintf(s, "%d", num));
} }
@ -157,7 +159,7 @@ void capifs_new_ncci(unsigned int number, dev_t device)
dentry = get_node(number); dentry = get_node(number);
if (!IS_ERR(dentry) && !dentry->d_inode) if (!IS_ERR(dentry) && !dentry->d_inode)
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
up(&capifs_root->d_inode->i_sem); mutex_unlock(&capifs_root->d_inode->i_mutex);
} }
void capifs_free_ncci(unsigned int number) void capifs_free_ncci(unsigned int number)
@ -173,7 +175,7 @@ void capifs_free_ncci(unsigned int number)
} }
dput(dentry); dput(dentry);
} }
up(&capifs_root->d_inode->i_sem); mutex_unlock(&capifs_root->d_inode->i_mutex);
} }
static int __init capifs_init(void) static int __init capifs_init(void)

View File

@ -53,8 +53,6 @@ MODULE_LICENSE("GPL");
static void avmcs_config(dev_link_t *link); static void avmcs_config(dev_link_t *link);
static void avmcs_release(dev_link_t *link); static void avmcs_release(dev_link_t *link);
static int avmcs_event(event_t event, int priority,
event_callback_args_t *args);
/* /*
The attach() and detach() entry points are used to create and destroy The attach() and detach() entry points are used to create and destroy
@ -62,16 +60,7 @@ static int avmcs_event(event_t event, int priority,
needed to manage one actual PCMCIA card. needed to manage one actual PCMCIA card.
*/ */
static dev_link_t *avmcs_attach(void); static void avmcs_detach(struct pcmcia_device *p_dev);
static void avmcs_detach(dev_link_t *);
/*
The dev_info variable is the "key" that is used to match up this
device driver with appropriate cards, through the card configuration
database.
*/
static dev_info_t dev_info = "avm_cs";
/* /*
A linked list of "instances" of the skeleton device. Each actual A linked list of "instances" of the skeleton device. Each actual
@ -83,15 +72,7 @@ static dev_info_t dev_info = "avm_cs";
device numbers are used to derive the corresponding array index. device numbers are used to derive the corresponding array index.
*/ */
static dev_link_t *dev_list = NULL;
/* /*
A dev_link_t structure has fields for most things that are needed
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
'priv' pointer in a dev_link_t structure can be used to point to
a device-specific private data structure, like this.
A driver needs to provide a dev_node_t structure for each device 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 on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be example, ethernet cards, modems). In other cases, there may be
@ -118,13 +99,11 @@ typedef struct local_info_t {
======================================================================*/ ======================================================================*/
static dev_link_t *avmcs_attach(void) static int avmcs_attach(struct pcmcia_device *p_dev)
{ {
client_reg_t client_reg;
dev_link_t *link; dev_link_t *link;
local_info_t *local; local_info_t *local;
int ret;
/* Initialize the dev_link_t structure */ /* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) if (!link)
@ -155,25 +134,19 @@ static dev_link_t *avmcs_attach(void)
goto err_kfree; goto err_kfree;
memset(local, 0, sizeof(local_info_t)); memset(local, 0, sizeof(local_info_t));
link->priv = local; link->priv = local;
/* Register with Card Services */ link->handle = p_dev;
link->next = dev_list; p_dev->instance = link;
dev_list = link;
client_reg.dev_info = &dev_info; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
client_reg.Version = 0x0210; avmcs_config(link);
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg); return 0;
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
avmcs_detach(link);
goto err;
}
return link;
err_kfree: err_kfree:
kfree(link); kfree(link);
err: err:
return NULL; return -EINVAL;
} /* avmcs_attach */ } /* avmcs_attach */
/*====================================================================== /*======================================================================
@ -185,33 +158,13 @@ static dev_link_t *avmcs_attach(void)
======================================================================*/ ======================================================================*/
static void avmcs_detach(dev_link_t *link) static void avmcs_detach(struct pcmcia_device *p_dev)
{ {
dev_link_t **linkp; dev_link_t *link = dev_to_instance(p_dev);
/* Locate device structure */ if (link->state & DEV_CONFIG)
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) avmcs_release(link);
if (*linkp == link) break;
if (*linkp == NULL)
return;
/*
If the device is currently configured and active, we won't
actually delete it yet. Instead, it is marked so that when
the release() function is called, that will trigger a proper
detach().
*/
if (link->state & DEV_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
}
/* Break the link with Card Services */
if (link->handle)
pcmcia_deregister_client(link->handle);
/* Unlink device structure, free pieces */
*linkp = link->next;
kfree(link->priv); kfree(link->priv);
kfree(link); kfree(link);
} /* avmcs_detach */ } /* avmcs_detach */
@ -424,12 +377,30 @@ static void avmcs_release(dev_link_t *link)
pcmcia_release_io(link->handle, &link->io); pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq); pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_LINK)
avmcs_detach(link);
} /* avmcs_release */ } /* 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 The card status event handler. Mostly, this schedules other
@ -444,38 +415,6 @@ static void avmcs_release(dev_link_t *link)
======================================================================*/ ======================================================================*/
static int avmcs_event(event_t event, int priority,
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
switch (event) {
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG)
avmcs_release(link);
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avmcs_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
break;
}
return 0;
} /* avmcs_event */
static struct pcmcia_device_id avmcs_ids[] = { static struct pcmcia_device_id avmcs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
@ -490,10 +429,11 @@ static struct pcmcia_driver avmcs_driver = {
.drv = { .drv = {
.name = "avm_cs", .name = "avm_cs",
}, },
.attach = avmcs_attach, .probe = avmcs_attach,
.event = avmcs_event, .remove = avmcs_detach,
.detach = avmcs_detach,
.id_table = avmcs_ids, .id_table = avmcs_ids,
.suspend= avmcs_suspend,
.resume = avmcs_resume,
}; };
static int __init avmcs_init(void) static int __init avmcs_init(void)
@ -504,7 +444,6 @@ static int __init avmcs_init(void)
static void __exit avmcs_exit(void) static void __exit avmcs_exit(void)
{ {
pcmcia_unregister_driver(&avmcs_driver); pcmcia_unregister_driver(&avmcs_driver);
BUG_ON(dev_list != NULL);
} }
module_init(avmcs_init); module_init(avmcs_init);

View File

@ -16,6 +16,7 @@
#include "diva_pci.h" #include "diva_pci.h"
#include "mi_pc.h" #include "mi_pc.h"
#include "dsrv4bri.h" #include "dsrv4bri.h"
#include "helpers.h"
static void *diva_xdiLoadFileFile = NULL; static void *diva_xdiLoadFileFile = NULL;
static dword diva_xdiLoadFileLength = 0; static dword diva_xdiLoadFileLength = 0;
@ -815,7 +816,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
return (ret); return (ret);
} }
void *xdiLoadFile(char *FileName, unsigned long *FileLength, void *xdiLoadFile(char *FileName, dword *FileLength,
unsigned long lim) unsigned long lim)
{ {
void *ret = diva_xdiLoadFileFile; void *ret = diva_xdiLoadFileFile;

View File

@ -16,6 +16,7 @@
#include "diva_pci.h" #include "diva_pci.h"
#include "mi_pc.h" #include "mi_pc.h"
#include "pc_maint.h" #include "pc_maint.h"
#include "dsrv_bri.h"
/* /*
** IMPORTS ** IMPORTS

View File

@ -18,6 +18,7 @@
#include "pc_maint.h" #include "pc_maint.h"
#include "dsp_tst.h" #include "dsp_tst.h"
#include "diva_dma.h" #include "diva_dma.h"
#include "dsrv_pri.h"
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
OS Dependent part of XDI driver for DIVA PRI Adapter OS Dependent part of XDI driver for DIVA PRI Adapter

View File

@ -110,7 +110,7 @@ config HISAX_16_3
config HISAX_TELESPCI config HISAX_TELESPCI
bool "Teles PCI" bool "Teles PCI"
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
help help
This enables HiSax support for the Teles PCI. This enables HiSax support for the Teles PCI.
See <file:Documentation/isdn/README.HiSax> on how to configure it. See <file:Documentation/isdn/README.HiSax> on how to configure it.
@ -238,7 +238,7 @@ config HISAX_MIC
config HISAX_NETJET config HISAX_NETJET
bool "NETjet card" bool "NETjet card"
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
help help
This enables HiSax support for the NetJet from Traverse This enables HiSax support for the NetJet from Traverse
Technologies. Technologies.
@ -249,7 +249,7 @@ config HISAX_NETJET
config HISAX_NETJET_U config HISAX_NETJET_U
bool "NETspider U card" bool "NETspider U card"
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
help help
This enables HiSax support for the Netspider U interface ISDN card This enables HiSax support for the Netspider U interface ISDN card
from Traverse Technologies. from Traverse Technologies.
@ -317,7 +317,7 @@ config HISAX_GAZEL
config HISAX_HFC_PCI config HISAX_HFC_PCI
bool "HFC PCI-Bus cards" bool "HFC PCI-Bus cards"
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
help help
This enables HiSax support for the HFC-S PCI 2BDS0 based cards. This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
@ -344,14 +344,14 @@ config HISAX_HFC_SX
config HISAX_ENTERNOW_PCI config HISAX_ENTERNOW_PCI
bool "Formula-n enter:now PCI card" bool "Formula-n enter:now PCI card"
depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
help help
This enables HiSax support for the Formula-n enter:now PCI This enables HiSax support for the Formula-n enter:now PCI
ISDN card. ISDN card.
config HISAX_AMD7930 config HISAX_AMD7930
bool "Am7930 (EXPERIMENTAL)" bool "Am7930 (EXPERIMENTAL)"
depends on EXPERIMENTAL && SPARC depends on EXPERIMENTAL && SPARC && BROKEN
help help
This enables HiSax support for the AMD7930 chips on some SPARCs. This enables HiSax support for the AMD7930 chips on some SPARCs.
This code is not finished yet. This code is not finished yet.

View File

@ -358,7 +358,7 @@ hdlc_fill_fifo(struct BCState *bcs)
} }
} }
static inline void static void
HDLC_irq(struct BCState *bcs, u_int stat) { HDLC_irq(struct BCState *bcs, u_int stat) {
int len; int len;
struct sk_buff *skb; struct sk_buff *skb;

View File

@ -69,8 +69,6 @@ module_param(isdnprot, int, 0);
static void avma1cs_config(dev_link_t *link); static void avma1cs_config(dev_link_t *link);
static void avma1cs_release(dev_link_t *link); static void avma1cs_release(dev_link_t *link);
static int avma1cs_event(event_t event, int priority,
event_callback_args_t *args);
/* /*
The attach() and detach() entry points are used to create and destroy The attach() and detach() entry points are used to create and destroy
@ -78,16 +76,8 @@ static int avma1cs_event(event_t event, int priority,
needed to manage one actual PCMCIA card. needed to manage one actual PCMCIA card.
*/ */
static dev_link_t *avma1cs_attach(void); static void avma1cs_detach(struct pcmcia_device *p_dev);
static void avma1cs_detach(dev_link_t *);
/*
The dev_info variable is the "key" that is used to match up this
device driver with appropriate cards, through the card configuration
database.
*/
static dev_info_t dev_info = "avma1_cs";
/* /*
A linked list of "instances" of the skeleton device. Each actual A linked list of "instances" of the skeleton device. Each actual
@ -99,15 +89,7 @@ static dev_info_t dev_info = "avma1_cs";
device numbers are used to derive the corresponding array index. device numbers are used to derive the corresponding array index.
*/ */
static dev_link_t *dev_list = NULL;
/* /*
A dev_link_t structure has fields for most things that are needed
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
'priv' pointer in a dev_link_t structure can be used to point to
a device-specific private data structure, like this.
A driver needs to provide a dev_node_t structure for each device 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 on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be example, ethernet cards, modems). In other cases, there may be
@ -134,26 +116,24 @@ typedef struct local_info_t {
======================================================================*/ ======================================================================*/
static dev_link_t *avma1cs_attach(void) static int avma1cs_attach(struct pcmcia_device *p_dev)
{ {
client_reg_t client_reg;
dev_link_t *link; dev_link_t *link;
local_info_t *local; local_info_t *local;
int ret;
DEBUG(0, "avma1cs_attach()\n"); DEBUG(0, "avma1cs_attach()\n");
/* Initialize the dev_link_t structure */ /* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) if (!link)
return NULL; return -ENOMEM;
memset(link, 0, sizeof(struct dev_link_t)); memset(link, 0, sizeof(struct dev_link_t));
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL); local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) { if (!local) {
kfree(link); kfree(link);
return NULL; return -ENOMEM;
} }
memset(local, 0, sizeof(local_info_t)); memset(local, 0, sizeof(local_info_t));
link->priv = local; link->priv = local;
@ -178,20 +158,13 @@ static dev_link_t *avma1cs_attach(void)
link->conf.ConfigIndex = 1; link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION; link->conf.Present = PRESENT_OPTION;
/* Register with Card Services */ link->handle = p_dev;
link->next = dev_list; p_dev->instance = link;
dev_list = link;
client_reg.dev_info = &dev_info;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
avma1cs_detach(link);
return NULL;
}
return link; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avma1cs_config(link);
return 0;
} /* avma1cs_attach */ } /* avma1cs_attach */
/*====================================================================== /*======================================================================
@ -203,42 +176,17 @@ static dev_link_t *avma1cs_attach(void)
======================================================================*/ ======================================================================*/
static void avma1cs_detach(dev_link_t *link) static void avma1cs_detach(struct pcmcia_device *p_dev)
{ {
dev_link_t **linkp; dev_link_t *link = dev_to_instance(p_dev);
DEBUG(0, "avma1cs_detach(0x%p)\n", link); DEBUG(0, "avma1cs_detach(0x%p)\n", link);
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link) break;
if (*linkp == NULL)
return;
/* if (link->state & DEV_CONFIG)
If the device is currently configured and active, we won't avma1cs_release(link);
actually delete it yet. Instead, it is marked so that when
the release() function is called, that will trigger a proper
detach().
*/
if (link->state & DEV_CONFIG) {
#ifdef PCMCIA_DEBUG
printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' "
"still locked\n", link->dev->dev_name);
#endif
link->state |= DEV_STALE_LINK;
return;
}
/* Break the link with Card Services */
if (link->handle)
pcmcia_deregister_client(link->handle);
/* Unlink device structure, free pieces */
*linkp = link->next;
kfree(link->priv); kfree(link->priv);
kfree(link); kfree(link);
} /* avma1cs_detach */ } /* avma1cs_detach */
/*====================================================================== /*======================================================================
@ -440,58 +388,30 @@ static void avma1cs_release(dev_link_t *link)
pcmcia_release_io(link->handle, &link->io); pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq); pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_LINK)
avma1cs_detach(link);
} /* avma1cs_release */ } /* avma1cs_release */
/*====================================================================== static int avma1cs_suspend(struct pcmcia_device *dev)
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 int avma1cs_event(event_t event, int priority,
event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = dev_to_instance(dev);
DEBUG(1, "avma1cs_event(0x%06x)\n", event); link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
switch (event) {
case CS_EVENT_CARD_REMOVAL:
if (link->state & DEV_CONFIG)
avma1cs_release(link);
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avma1cs_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle); pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME: return 0;
link->state &= ~DEV_SUSPEND; }
/* Fall through... */
case CS_EVENT_CARD_RESET: static int avma1cs_resume(struct pcmcia_device *dev)
if (link->state & DEV_CONFIG) {
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf); pcmcia_request_configuration(link->handle, &link->conf);
break;
} return 0;
return 0; }
} /* avma1cs_event */
static struct pcmcia_device_id avma1cs_ids[] = { static struct pcmcia_device_id avma1cs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
@ -505,10 +425,11 @@ static struct pcmcia_driver avma1cs_driver = {
.drv = { .drv = {
.name = "avma1_cs", .name = "avma1_cs",
}, },
.attach = avma1cs_attach, .probe = avma1cs_attach,
.event = avma1cs_event, .remove = avma1cs_detach,
.detach = avma1cs_detach,
.id_table = avma1cs_ids, .id_table = avma1cs_ids,
.suspend = avma1cs_suspend,
.resume = avma1cs_resume,
}; };
/*====================================================================*/ /*====================================================================*/
@ -521,7 +442,6 @@ static int __init init_avma1_cs(void)
static void __exit exit_avma1_cs(void) static void __exit exit_avma1_cs(void)
{ {
pcmcia_unregister_driver(&avma1cs_driver); pcmcia_unregister_driver(&avma1cs_driver);
BUG_ON(dev_list != NULL);
} }
module_init(init_avma1_cs); module_init(init_avma1_cs);

View File

@ -476,7 +476,7 @@ Memhscx_fill_fifo(struct BCState *bcs)
} }
} }
static inline void static void
Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
{ {
u_char r; u_char r;

View File

@ -96,8 +96,6 @@ module_param(protocol, int, 0);
static void elsa_cs_config(dev_link_t *link); static void elsa_cs_config(dev_link_t *link);
static void elsa_cs_release(dev_link_t *link); static void elsa_cs_release(dev_link_t *link);
static int elsa_cs_event(event_t event, int priority,
event_callback_args_t *args);
/* /*
The attach() and detach() entry points are used to create and destroy The attach() and detach() entry points are used to create and destroy
@ -105,39 +103,9 @@ static int elsa_cs_event(event_t event, int priority,
needed to manage one actual PCMCIA card. needed to manage one actual PCMCIA card.
*/ */
static dev_link_t *elsa_cs_attach(void); static void elsa_cs_detach(struct pcmcia_device *p_dev);
static void elsa_cs_detach(dev_link_t *);
/* /*
The dev_info variable is the "key" that is used to match up this
device driver with appropriate cards, through the card configuration
database.
*/
static dev_info_t dev_info = "elsa_cs";
/*
A linked list of "instances" of the elsa_cs 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.
*/
static dev_link_t *dev_list = NULL;
/*
A dev_link_t structure has fields for most things that are needed
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
'priv' pointer in a dev_link_t structure can be used to point to
a device-specific private data structure, like this.
To simplify the data structure handling, we actually include the
dev_link_t structure in the device's private data structure.
A driver needs to provide a dev_node_t structure for each device 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 on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be example, ethernet cards, modems). In other cases, there may be
@ -171,18 +139,16 @@ typedef struct local_info_t {
======================================================================*/ ======================================================================*/
static dev_link_t *elsa_cs_attach(void) static int elsa_cs_attach(struct pcmcia_device *p_dev)
{ {
client_reg_t client_reg;
dev_link_t *link; dev_link_t *link;
local_info_t *local; local_info_t *local;
int ret;
DEBUG(0, "elsa_cs_attach()\n"); DEBUG(0, "elsa_cs_attach()\n");
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL); local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) return NULL; if (!local) return -ENOMEM;
memset(local, 0, sizeof(local_info_t)); memset(local, 0, sizeof(local_info_t));
local->cardnr = -1; local->cardnr = -1;
link = &local->link; link->priv = local; link = &local->link; link->priv = local;
@ -207,20 +173,13 @@ static dev_link_t *elsa_cs_attach(void)
link->conf.Vcc = 50; link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
/* Register with Card Services */ link->handle = p_dev;
link->next = dev_list; p_dev->instance = link;
dev_list = link;
client_reg.dev_info = &dev_info;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
elsa_cs_detach(link);
return NULL;
}
return link; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
elsa_cs_config(link);
return 0;
} /* elsa_cs_attach */ } /* elsa_cs_attach */
/*====================================================================== /*======================================================================
@ -232,32 +191,18 @@ static dev_link_t *elsa_cs_attach(void)
======================================================================*/ ======================================================================*/
static void elsa_cs_detach(dev_link_t *link) static void elsa_cs_detach(struct pcmcia_device *p_dev)
{ {
dev_link_t **linkp; dev_link_t *link = dev_to_instance(p_dev);
local_info_t *info = link->priv; local_info_t *info = link->priv;
int ret;
DEBUG(0, "elsa_cs_detach(0x%p)\n", link); DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
/* Locate device structure */ if (link->state & DEV_CONFIG) {
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) info->busy = 1;
if (*linkp == link) break; elsa_cs_release(link);
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG)
elsa_cs_release(link);
/* Break the link with Card Services */
if (link->handle) {
ret = pcmcia_deregister_client(link->handle);
if (ret != CS_SUCCESS)
cs_error(link->handle, DeregisterClient, ret);
} }
/* Unlink device structure and free it */
*linkp = link->next;
kfree(info); kfree(info);
} /* elsa_cs_detach */ } /* elsa_cs_detach */
@ -447,60 +392,31 @@ static void elsa_cs_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} /* elsa_cs_release */ } /* elsa_cs_release */
/*====================================================================== static int elsa_suspend(struct pcmcia_device *p_dev)
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 int elsa_cs_event(event_t event, int priority,
event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv; local_info_t *dev = link->priv;
DEBUG(1, "elsa_cs_event(%d)\n", event); link->state |= DEV_SUSPEND;
switch (event) {
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
((local_info_t*)link->priv)->busy = 1;
elsa_cs_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
elsa_cs_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
dev->busy = 1; dev->busy = 1;
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle); pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME: return 0;
link->state &= ~DEV_SUSPEND; }
/* Fall through... */
case CS_EVENT_CARD_RESET: static int elsa_resume(struct pcmcia_device *p_dev)
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf); dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0; dev->busy = 0;
break;
} return 0;
return 0; }
} /* elsa_cs_event */
static struct pcmcia_device_id elsa_ids[] = { static struct pcmcia_device_id elsa_ids[] = {
PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257), PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
@ -514,10 +430,11 @@ static struct pcmcia_driver elsa_cs_driver = {
.drv = { .drv = {
.name = "elsa_cs", .name = "elsa_cs",
}, },
.attach = elsa_cs_attach, .probe = elsa_cs_attach,
.event = elsa_cs_event, .remove = elsa_cs_detach,
.detach = elsa_cs_detach,
.id_table = elsa_ids, .id_table = elsa_ids,
.suspend = elsa_suspend,
.resume = elsa_resume,
}; };
static int __init init_elsa_cs(void) static int __init init_elsa_cs(void)
@ -528,7 +445,6 @@ static int __init init_elsa_cs(void)
static void __exit exit_elsa_cs(void) static void __exit exit_elsa_cs(void)
{ {
pcmcia_unregister_driver(&elsa_cs_driver); pcmcia_unregister_driver(&elsa_cs_driver);
BUG_ON(dev_list != NULL);
} }
module_init(init_elsa_cs); module_init(init_elsa_cs);

View File

@ -29,10 +29,11 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <asm/io.h>
#include "hisax_if.h" #include "hisax_if.h"
#include "hfc4s8s_l1.h" #include "hfc4s8s_l1.h"
static const char hfc4s8s_rev[] = "Revision: 1.11"; static const char hfc4s8s_rev[] = "Revision: 1.10";
/***************************************************************/ /***************************************************************/
/* adjustable transparent mode fifo threshold */ /* adjustable transparent mode fifo threshold */
@ -311,7 +312,7 @@ wait_busy(hfc4s8s_hw * a)
/* function to read critical counter registers that */ /* function to read critical counter registers that */
/* may be udpated by the chip during read */ /* may be udpated by the chip during read */
/******************************************************/ /******************************************************/
static volatile u_char static u_char
Read_hfc8_stable(hfc4s8s_hw * hw, int reg) Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
{ {
u_char ref8; u_char ref8;
@ -323,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
return in8; return in8;
} }
static volatile int static int
Read_hfc16_stable(hfc4s8s_hw * hw, int reg) Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
{ {
int ref16; int ref16;
@ -873,7 +874,7 @@ rx_b_frame(struct hfc4s8s_btype *bch)
bch->rx_ptr += 4; bch->rx_ptr += 4;
z1 -= 4; z1 -= 4;
} }
while (z1--) while (z1--)
#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
*(bch->rx_ptr++) = Read_hfc8(l1->hw, A_FIFO_DATA0); *(bch->rx_ptr++) = Read_hfc8(l1->hw, A_FIFO_DATA0);
@ -1357,7 +1358,7 @@ chipreset(hfc4s8s_hw * hw)
/********************************************/ /********************************************/
/* disable/enable hardware in nt or te mode */ /* disable/enable hardware in nt or te mode */
/********************************************/ /********************************************/
void static void
hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode) hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
{ {
u_long flags; u_long flags;
@ -1464,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
/******************************************/ /******************************************/
/* disable memory mapped ports / io ports */ /* disable memory mapped ports / io ports */
/******************************************/ /******************************************/
void static void
release_pci_ports(hfc4s8s_hw * hw) release_pci_ports(hfc4s8s_hw * hw)
{ {
pci_write_config_word(hw->pdev, PCI_COMMAND, 0); pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
@ -1480,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw)
/*****************************************/ /*****************************************/
/* enable memory mapped ports / io ports */ /* enable memory mapped ports / io ports */
/*****************************************/ /*****************************************/
void static void
enable_pci_ports(hfc4s8s_hw * hw) enable_pci_ports(hfc4s8s_hw * hw)
{ {
#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
@ -1604,7 +1605,7 @@ hfc4s8s_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->cardnum = card_cnt; hw->cardnum = card_cnt;
sprintf(hw->card_name, "hfc4s8s_%d", hw->cardnum); sprintf(hw->card_name, "hfc4s8s_%d", hw->cardnum);
printk(KERN_INFO "HFC-4S/8S: found adapter %s (%s) at %s\n", printk(KERN_INFO "HFC-4S/8S: found adapter %s (%s) at %s\n",
driver_data->device_name, hw->card_name, pdev->slot_name); driver_data->device_name, hw->card_name, pci_name(pdev));
spin_lock_init(&hw->lock); spin_lock_init(&hw->lock);

View File

@ -1,5 +1,5 @@
/***************************************************************/ /***************************************************************/
/* Id: hfc4s8s_l1.h,v 1.1 2005/02/02 17:28:55 martinb1 Exp */ /* $Id$ */
/* */ /* */
/* This file is a minimal required extraction of hfc48scu.h */ /* This file is a minimal required extraction of hfc48scu.h */
/* (Genero 3.2, HFC XML 1.7a for HFC-E1, HFC-4S and HFC-8S) */ /* (Genero 3.2, HFC XML 1.7a for HFC-E1, HFC-4S and HFC-8S) */

View File

@ -63,7 +63,7 @@ static const PCI_ENTRY id_list[] =
{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"}, {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"}, {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"}, {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
{PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2,"Sitecom Connectivity", "DC-105 ISDN TA"}, {PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2, "Sitecom Europe", "DC-105 ISDN PCI"},
{0, 0, NULL, NULL}, {0, 0, NULL, NULL},
}; };

View File

@ -216,7 +216,7 @@ struct Layer1 {
#define GROUP_TEI 127 #define GROUP_TEI 127
#define TEI_SAPI 63 #define TEI_SAPI 63
#define CTRL_SAPI 0 #define CTRL_SAPI 0
#define PACKET_NOACK 250 #define PACKET_NOACK 7
/* Layer2 Flags */ /* Layer2 Flags */
@ -396,17 +396,17 @@ struct isar_hw {
struct hdlc_stat_reg { struct hdlc_stat_reg {
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
u_char fill __attribute__((packed)); u_char fill;
u_char mode __attribute__((packed)); u_char mode;
u_char xml __attribute__((packed)); u_char xml;
u_char cmd __attribute__((packed)); u_char cmd;
#else #else
u_char cmd __attribute__((packed)); u_char cmd;
u_char xml __attribute__((packed)); u_char xml;
u_char mode __attribute__((packed)); u_char mode;
u_char fill __attribute__((packed)); u_char fill;
#endif #endif
}; } __attribute__((packed));
struct hdlc_hw { struct hdlc_hw {
union { union {

View File

@ -12,17 +12,17 @@ enum {
struct hdlc_stat_reg { struct hdlc_stat_reg {
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
u_char fill __attribute__((packed)); u_char fill;
u_char mode __attribute__((packed)); u_char mode;
u_char xml __attribute__((packed)); u_char xml;
u_char cmd __attribute__((packed)); u_char cmd;
#else #else
u_char cmd __attribute__((packed)); u_char cmd;
u_char xml __attribute__((packed)); u_char xml;
u_char mode __attribute__((packed)); u_char mode;
u_char fill __attribute__((packed)); u_char fill;
#endif #endif
}; } __attribute__((packed));
struct fritz_bcs { struct fritz_bcs {
struct hisax_b_if b_if; struct hisax_b_if b_if;

View File

@ -119,7 +119,7 @@ hscx_fill_fifo(struct BCState *bcs)
} }
} }
static inline void static void
hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
{ {
u_char r; u_char r;
@ -221,7 +221,7 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
} }
} }
static inline void static void
hscx_int_main(struct IsdnCardState *cs, u_char val) hscx_int_main(struct IsdnCardState *cs, u_char val)
{ {

View File

@ -110,7 +110,7 @@ jade_fill_fifo(struct BCState *bcs)
} }
static inline void static void
jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade) jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade)
{ {
u_char r; u_char r;

View File

@ -97,8 +97,6 @@ module_param(protocol, int, 0);
static void sedlbauer_config(dev_link_t *link); static void sedlbauer_config(dev_link_t *link);
static void sedlbauer_release(dev_link_t *link); static void sedlbauer_release(dev_link_t *link);
static int sedlbauer_event(event_t event, int priority,
event_callback_args_t *args);
/* /*
The attach() and detach() entry points are used to create and destroy The attach() and detach() entry points are used to create and destroy
@ -106,8 +104,7 @@ static int sedlbauer_event(event_t event, int priority,
needed to manage one actual PCMCIA card. needed to manage one actual PCMCIA card.
*/ */
static dev_link_t *sedlbauer_attach(void); static void sedlbauer_detach(struct pcmcia_device *p_dev);
static void sedlbauer_detach(dev_link_t *);
/* /*
You'll also need to prototype all the functions that will actually You'll also need to prototype all the functions that will actually
@ -117,35 +114,6 @@ static void sedlbauer_detach(dev_link_t *);
*/ */
/* /*
The dev_info variable is the "key" that is used to match up this
device driver with appropriate cards, through the card configuration
database.
*/
static dev_info_t dev_info = "sedlbauer_cs";
/*
A linked list of "instances" of the sedlbauer 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.
*/
static dev_link_t *dev_list = NULL;
/*
A dev_link_t structure has fields for most things that are needed
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
'priv' pointer in a dev_link_t structure can be used to point to
a device-specific private data structure, like this.
To simplify the data structure handling, we actually include the
dev_link_t structure in the device's private data structure.
A driver needs to provide a dev_node_t structure for each device 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 on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be example, ethernet cards, modems). In other cases, there may be
@ -180,18 +148,16 @@ typedef struct local_info_t {
======================================================================*/ ======================================================================*/
static dev_link_t *sedlbauer_attach(void) static int sedlbauer_attach(struct pcmcia_device *p_dev)
{ {
local_info_t *local; local_info_t *local;
dev_link_t *link; dev_link_t *link;
client_reg_t client_reg;
int ret;
DEBUG(0, "sedlbauer_attach()\n"); DEBUG(0, "sedlbauer_attach()\n");
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL); local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) return NULL; if (!local) return -ENOMEM;
memset(local, 0, sizeof(local_info_t)); memset(local, 0, sizeof(local_info_t));
local->cardnr = -1; local->cardnr = -1;
link = &local->link; link->priv = local; link = &local->link; link->priv = local;
@ -221,20 +187,13 @@ static dev_link_t *sedlbauer_attach(void)
link->conf.Vcc = 50; link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
/* Register with Card Services */ link->handle = p_dev;
link->next = dev_list; p_dev->instance = link;
dev_list = link;
client_reg.dev_info = &dev_info;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
sedlbauer_detach(link);
return NULL;
}
return link; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
sedlbauer_config(link);
return 0;
} /* sedlbauer_attach */ } /* sedlbauer_attach */
/*====================================================================== /*======================================================================
@ -246,39 +205,17 @@ static dev_link_t *sedlbauer_attach(void)
======================================================================*/ ======================================================================*/
static void sedlbauer_detach(dev_link_t *link) static void sedlbauer_detach(struct pcmcia_device *p_dev)
{ {
dev_link_t **linkp; dev_link_t *link = dev_to_instance(p_dev);
DEBUG(0, "sedlbauer_detach(0x%p)\n", link); DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link) break;
if (*linkp == NULL)
return;
/*
If the device is currently configured and active, we won't
actually delete it yet. Instead, it is marked so that when
the release() function is called, that will trigger a proper
detach().
*/
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
#ifdef PCMCIA_DEBUG ((local_info_t *)link->priv)->stop = 1;
printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' " sedlbauer_release(link);
"still locked\n", link->dev->dev_name);
#endif
link->state |= DEV_STALE_LINK;
return;
} }
/* Break the link with Card Services */
if (link->handle)
pcmcia_deregister_client(link->handle);
/* Unlink device structure, and free it */
*linkp = link->next;
/* This points to the parent local_info_t struct */ /* This points to the parent local_info_t struct */
kfree(link->priv); kfree(link->priv);
} /* sedlbauer_detach */ } /* sedlbauer_detach */
@ -547,68 +484,34 @@ static void sedlbauer_release(dev_link_t *link)
if (link->irq.AssignedIRQ) if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq); pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_LINK)
sedlbauer_detach(link);
} /* sedlbauer_release */ } /* sedlbauer_release */
/*====================================================================== static int sedlbauer_suspend(struct pcmcia_device *p_dev)
The card status event handler. Mostly, this schedules other
stuff to run after an event is received.
When a CARD_REMOVAL event is received, we immediately set a
private 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 int sedlbauer_event(event_t event, int priority,
event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv; local_info_t *dev = link->priv;
DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
switch (event) {
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
((local_info_t *)link->priv)->stop = 1;
sedlbauer_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
sedlbauer_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND; link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
dev->stop = 1; dev->stop = 1;
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle); pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME: return 0;
}
static int sedlbauer_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND; link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf); pcmcia_request_configuration(link->handle, &link->conf);
dev->stop = 0; dev->stop = 0;
/*
In a normal driver, additional code may go here to restore return 0;
the device state and restart IO. }
*/
break;
}
return 0;
} /* sedlbauer_event */
static struct pcmcia_device_id sedlbauer_ids[] = { static struct pcmcia_device_id sedlbauer_ids[] = {
PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
@ -627,10 +530,11 @@ static struct pcmcia_driver sedlbauer_driver = {
.drv = { .drv = {
.name = "sedlbauer_cs", .name = "sedlbauer_cs",
}, },
.attach = sedlbauer_attach, .probe = sedlbauer_attach,
.event = sedlbauer_event, .remove = sedlbauer_detach,
.detach = sedlbauer_detach,
.id_table = sedlbauer_ids, .id_table = sedlbauer_ids,
.suspend = sedlbauer_suspend,
.resume = sedlbauer_resume,
}; };
static int __init init_sedlbauer_cs(void) static int __init init_sedlbauer_cs(void)
@ -641,7 +545,6 @@ static int __init init_sedlbauer_cs(void)
static void __exit exit_sedlbauer_cs(void) static void __exit exit_sedlbauer_cs(void)
{ {
pcmcia_unregister_driver(&sedlbauer_driver); pcmcia_unregister_driver(&sedlbauer_driver);
BUG_ON(dev_list != NULL);
} }
module_init(init_sedlbauer_cs); module_init(init_sedlbauer_cs);

View File

@ -180,7 +180,6 @@ static struct usb_device_id st5481_ids[] = {
MODULE_DEVICE_TABLE (usb, st5481_ids); MODULE_DEVICE_TABLE (usb, st5481_ids);
static struct usb_driver st5481_usb_driver = { static struct usb_driver st5481_usb_driver = {
.owner = THIS_MODULE,
.name = "st5481_usb", .name = "st5481_usb",
.probe = probe_st5481, .probe = probe_st5481,
.disconnect = disconnect_st5481, .disconnect = disconnect_st5481,

View File

@ -77,8 +77,6 @@ module_param(protocol, int, 0);
static void teles_cs_config(dev_link_t *link); static void teles_cs_config(dev_link_t *link);
static void teles_cs_release(dev_link_t *link); static void teles_cs_release(dev_link_t *link);
static int teles_cs_event(event_t event, int priority,
event_callback_args_t *args);
/* /*
The attach() and detach() entry points are used to create and destroy The attach() and detach() entry points are used to create and destroy
@ -86,16 +84,7 @@ static int teles_cs_event(event_t event, int priority,
needed to manage one actual PCMCIA card. needed to manage one actual PCMCIA card.
*/ */
static dev_link_t *teles_attach(void); static void teles_detach(struct pcmcia_device *p_dev);
static void teles_detach(dev_link_t *);
/*
The dev_info variable is the "key" that is used to match up this
device driver with appropriate cards, through the card configuration
database.
*/
static dev_info_t dev_info = "teles_cs";
/* /*
A linked list of "instances" of the teles_cs device. Each actual A linked list of "instances" of the teles_cs device. Each actual
@ -107,18 +96,7 @@ static dev_info_t dev_info = "teles_cs";
device numbers are used to derive the corresponding array index. device numbers are used to derive the corresponding array index.
*/ */
static dev_link_t *dev_list = NULL;
/* /*
A dev_link_t structure has fields for most things that are needed
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
'priv' pointer in a dev_link_t structure can be used to point to
a device-specific private data structure, like this.
To simplify the data structure handling, we actually include the
dev_link_t structure in the device's private data structure.
A driver needs to provide a dev_node_t structure for each device 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 on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be example, ethernet cards, modems). In other cases, there may be
@ -152,18 +130,16 @@ typedef struct local_info_t {
======================================================================*/ ======================================================================*/
static dev_link_t *teles_attach(void) static int teles_attach(struct pcmcia_device *p_dev)
{ {
client_reg_t client_reg;
dev_link_t *link; dev_link_t *link;
local_info_t *local; local_info_t *local;
int ret;
DEBUG(0, "teles_attach()\n"); DEBUG(0, "teles_attach()\n");
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL); local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) return NULL; if (!local) return -ENOMEM;
memset(local, 0, sizeof(local_info_t)); memset(local, 0, sizeof(local_info_t));
local->cardnr = -1; local->cardnr = -1;
link = &local->link; link->priv = local; link = &local->link; link->priv = local;
@ -188,20 +164,13 @@ static dev_link_t *teles_attach(void)
link->conf.Vcc = 50; link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.IntType = INT_MEMORY_AND_IO;
/* Register with Card Services */ link->handle = p_dev;
link->next = dev_list; p_dev->instance = link;
dev_list = link;
client_reg.dev_info = &dev_info;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = pcmcia_register_client(&link->handle, &client_reg);
if (ret != CS_SUCCESS) {
cs_error(link->handle, RegisterClient, ret);
teles_detach(link);
return NULL;
}
return link; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
teles_cs_config(link);
return 0;
} /* teles_attach */ } /* teles_attach */
/*====================================================================== /*======================================================================
@ -213,32 +182,18 @@ static dev_link_t *teles_attach(void)
======================================================================*/ ======================================================================*/
static void teles_detach(dev_link_t *link) static void teles_detach(struct pcmcia_device *p_dev)
{ {
dev_link_t **linkp; dev_link_t *link = dev_to_instance(p_dev);
local_info_t *info = link->priv; local_info_t *info = link->priv;
int ret;
DEBUG(0, "teles_detach(0x%p)\n", link); DEBUG(0, "teles_detach(0x%p)\n", link);
/* Locate device structure */ if (link->state & DEV_CONFIG) {
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) info->busy = 1;
if (*linkp == link) break; teles_cs_release(link);
if (*linkp == NULL)
return;
if (link->state & DEV_CONFIG)
teles_cs_release(link);
/* Break the link with Card Services */
if (link->handle) {
ret = pcmcia_deregister_client(link->handle);
if (ret != CS_SUCCESS)
cs_error(link->handle, DeregisterClient, ret);
} }
/* Unlink device structure and free it */
*linkp = link->next;
kfree(info); kfree(info);
} /* teles_detach */ } /* teles_detach */
@ -428,60 +383,32 @@ static void teles_cs_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} /* teles_cs_release */ } /* teles_cs_release */
/*====================================================================== static int teles_suspend(struct pcmcia_device *p_dev)
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 int teles_cs_event(event_t event, int priority,
event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv; local_info_t *dev = link->priv;
DEBUG(1, "teles_cs_event(%d)\n", event); link->state |= DEV_SUSPEND;
switch (event) {
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
((local_info_t*)link->priv)->busy = 1;
teles_cs_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
teles_cs_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
dev->busy = 1; dev->busy = 1;
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle); pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME: return 0;
link->state &= ~DEV_SUSPEND; }
/* Fall through... */
case CS_EVENT_CARD_RESET: static int teles_resume(struct pcmcia_device *p_dev)
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf); dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0; dev->busy = 0;
break;
} return 0;
return 0; }
} /* teles_cs_event */
static struct pcmcia_device_id teles_ids[] = { static struct pcmcia_device_id teles_ids[] = {
PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119), PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
@ -494,10 +421,11 @@ static struct pcmcia_driver teles_cs_driver = {
.drv = { .drv = {
.name = "teles_cs", .name = "teles_cs",
}, },
.attach = teles_attach, .probe = teles_attach,
.event = teles_cs_event, .remove = teles_detach,
.detach = teles_detach,
.id_table = teles_ids, .id_table = teles_ids,
.suspend = teles_suspend,
.resume = teles_resume,
}; };
static int __init init_teles_cs(void) static int __init init_teles_cs(void)
@ -508,7 +436,6 @@ static int __init init_teles_cs(void)
static void __exit exit_teles_cs(void) static void __exit exit_teles_cs(void)
{ {
pcmcia_unregister_driver(&teles_cs_driver); pcmcia_unregister_driver(&teles_cs_driver);
BUG_ON(dev_list != NULL);
} }
module_init(init_teles_cs); module_init(init_teles_cs);

View File

@ -857,6 +857,118 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que
return count; return count;
} }
/*
* isdn_readbchan_tty() tries to get data from the read-queue.
* It MUST be called with interrupts off.
*
* Be aware that this is not an atomic operation when sleep != 0, even though
* interrupts are turned off! Well, like that we are currently only called
* on behalf of a read system call on raw device files (which are documented
* to be dangerous and for for debugging purpose only). The inode semaphore
* takes care that this is not called for the same minor device number while
* we are sleeping, but access is not serialized against simultaneous read()
* from the corresponding ttyI device. Can other ugly events, like changes
* of the mapping (di,ch)<->minor, happen during the sleep? --he
*/
int
isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
{
int count;
int count_pull;
int count_put;
int dflag;
struct sk_buff *skb;
char last = 0;
int len;
if (!dev->drv[di])
return 0;
if (skb_queue_empty(&dev->drv[di]->rpqueue[channel]))
return 0;
len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]);
if(len == 0)
return len;
count = 0;
while (len) {
if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel])))
break;
#ifdef CONFIG_ISDN_AUDIO
if (ISDN_AUDIO_SKB_LOCK(skb))
break;
ISDN_AUDIO_SKB_LOCK(skb) = 1;
if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) {
char *p = skb->data;
unsigned long DLEmask = (1 << channel);
dflag = 0;
count_pull = count_put = 0;
while ((count_pull < skb->len) && (len > 0)) {
len--;
if (dev->drv[di]->DLEflag & DLEmask) {
last = DLE;
dev->drv[di]->DLEflag &= ~DLEmask;
} else {
last = *p;
if (last == DLE) {
dev->drv[di]->DLEflag |= DLEmask;
(ISDN_AUDIO_SKB_DLECOUNT(skb))--;
}
p++;
count_pull++;
}
count_put++;
}
if (count_pull >= skb->len)
dflag = 1;
} else {
#endif
/* No DLE's in buff, so simply copy it */
dflag = 1;
if ((count_pull = skb->len) > len) {
count_pull = len;
dflag = 0;
}
count_put = count_pull;
if(count_put > 1)
tty_insert_flip_string(tty, skb->data, count_put - 1);
last = skb->data[count_put] - 1;
len -= count_put;
#ifdef CONFIG_ISDN_AUDIO
}
#endif
count += count_put;
if (dflag) {
/* We got all the data in this buff.
* Now we can dequeue it.
*/
if(cisco_hack)
tty_insert_flip_char(tty, last, 0xFF);
else
tty_insert_flip_char(tty, last, TTY_NORMAL);
#ifdef CONFIG_ISDN_AUDIO
ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif
skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]);
dev_kfree_skb(skb);
} else {
tty_insert_flip_char(tty, last, TTY_NORMAL);
/* Not yet emptied this buff, so it
* must stay in the queue, for further calls
* but we pull off the data we got until now.
*/
skb_pull(skb, count_pull);
#ifdef CONFIG_ISDN_AUDIO
ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif
}
dev->drv[di]->rcvcount[channel] -= count_put;
}
return count;
}
static __inline int static __inline int
isdn_minor2drv(int minor) isdn_minor2drv(int minor)
{ {

View File

@ -37,6 +37,7 @@ extern void isdn_timer_ctrl(int tf, int onoff);
extern void isdn_unexclusive_channel(int di, int ch); extern void isdn_unexclusive_channel(int di, int ch);
extern int isdn_getnum(char **); extern int isdn_getnum(char **);
extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *);
extern int isdn_readbchan_tty(int, int, struct tty_struct *, int);
extern int isdn_get_free_channel(int, int, int, int, int, char *); extern int isdn_get_free_channel(int, int, int, int, int, char *);
extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
extern int register_isdn(isdn_if * i); extern int register_isdn(isdn_if * i);

View File

@ -64,37 +64,42 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb)
int c; int c;
int len; int len;
struct tty_struct *tty; struct tty_struct *tty;
char last;
if (info->online) { if (info->online) {
if ((tty = info->tty)) { if ((tty = info->tty)) {
if (info->mcr & UART_MCR_RTS) { if (info->mcr & UART_MCR_RTS) {
c = TTY_FLIPBUF_SIZE - tty->flip.count;
len = skb->len len = skb->len
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
+ ISDN_AUDIO_SKB_DLECOUNT(skb) + ISDN_AUDIO_SKB_DLECOUNT(skb)
#endif #endif
; ;
c = tty_buffer_request_room(tty, len);
if (c >= len) { if (c >= len) {
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
if (ISDN_AUDIO_SKB_DLECOUNT(skb)) if (ISDN_AUDIO_SKB_DLECOUNT(skb)) {
while (skb->len--) { int l = skb->len;
unsigned char *dp = skb->data;
while (--l) {
if (*skb->data == DLE) if (*skb->data == DLE)
tty_insert_flip_char(tty, DLE, 0); tty_insert_flip_char(tty, DLE, 0);
tty_insert_flip_char(tty, *skb->data++, 0); tty_insert_flip_char(tty, *dp++, 0);
}
last = *dp;
} else { } else {
#endif #endif
memcpy(tty->flip.char_buf_ptr, if(len > 1)
skb->data, len); tty_insert_flip_string(tty, skb->data, len - 1);
tty->flip.count += len; last = skb->data[len - 1];
tty->flip.char_buf_ptr += len;
memset(tty->flip.flag_buf_ptr, 0, len);
tty->flip.flag_buf_ptr += len;
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
} }
#endif #endif
if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP)
tty->flip.flag_buf_ptr[len - 1] = 0xff; tty_insert_flip_char(tty, last, 0xFF);
schedule_delayed_work(&tty->flip.work, 1); else
tty_insert_flip_char(tty, last, TTY_NORMAL);
tty_flip_buffer_push(tty);
kfree_skb(skb); kfree_skb(skb);
return 1; return 1;
} }
@ -114,7 +119,6 @@ isdn_tty_readmodem(void)
int resched = 0; int resched = 0;
int midx; int midx;
int i; int i;
int c;
int r; int r;
struct tty_struct *tty; struct tty_struct *tty;
modem_info *info; modem_info *info;
@ -131,20 +135,13 @@ isdn_tty_readmodem(void)
#endif #endif
if ((tty = info->tty)) { if ((tty = info->tty)) {
if (info->mcr & UART_MCR_RTS) { if (info->mcr & UART_MCR_RTS) {
c = TTY_FLIPBUF_SIZE - tty->flip.count; /* CISCO AsyncPPP Hack */
if (c > 0) { if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
r = isdn_readbchan(info->isdn_driver, info->isdn_channel, r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0);
tty->flip.char_buf_ptr, else
tty->flip.flag_buf_ptr, c, NULL); r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1);
/* CISCO AsyncPPP Hack */ if (r)
if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) tty_flip_buffer_push(tty);
memset(tty->flip.flag_buf_ptr, 0, r);
tty->flip.count += r;
tty->flip.flag_buf_ptr += r;
tty->flip.char_buf_ptr += r;
if (r)
schedule_delayed_work(&tty->flip.work, 1);
}
} else } else
r = 1; r = 1;
} else } else
@ -249,7 +246,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
} }
#endif #endif
#endif #endif
/* Try to deliver directly via tty-flip-buf if queue is empty */ /* Try to deliver directly via tty-buf if queue is empty */
spin_lock_irqsave(&info->readlock, flags); spin_lock_irqsave(&info->readlock, flags);
if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) if (skb_queue_empty(&dev->drv[di]->rpqueue[channel]))
if (isdn_tty_try_read(info, skb)) { if (isdn_tty_try_read(info, skb)) {
@ -534,7 +531,7 @@ isdn_tty_senddown(modem_info * info)
/* The next routine is called once from within timer-interrupt /* The next routine is called once from within timer-interrupt
* triggered within isdn_tty_modem_ncarrier(). It calls * triggered within isdn_tty_modem_ncarrier(). It calls
* isdn_tty_modem_result() to stuff a "NO CARRIER" Message * isdn_tty_modem_result() to stuff a "NO CARRIER" Message
* into the tty's flip-buffer. * into the tty's buffer.
*/ */
static void static void
isdn_tty_modem_do_ncarrier(unsigned long data) isdn_tty_modem_do_ncarrier(unsigned long data)
@ -1685,6 +1682,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
#ifdef ISDN_DEBUG_MODEM_OPEN #ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n");
#endif #endif
module_put(info->owner);
return; return;
} }
info->flags |= ISDN_ASYNC_CLOSING; info->flags |= ISDN_ASYNC_CLOSING;
@ -2347,6 +2345,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
u_long flags; u_long flags;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
char *sp = NULL; char *sp = NULL;
int l = strlen(msg);
if (!msg) { if (!msg) {
printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n");
@ -2359,16 +2358,16 @@ isdn_tty_at_cout(char *msg, modem_info * info)
return; return;
} }
/* use queue instead of direct flip, if online and */ /* use queue instead of direct, if online and */
/* data is in queue or flip buffer is full */ /* data is in queue or buffer is full */
if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || if (info->online && ((tty_buffer_request_room(tty, l) < l) ||
(!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) { !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) {
skb = alloc_skb(strlen(msg), GFP_ATOMIC); skb = alloc_skb(l, GFP_ATOMIC);
if (!skb) { if (!skb) {
spin_unlock_irqrestore(&info->readlock, flags); spin_unlock_irqrestore(&info->readlock, flags);
return; return;
} }
sp = skb_put(skb, strlen(msg)); sp = skb_put(skb, l);
#ifdef CONFIG_ISDN_AUDIO #ifdef CONFIG_ISDN_AUDIO
ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
ISDN_AUDIO_SKB_LOCK(skb) = 0; ISDN_AUDIO_SKB_LOCK(skb) = 0;
@ -2392,9 +2391,8 @@ isdn_tty_at_cout(char *msg, modem_info * info)
if (skb) { if (skb) {
*sp++ = c; *sp++ = c;
} else { } else {
if (tty->flip.count >= TTY_FLIPBUF_SIZE) if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0)
break; break;
tty_insert_flip_char(tty, c, 0);
} }
} }
if (skb) { if (skb) {
@ -2402,12 +2400,12 @@ isdn_tty_at_cout(char *msg, modem_info * info)
dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len;
spin_unlock_irqrestore(&info->readlock, flags); spin_unlock_irqrestore(&info->readlock, flags);
/* Schedule dequeuing */ /* Schedule dequeuing */
if ((dev->modempoll) && (info->rcvsched)) if (dev->modempoll && info->rcvsched)
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
} else { } else {
spin_unlock_irqrestore(&info->readlock, flags); spin_unlock_irqrestore(&info->readlock, flags);
schedule_delayed_work(&tty->flip.work, 1); tty_flip_buffer_push(tty);
} }
} }

View File

@ -43,7 +43,6 @@ extern int send_and_receive(int, unsigned int, unsigned char, unsigned char,
RspMessage *, int); RspMessage *, int);
extern int sendmessage(int, unsigned int, unsigned int, unsigned int, extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int, unsigned int *); unsigned int, unsigned int, unsigned int, unsigned int *);
extern inline void pullphone(char *, char *);
#ifdef DEBUG #ifdef DEBUG
/* /*

View File

@ -71,14 +71,14 @@ int sc_ioctl(int card, scs_ioctl *data)
/* /*
* Get the SRec from user space * Get the SRec from user space
*/ */
if (copy_from_user(srec, data->dataptr, sizeof(srec))) { if (copy_from_user(srec, data->dataptr, SCIOC_SRECSIZE)) {
kfree(rcvmsg); kfree(rcvmsg);
kfree(srec); kfree(srec);
return -EFAULT; return -EFAULT;
} }
status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc, status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc,
0, sizeof(srec), srec, rcvmsg, SAR_TIMEOUT); 0, SCIOC_SRECSIZE, srec, rcvmsg, SAR_TIMEOUT);
kfree(rcvmsg); kfree(rcvmsg);
kfree(srec); kfree(srec);

View File

@ -282,43 +282,43 @@ typedef struct setup_parm {
typedef struct T30_s { typedef struct T30_s {
/* session parameters */ /* session parameters */
__u8 resolution __attribute__ ((packed)); __u8 resolution;
__u8 rate __attribute__ ((packed)); __u8 rate;
__u8 width __attribute__ ((packed)); __u8 width;
__u8 length __attribute__ ((packed)); __u8 length;
__u8 compression __attribute__ ((packed)); __u8 compression;
__u8 ecm __attribute__ ((packed)); __u8 ecm;
__u8 binary __attribute__ ((packed)); __u8 binary;
__u8 scantime __attribute__ ((packed)); __u8 scantime;
__u8 id[FAXIDLEN] __attribute__ ((packed)); __u8 id[FAXIDLEN];
/* additional parameters */ /* additional parameters */
__u8 phase __attribute__ ((packed)); __u8 phase;
__u8 direction __attribute__ ((packed)); __u8 direction;
__u8 code __attribute__ ((packed)); __u8 code;
__u8 badlin __attribute__ ((packed)); __u8 badlin;
__u8 badmul __attribute__ ((packed)); __u8 badmul;
__u8 bor __attribute__ ((packed)); __u8 bor;
__u8 fet __attribute__ ((packed)); __u8 fet;
__u8 pollid[FAXIDLEN] __attribute__ ((packed)); __u8 pollid[FAXIDLEN];
__u8 cq __attribute__ ((packed)); __u8 cq;
__u8 cr __attribute__ ((packed)); __u8 cr;
__u8 ctcrty __attribute__ ((packed)); __u8 ctcrty;
__u8 minsp __attribute__ ((packed)); __u8 minsp;
__u8 phcto __attribute__ ((packed)); __u8 phcto;
__u8 rel __attribute__ ((packed)); __u8 rel;
__u8 nbc __attribute__ ((packed)); __u8 nbc;
/* remote station parameters */ /* remote station parameters */
__u8 r_resolution __attribute__ ((packed)); __u8 r_resolution;
__u8 r_rate __attribute__ ((packed)); __u8 r_rate;
__u8 r_width __attribute__ ((packed)); __u8 r_width;
__u8 r_length __attribute__ ((packed)); __u8 r_length;
__u8 r_compression __attribute__ ((packed)); __u8 r_compression;
__u8 r_ecm __attribute__ ((packed)); __u8 r_ecm;
__u8 r_binary __attribute__ ((packed)); __u8 r_binary;
__u8 r_scantime __attribute__ ((packed)); __u8 r_scantime;
__u8 r_id[FAXIDLEN] __attribute__ ((packed)); __u8 r_id[FAXIDLEN];
__u8 r_code __attribute__ ((packed)); __u8 r_code;
} T30_s; } __attribute__((packed)) T30_s;
#define ISDN_TTY_FAX_CONN_IN 0 #define ISDN_TTY_FAX_CONN_IN 0
#define ISDN_TTY_FAX_CONN_OUT 1 #define ISDN_TTY_FAX_CONN_OUT 1