diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 104 |
1 files changed, 52 insertions, 52 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 46e14f22ec18..1bb55086db9f 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -30,7 +30,6 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *, | |||
30 | void (*done) (struct scsi_cmnd *)); | 30 | void (*done) (struct scsi_cmnd *)); |
31 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); | 31 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); |
32 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); | 32 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); |
33 | static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *); | ||
34 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); | 33 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); |
35 | static int zfcp_task_management_function(struct zfcp_unit *, u8, | 34 | static int zfcp_task_management_function(struct zfcp_unit *, u8, |
36 | struct scsi_cmnd *); | 35 | struct scsi_cmnd *); |
@@ -44,33 +43,24 @@ struct scsi_transport_template *zfcp_transport_template; | |||
44 | 43 | ||
45 | struct zfcp_data zfcp_data = { | 44 | struct zfcp_data zfcp_data = { |
46 | .scsi_host_template = { | 45 | .scsi_host_template = { |
47 | name: ZFCP_NAME, | 46 | .name = ZFCP_NAME, |
48 | proc_name: "zfcp", | 47 | .proc_name = "zfcp", |
49 | proc_info: NULL, | 48 | .slave_alloc = zfcp_scsi_slave_alloc, |
50 | detect: NULL, | 49 | .slave_configure = zfcp_scsi_slave_configure, |
51 | slave_alloc: zfcp_scsi_slave_alloc, | 50 | .slave_destroy = zfcp_scsi_slave_destroy, |
52 | slave_configure: zfcp_scsi_slave_configure, | 51 | .queuecommand = zfcp_scsi_queuecommand, |
53 | slave_destroy: zfcp_scsi_slave_destroy, | 52 | .eh_abort_handler = zfcp_scsi_eh_abort_handler, |
54 | queuecommand: zfcp_scsi_queuecommand, | 53 | .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, |
55 | eh_abort_handler: zfcp_scsi_eh_abort_handler, | 54 | .eh_bus_reset_handler = zfcp_scsi_eh_host_reset_handler, |
56 | eh_device_reset_handler: zfcp_scsi_eh_device_reset_handler, | 55 | .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, |
57 | eh_bus_reset_handler: zfcp_scsi_eh_bus_reset_handler, | 56 | .can_queue = 4096, |
58 | eh_host_reset_handler: zfcp_scsi_eh_host_reset_handler, | 57 | .this_id = -1, |
59 | /* FIXME(openfcp): Tune */ | 58 | .sg_tablesize = ZFCP_MAX_SBALES_PER_REQ, |
60 | can_queue: 4096, | 59 | .cmd_per_lun = 1, |
61 | this_id: -1, | 60 | .use_clustering = 1, |
62 | /* | 61 | .sdev_attrs = zfcp_sysfs_sdev_attrs, |
63 | * FIXME: | ||
64 | * one less? can zfcp_create_sbale cope with it? | ||
65 | */ | ||
66 | sg_tablesize: ZFCP_MAX_SBALES_PER_REQ, | ||
67 | cmd_per_lun: 1, | ||
68 | unchecked_isa_dma: 0, | ||
69 | use_clustering: 1, | ||
70 | sdev_attrs: zfcp_sysfs_sdev_attrs, | ||
71 | }, | 62 | }, |
72 | .driver_version = ZFCP_VERSION, | 63 | .driver_version = ZFCP_VERSION, |
73 | /* rest initialised with zeros */ | ||
74 | }; | 64 | }; |
75 | 65 | ||
76 | /* Find start of Response Information in FCP response unit*/ | 66 | /* Find start of Response Information in FCP response unit*/ |
@@ -177,8 +167,14 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp) | |||
177 | return retval; | 167 | return retval; |
178 | } | 168 | } |
179 | 169 | ||
180 | static void | 170 | /** |
181 | zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | 171 | * zfcp_scsi_slave_destroy - called when scsi device is removed |
172 | * | ||
173 | * Remove reference to associated scsi device for an zfcp_unit. | ||
174 | * Mark zfcp_unit as failed. The scsi device might be deleted via sysfs | ||
175 | * or a scan for this device might have failed. | ||
176 | */ | ||
177 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | ||
182 | { | 178 | { |
183 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 179 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; |
184 | 180 | ||
@@ -186,6 +182,7 @@ zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | |||
186 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); | 182 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); |
187 | sdpnt->hostdata = NULL; | 183 | sdpnt->hostdata = NULL; |
188 | unit->device = NULL; | 184 | unit->device = NULL; |
185 | zfcp_erp_unit_failed(unit); | ||
189 | zfcp_unit_put(unit); | 186 | zfcp_unit_put(unit); |
190 | } else { | 187 | } else { |
191 | ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " | 188 | ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " |
@@ -550,35 +547,38 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags, | |||
550 | } | 547 | } |
551 | 548 | ||
552 | /** | 549 | /** |
553 | * zfcp_scsi_eh_bus_reset_handler - reset bus (reopen adapter) | 550 | * zfcp_scsi_eh_host_reset_handler - handler for host and bus reset |
551 | * | ||
552 | * If ERP is already running it will be stopped. | ||
554 | */ | 553 | */ |
555 | int | 554 | int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) |
556 | zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt) | ||
557 | { | 555 | { |
558 | struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata; | 556 | struct zfcp_unit *unit; |
559 | struct zfcp_adapter *adapter = unit->port->adapter; | 557 | struct zfcp_adapter *adapter; |
560 | 558 | unsigned long flags; | |
561 | ZFCP_LOG_NORMAL("bus reset because of problems with " | ||
562 | "unit 0x%016Lx\n", unit->fcp_lun); | ||
563 | zfcp_erp_adapter_reopen(adapter, 0); | ||
564 | zfcp_erp_wait(adapter); | ||
565 | |||
566 | return SUCCESS; | ||
567 | } | ||
568 | 559 | ||
569 | /** | 560 | unit = (struct zfcp_unit*) scpnt->device->hostdata; |
570 | * zfcp_scsi_eh_host_reset_handler - reset host (reopen adapter) | 561 | adapter = unit->port->adapter; |
571 | */ | ||
572 | int | ||
573 | zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | ||
574 | { | ||
575 | struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata; | ||
576 | struct zfcp_adapter *adapter = unit->port->adapter; | ||
577 | 562 | ||
578 | ZFCP_LOG_NORMAL("host reset because of problems with " | 563 | ZFCP_LOG_NORMAL("host/bus reset because of problems with " |
579 | "unit 0x%016Lx\n", unit->fcp_lun); | 564 | "unit 0x%016Lx\n", unit->fcp_lun); |
580 | zfcp_erp_adapter_reopen(adapter, 0); | 565 | |
581 | zfcp_erp_wait(adapter); | 566 | write_lock_irqsave(&adapter->erp_lock, flags); |
567 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, | ||
568 | &adapter->status)) { | ||
569 | zfcp_erp_modify_adapter_status(adapter, | ||
570 | ZFCP_STATUS_COMMON_UNBLOCKED|ZFCP_STATUS_COMMON_OPEN, | ||
571 | ZFCP_CLEAR); | ||
572 | zfcp_erp_action_dismiss_adapter(adapter); | ||
573 | write_unlock_irqrestore(&adapter->erp_lock, flags); | ||
574 | zfcp_fsf_req_dismiss_all(adapter); | ||
575 | adapter->fsf_req_seq_no = 0; | ||
576 | zfcp_erp_adapter_reopen(adapter, 0); | ||
577 | } else { | ||
578 | write_unlock_irqrestore(&adapter->erp_lock, flags); | ||
579 | zfcp_erp_adapter_reopen(adapter, 0); | ||
580 | zfcp_erp_wait(adapter); | ||
581 | } | ||
582 | 582 | ||
583 | return SUCCESS; | 583 | return SUCCESS; |
584 | } | 584 | } |