diff options
-rw-r--r-- | drivers/ieee1394/sbp2.c | 21 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 9 |
2 files changed, 19 insertions, 11 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 3cb6b479b2ef..017259cc34f3 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -478,7 +478,7 @@ static void sbp2util_notify_fetch_agent(struct scsi_id_instance_data *scsi_id, | |||
478 | * There is a small window after a bus reset within which the node | 478 | * There is a small window after a bus reset within which the node |
479 | * entry's generation is current but the reconnect wasn't completed. | 479 | * entry's generation is current but the reconnect wasn't completed. |
480 | */ | 480 | */ |
481 | if (atomic_read(&scsi_id->unfinished_reset)) | 481 | if (unlikely(atomic_read(&scsi_id->state) == SBP2LU_STATE_IN_RESET)) |
482 | return; | 482 | return; |
483 | 483 | ||
484 | if (hpsb_node_write(scsi_id->ne, | 484 | if (hpsb_node_write(scsi_id->ne, |
@@ -489,7 +489,7 @@ static void sbp2util_notify_fetch_agent(struct scsi_id_instance_data *scsi_id, | |||
489 | * Now accept new SCSI commands, unless a bus reset happended during | 489 | * Now accept new SCSI commands, unless a bus reset happended during |
490 | * hpsb_node_write. | 490 | * hpsb_node_write. |
491 | */ | 491 | */ |
492 | if (!atomic_read(&scsi_id->unfinished_reset)) | 492 | if (likely(atomic_read(&scsi_id->state) != SBP2LU_STATE_IN_RESET)) |
493 | scsi_unblock_requests(scsi_id->scsi_host); | 493 | scsi_unblock_requests(scsi_id->scsi_host); |
494 | } | 494 | } |
495 | 495 | ||
@@ -756,7 +756,7 @@ static int sbp2_remove(struct device *dev) | |||
756 | sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); | 756 | sbp2scsi_complete_all_commands(scsi_id, DID_NO_CONNECT); |
757 | /* scsi_remove_device() will trigger shutdown functions of SCSI | 757 | /* scsi_remove_device() will trigger shutdown functions of SCSI |
758 | * highlevel drivers which would deadlock if blocked. */ | 758 | * highlevel drivers which would deadlock if blocked. */ |
759 | atomic_set(&scsi_id->unfinished_reset, 0); | 759 | atomic_set(&scsi_id->state, SBP2LU_STATE_IN_SHUTDOWN); |
760 | scsi_unblock_requests(scsi_id->scsi_host); | 760 | scsi_unblock_requests(scsi_id->scsi_host); |
761 | } | 761 | } |
762 | sdev = scsi_id->sdev; | 762 | sdev = scsi_id->sdev; |
@@ -811,7 +811,7 @@ static int sbp2_update(struct unit_directory *ud) | |||
811 | /* Accept new commands unless there was another bus reset in the | 811 | /* Accept new commands unless there was another bus reset in the |
812 | * meantime. */ | 812 | * meantime. */ |
813 | if (hpsb_node_entry_valid(scsi_id->ne)) { | 813 | if (hpsb_node_entry_valid(scsi_id->ne)) { |
814 | atomic_set(&scsi_id->unfinished_reset, 0); | 814 | atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING); |
815 | scsi_unblock_requests(scsi_id->scsi_host); | 815 | scsi_unblock_requests(scsi_id->scsi_host); |
816 | } | 816 | } |
817 | return 0; | 817 | return 0; |
@@ -842,7 +842,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
842 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); | 842 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); |
843 | INIT_LIST_HEAD(&scsi_id->scsi_list); | 843 | INIT_LIST_HEAD(&scsi_id->scsi_list); |
844 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); | 844 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); |
845 | atomic_set(&scsi_id->unfinished_reset, 0); | 845 | atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING); |
846 | INIT_WORK(&scsi_id->protocol_work, NULL, NULL); | 846 | INIT_WORK(&scsi_id->protocol_work, NULL, NULL); |
847 | 847 | ||
848 | ud->device.driver_data = scsi_id; | 848 | ud->device.driver_data = scsi_id; |
@@ -926,13 +926,14 @@ static void sbp2_host_reset(struct hpsb_host *host) | |||
926 | struct scsi_id_instance_data *scsi_id; | 926 | struct scsi_id_instance_data *scsi_id; |
927 | 927 | ||
928 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); | 928 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); |
929 | 929 | if (!hi) | |
930 | if (hi) { | 930 | return; |
931 | list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list) { | 931 | list_for_each_entry(scsi_id, &hi->scsi_ids, scsi_list) |
932 | atomic_set(&scsi_id->unfinished_reset, 1); | 932 | if (likely(atomic_read(&scsi_id->state) != |
933 | SBP2LU_STATE_IN_SHUTDOWN)) { | ||
934 | atomic_set(&scsi_id->state, SBP2LU_STATE_IN_RESET); | ||
933 | scsi_block_requests(scsi_id->scsi_host); | 935 | scsi_block_requests(scsi_id->scsi_host); |
934 | } | 936 | } |
935 | } | ||
936 | } | 937 | } |
937 | 938 | ||
938 | /* | 939 | /* |
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index 34c52bf4fa34..abbe48e646c3 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
@@ -347,10 +347,17 @@ struct scsi_id_instance_data { | |||
347 | /* Device specific workarounds/brokeness */ | 347 | /* Device specific workarounds/brokeness */ |
348 | unsigned workarounds; | 348 | unsigned workarounds; |
349 | 349 | ||
350 | atomic_t unfinished_reset; | 350 | atomic_t state; |
351 | struct work_struct protocol_work; | 351 | struct work_struct protocol_work; |
352 | }; | 352 | }; |
353 | 353 | ||
354 | /* For use in scsi_id_instance_data.state */ | ||
355 | enum sbp2lu_state_types { | ||
356 | SBP2LU_STATE_RUNNING, /* all normal */ | ||
357 | SBP2LU_STATE_IN_RESET, /* between bus reset and reconnect */ | ||
358 | SBP2LU_STATE_IN_SHUTDOWN /* when sbp2_remove was called */ | ||
359 | }; | ||
360 | |||
354 | /* Sbp2 host data structure (one per IEEE1394 host) */ | 361 | /* Sbp2 host data structure (one per IEEE1394 host) */ |
355 | struct sbp2scsi_host_info { | 362 | struct sbp2scsi_host_info { |
356 | struct hpsb_host *host; /* IEEE1394 host */ | 363 | struct hpsb_host *host; /* IEEE1394 host */ |