aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmol Lad <amol@verismonetworks.com>2006-11-03 01:07:25 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-11-03 15:27:59 -0500
commit1f604c4bc078213aa1c4576efa0e8dad98522fa7 (patch)
treeace4a7db5da33a894009877e2b327bf56624efaa
parent43530d2b04b63ac4bb4ac25deee5f1180ccedc2e (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.c19
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