]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/s390-11-12-zfcp_scsi_scan.patch
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / s390-11-12-zfcp_scsi_scan.patch
CommitLineData
2cb7cef9
BS
1From: Gerald Schaefer <geraldsc@de.ibm.com>
2Subject: zfcp: Move scan_target to scsi host workqueue
3References: bnc#484767,LTC#52236
4
5Symptom: Trying to attach a non-existing LUN blocks all state
6 changes in the zfcp driver.
7Problem: If the storage server does not respond, the
8 scsi_scan_target call blocks until it reaches all
9 timeouts. This blocks all other tasks on the zfcp workqueue.
10Solution: Run the scsi_scan_target work on the scsi host
11 workqueue, the same one where the scan from the SCSI
12 midlayer runs on.
13
14Acked-by: John Jolly <jjolly@suse.de>
15---
16 drivers/s390/scsi/zfcp_aux.c | 5 +---
17 drivers/s390/scsi/zfcp_def.h | 2 -
18 drivers/s390/scsi/zfcp_erp.c | 49 +++---------------------------------------
19 drivers/s390/scsi/zfcp_ext.h | 1
20 drivers/s390/scsi/zfcp_scsi.c | 14 ++++++++++++
21 5 files changed, 22 insertions(+), 49 deletions(-)
22
23--- a/drivers/s390/scsi/zfcp_aux.c 2009-03-16 16:41:33.000000000 +0100
24+++ b/drivers/s390/scsi/zfcp_aux.c 2009-03-16 16:42:42.000000000 +0100
25@@ -133,9 +133,7 @@ static void __init zfcp_init_device_conf
26 ccw_device_set_online(adapter->ccw_device);
27
28 zfcp_erp_wait(adapter);
29- wait_event(adapter->erp_done_wqh,
30- !(atomic_read(&unit->status) &
31- ZFCP_STATUS_UNIT_SCSI_WORK_PENDING));
32+ flush_work(&unit->scsi_work);
33
34 down(&zfcp_data.config_sema);
35 zfcp_unit_put(unit);
36@@ -288,6 +286,7 @@ struct zfcp_unit *zfcp_unit_enqueue(stru
37
38 atomic_set(&unit->refcount, 0);
39 init_waitqueue_head(&unit->remove_wq);
40+ INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
41
42 unit->port = port;
43 unit->fcp_lun = fcp_lun;
44--- a/drivers/s390/scsi/zfcp_def.h 2009-03-16 16:41:33.000000000 +0100
45+++ b/drivers/s390/scsi/zfcp_def.h 2009-03-16 16:43:18.000000000 +0100
46@@ -273,7 +273,6 @@ enum zfcp_wka_status {
47 #define ZFCP_STATUS_UNIT_SHARED 0x00000004
48 #define ZFCP_STATUS_UNIT_READONLY 0x00000008
49 #define ZFCP_STATUS_UNIT_REGISTERED 0x00000010
50-#define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING 0x00000020
51
52 /* FSF request status (this does not have a common part) */
53 #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002
54@@ -558,6 +557,7 @@ struct zfcp_unit {
55 struct zfcp_erp_action erp_action; /* pending error recovery */
56 atomic_t erp_counter;
57 struct zfcp_latencies latencies;
58+ struct work_struct scsi_work;
59 };
60
61 /* FSF request */
62--- a/drivers/s390/scsi/zfcp_erp.c 2009-03-16 16:41:33.000000000 +0100
63+++ b/drivers/s390/scsi/zfcp_erp.c 2009-03-16 16:44:04.000000000 +0100
64@@ -1184,48 +1184,6 @@ static void zfcp_erp_action_dequeue(stru
65 }
66 }
67
68-struct zfcp_erp_add_work {
69- struct zfcp_unit *unit;
70- struct work_struct work;
71-};
72-
73-static void zfcp_erp_scsi_scan(struct work_struct *work)
74-{
75- struct zfcp_erp_add_work *p =
76- container_of(work, struct zfcp_erp_add_work, work);
77- struct zfcp_unit *unit = p->unit;
78- struct fc_rport *rport = unit->port->rport;
79-
80- if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
81- scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
82- scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0);
83- atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
84- zfcp_unit_put(unit);
85- wake_up(&unit->port->adapter->erp_done_wqh);
86- kfree(p);
87-}
88-
89-static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
90-{
91- struct zfcp_erp_add_work *p;
92-
93- p = kzalloc(sizeof(*p), GFP_KERNEL);
94- if (!p) {
95- dev_err(&unit->port->adapter->ccw_device->dev,
96- "Registering unit 0x%016Lx on port 0x%016Lx failed\n",
97- (unsigned long long)unit->fcp_lun,
98- (unsigned long long)unit->port->wwpn);
99- return;
100- }
101-
102- zfcp_unit_get(unit);
103- atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
104- INIT_WORK(&p->work, zfcp_erp_scsi_scan);
105- p->unit = unit;
106- if (!queue_work(zfcp_data.work_queue, &p->work))
107- zfcp_unit_put(unit);
108-}
109-
110 static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
111 {
112 struct zfcp_adapter *adapter = act->adapter;
113@@ -1238,9 +1196,10 @@ static void zfcp_erp_action_cleanup(stru
114 if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
115 atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED,
116 &unit->status);
117- if (!(atomic_read(&unit->status) &
118- ZFCP_STATUS_UNIT_SCSI_WORK_PENDING))
119- zfcp_erp_schedule_work(unit);
120+ zfcp_unit_get(unit);
121+ if (scsi_queue_work(unit->port->adapter->scsi_host,
122+ &unit->scsi_work) <= 0)
123+ zfcp_unit_put(unit);
124 }
125 zfcp_unit_put(unit);
126 break;
127--- a/drivers/s390/scsi/zfcp_scsi.c 2009-03-16 16:41:33.000000000 +0100
128+++ b/drivers/s390/scsi/zfcp_scsi.c 2009-03-16 16:42:42.000000000 +0100
129@@ -588,6 +588,20 @@ void zfcp_scsi_rport_work(struct work_st
130 }
131
132
133+void zfcp_scsi_scan(struct work_struct *work)
134+{
135+ struct zfcp_unit *unit = container_of(work, struct zfcp_unit,
136+ scsi_work);
137+ struct fc_rport *rport = unit->port->rport;
138+
139+ if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
140+ scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
141+ scsilun_to_int((struct scsi_lun *)
142+ &unit->fcp_lun), 0);
143+
144+ zfcp_unit_put(unit);
145+}
146+
147 struct fc_function_template zfcp_transport_functions = {
148 .show_starget_port_id = 1,
149 .show_starget_port_name = 1,
150--- a/drivers/s390/scsi/zfcp_ext.h 2009-03-16 16:41:33.000000000 +0100
151+++ b/drivers/s390/scsi/zfcp_ext.h 2009-03-16 16:42:42.000000000 +0100
152@@ -159,6 +159,7 @@ extern void zfcp_scsi_rport_work(struct
153 extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
154 extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *);
155 extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *);
156+extern void zfcp_scsi_scan(struct work_struct *);
157
158 /* zfcp_sysfs.c */
159 extern struct attribute_group zfcp_sysfs_unit_attrs;