diff options
Diffstat (limited to 'drivers/scsi/aacraid/dpcsup.c')
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index abc9ef5d1b10..9c7408fe8c7d 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
@@ -57,9 +57,9 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
57 | struct hw_fib * hwfib; | 57 | struct hw_fib * hwfib; |
58 | struct fib * fib; | 58 | struct fib * fib; |
59 | int consumed = 0; | 59 | int consumed = 0; |
60 | unsigned long flags; | 60 | unsigned long flags, mflags; |
61 | 61 | ||
62 | spin_lock_irqsave(q->lock, flags); | 62 | spin_lock_irqsave(q->lock, flags); |
63 | /* | 63 | /* |
64 | * Keep pulling response QEs off the response queue and waking | 64 | * Keep pulling response QEs off the response queue and waking |
65 | * up the waiters until there are no more QEs. We then return | 65 | * up the waiters until there are no more QEs. We then return |
@@ -125,12 +125,21 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
125 | } else { | 125 | } else { |
126 | unsigned long flagv; | 126 | unsigned long flagv; |
127 | spin_lock_irqsave(&fib->event_lock, flagv); | 127 | spin_lock_irqsave(&fib->event_lock, flagv); |
128 | if (!fib->done) | 128 | if (!fib->done) { |
129 | fib->done = 1; | 129 | fib->done = 1; |
130 | up(&fib->event_wait); | 130 | up(&fib->event_wait); |
131 | } | ||
131 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 132 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
133 | |||
134 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
135 | dev->management_fib_count--; | ||
136 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
137 | |||
132 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 138 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
133 | if (fib->done == 2) { | 139 | if (fib->done == 2) { |
140 | spin_lock_irqsave(&fib->event_lock, flagv); | ||
141 | fib->done = 0; | ||
142 | spin_unlock_irqrestore(&fib->event_lock, flagv); | ||
134 | aac_fib_complete(fib); | 143 | aac_fib_complete(fib); |
135 | aac_fib_free(fib); | 144 | aac_fib_free(fib); |
136 | } | 145 | } |
@@ -232,6 +241,7 @@ unsigned int aac_command_normal(struct aac_queue *q) | |||
232 | 241 | ||
233 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) | 242 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) |
234 | { | 243 | { |
244 | unsigned long mflags; | ||
235 | dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); | 245 | dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); |
236 | if ((index & 0x00000002L)) { | 246 | if ((index & 0x00000002L)) { |
237 | struct hw_fib * hw_fib; | 247 | struct hw_fib * hw_fib; |
@@ -320,11 +330,25 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) | |||
320 | unsigned long flagv; | 330 | unsigned long flagv; |
321 | dprintk((KERN_INFO "event_wait up\n")); | 331 | dprintk((KERN_INFO "event_wait up\n")); |
322 | spin_lock_irqsave(&fib->event_lock, flagv); | 332 | spin_lock_irqsave(&fib->event_lock, flagv); |
323 | if (!fib->done) | 333 | if (!fib->done) { |
324 | fib->done = 1; | 334 | fib->done = 1; |
325 | up(&fib->event_wait); | 335 | up(&fib->event_wait); |
336 | } | ||
326 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 337 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
338 | |||
339 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
340 | dev->management_fib_count--; | ||
341 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
342 | |||
327 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 343 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
344 | if (fib->done == 2) { | ||
345 | spin_lock_irqsave(&fib->event_lock, flagv); | ||
346 | fib->done = 0; | ||
347 | spin_unlock_irqrestore(&fib->event_lock, flagv); | ||
348 | aac_fib_complete(fib); | ||
349 | aac_fib_free(fib); | ||
350 | } | ||
351 | |||
328 | } | 352 | } |
329 | return 0; | 353 | return 0; |
330 | } | 354 | } |