diff options
author | Amol Lad <amol@verismonetworks.com> | 2006-11-03 01:07:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-11-03 15:27:59 -0500 |
commit | 1f604c4bc078213aa1c4576efa0e8dad98522fa7 (patch) | |
tree | ace4a7db5da33a894009877e2b327bf56624efaa | |
parent | 43530d2b04b63ac4bb4ac25deee5f1180ccedc2e (diff) |
[PATCH] drivers/isdn/hysdn/hysdn_sched.c: sleep after taking spinlock fix
spin_lock_irq{save,restore} is incorrectly called here (the function can
sleep after acquring the lock).
done the necessary corrections and removed unwanted cli/sti.
Signed-off-by: Amol Lad <amol@verismonetworks.com>
Signed-off-by: Karsten Keil <kkeil@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/isdn/hysdn/hysdn_sched.c | 19 |
1 files changed, 4 insertions, 15 deletions
diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c index 1fadf0133e9b..18758772b744 100644 --- a/drivers/isdn/hysdn/hysdn_sched.c +++ b/drivers/isdn/hysdn/hysdn_sched.c | |||
@@ -155,21 +155,17 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) | |||
155 | if (card->debug_flags & LOG_SCHED_ASYN) | 155 | if (card->debug_flags & LOG_SCHED_ASYN) |
156 | hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); | 156 | hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); |
157 | 157 | ||
158 | spin_lock_irqsave(&card->hysdn_lock, flags); | ||
159 | while (card->async_busy) { | 158 | while (card->async_busy) { |
160 | sti(); | ||
161 | 159 | ||
162 | if (card->debug_flags & LOG_SCHED_ASYN) | 160 | if (card->debug_flags & LOG_SCHED_ASYN) |
163 | hysdn_addlog(card, "async tx-cfg delayed"); | 161 | hysdn_addlog(card, "async tx-cfg delayed"); |
164 | 162 | ||
165 | msleep_interruptible(20); /* Timeout 20ms */ | 163 | msleep_interruptible(20); /* Timeout 20ms */ |
166 | if (!--cnt) { | 164 | if (!--cnt) |
167 | spin_unlock_irqrestore(&card->hysdn_lock, flags); | ||
168 | return (-ERR_ASYNC_TIME); /* timed out */ | 165 | return (-ERR_ASYNC_TIME); /* timed out */ |
169 | } | ||
170 | cli(); | ||
171 | } /* wait for buffer to become free */ | 166 | } /* wait for buffer to become free */ |
172 | 167 | ||
168 | spin_lock_irqsave(&card->hysdn_lock, flags); | ||
173 | strcpy(card->async_data, line); | 169 | strcpy(card->async_data, line); |
174 | card->async_len = strlen(line) + 1; | 170 | card->async_len = strlen(line) + 1; |
175 | card->async_channel = chan; | 171 | card->async_channel = chan; |
@@ -177,30 +173,23 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) | |||
177 | 173 | ||
178 | /* now queue the task */ | 174 | /* now queue the task */ |
179 | schedule_work(&card->irq_queue); | 175 | schedule_work(&card->irq_queue); |
180 | sti(); | 176 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
181 | 177 | ||
182 | if (card->debug_flags & LOG_SCHED_ASYN) | 178 | if (card->debug_flags & LOG_SCHED_ASYN) |
183 | hysdn_addlog(card, "async tx-cfg data queued"); | 179 | hysdn_addlog(card, "async tx-cfg data queued"); |
184 | 180 | ||
185 | cnt++; /* short delay */ | 181 | cnt++; /* short delay */ |
186 | cli(); | ||
187 | 182 | ||
188 | while (card->async_busy) { | 183 | while (card->async_busy) { |
189 | sti(); | ||
190 | 184 | ||
191 | if (card->debug_flags & LOG_SCHED_ASYN) | 185 | if (card->debug_flags & LOG_SCHED_ASYN) |
192 | hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); | 186 | hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); |
193 | 187 | ||
194 | msleep_interruptible(20); /* Timeout 20ms */ | 188 | msleep_interruptible(20); /* Timeout 20ms */ |
195 | if (!--cnt) { | 189 | if (!--cnt) |
196 | spin_unlock_irqrestore(&card->hysdn_lock, flags); | ||
197 | return (-ERR_ASYNC_TIME); /* timed out */ | 190 | return (-ERR_ASYNC_TIME); /* timed out */ |
198 | } | ||
199 | cli(); | ||
200 | } /* wait for buffer to become free again */ | 191 | } /* wait for buffer to become free again */ |
201 | 192 | ||
202 | spin_unlock_irqrestore(&card->hysdn_lock, flags); | ||
203 | |||
204 | if (card->debug_flags & LOG_SCHED_ASYN) | 193 | if (card->debug_flags & LOG_SCHED_ASYN) |
205 | hysdn_addlog(card, "async tx-cfg data send"); | 194 | hysdn_addlog(card, "async tx-cfg data send"); |
206 | 195 | ||