diff options
author | Tilman Schmidt <tilman@imap.cc> | 2006-04-11 01:55:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-11 09:18:50 -0400 |
commit | 69049cc87dccb1e6fb54aa25c63033efac805dbd (patch) | |
tree | 9db1953a831091335b98f8749865f4c8b410ff9b /drivers/isdn/gigaset/bas-gigaset.c | |
parent | 27d1ac2ef7d0b9250ca9fd2ef506e12866ce8fdf (diff) |
[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.c | 48 |
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) | |||
367 | unsigned long flags; | 367 | unsigned long flags; |
368 | 368 | ||
369 | spin_lock_irqsave(&cs->lock, flags); | 369 | spin_lock_irqsave(&cs->lock, flags); |
370 | if (unlikely(!atomic_read(&cs->connected))) { | 370 | if (unlikely(!cs->connected)) { |
371 | gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__); | 371 | gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__); |
372 | spin_unlock_irqrestore(&cs->lock, flags); | 372 | spin_unlock_irqrestore(&cs->lock, flags); |
373 | return; | 373 | return; |
@@ -475,11 +475,6 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
475 | unsigned l; | 475 | unsigned l; |
476 | int channel; | 476 | int channel; |
477 | 477 | ||
478 | if (unlikely(!atomic_read(&cs->connected))) { | ||
479 | warn("%s: disconnected", __func__); | ||
480 | return; | ||
481 | } | ||
482 | |||
483 | switch (urb->status) { | 478 | switch (urb->status) { |
484 | case 0: /* success */ | 479 | case 0: /* success */ |
485 | break; | 480 | break; |
@@ -603,7 +598,9 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
603 | check_pending(ucs); | 598 | check_pending(ucs); |
604 | 599 | ||
605 | resubmit: | 600 | resubmit: |
606 | status = usb_submit_urb(urb, SLAB_ATOMIC); | 601 | spin_lock_irqsave(&cs->lock, flags); |
602 | status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
603 | spin_unlock_irqrestore(&cs->lock, flags); | ||
607 | if (unlikely(status)) { | 604 | if (unlikely(status)) { |
608 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", | 605 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", |
609 | get_usb_statmsg(status)); | 606 | get_usb_statmsg(status)); |
@@ -628,7 +625,7 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
628 | unsigned long flags; | 625 | unsigned long flags; |
629 | 626 | ||
630 | spin_lock_irqsave(&cs->lock, flags); | 627 | spin_lock_irqsave(&cs->lock, flags); |
631 | if (unlikely(!atomic_read(&cs->connected))) { | 628 | if (unlikely(!cs->connected)) { |
632 | warn("%s: disconnected", __func__); | 629 | warn("%s: disconnected", __func__); |
633 | spin_unlock_irqrestore(&cs->lock, flags); | 630 | spin_unlock_irqrestore(&cs->lock, flags); |
634 | return; | 631 | return; |
@@ -949,6 +946,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
949 | struct bas_bc_state *ubc = ucx->bcs->hw.bas; | 946 | struct bas_bc_state *ubc = ucx->bcs->hw.bas; |
950 | struct usb_iso_packet_descriptor *ifd; | 947 | struct usb_iso_packet_descriptor *ifd; |
951 | int corrbytes, nframe, rc; | 948 | int corrbytes, nframe, rc; |
949 | unsigned long flags; | ||
952 | 950 | ||
953 | /* urb->dev is clobbered by USB subsystem */ | 951 | /* urb->dev is clobbered by USB subsystem */ |
954 | urb->dev = ucx->bcs->cs->hw.bas->udev; | 952 | urb->dev = ucx->bcs->cs->hw.bas->udev; |
@@ -995,7 +993,11 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
995 | ifd->actual_length = 0; | 993 | ifd->actual_length = 0; |
996 | } | 994 | } |
997 | if ((urb->number_of_packets = nframe) > 0) { | 995 | if ((urb->number_of_packets = nframe) > 0) { |
998 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 996 | spin_lock_irqsave(&ucx->bcs->cs->lock, flags); |
997 | rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
998 | spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags); | ||
999 | |||
1000 | if (rc) { | ||
999 | dev_err(ucx->bcs->cs->dev, | 1001 | dev_err(ucx->bcs->cs->dev, |
1000 | "could not submit isochronous write URB: %s\n", | 1002 | "could not submit isochronous write URB: %s\n", |
1001 | get_usb_statmsg(rc)); | 1003 | get_usb_statmsg(rc)); |
@@ -1029,11 +1031,6 @@ static void write_iso_tasklet(unsigned long data) | |||
1029 | 1031 | ||
1030 | /* loop while completed URBs arrive in time */ | 1032 | /* loop while completed URBs arrive in time */ |
1031 | for (;;) { | 1033 | for (;;) { |
1032 | if (unlikely(!atomic_read(&cs->connected))) { | ||
1033 | warn("%s: disconnected", __func__); | ||
1034 | return; | ||
1035 | } | ||
1036 | |||
1037 | if (unlikely(!(atomic_read(&ubc->running)))) { | 1034 | if (unlikely(!(atomic_read(&ubc->running)))) { |
1038 | gig_dbg(DEBUG_ISO, "%s: not running", __func__); | 1035 | gig_dbg(DEBUG_ISO, "%s: not running", __func__); |
1039 | return; | 1036 | return; |
@@ -1190,11 +1187,6 @@ static void read_iso_tasklet(unsigned long data) | |||
1190 | 1187 | ||
1191 | /* loop while more completed URBs arrive in the meantime */ | 1188 | /* loop while more completed URBs arrive in the meantime */ |
1192 | for (;;) { | 1189 | for (;;) { |
1193 | if (unlikely(!atomic_read(&cs->connected))) { | ||
1194 | warn("%s: disconnected", __func__); | ||
1195 | return; | ||
1196 | } | ||
1197 | |||
1198 | /* retrieve URB */ | 1190 | /* retrieve URB */ |
1199 | spin_lock_irqsave(&ubc->isoinlock, flags); | 1191 | spin_lock_irqsave(&ubc->isoinlock, flags); |
1200 | if (!(urb = ubc->isoindone)) { | 1192 | if (!(urb = ubc->isoindone)) { |
@@ -1298,7 +1290,10 @@ static void read_iso_tasklet(unsigned long data) | |||
1298 | urb->dev = bcs->cs->hw.bas->udev; | 1290 | urb->dev = bcs->cs->hw.bas->udev; |
1299 | urb->transfer_flags = URB_ISO_ASAP; | 1291 | urb->transfer_flags = URB_ISO_ASAP; |
1300 | urb->number_of_packets = BAS_NUMFRAMES; | 1292 | urb->number_of_packets = BAS_NUMFRAMES; |
1301 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 1293 | spin_lock_irqsave(&cs->lock, flags); |
1294 | rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | ||
1295 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1296 | if (rc) { | ||
1302 | dev_err(cs->dev, | 1297 | dev_err(cs->dev, |
1303 | "could not resubmit isochronous read URB: %s\n", | 1298 | "could not resubmit isochronous read URB: %s\n", |
1304 | get_usb_statmsg(rc)); | 1299 | get_usb_statmsg(rc)); |
@@ -1639,6 +1634,7 @@ static void atrdy_timeout(unsigned long data) | |||
1639 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | 1634 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) |
1640 | { | 1635 | { |
1641 | struct bas_cardstate *ucs = cs->hw.bas; | 1636 | struct bas_cardstate *ucs = cs->hw.bas; |
1637 | unsigned long flags; | ||
1642 | int ret; | 1638 | int ret; |
1643 | 1639 | ||
1644 | gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); | 1640 | 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) | |||
1659 | (unsigned char*) &ucs->dr_cmd_out, buf, len, | 1655 | (unsigned char*) &ucs->dr_cmd_out, buf, len, |
1660 | write_command_callback, cs); | 1656 | write_command_callback, cs); |
1661 | 1657 | ||
1662 | if ((ret = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC)) != 0) { | 1658 | spin_lock_irqsave(&cs->lock, flags); |
1659 | ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV; | ||
1660 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1661 | |||
1662 | if (ret) { | ||
1663 | dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", | 1663 | dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", |
1664 | get_usb_statmsg(ret)); | 1664 | get_usb_statmsg(ret)); |
1665 | return ret; | 1665 | return ret; |
@@ -1758,11 +1758,6 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
1758 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 1758 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
1759 | "CMD Transmit", len, buf); | 1759 | "CMD Transmit", len, buf); |
1760 | 1760 | ||
1761 | if (unlikely(!atomic_read(&cs->connected))) { | ||
1762 | err("%s: disconnected", __func__); | ||
1763 | return -ENODEV; | ||
1764 | } | ||
1765 | |||
1766 | if (len <= 0) | 1761 | if (len <= 0) |
1767 | return 0; /* nothing to do */ | 1762 | return 0; /* nothing to do */ |
1768 | 1763 | ||
@@ -2186,6 +2181,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2186 | 2181 | ||
2187 | error: | 2182 | error: |
2188 | freeurbs(cs); | 2183 | freeurbs(cs); |
2184 | usb_set_intfdata(interface, NULL); | ||
2189 | gigaset_unassign(cs); | 2185 | gigaset_unassign(cs); |
2190 | return -ENODEV; | 2186 | return -ENODEV; |
2191 | } | 2187 | } |