summaryrefslogtreecommitdiff
path: root/drivers/isdn/gigaset/bas-gigaset.c
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2006-04-11 09:55:16 +0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-11 17:18:50 +0400
commit69049cc87dccb1e6fb54aa25c63033efac805dbd (patch)
tree9db1953a831091335b98f8749865f4c8b410ff9b /drivers/isdn/gigaset/bas-gigaset.c
parent27d1ac2ef7d0b9250ca9fd2ef506e12866ce8fdf (diff)
downloadlinux-69049cc87dccb1e6fb54aa25c63033efac805dbd.tar.xz
[PATCH] isdn4linux: Siemens Gigaset drivers: make some variables non-atomic
With Hansjoerg Lipp <hjlipp@web.de> Replace some atomic_t variables in the Gigaset drivers by non-atomic ones, using spinlocks instead to assure atomicity, as proposed in discussions on the linux-kernel mailing list. Signed-off-by: Hansjoerg Lipp <hjlipp@web.de> Signed-off-by: Tilman Schmidt <tilman@imap.cc> Cc: Karsten Keil <kkeil@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/isdn/gigaset/bas-gigaset.c')
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index fa37db68c962..f86ed6af3aa2 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -367,7 +367,7 @@ static void cmd_in_timeout(unsigned long data)
unsigned long flags;
spin_lock_irqsave(&cs->lock, flags);
- if (unlikely(!atomic_read(&cs->connected))) {
+ if (unlikely(!cs->connected)) {
gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__);
spin_unlock_irqrestore(&cs->lock, flags);
return;
@@ -475,11 +475,6 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
unsigned l;
int channel;
- if (unlikely(!atomic_read(&cs->connected))) {
- warn("%s: disconnected", __func__);
- return;
- }
-
switch (urb->status) {
case 0: /* success */
break;
@@ -603,7 +598,9 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
check_pending(ucs);
resubmit:
- status = usb_submit_urb(urb, SLAB_ATOMIC);
+ spin_lock_irqsave(&cs->lock, flags);
+ status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
+ spin_unlock_irqrestore(&cs->lock, flags);
if (unlikely(status)) {
dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
get_usb_statmsg(status));
@@ -628,7 +625,7 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
unsigned long flags;
spin_lock_irqsave(&cs->lock, flags);
- if (unlikely(!atomic_read(&cs->connected))) {
+ if (unlikely(!cs->connected)) {
warn("%s: disconnected", __func__);
spin_unlock_irqrestore(&cs->lock, flags);
return;
@@ -949,6 +946,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
struct bas_bc_state *ubc = ucx->bcs->hw.bas;
struct usb_iso_packet_descriptor *ifd;
int corrbytes, nframe, rc;
+ unsigned long flags;
/* urb->dev is clobbered by USB subsystem */
urb->dev = ucx->bcs->cs->hw.bas->udev;
@@ -995,7 +993,11 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
ifd->actual_length = 0;
}
if ((urb->number_of_packets = nframe) > 0) {
- if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) {
+ spin_lock_irqsave(&ucx->bcs->cs->lock, flags);
+ rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
+ spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags);
+
+ if (rc) {
dev_err(ucx->bcs->cs->dev,
"could not submit isochronous write URB: %s\n",
get_usb_statmsg(rc));
@@ -1029,11 +1031,6 @@ static void write_iso_tasklet(unsigned long data)
/* loop while completed URBs arrive in time */
for (;;) {
- if (unlikely(!atomic_read(&cs->connected))) {
- warn("%s: disconnected", __func__);
- return;
- }
-
if (unlikely(!(atomic_read(&ubc->running)))) {
gig_dbg(DEBUG_ISO, "%s: not running", __func__);
return;
@@ -1190,11 +1187,6 @@ static void read_iso_tasklet(unsigned long data)
/* loop while more completed URBs arrive in the meantime */
for (;;) {
- if (unlikely(!atomic_read(&cs->connected))) {
- warn("%s: disconnected", __func__);
- return;
- }
-
/* retrieve URB */
spin_lock_irqsave(&ubc->isoinlock, flags);
if (!(urb = ubc->isoindone)) {
@@ -1298,7 +1290,10 @@ static void read_iso_tasklet(unsigned long data)
urb->dev = bcs->cs->hw.bas->udev;
urb->transfer_flags = URB_ISO_ASAP;
urb->number_of_packets = BAS_NUMFRAMES;
- if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) {
+ spin_lock_irqsave(&cs->lock, flags);
+ rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
+ spin_unlock_irqrestore(&cs->lock, flags);
+ if (rc) {
dev_err(cs->dev,
"could not resubmit isochronous read URB: %s\n",
get_usb_statmsg(rc));
@@ -1639,6 +1634,7 @@ static void atrdy_timeout(unsigned long data)
static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
{
struct bas_cardstate *ucs = cs->hw.bas;
+ unsigned long flags;
int ret;
gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len);
@@ -1659,7 +1655,11 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
(unsigned char*) &ucs->dr_cmd_out, buf, len,
write_command_callback, cs);
- if ((ret = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC)) != 0) {
+ spin_lock_irqsave(&cs->lock, flags);
+ ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV;
+ spin_unlock_irqrestore(&cs->lock, flags);
+
+ if (ret) {
dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n",
get_usb_statmsg(ret));
return ret;
@@ -1758,11 +1758,6 @@ static int gigaset_write_cmd(struct cardstate *cs,
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
"CMD Transmit", len, buf);
- if (unlikely(!atomic_read(&cs->connected))) {
- err("%s: disconnected", __func__);
- return -ENODEV;
- }
-
if (len <= 0)
return 0; /* nothing to do */
@@ -2186,6 +2181,7 @@ static int gigaset_probe(struct usb_interface *interface,
error:
freeurbs(cs);
+ usb_set_intfdata(interface, NULL);
gigaset_unassign(cs);
return -ENODEV;
}