diff options
Diffstat (limited to 'drivers/isdn')
25 files changed, 423 insertions, 707 deletions
diff --git a/drivers/isdn/act2000/act2000.h b/drivers/isdn/act2000/act2000.h index b091d1a54125..d4c50512a1ff 100644 --- a/drivers/isdn/act2000/act2000.h +++ b/drivers/isdn/act2000/act2000.h @@ -181,17 +181,17 @@ typedef struct act2000_card { char regname[35]; /* Name used for request_region */ } 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); } -extern __inline__ void act2000_schedule_rx(act2000_card *card) +static inline void act2000_schedule_rx(act2000_card *card) { 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); } diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h index f6d5f530b86b..49f453c53c64 100644 --- a/drivers/isdn/act2000/capi.h +++ b/drivers/isdn/act2000/capi.h @@ -78,29 +78,29 @@ typedef union actcapi_infoel { /* info element */ typedef struct actcapi_msn { __u8 eaz; __u8 len; /* Length of MSN */ - __u8 msn[15] __attribute__ ((packed)); -} actcapi_msn; + __u8 msn[15]; +} __attribute__((packed)) actcapi_msn; typedef struct actcapi_dlpd { __u8 len; /* Length of structure */ - __u16 dlen __attribute__ ((packed)); /* Data Length */ - __u8 laa __attribute__ ((packed)); /* Link Address A */ + __u16 dlen; /* Data Length */ + __u8 laa; /* Link Address A */ __u8 lab; /* Link Address B */ __u8 modulo; /* Modulo Mode */ __u8 win; /* Window size */ __u8 xid[100]; /* XID Information */ -} actcapi_dlpd; +} __attribute__((packed)) actcapi_dlpd; typedef struct actcapi_ncpd { __u8 len; /* Length of structure */ - __u16 lic __attribute__ ((packed)); - __u16 hic __attribute__ ((packed)); - __u16 ltc __attribute__ ((packed)); - __u16 htc __attribute__ ((packed)); - __u16 loc __attribute__ ((packed)); - __u16 hoc __attribute__ ((packed)); - __u8 modulo __attribute__ ((packed)); -} actcapi_ncpd; + __u16 lic; + __u16 hic; + __u16 ltc; + __u16 htc; + __u16 loc; + __u16 hoc; + __u8 modulo; +} __attribute__((packed)) actcapi_ncpd; #define actcapi_ncpi actcapi_ncpd /* @@ -168,19 +168,19 @@ typedef struct actcapi_msg { __u16 manuf_msg; __u16 controller; actcapi_msn msnmap; - } manufacturer_req_msn; + } __attribute ((packed)) manufacturer_req_msn; /* TODO: TraceInit-req/conf/ind/resp and * TraceDump-req/conf/ind/resp */ struct connect_req { __u8 controller; __u8 bchan; - __u32 infomask __attribute__ ((packed)); + __u32 infomask; __u8 si1; __u8 si2; __u8 eaz; actcapi_addr addr; - } connect_req; + } __attribute__ ((packed)) connect_req; struct connect_conf { __u16 plci; __u16 info; @@ -192,7 +192,7 @@ typedef struct actcapi_msg { __u8 si2; __u8 eaz; actcapi_addr addr; - } connect_ind; + } __attribute__ ((packed)) connect_ind; struct connect_resp { __u16 plci; __u8 rejectcause; @@ -200,14 +200,14 @@ typedef struct actcapi_msg { struct connect_active_ind { __u16 plci; actcapi_addr addr; - } connect_active_ind; + } __attribute__ ((packed)) connect_active_ind; struct connect_active_resp { __u16 plci; } connect_active_resp; struct connect_b3_req { __u16 plci; actcapi_ncpi ncpi; - } connect_b3_req; + } __attribute__ ((packed)) connect_b3_req; struct connect_b3_conf { __u16 plci; __u16 ncci; @@ -217,12 +217,12 @@ typedef struct actcapi_msg { __u16 ncci; __u16 plci; actcapi_ncpi ncpi; - } connect_b3_ind; + } __attribute__ ((packed)) connect_b3_ind; struct connect_b3_resp { __u16 ncci; __u8 rejectcause; - actcapi_ncpi ncpi __attribute__ ((packed)); - } connect_b3_resp; + actcapi_ncpi ncpi; + } __attribute__ ((packed)) connect_b3_resp; struct disconnect_req { __u16 plci; __u8 cause; @@ -241,14 +241,14 @@ typedef struct actcapi_msg { struct connect_b3_active_ind { __u16 ncci; actcapi_ncpi ncpi; - } connect_b3_active_ind; + } __attribute__ ((packed)) connect_b3_active_ind; struct connect_b3_active_resp { __u16 ncci; } connect_b3_active_resp; struct disconnect_b3_req { __u16 ncci; actcapi_ncpi ncpi; - } disconnect_b3_req; + } __attribute__ ((packed)) disconnect_b3_req; struct disconnect_b3_conf { __u16 ncci; __u16 info; @@ -257,7 +257,7 @@ typedef struct actcapi_msg { __u16 ncci; __u16 info; actcapi_ncpi ncpi; - } disconnect_b3_ind; + } __attribute__ ((packed)) disconnect_b3_ind; struct disconnect_b3_resp { __u16 ncci; } disconnect_b3_resp; @@ -265,7 +265,7 @@ typedef struct actcapi_msg { __u16 plci; actcapi_infonr nr; actcapi_infoel el; - } info_ind; + } __attribute__ ((packed)) info_ind; struct info_resp { __u16 plci; } info_resp; @@ -279,8 +279,8 @@ typedef struct actcapi_msg { struct select_b2_protocol_req { __u16 plci; __u8 protocol; - actcapi_dlpd dlpd __attribute__ ((packed)); - } select_b2_protocol_req; + actcapi_dlpd dlpd; + } __attribute__ ((packed)) select_b2_protocol_req; struct select_b2_protocol_conf { __u16 plci; __u16 info; @@ -288,49 +288,49 @@ typedef struct actcapi_msg { struct select_b3_protocol_req { __u16 plci; __u8 protocol; - actcapi_ncpd ncpd __attribute__ ((packed)); - } select_b3_protocol_req; + actcapi_ncpd ncpd; + } __attribute__ ((packed)) select_b3_protocol_req; struct select_b3_protocol_conf { __u16 plci; __u16 info; } select_b3_protocol_conf; struct listen_req { __u8 controller; - __u32 infomask __attribute__ ((packed)); - __u16 eazmask __attribute__ ((packed)); - __u16 simask __attribute__ ((packed)); - } listen_req; + __u32 infomask; + __u16 eazmask; + __u16 simask; + } __attribute__ ((packed)) listen_req; struct listen_conf { __u8 controller; - __u16 info __attribute__ ((packed)); - } listen_conf; + __u16 info; + } __attribute__ ((packed)) listen_conf; struct data_b3_req { __u16 fakencci; __u16 datalen; __u32 unused; __u8 blocknr; - __u16 flags __attribute__ ((packed)); - } data_b3_req; + __u16 flags; + } __attribute ((packed)) data_b3_req; struct data_b3_ind { __u16 fakencci; __u16 datalen; __u32 unused; __u8 blocknr; - __u16 flags __attribute__ ((packed)); - } data_b3_ind; + __u16 flags; + } __attribute__ ((packed)) data_b3_ind; struct data_b3_resp { __u16 ncci; __u8 blocknr; - } data_b3_resp; + } __attribute__ ((packed)) data_b3_resp; struct data_b3_conf { __u16 ncci; __u8 blocknr; - __u16 info __attribute__ ((packed)); - } data_b3_conf; + __u16 info; + } __attribute__ ((packed)) data_b3_conf; } msg; -} actcapi_msg; +} __attribute__ ((packed)) actcapi_msg; -extern __inline__ unsigned short +static inline unsigned short actcapi_nextsmsg(act2000_card *card) { unsigned long flags; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 11ae0fddea04..623adbb0d13a 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -463,8 +463,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) #endif goto bad; } - if (ld->receive_room && - ld->receive_room(mp->tty) < datalen) { + if (mp->tty->receive_room < datalen) { #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) printk(KERN_DEBUG "capi: no room in tty\n"); #endif diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index 7b564c0dd996..0a37aded4b54 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c @@ -17,6 +17,8 @@ #include <linux/ctype.h> #include <linux/sched.h> /* current */ +#include "capifs.h" + MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem"); MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); @@ -136,7 +138,7 @@ static struct dentry *get_node(int num) { char s[10]; 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)); } @@ -157,7 +159,7 @@ void capifs_new_ncci(unsigned int number, dev_t device) dentry = get_node(number); if (!IS_ERR(dentry) && !dentry->d_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) @@ -173,7 +175,7 @@ void capifs_free_ncci(unsigned int number) } dput(dentry); } - up(&capifs_root->d_inode->i_sem); + mutex_unlock(&capifs_root->d_inode->i_mutex); } static int __init capifs_init(void) diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 27391c32f3eb..2a2b03ff096b 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -53,8 +53,6 @@ MODULE_LICENSE("GPL"); static void avmcs_config(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 @@ -62,16 +60,7 @@ static int avmcs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *avmcs_attach(void); -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"; +static void avmcs_detach(struct pcmcia_device *p_dev); /* 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. */ -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 on a card. In some cases, there is only one device per card (for 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; local_info_t *local; - int ret; - + /* Initialize the dev_link_t structure */ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); if (!link) @@ -155,25 +134,19 @@ static dev_link_t *avmcs_attach(void) goto err_kfree; memset(local, 0, sizeof(local_info_t)); link->priv = local; - - /* Register with Card Services */ - link->next = dev_list; - 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); - avmcs_detach(link); - goto err; - } - return link; + + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + avmcs_config(link); + + return 0; err_kfree: kfree(link); err: - return NULL; + return -EINVAL; } /* 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; - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; + dev_link_t *link = dev_to_instance(p_dev); - /* - 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; - } + if (link->state & DEV_CONFIG) + avmcs_release(link); - /* 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); } /* avmcs_detach */ @@ -424,12 +377,30 @@ static void avmcs_release(dev_link_t *link) pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) - avmcs_detach(link); - } /* avmcs_release */ +static int avmcs_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int avmcs_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + + return 0; +} + /*====================================================================== The card status event handler. Mostly, this schedules other @@ -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[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), @@ -490,10 +429,11 @@ static struct pcmcia_driver avmcs_driver = { .drv = { .name = "avm_cs", }, - .attach = avmcs_attach, - .event = avmcs_event, - .detach = avmcs_detach, + .probe = avmcs_attach, + .remove = avmcs_detach, .id_table = avmcs_ids, + .suspend= avmcs_suspend, + .resume = avmcs_resume, }; static int __init avmcs_init(void) @@ -504,7 +444,6 @@ static int __init avmcs_init(void) static void __exit avmcs_exit(void) { pcmcia_unregister_driver(&avmcs_driver); - BUG_ON(dev_list != NULL); } module_init(avmcs_init); diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c index cccfabc1117d..11e6f937c1e4 100644 --- a/drivers/isdn/hardware/eicon/os_4bri.c +++ b/drivers/isdn/hardware/eicon/os_4bri.c @@ -16,6 +16,7 @@ #include "diva_pci.h" #include "mi_pc.h" #include "dsrv4bri.h" +#include "helpers.h" static void *diva_xdiLoadFileFile = NULL; static dword diva_xdiLoadFileLength = 0; @@ -815,7 +816,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, return (ret); } -void *xdiLoadFile(char *FileName, unsigned long *FileLength, +void *xdiLoadFile(char *FileName, dword *FileLength, unsigned long lim) { void *ret = diva_xdiLoadFileFile; diff --git a/drivers/isdn/hardware/eicon/os_bri.c b/drivers/isdn/hardware/eicon/os_bri.c index 4cc44a5dd1db..f31bba5b16ff 100644 --- a/drivers/isdn/hardware/eicon/os_bri.c +++ b/drivers/isdn/hardware/eicon/os_bri.c @@ -16,6 +16,7 @@ #include "diva_pci.h" #include "mi_pc.h" #include "pc_maint.h" +#include "dsrv_bri.h" /* ** IMPORTS diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c index 8ac207f75e54..a296a846f296 100644 --- a/drivers/isdn/hardware/eicon/os_pri.c +++ b/drivers/isdn/hardware/eicon/os_pri.c @@ -18,6 +18,7 @@ #include "pc_maint.h" #include "dsp_tst.h" #include "diva_dma.h" +#include "dsrv_pri.h" /* -------------------------------------------------------------------------- OS Dependent part of XDI driver for DIVA PRI Adapter diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index c82105920d71..0ef560144be3 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -110,7 +110,7 @@ config HISAX_16_3 config HISAX_TELESPCI bool "Teles PCI" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) help This enables HiSax support for the Teles PCI. See <file:Documentation/isdn/README.HiSax> on how to configure it. @@ -238,7 +238,7 @@ config HISAX_MIC config HISAX_NETJET bool "NETjet card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) help This enables HiSax support for the NetJet from Traverse Technologies. @@ -249,7 +249,7 @@ config HISAX_NETJET config HISAX_NETJET_U bool "NETspider U card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) help This enables HiSax support for the Netspider U interface ISDN card from Traverse Technologies. @@ -317,7 +317,7 @@ config HISAX_GAZEL config HISAX_HFC_PCI bool "HFC PCI-Bus cards" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) help This enables HiSax support for the HFC-S PCI 2BDS0 based cards. @@ -344,7 +344,7 @@ config HISAX_HFC_SX config HISAX_ENTERNOW_PCI 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 This enables HiSax support for the Formula-n enter:now PCI ISDN card. diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index 5d8ee7368f7b..4abe5ff10e72 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -358,7 +358,7 @@ hdlc_fill_fifo(struct BCState *bcs) } } -static inline void +static void HDLC_irq(struct BCState *bcs, u_int stat) { int len; struct sk_buff *skb; diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 5f5a5ae740d2..969da40c4248 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -69,8 +69,6 @@ module_param(isdnprot, int, 0); static void avma1cs_config(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 @@ -78,16 +76,8 @@ static int avma1cs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *avma1cs_attach(void); -static void avma1cs_detach(dev_link_t *); +static void avma1cs_detach(struct pcmcia_device *p_dev); -/* - 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 @@ -99,15 +89,7 @@ static dev_info_t dev_info = "avma1_cs"; 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 on a card. In some cases, there is only one device per card (for 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; local_info_t *local; - int ret; - + DEBUG(0, "avma1cs_attach()\n"); /* Initialize the dev_link_t structure */ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); if (!link) - return NULL; + return -ENOMEM; memset(link, 0, sizeof(struct dev_link_t)); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) { kfree(link); - return NULL; + return -ENOMEM; } memset(local, 0, sizeof(local_info_t)); link->priv = local; @@ -178,20 +158,13 @@ static dev_link_t *avma1cs_attach(void) link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - /* Register with Card Services */ - link->next = dev_list; - 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; - } + link->handle = p_dev; + p_dev->instance = link; - return link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + avma1cs_config(link); + + return 0; } /* 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); - - /* 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) { -#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; - } + if (link->state & DEV_CONFIG) + avma1cs_release(link); - /* 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); - } /* avma1cs_detach */ /*====================================================================== @@ -440,58 +388,30 @@ static void avma1cs_release(dev_link_t *link) pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) - avma1cs_detach(link); } /* avma1cs_release */ -/*====================================================================== +static int avma1cs_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(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. + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); - 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. - -======================================================================*/ + return 0; +} -static int avma1cs_event(event_t event, int priority, - event_callback_args_t *args) +static int avma1cs_resume(struct pcmcia_device *dev) { - dev_link_t *link = args->client_data; + dev_link_t *link = dev_to_instance(dev); - DEBUG(1, "avma1cs_event(0x%06x)\n", event); - - 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); - break; - case CS_EVENT_PM_RESUME: - link->state &= ~DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_CARD_RESET: - if (link->state & DEV_CONFIG) + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) pcmcia_request_configuration(link->handle, &link->conf); - break; - } - return 0; -} /* avma1cs_event */ + + return 0; +} + static struct pcmcia_device_id avma1cs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), @@ -505,10 +425,11 @@ static struct pcmcia_driver avma1cs_driver = { .drv = { .name = "avma1_cs", }, - .attach = avma1cs_attach, - .event = avma1cs_event, - .detach = avma1cs_detach, + .probe = avma1cs_attach, + .remove = avma1cs_detach, .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) { pcmcia_unregister_driver(&avma1cs_driver); - BUG_ON(dev_list != NULL); } module_init(init_avma1_cs); diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index b62d6b30b72b..b0ff1cc97d7c 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -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) { u_char r; diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 6fc6868de0b0..062fb8f0739f 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -96,8 +96,6 @@ module_param(protocol, int, 0); static void elsa_cs_config(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 @@ -105,39 +103,9 @@ static int elsa_cs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *elsa_cs_attach(void); -static void elsa_cs_detach(dev_link_t *); +static void elsa_cs_detach(struct pcmcia_device *p_dev); /* - 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 on a card. In some cases, there is only one device per card (for 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; local_info_t *local; - int ret; DEBUG(0, "elsa_cs_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return NULL; + if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; link = &local->link; link->priv = local; @@ -207,20 +173,13 @@ static dev_link_t *elsa_cs_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = dev_list; - 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; - } + link->handle = p_dev; + p_dev->instance = link; - return link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + elsa_cs_config(link); + + return 0; } /* 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; - int ret; DEBUG(0, "elsa_cs_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) - 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); + if (link->state & DEV_CONFIG) { + info->busy = 1; + elsa_cs_release(link); } - /* Unlink device structure and free it */ - *linkp = link->next; kfree(info); } /* elsa_cs_detach */ @@ -447,60 +392,31 @@ static void elsa_cs_release(dev_link_t *link) link->state &= ~DEV_CONFIG; } /* elsa_cs_release */ -/*====================================================================== - - 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. +static int elsa_suspend(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - 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. + link->state |= DEV_SUSPEND; + dev->busy = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); -======================================================================*/ + return 0; +} -static int elsa_cs_event(event_t event, int priority, - event_callback_args_t *args) +static int elsa_resume(struct pcmcia_device *p_dev) { - dev_link_t *link = args->client_data; - local_info_t *dev = link->priv; - - DEBUG(1, "elsa_cs_event(%d)\n", event); + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - 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; - 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); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; - break; - } - return 0; -} /* elsa_cs_event */ + + return 0; +} static struct pcmcia_device_id elsa_ids[] = { 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 = { .name = "elsa_cs", }, - .attach = elsa_cs_attach, - .event = elsa_cs_event, - .detach = elsa_cs_detach, + .probe = elsa_cs_attach, + .remove = elsa_cs_detach, .id_table = elsa_ids, + .suspend = elsa_suspend, + .resume = elsa_resume, }; 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) { pcmcia_unregister_driver(&elsa_cs_driver); - BUG_ON(dev_list != NULL); } module_init(init_elsa_cs); diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index f8457ef48826..ca5b4a3b683e 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -1715,7 +1715,6 @@ hfc_usb_disconnect(struct usb_interface /* our driver information structure */ /************************************/ static struct usb_driver hfc_drv = { - .owner = THIS_MODULE, .name = "hfc_usb", .id_table = hfcusb_idtab, .probe = hfc_usb_probe, diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 26c545fa223b..1b85ce166af8 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -396,17 +396,17 @@ struct isar_hw { struct hdlc_stat_reg { #ifdef __BIG_ENDIAN - u_char fill __attribute__((packed)); - u_char mode __attribute__((packed)); - u_char xml __attribute__((packed)); - u_char cmd __attribute__((packed)); + u_char fill; + u_char mode; + u_char xml; + u_char cmd; #else - u_char cmd __attribute__((packed)); - u_char xml __attribute__((packed)); - u_char mode __attribute__((packed)); - u_char fill __attribute__((packed)); + u_char cmd; + u_char xml; + u_char mode; + u_char fill; #endif -}; +} __attribute__((packed)); struct hdlc_hw { union { diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.h b/drivers/isdn/hisax/hisax_fcpcipnp.h index bd8a22e4d6a2..21fbcedf3a94 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.h +++ b/drivers/isdn/hisax/hisax_fcpcipnp.h @@ -12,17 +12,17 @@ enum { struct hdlc_stat_reg { #ifdef __BIG_ENDIAN - u_char fill __attribute__((packed)); - u_char mode __attribute__((packed)); - u_char xml __attribute__((packed)); - u_char cmd __attribute__((packed)); + u_char fill; + u_char mode; + u_char xml; + u_char cmd; #else - u_char cmd __attribute__((packed)); - u_char xml __attribute__((packed)); - u_char mode __attribute__((packed)); - u_char fill __attribute__((packed)); + u_char cmd; + u_char xml; + u_char mode; + u_char fill; #endif -}; +} __attribute__((packed)); struct fritz_bcs { struct hisax_b_if b_if; diff --git a/drivers/isdn/hisax/hscx_irq.c b/drivers/isdn/hisax/hscx_irq.c index 5fe9d42d03a3..7b1ad5e4ecda 100644 --- a/drivers/isdn/hisax/hscx_irq.c +++ b/drivers/isdn/hisax/hscx_irq.c @@ -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) { 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) { diff --git a/drivers/isdn/hisax/jade_irq.c b/drivers/isdn/hisax/jade_irq.c index 08563400e4fd..1f201af15a0f 100644 --- a/drivers/isdn/hisax/jade_irq.c +++ b/drivers/isdn/hisax/jade_irq.c @@ -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) { u_char r; diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index dc334aab433e..6f5213a18a8d 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -97,8 +97,6 @@ module_param(protocol, int, 0); static void sedlbauer_config(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 @@ -106,8 +104,7 @@ static int sedlbauer_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *sedlbauer_attach(void); -static void sedlbauer_detach(dev_link_t *); +static void sedlbauer_detach(struct pcmcia_device *p_dev); /* 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 on a card. In some cases, there is only one device per card (for 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; dev_link_t *link; - client_reg_t client_reg; - int ret; DEBUG(0, "sedlbauer_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return NULL; + if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; link = &local->link; link->priv = local; @@ -221,20 +187,13 @@ static dev_link_t *sedlbauer_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = dev_list; - 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; - } + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + sedlbauer_config(link); - return link; + return 0; } /* 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); - - /* 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) { -#ifdef PCMCIA_DEBUG - printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' " - "still locked\n", link->dev->dev_name); -#endif - link->state |= DEV_STALE_LINK; - return; + ((local_info_t *)link->priv)->stop = 1; + sedlbauer_release(link); } - /* 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 */ kfree(link->priv); } /* sedlbauer_detach */ @@ -547,68 +484,34 @@ static void sedlbauer_release(dev_link_t *link) if (link->irq.AssignedIRQ) pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) - sedlbauer_detach(link); - } /* sedlbauer_release */ -/*====================================================================== - - 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) +static int sedlbauer_suspend(struct pcmcia_device *p_dev) { - dev_link_t *link = args->client_data; - 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: + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; + link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - /* Mark the device as stopped, to block IO until later */ dev->stop = 1; if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - break; - case CS_EVENT_PM_RESUME: + pcmcia_release_configuration(link->handle); + + 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; - /* Fall through... */ - case CS_EVENT_CARD_RESET: if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); + pcmcia_request_configuration(link->handle, &link->conf); dev->stop = 0; - /* - In a normal driver, additional code may go here to restore - the device state and restart IO. - */ - break; - } - return 0; -} /* sedlbauer_event */ + + return 0; +} + static struct pcmcia_device_id sedlbauer_ids[] = { 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 = { .name = "sedlbauer_cs", }, - .attach = sedlbauer_attach, - .event = sedlbauer_event, - .detach = sedlbauer_detach, + .probe = sedlbauer_attach, + .remove = sedlbauer_detach, .id_table = sedlbauer_ids, + .suspend = sedlbauer_suspend, + .resume = sedlbauer_resume, }; 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) { pcmcia_unregister_driver(&sedlbauer_driver); - BUG_ON(dev_list != NULL); } module_init(init_sedlbauer_cs); diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c index 8e192a3a3490..99cb0f3d59a1 100644 --- a/drivers/isdn/hisax/st5481_init.c +++ b/drivers/isdn/hisax/st5481_init.c @@ -180,7 +180,6 @@ static struct usb_device_id st5481_ids[] = { MODULE_DEVICE_TABLE (usb, st5481_ids); static struct usb_driver st5481_usb_driver = { - .owner = THIS_MODULE, .name = "st5481_usb", .probe = probe_st5481, .disconnect = disconnect_st5481, diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 0ddef1bf778b..4e5c14c7240e 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -77,8 +77,6 @@ module_param(protocol, int, 0); static void teles_cs_config(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 @@ -86,16 +84,7 @@ static int teles_cs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *teles_attach(void); -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"; +static void teles_detach(struct pcmcia_device *p_dev); /* 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. */ -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 on a card. In some cases, there is only one device per card (for 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; local_info_t *local; - int ret; DEBUG(0, "teles_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return NULL; + if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; link = &local->link; link->priv = local; @@ -188,20 +164,13 @@ static dev_link_t *teles_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = dev_list; - 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; - } + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + teles_cs_config(link); - return link; + return 0; } /* 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; - int ret; DEBUG(0, "teles_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) - 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); + if (link->state & DEV_CONFIG) { + info->busy = 1; + teles_cs_release(link); } - /* Unlink device structure and free it */ - *linkp = link->next; kfree(info); } /* teles_detach */ @@ -428,60 +383,32 @@ static void teles_cs_release(dev_link_t *link) link->state &= ~DEV_CONFIG; } /* teles_cs_release */ -/*====================================================================== - - 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. +static int teles_suspend(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - 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. + link->state |= DEV_SUSPEND; + dev->busy = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); -======================================================================*/ + return 0; +} -static int teles_cs_event(event_t event, int priority, - event_callback_args_t *args) +static int teles_resume(struct pcmcia_device *p_dev) { - dev_link_t *link = args->client_data; - local_info_t *dev = link->priv; - - DEBUG(1, "teles_cs_event(%d)\n", event); + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - 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; - 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); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; - break; - } - return 0; -} /* teles_cs_event */ + + return 0; +} + static struct pcmcia_device_id teles_ids[] = { PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119), @@ -494,10 +421,11 @@ static struct pcmcia_driver teles_cs_driver = { .drv = { .name = "teles_cs", }, - .attach = teles_attach, - .event = teles_cs_event, - .detach = teles_detach, + .probe = teles_attach, + .remove = teles_detach, .id_table = teles_ids, + .suspend = teles_suspend, + .resume = teles_resume, }; 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) { pcmcia_unregister_driver(&teles_cs_driver); - BUG_ON(dev_list != NULL); } module_init(init_teles_cs); diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 4643df097bfe..22759c01746a 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -857,6 +857,118 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que 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 isdn_minor2drv(int minor) { diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h index e27e9c3a81ed..082735dbb412 100644 --- a/drivers/isdn/i4l/isdn_common.h +++ b/drivers/isdn/i4l/isdn_common.h @@ -37,6 +37,7 @@ extern void isdn_timer_ctrl(int tf, int onoff); extern void isdn_unexclusive_channel(int di, int ch); extern int isdn_getnum(char **); 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_writebuf_skb_stub(int, int, int, struct sk_buff *); extern int register_isdn(isdn_if * i); diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 8c404b4e2482..f190a99604f0 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -64,37 +64,42 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) int c; int len; struct tty_struct *tty; + char last; if (info->online) { if ((tty = info->tty)) { if (info->mcr & UART_MCR_RTS) { - c = TTY_FLIPBUF_SIZE - tty->flip.count; len = skb->len #ifdef CONFIG_ISDN_AUDIO + ISDN_AUDIO_SKB_DLECOUNT(skb) #endif ; + + c = tty_buffer_request_room(tty, len); if (c >= len) { #ifdef CONFIG_ISDN_AUDIO - if (ISDN_AUDIO_SKB_DLECOUNT(skb)) - while (skb->len--) { + if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { + int l = skb->len; + unsigned char *dp = skb->data; + while (--l) { if (*skb->data == DLE) 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 { #endif - memcpy(tty->flip.char_buf_ptr, - skb->data, len); - tty->flip.count += len; - tty->flip.char_buf_ptr += len; - memset(tty->flip.flag_buf_ptr, 0, len); - tty->flip.flag_buf_ptr += len; + if(len > 1) + tty_insert_flip_string(tty, skb->data, len - 1); + last = skb->data[len - 1]; #ifdef CONFIG_ISDN_AUDIO } #endif if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) - tty->flip.flag_buf_ptr[len - 1] = 0xff; - schedule_delayed_work(&tty->flip.work, 1); + tty_insert_flip_char(tty, last, 0xFF); + else + tty_insert_flip_char(tty, last, TTY_NORMAL); + tty_flip_buffer_push(tty); kfree_skb(skb); return 1; } @@ -114,7 +119,6 @@ isdn_tty_readmodem(void) int resched = 0; int midx; int i; - int c; int r; struct tty_struct *tty; modem_info *info; @@ -131,20 +135,13 @@ isdn_tty_readmodem(void) #endif if ((tty = info->tty)) { if (info->mcr & UART_MCR_RTS) { - c = TTY_FLIPBUF_SIZE - tty->flip.count; - if (c > 0) { - r = isdn_readbchan(info->isdn_driver, info->isdn_channel, - tty->flip.char_buf_ptr, - tty->flip.flag_buf_ptr, c, NULL); - /* CISCO AsyncPPP Hack */ - if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) - 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); - } + /* CISCO AsyncPPP Hack */ + if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) + r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); + else + r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); + if (r) + tty_flip_buffer_push(tty); } else r = 1; } else @@ -249,7 +246,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb) } #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); if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) 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 * triggered within isdn_tty_modem_ncarrier(). It calls * isdn_tty_modem_result() to stuff a "NO CARRIER" Message - * into the tty's flip-buffer. + * into the tty's buffer. */ static void isdn_tty_modem_do_ncarrier(unsigned long data) @@ -2347,6 +2344,7 @@ isdn_tty_at_cout(char *msg, modem_info * info) u_long flags; struct sk_buff *skb = NULL; char *sp = NULL; + int l = strlen(msg); if (!msg) { printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); @@ -2359,16 +2357,16 @@ isdn_tty_at_cout(char *msg, modem_info * info) return; } - /* use queue instead of direct flip, if online and */ - /* data is in queue or flip buffer is full */ - if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || - (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) { - skb = alloc_skb(strlen(msg), GFP_ATOMIC); + /* use queue instead of direct, if online and */ + /* data is in queue or buffer is full */ + if ((info->online && tty_buffer_request_room(tty, l) < l) || + (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { + skb = alloc_skb(l, GFP_ATOMIC); if (!skb) { spin_unlock_irqrestore(&info->readlock, flags); return; } - sp = skb_put(skb, strlen(msg)); + sp = skb_put(skb, l); #ifdef CONFIG_ISDN_AUDIO ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; ISDN_AUDIO_SKB_LOCK(skb) = 0; @@ -2392,9 +2390,8 @@ isdn_tty_at_cout(char *msg, modem_info * info) if (skb) { *sp++ = c; } else { - if (tty->flip.count >= TTY_FLIPBUF_SIZE) + if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0) break; - tty_insert_flip_char(tty, c, 0); } } if (skb) { @@ -2402,12 +2399,12 @@ isdn_tty_at_cout(char *msg, modem_info * info) dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; spin_unlock_irqrestore(&info->readlock, flags); /* Schedule dequeuing */ - if ((dev->modempoll) && (info->rcvsched)) + if (dev->modempoll && info->rcvsched) isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); } else { spin_unlock_irqrestore(&info->readlock, flags); - schedule_delayed_work(&tty->flip.work, 1); + tty_flip_buffer_push(tty); } } diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c index 19f2fcf0ae4a..b4b24335f716 100644 --- a/drivers/isdn/sc/command.c +++ b/drivers/isdn/sc/command.c @@ -43,7 +43,6 @@ extern int send_and_receive(int, unsigned int, unsigned char, unsigned char, RspMessage *, int); extern int sendmessage(int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int *); -extern inline void pullphone(char *, char *); #ifdef DEBUG /* |