* There is a small window after a bus reset within which the node
* entry's generation is current but the reconnect wasn't completed.
*/
- if (atomic_read(&scsi_id->unfinished_reset))
+ if (unlikely(atomic_read(&scsi_id->state) == SBP2LU_STATE_IN_RESET))
return;
if (hpsb_node_write(scsi_id->ne,
* Now accept new SCSI commands, unless a bus reset happended during
* hpsb_node_write.
*/
- if (!atomic_read(&scsi_id->unfinished_reset))
+ if (likely(atomic_read(&scsi_id->state) != SBP2LU_STATE_IN_RESET))
scsi_unblock_requests(scsi_id->scsi_host);
}
sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT);
/* scsi_remove_device() will trigger shutdown functions of SCSI
* highlevel drivers which would deadlock if blocked. */
- atomic_set(&scsi_id->unfinished_reset, 0);
+ atomic_set(&scsi_id->state, SBP2LU_STATE_IN_SHUTDOWN);
scsi_unblock_requests(scsi_id->scsi_host);
}
sdev = scsi_id->sdev;
/* Accept new commands unless there was another bus reset in the
* meantime. */
if (hpsb_node_entry_valid(scsi_id->ne)) {
- atomic_set(&scsi_id->unfinished_reset, 0);
+ atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING);
scsi_unblock_requests(scsi_id->scsi_host);
}
return 0;
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
INIT_LIST_HEAD(&scsi_id->scsi_list);
spin_lock_init(&scsi_id->sbp2_command_orb_lock);
- atomic_set(&scsi_id->unfinished_reset, 0);
+ atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING);
INIT_WORK(&scsi_id->protocol_work, NULL, NULL);
ud->device.driver_data = scsi_id;
struct scsi_id_instance_data *scsi_id;
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
-
- if (hi) {
- list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list) {
- atomic_set(&scsi_id->unfinished_reset, 1);
+ if (!hi)
+ return;
+ list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list)
+ if (likely(atomic_read(&scsi_id->state) !=
+ SBP2LU_STATE_IN_SHUTDOWN)) {
+ atomic_set(&scsi_id->state, SBP2LU_STATE_IN_RESET);
scsi_block_requests(scsi_id->scsi_host);
}
- }
}
/*
/* Device specific workarounds/brokeness */
unsigned workarounds;
- atomic_t unfinished_reset;
+ atomic_t state;
struct work_struct protocol_work;
};
+/* For use in scsi_id_instance_data.state */
+enum sbp2lu_state_types {
+ SBP2LU_STATE_RUNNING, /* all normal */
+ SBP2LU_STATE_IN_RESET, /* between bus reset and reconnect */
+ SBP2LU_STATE_IN_SHUTDOWN /* when sbp2_remove was called */
+};
+
/* Sbp2 host data structure (one per IEEE1394 host) */
struct sbp2scsi_host_info {
struct hpsb_host *host; /* IEEE1394 host */