diff options
Diffstat (limited to 'drivers/scsi/isci/unsolicited_frame_control.c')
-rw-r--r-- | drivers/scsi/isci/unsolicited_frame_control.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/drivers/scsi/isci/unsolicited_frame_control.c b/drivers/scsi/isci/unsolicited_frame_control.c index d89570700ffd..680582d8cde5 100644 --- a/drivers/scsi/isci/unsolicited_frame_control.c +++ b/drivers/scsi/isci/unsolicited_frame_control.c | |||
@@ -209,7 +209,8 @@ bool scic_sds_unsolicited_frame_control_release_frame( | |||
209 | /* | 209 | /* |
210 | * In the event there are NULL entries in the UF table, we need to | 210 | * In the event there are NULL entries in the UF table, we need to |
211 | * advance the get pointer in order to find out if this frame should | 211 | * advance the get pointer in order to find out if this frame should |
212 | * be released (i.e. update the get pointer). */ | 212 | * be released (i.e. update the get pointer) |
213 | */ | ||
213 | while (lower_32_bits(uf_control->address_table.array[frame_get]) == 0 && | 214 | while (lower_32_bits(uf_control->address_table.array[frame_get]) == 0 && |
214 | upper_32_bits(uf_control->address_table.array[frame_get]) == 0 && | 215 | upper_32_bits(uf_control->address_table.array[frame_get]) == 0 && |
215 | frame_get < SCU_MAX_UNSOLICITED_FRAMES) | 216 | frame_get < SCU_MAX_UNSOLICITED_FRAMES) |
@@ -217,40 +218,37 @@ bool scic_sds_unsolicited_frame_control_release_frame( | |||
217 | 218 | ||
218 | /* | 219 | /* |
219 | * The table has a NULL entry as it's last element. This is | 220 | * The table has a NULL entry as it's last element. This is |
220 | * illegal. */ | 221 | * illegal. |
222 | */ | ||
221 | BUG_ON(frame_get >= SCU_MAX_UNSOLICITED_FRAMES); | 223 | BUG_ON(frame_get >= SCU_MAX_UNSOLICITED_FRAMES); |
224 | if (frame_index >= SCU_MAX_UNSOLICITED_FRAMES) | ||
225 | return false; | ||
222 | 226 | ||
223 | if (frame_index < SCU_MAX_UNSOLICITED_FRAMES) { | 227 | uf_control->buffers.array[frame_index].state = UNSOLICITED_FRAME_RELEASED; |
224 | uf_control->buffers.array[frame_index].state = UNSOLICITED_FRAME_RELEASED; | ||
225 | 228 | ||
229 | if (frame_get != frame_index) { | ||
226 | /* | 230 | /* |
227 | * The frame index is equal to the current get pointer so we | 231 | * Frames remain in use until we advance the get pointer |
228 | * can now free up all of the frame entries that */ | 232 | * so there is nothing we can do here |
229 | if (frame_get == frame_index) { | 233 | */ |
230 | while ( | 234 | return false; |
231 | uf_control->buffers.array[frame_get].state | 235 | } |
232 | == UNSOLICITED_FRAME_RELEASED | ||
233 | ) { | ||
234 | uf_control->buffers.array[frame_get].state = UNSOLICITED_FRAME_EMPTY; | ||
235 | |||
236 | INCREMENT_QUEUE_GET( | ||
237 | frame_get, | ||
238 | frame_cycle, | ||
239 | SCU_MAX_UNSOLICITED_FRAMES - 1, | ||
240 | SCU_MAX_UNSOLICITED_FRAMES); | ||
241 | } | ||
242 | |||
243 | uf_control->get = | ||
244 | (SCU_UFQGP_GEN_BIT(ENABLE_BIT) | frame_cycle | frame_get); | ||
245 | 236 | ||
246 | return true; | 237 | /* |
247 | } else { | 238 | * The frame index is equal to the current get pointer so we |
248 | /* | 239 | * can now free up all of the frame entries that |
249 | * Frames remain in use until we advance the get pointer | 240 | */ |
250 | * so there is nothing we can do here */ | 241 | while (uf_control->buffers.array[frame_get].state == UNSOLICITED_FRAME_RELEASED) { |
251 | } | 242 | uf_control->buffers.array[frame_get].state = UNSOLICITED_FRAME_EMPTY; |
243 | |||
244 | if (frame_get+1 == SCU_MAX_UNSOLICITED_FRAMES-1) { | ||
245 | frame_cycle ^= SCU_MAX_UNSOLICITED_FRAMES; | ||
246 | frame_get = 0; | ||
247 | } else | ||
248 | frame_get++; | ||
252 | } | 249 | } |
253 | 250 | ||
254 | return false; | 251 | uf_control->get = SCU_UFQGP_GEN_BIT(ENABLE_BIT) | frame_cycle | frame_get; |
255 | } | ||
256 | 252 | ||
253 | return true; | ||
254 | } | ||