rebase on mainstream patchset 2.6.16
This commit is contained in:
parent
7a49a4e11a
commit
4b242c7873
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
|
@ -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},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue