+static void hpsa_cmd_resolve_events(struct ctlr_info *h,
+ struct CommandList *c)
+{
+ /*
+ * Prevent the following race in the abort handler:
+ *
+ * 1. LLD is requested to abort a SCSI command
+ * 2. The SCSI command completes
+ * 3. The struct CommandList associated with step 2 is made available
+ * 4. New I/O request to LLD to another LUN re-uses struct CommandList
+ * 5. Abort handler follows scsi_cmnd->host_scribble and
+ * finds struct CommandList and tries to aborts it
+ * Now we have aborted the wrong command.
+ *
+ * Clear c->scsi_cmd here so that the abort handler will know this
+ * command has completed. Then, check to see if the abort handler is
+ * waiting for this command, and, if so, wake it.
+ */
+ c->scsi_cmd = SCSI_CMD_IDLE;
+ mb(); /* Ensure c->scsi_cmd is set to SCSI_CMD_IDLE */
+ if (c->abort_pending) {
+ c->abort_pending = false;
+ wake_up_all(&h->abort_sync_wait_queue);
+ }
+}
+