aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/capi/capi.c60
-rw-r--r--drivers/isdn/capi/capifs.c6
-rw-r--r--drivers/isdn/capi/capiutil.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c2
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c302
-rw-r--r--drivers/isdn/gigaset/common.c19
-rw-r--r--drivers/isdn/gigaset/ev-layer.c13
-rw-r--r--drivers/isdn/gigaset/gigaset.h5
-rw-r--r--drivers/isdn/gigaset/interface.c16
-rw-r--r--drivers/isdn/gigaset/proc.c21
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c4
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c1
-rw-r--r--drivers/isdn/hardware/avm/b1pci.c5
-rw-r--r--drivers/isdn/hardware/avm/b1pcmcia.c2
-rw-r--r--drivers/isdn/hardware/avm/c4.c3
-rw-r--r--drivers/isdn/hardware/avm/t1pci.c3
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c1
-rw-r--r--drivers/isdn/hardware/eicon/diva_didd.c1
-rw-r--r--drivers/isdn/hardware/eicon/divamnt.c4
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c4
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c6
-rw-r--r--drivers/isdn/hardware/eicon/divasproc.c1
-rw-r--r--drivers/isdn/hardware/eicon/platform.h1
-rw-r--r--drivers/isdn/hisax/avm_a1p.c2
-rw-r--r--drivers/isdn/hisax/avm_pci.c3
-rw-r--r--drivers/isdn/hisax/bkm_a4t.c3
-rw-r--r--drivers/isdn/hisax/bkm_a8.c3
-rw-r--r--drivers/isdn/hisax/config.c1
-rw-r--r--drivers/isdn/hisax/diva.c3
-rw-r--r--drivers/isdn/hisax/elsa.c23
-rw-r--r--drivers/isdn/hisax/elsa_ser.c1
-rw-r--r--drivers/isdn/hisax/enternow_pci.c3
-rw-r--r--drivers/isdn/hisax/gazel.c3
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c3
-rw-r--r--drivers/isdn/hisax/hfc_pci.c5
-rw-r--r--drivers/isdn/hisax/hfc_usb.c1
-rw-r--r--drivers/isdn/hisax/hisax.h1
-rw-r--r--drivers/isdn/hisax/hisax_debug.h1
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c4
-rw-r--r--drivers/isdn/hisax/ipacx.c1
-rw-r--r--drivers/isdn/hisax/isdnl3.c1
-rw-r--r--drivers/isdn/hisax/l3dss1.c1
-rw-r--r--drivers/isdn/hisax/niccy.c3
-rw-r--r--drivers/isdn/hisax/nj_s.c3
-rw-r--r--drivers/isdn/hisax/nj_u.c3
-rw-r--r--drivers/isdn/hisax/q931.c4
-rw-r--r--drivers/isdn/hisax/sedlbauer.c5
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c2
-rw-r--r--drivers/isdn/hisax/st5481.h1
-rw-r--r--drivers/isdn/hisax/st5481_init.c1
-rw-r--r--drivers/isdn/hisax/teles3.c1
-rw-r--r--drivers/isdn/hisax/telespci.c8
-rw-r--r--drivers/isdn/hisax/w6692.c3
-rw-r--r--drivers/isdn/hysdn/boardergo.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_defs.h1
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_sched.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c29
-rw-r--r--drivers/isdn/i4l/isdn_net.c1
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c1
-rw-r--r--drivers/isdn/i4l/isdn_tty.c6
-rw-r--r--drivers/isdn/i4l/isdn_tty.h1
-rw-r--r--drivers/isdn/i4l/isdn_x25iface.c4
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c1
-rw-r--r--drivers/isdn/sc/init.c2
-rw-r--r--drivers/isdn/sc/ioctl.c1
67 files changed, 331 insertions, 300 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 173c899a1fb..669f76393b5 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -9,7 +9,6 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -39,7 +38,6 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/moduleparam.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/isdn/capiutil.h>
#include <linux/isdn/capicmd.h>
#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
@@ -87,6 +85,11 @@ struct capincci;
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
struct capiminor;
+struct datahandle_queue {
+ struct list_head list;
+ u16 datahandle;
+};
+
struct capiminor {
struct list_head list;
struct capincci *nccip;
@@ -109,12 +112,9 @@ struct capiminor {
int outbytes;
/* transmit path */
- struct datahandle_queue {
- struct datahandle_queue *next;
- u16 datahandle;
- } *ackqueue;
+ struct list_head ackqueue;
int nack;
-
+ spinlock_t ackqlock;
};
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
@@ -156,48 +156,54 @@ static LIST_HEAD(capiminor_list);
static int capincci_add_ack(struct capiminor *mp, u16 datahandle)
{
- struct datahandle_queue *n, **pp;
+ struct datahandle_queue *n;
+ unsigned long flags;
n = kmalloc(sizeof(*n), GFP_ATOMIC);
- if (!n) {
- printk(KERN_ERR "capi: alloc datahandle failed\n");
- return -1;
+ if (unlikely(!n)) {
+ printk(KERN_ERR "capi: alloc datahandle failed\n");
+ return -1;
}
- n->next = NULL;
n->datahandle = datahandle;
- for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) ;
- *pp = n;
+ INIT_LIST_HEAD(&n->list);
+ spin_lock_irqsave(&mp->ackqlock, flags);
+ list_add_tail(&n->list, &mp->ackqueue);
mp->nack++;
+ spin_unlock_irqrestore(&mp->ackqlock, flags);
return 0;
}
static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
{
- struct datahandle_queue **pp, *p;
+ struct datahandle_queue *p, *tmp;
+ unsigned long flags;
- for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) {
- if ((*pp)->datahandle == datahandle) {
- p = *pp;
- *pp = (*pp)->next;
+ spin_lock_irqsave(&mp->ackqlock, flags);
+ list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
+ if (p->datahandle == datahandle) {
+ list_del(&p->list);
kfree(p);
mp->nack--;
+ spin_unlock_irqrestore(&mp->ackqlock, flags);
return 0;
}
}
+ spin_unlock_irqrestore(&mp->ackqlock, flags);
return -1;
}
static void capiminor_del_all_ack(struct capiminor *mp)
{
- struct datahandle_queue **pp, *p;
+ struct datahandle_queue *p, *tmp;
+ unsigned long flags;
- pp = &mp->ackqueue;
- while (*pp) {
- p = *pp;
- *pp = (*pp)->next;
+ spin_lock_irqsave(&mp->ackqlock, flags);
+ list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
+ list_del(&p->list);
kfree(p);
mp->nack--;
}
+ spin_unlock_irqrestore(&mp->ackqlock, flags);
}
@@ -220,6 +226,8 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
mp->ncci = ncci;
mp->msgid = 0;
atomic_set(&mp->ttyopencount,0);
+ INIT_LIST_HEAD(&mp->ackqueue);
+ spin_lock_init(&mp->ackqlock);
skb_queue_head_init(&mp->inqueue);
skb_queue_head_init(&mp->outqueue);
@@ -1327,7 +1335,6 @@ static int capinc_tty_init(void)
drv->owner = THIS_MODULE;
drv->driver_name = "capi_nc";
- drv->devfs_name = "capi/";
drv->name = "capi";
drv->major = capi_ttymajor;
drv->minor_start = 0;
@@ -1506,8 +1513,6 @@ static int __init capi_init(void)
}
class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
- devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
- "isdn/capi20");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
if (capinc_tty_init() < 0) {
@@ -1542,7 +1547,6 @@ static void __exit capi_exit(void)
class_device_destroy(capi_class, MKDEV(capi_major, 0));
class_destroy(capi_class);
unregister_chrdev(capi_major, "capi20");
- devfs_remove("isdn/capi20");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
capinc_tty_exit();
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 0a37aded4b5..9ea6bd0ddc3 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -121,10 +121,10 @@ fail:
return -ENOMEM;
}
-static struct super_block *capifs_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+static int capifs_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
- return get_sb_single(fs_type, flags, data, capifs_fill_super);
+ return get_sb_single(fs_type, flags, data, capifs_fill_super, mnt);
}
static struct file_system_type capifs_fs_type = {
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index e7cf6bc286a..c1b21552fc0 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
-#include <linux/config.h>
#include <linux/isdn/capiutil.h>
/* from CAPI2.0 DDK AVM Berlin GmbH */
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 1b37d86d5ee..399b316111f 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -9,7 +9,6 @@
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index f1a1f9a9b88..1f5ebe9ee72 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -592,7 +592,7 @@ static int put_address(char *st, u_char *p, int len)
} /* put_address */
/*************************************/
-/* report a succesfull interrogation */
+/* report a successful interrogation */
/*************************************/
static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs)
{ char *src = ic->parm.dss1_io.data;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index eb41aba3dde..3845defd490 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -41,7 +41,6 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
#define GIGASET_MINORS 1
#define GIGASET_MINOR 16
#define GIGASET_MODULENAME "bas_gigaset"
-#define GIGASET_DEVFSNAME "gig/bas/"
#define GIGASET_DEVNAME "ttyGB"
/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
@@ -65,23 +64,22 @@ static struct usb_device_id gigaset_table [] = {
MODULE_DEVICE_TABLE(usb, gigaset_table);
-/*======================= local function prototypes =============================*/
+/*======================= local function prototypes ==========================*/
-/* This function is called if a new device is connected to the USB port. It
- * checks whether this new device belongs to this driver.
- */
+/* function called if a new device belonging to this driver is connected */
static int gigaset_probe(struct usb_interface *interface,
const struct usb_device_id *id);
/* Function will be called if the device is unplugged */
static void gigaset_disconnect(struct usb_interface *interface);
-static void read_ctrl_callback(struct urb *, struct pt_regs *);
+static int atread_submit(struct cardstate *, int);
static void stopurbs(struct bas_bc_state *);
+static int req_submit(struct bc_state *, int, int, int);
static int atwrite_submit(struct cardstate *, unsigned char *, int);
static int start_cbsend(struct cardstate *);
-/*==============================================================================*/
+/*============================================================================*/
struct bas_cardstate {
struct usb_device *udev; /* USB device pointer */
@@ -91,6 +89,7 @@ struct bas_cardstate {
struct urb *urb_ctrl; /* control pipe default URB */
struct usb_ctrlrequest dr_ctrl;
struct timer_list timer_ctrl; /* control request timeout */
+ int retry_ctrl;
struct timer_list timer_atrdy; /* AT command ready timeout */
struct urb *urb_cmd_out; /* for sending AT commands */
@@ -307,6 +306,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
* hang up any existing connection because of an unrecoverable error
* This function may be called from any context and takes care of scheduling
* the necessary actions for execution outside of interrupt context.
+ * cs->lock must not be held.
* argument:
* B channel control structure
*/
@@ -325,14 +325,17 @@ static inline void error_hangup(struct bc_state *bcs)
/* error_reset
* reset Gigaset device because of an unrecoverable error
- * This function may be called from any context, and should take care of
+ * This function may be called from any context, and takes care of
* scheduling the necessary actions for execution outside of interrupt context.
- * Right now, it just generates a kernel message calling for help.
+ * cs->lock must not be held.
* argument:
* controller state structure
*/
static inline void error_reset(struct cardstate *cs)
{
+ /* close AT command channel to recover (ignore errors) */
+ req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
+
//FIXME try to recover without bothering the user
dev_err(cs->dev,
"unrecoverable error - please disconnect Gigaset base to reset\n");
@@ -403,14 +406,30 @@ static void cmd_in_timeout(unsigned long data)
{
struct cardstate *cs = (struct cardstate *) data;
struct bas_cardstate *ucs = cs->hw.bas;
+ int rc;
if (!ucs->rcvbuf_size) {
gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__);
return;
}
- dev_err(cs->dev, "timeout reading AT response\n");
- error_reset(cs); //FIXME retry?
+ if (ucs->retry_cmd_in++ < BAS_RETRY) {
+ dev_notice(cs->dev, "control read: timeout, retry %d\n",
+ ucs->retry_cmd_in);
+ rc = atread_submit(cs, BAS_TIMEOUT);
+ if (rc >= 0 || rc == -ENODEV)
+ /* resubmitted or disconnected */
+ /* - bypass regular exit block */
+ return;
+ } else {
+ dev_err(cs->dev,
+ "control read: timeout, giving up after %d tries\n",
+ ucs->retry_cmd_in);
+ }
+ kfree(ucs->rcvbuf);
+ ucs->rcvbuf = NULL;
+ ucs->rcvbuf_size = 0;
+ error_reset(cs);
}
/* set/clear bits in base connection state, return previous state
@@ -428,6 +447,96 @@ inline static int update_basstate(struct bas_cardstate *ucs,
return state;
}
+/* read_ctrl_callback
+ * USB completion handler for control pipe input
+ * called by the USB subsystem in interrupt context
+ * parameter:
+ * urb USB request block
+ * urb->context = inbuf structure for controller state
+ */
+static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct inbuf_t *inbuf = urb->context;
+ struct cardstate *cs = inbuf->cs;
+ struct bas_cardstate *ucs = cs->hw.bas;
+ int have_data = 0;
+ unsigned numbytes;
+ int rc;
+
+ update_basstate(ucs, 0, BS_ATRDPEND);
+
+ if (!ucs->rcvbuf_size) {
+ dev_warn(cs->dev, "%s: no receive in progress\n", __func__);
+ return;
+ }
+
+ del_timer(&ucs->timer_cmd_in);
+
+ switch (urb->status) {
+ case 0: /* normal completion */
+ numbytes = urb->actual_length;
+ if (unlikely(numbytes != ucs->rcvbuf_size)) {
+ dev_warn(cs->dev,
+ "control read: received %d chars, expected %d\n",
+ numbytes, ucs->rcvbuf_size);
+ if (numbytes > ucs->rcvbuf_size)
+ numbytes = ucs->rcvbuf_size;
+ }
+
+ /* copy received bytes to inbuf */
+ have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes);
+
+ if (unlikely(numbytes < ucs->rcvbuf_size)) {
+ /* incomplete - resubmit for remaining bytes */
+ ucs->rcvbuf_size -= numbytes;
+ ucs->retry_cmd_in = 0;
+ rc = atread_submit(cs, BAS_TIMEOUT);
+ if (rc >= 0 || rc == -ENODEV)
+ /* resubmitted or disconnected */
+ /* - bypass regular exit block */
+ return;
+ error_reset(cs);
+ }
+ break;
+
+ case -ENOENT: /* cancelled */
+ case -ECONNRESET: /* cancelled (async) */
+ case -EINPROGRESS: /* pending */
+ case -ENODEV: /* device removed */
+ case -ESHUTDOWN: /* device shut down */
+ /* no action necessary */
+ gig_dbg(DEBUG_USBREQ, "%s: %s",
+ __func__, get_usb_statmsg(urb->status));
+ break;
+
+ default: /* severe trouble */
+ dev_warn(cs->dev, "control read: %s\n",
+ get_usb_statmsg(urb->status));
+ if (ucs->retry_cmd_in++ < BAS_RETRY) {
+ dev_notice(cs->dev, "control read: retry %d\n",
+ ucs->retry_cmd_in);
+ rc = atread_submit(cs, BAS_TIMEOUT);
+ if (rc >= 0 || rc == -ENODEV)
+ /* resubmitted or disconnected */
+ /* - bypass regular exit block */
+ return;
+ } else {
+ dev_err(cs->dev,
+ "control read: giving up after %d tries\n",
+ ucs->retry_cmd_in);
+ }
+ error_reset(cs);
+ }
+
+ kfree(ucs->rcvbuf);
+ ucs->rcvbuf = NULL;
+ ucs->rcvbuf_size = 0;
+ if (have_data) {
+ gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
+ gigaset_schedule_event(cs);
+ }
+}
+
/* atread_submit
* submit an HD_READ_ATMESSAGE command URB and optionally start a timeout
* parameters:
@@ -466,7 +575,7 @@ static int atread_submit(struct cardstate *cs, int timeout)
if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) {
update_basstate(ucs, 0, BS_ATRDPEND);
dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n",
- get_usb_statmsg(ret));
+ get_usb_rcmsg(ret));
return ret;
}
@@ -611,9 +720,12 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
kfree(ucs->rcvbuf);
ucs->rcvbuf = NULL;
ucs->rcvbuf_size = 0;
- if (rc != -ENODEV)
+ if (rc != -ENODEV) {
//FIXME corrective action?
+ spin_unlock_irqrestore(&cs->lock, flags);
error_reset(cs);
+ break;
+ }
}
spin_unlock_irqrestore(&cs->lock, flags);
break;
@@ -643,97 +755,6 @@ resubmit:
}
}
-/* read_ctrl_callback
- * USB completion handler for control pipe input
- * called by the USB subsystem in interrupt context
- * parameter:
- * urb USB request block
- * urb->context = inbuf structure for controller state
- */
-static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
-{
- struct inbuf_t *inbuf = urb->context;
- struct cardstate *cs = inbuf->cs;
- struct bas_cardstate *ucs = cs->hw.bas;
- int have_data = 0;
- unsigned numbytes;
- int rc;
-
- update_basstate(ucs, 0, BS_ATRDPEND);
-
- if (!ucs->rcvbuf_size) {
- dev_warn(cs->dev, "%s: no receive in progress\n", __func__);
- return;
- }
-
- del_timer(&ucs->timer_cmd_in);
-
- switch (urb->status) {
- case 0: /* normal completion */
- numbytes = urb->actual_length;
- if (unlikely(numbytes == 0)) {
- dev_warn(cs->dev,
- "control read: empty block received\n");
- goto retry;
- }
- if (unlikely(numbytes != ucs->rcvbuf_size)) {
- dev_warn(cs->dev,
- "control read: received %d chars, expected %d\n",
- numbytes, ucs->rcvbuf_size);
- if (numbytes > ucs->rcvbuf_size)
- numbytes = ucs->rcvbuf_size;
- }
-
- /* copy received bytes to inbuf */
- have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes);
-
- if (unlikely(numbytes < ucs->rcvbuf_size)) {
- /* incomplete - resubmit for remaining bytes */
- ucs->rcvbuf_size -= numbytes;
- ucs->retry_cmd_in = 0;
- goto retry;
- }
- break;
-
- case -ENOENT: /* cancelled */
- case -ECONNRESET: /* cancelled (async) */
- case -EINPROGRESS: /* pending */
- case -ENODEV: /* device removed */
- case -ESHUTDOWN: /* device shut down */
- /* no action necessary */
- gig_dbg(DEBUG_USBREQ, "%s: %s",
- __func__, get_usb_statmsg(urb->status));
- break;
-
- default: /* severe trouble */
- dev_warn(cs->dev, "control read: %s\n",
- get_usb_statmsg(urb->status));
- retry:
- if (ucs->retry_cmd_in++ < BAS_RETRY) {
- dev_notice(cs->dev, "control read: retry %d\n",
- ucs->retry_cmd_in);
- rc = atread_submit(cs, BAS_TIMEOUT);
- if (rc >= 0 || rc == -ENODEV)
- /* resubmitted or disconnected */
- /* - bypass regular exit block */
- return;
- } else {
- dev_err(cs->dev,
- "control read: giving up after %d tries\n",
- ucs->retry_cmd_in);
- }
- error_reset(cs);
- }
-
- kfree(ucs->rcvbuf);
- ucs->rcvbuf = NULL;
- ucs->rcvbuf_size = 0;
- if (have_data) {
- gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
- gigaset_schedule_event(cs);
- }
-}
-
/* read_iso_callback
* USB completion handler for B channel isochronous input
* called by the USB subsystem in interrupt context
@@ -1378,6 +1399,7 @@ static void req_timeout(unsigned long data)
case HD_CLOSE_B1CHANNEL:
dev_err(bcs->cs->dev, "timeout closing channel %d\n",
bcs->channel + 1);
+ error_reset(bcs->cs);
break;
default:
@@ -1396,22 +1418,61 @@ static void req_timeout(unsigned long data)
static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs)
{
struct bas_cardstate *ucs = urb->context;
+ int rc;
unsigned long flags;
- spin_lock_irqsave(&ucs->lock, flags);
- if (urb->status && ucs->pending) {
- dev_err(&ucs->interface->dev,
- "control request 0x%02x failed: %s\n",
- ucs->pending, get_usb_statmsg(urb->status));
- del_timer(&ucs->timer_ctrl);
- ucs->pending = 0;
- }
- /* individual handling of specific request types */
- switch (ucs->pending) {
- case HD_DEVICE_INIT_ACK: /* no reply expected */
- ucs->pending = 0;
+ /* check status */
+ switch (urb->status) {
+ case 0: /* normal completion */
+ spin_