]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.drivers/qla4xxx-5.01.00-k8_sles11-04-update
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / qla4xxx-5.01.00-k8_sles11-04-update
CommitLineData
2cb7cef9
BS
1From: David Somayajulu <david.somayajulu@qlogic.com>
2Subject: qla4xxx driver SLES 11 Beta6 update
3References: bnc#458186
4
5This updates the qla4xxx driver with the following bug fixes:
61. Fix the handling of qla4xxx firmware Device DataBase Entry removal.
72. Fix the pass thru scsi_cmnd handling. This prevented our
8 configuration tool SanSurfer from operating properly.
93. updates version to 5.01.00-k8_sles11-04
10
11and quite some whitespace fixes.
12
13Signed-off-by: David Somayajulu <david.somayajulu@qlogic.com>
14Signed-off-by: Hannes Reinecke <hare@suse.de>
15
16diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
17index 5764a25..2b5af89 100644
18--- a/drivers/scsi/qla4xxx/ql4_def.h
19+++ b/drivers/scsi/qla4xxx/ql4_def.h
20@@ -144,7 +144,6 @@
21 #define RESET_FIRMWARE_TOV 30
22 #define LOGOUT_TOV 10
23 #define IOCB_TOV_MARGIN 10
24-#define ISNS_DEREG_TOV 5
25
26 #define MAX_RESET_HA_RETRIES 2
27
28@@ -232,6 +231,8 @@ struct ddb_entry {
29 uint8_t ip_addr[ISCSI_IPADDR_SIZE];
30 uint8_t iscsi_name[ISCSI_NAME_SIZE]; /* 72 x48 */
31 uint8_t iscsi_alias[0x20];
32+ uint8_t isid[6];
33+ uint8_t rsrvd[2];
34 };
35
36 /*
37@@ -243,6 +244,8 @@ struct ddb_entry {
38 * commands */
39 #define DDB_STATE_MISSING 2 /* Device logged off, trying
40 * to re-login */
41+#define DDB_STATE_REMOVED 3 /* The fw ddb_entry is freed
42+ * the session can be destroyed */
43
44 /*
45 * DDB flags.
46@@ -252,7 +255,7 @@ struct ddb_entry {
47 * logged it out */
48 #define DF_SCAN_ISSUED 2
49 #define DF_OFFLINE 3 /* Offline Device */
50-#define DF_DELETED 4 /* Device has been removed */
51+#define DF_REMOVE 4 /* FW DDB is destroyed */
52
53 /*
54 * Asynchronous Event Queue structure
55@@ -305,11 +308,10 @@ struct scsi_qla_host {
56 #define DPC_RELOGIN_DEVICE 3 /* 0x00000008 */
57 #define DPC_RESET_HA_DESTROY_DDB_LIST 4 /* 0x00000010 */
58 #define DPC_RESET_HA_INTR 5 /* 0x00000020 */
59-#define DPC_ISNS_RESTART 7 /* 0x00000080 */
60 #define DPC_AEN 9 /* 0x00000200 */
61 #define DPC_GET_DHCP_IP_ADDR 15 /* 0x00008000 */
62 #define DPC_OFFLINE_DEVICE 16 /* 0x00010000 */
63-#define DPC_DELETE_DEVICE 17 /* 0x00020000 */
64+#define DPC_REMOVE_DEVICE 17 /* 0x00020000 */
65
66 uint16_t iocb_cnt;
67 uint16_t iocb_hiwat;
68diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
69index 3b38d79..cc17469 100644
70--- a/drivers/scsi/qla4xxx/ql4_init.c
71+++ b/drivers/scsi/qla4xxx/ql4_init.c
72@@ -14,7 +14,7 @@
73
74 /* link auto negotiation normally takes roughly 2s. */
75 /* If we don't have link in 3 times that period quit. */
76-#define QLA4XXX_LINK_UP_DELAY 6
77+#define QLA4XXX_LINK_UP_DELAY 6
78
79 /*
80 * QLogic ISP4xxx Hardware Support Function Prototypes.
81@@ -63,8 +63,10 @@ void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry)
82 list_del_init(&ddb_entry->list);
83
84 /* Remove device pointer from index mapping arrays */
85- ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = NULL;
86- ha->tot_ddbs--;
87+ if (!QL_DDB_STATE_REMOVED(ddb_entry)) {
88+ ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = NULL;
89+ ha->tot_ddbs--;
90+ }
91
92 /* Free memory and scsi-ml struct for device entry */
93 qla4xxx_destroy_sess(ddb_entry);
94@@ -267,14 +269,6 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha)
95 (ha->addl_fw_state &
96 FW_ADDSTATE_LINK_UP) != 0 ?
97 "UP" : "DOWN"));
98- DEBUG2(dev_info(&ha->pdev->dev,
99- "scsi%ld: %s: iSNS Service "
100- "Started %s\n",
101- ha->host_no, __func__,
102- (ha->addl_fw_state &
103- FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ?
104- "YES" : "NO"));
105-
106 ready = 1;
107 break;
108 }
109@@ -341,6 +335,7 @@ static void qla4xxx_fill_ddb(struct ddb_entry *ddb_entry,
110
111 ddb_entry->port = le16_to_cpu(fw_ddb_entry->port);
112 ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
113+ memcpy(ddb_entry->isid, fw_ddb_entry->isid, sizeof(ddb_entry->isid));
114 memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],
115 min(sizeof(ddb_entry->iscsi_name),
116 sizeof(fw_ddb_entry->iscsi_name)));
2cb7cef9
BS
117@@ -486,19 +481,6 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
118 qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry);
119 ddb_entry->fw_ddb_device_state = ddb_state;
120
121- if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) {
122- atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
123- dev_info(&ha->pdev->dev,
124- "scsi%ld: %s: ddb[%d] os[%d] marked ONLINE\n",
125- ha->host_no, __func__, ddb_entry->fw_ddb_index,
126- ddb_entry->os_target_id);
127- } else {
128- atomic_set(&ddb_entry->state, DDB_STATE_MISSING);
129- dev_info(&ha->pdev->dev,
130- "scsi%ld: %s: ddb[%d] os[%d] marked MISSING\n",
131- ha->host_no, __func__, ddb_entry->fw_ddb_index,
132- ddb_entry->os_target_id);
133- }
134 DEBUG6(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d State %04x"
135 " ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n", __func__,
136 fw_ddb_index, ddb_entry->os_target_id, ddb_state, conn_err,
137@@ -714,7 +696,7 @@ static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha)
138 }
139
140 /**
141- * qla4xxx_update_ddb_list - update the driver ddb list
142+ * qla4xxx_reinitialize_ddb_list - update the driver ddb list
143 * @ha: pointer to host adapter structure.
144 *
145 * This routine obtains device information from the F/W database after
146@@ -735,11 +717,12 @@ int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host *ha)
147
148 /* Update the device information for all devices. */
149 list_for_each_entry_safe(ddb_entry, detemp, &ha->ddb_list, list) {
150- if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,
151- fw_ddb_entry, fw_ddb_entry_dma, NULL, NULL,
152- &ddb_entry->fw_ddb_device_state, NULL,
153- &ddb_entry->tcp_source_port_num,
154- &ddb_entry->connection_id) == QLA_SUCCESS) {
155+ if (!QL_DDB_STATE_REMOVED(ddb_entry) &&
156+ (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,
157+ fw_ddb_entry, fw_ddb_entry_dma, NULL, NULL,
158+ &ddb_entry->fw_ddb_device_state, NULL,
159+ &ddb_entry->tcp_source_port_num,
160+ &ddb_entry->connection_id) == QLA_SUCCESS)) {
161
162 qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry);
163
164@@ -1192,8 +1175,13 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha,
165 }
166
167 list_for_each_entry(ddb_entry, &ha->ddb_list, list) {
168- if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
169- ISCSI_NAME_SIZE) == 0) {
170+ if ((memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
171+ ISCSI_NAME_SIZE) == 0) &&
172+ (ddb_entry->tpgt ==
173+ le32_to_cpu(fw_ddb_entry->tgt_portal_grp)) &&
174+ (memcmp(ddb_entry->isid, fw_ddb_entry->isid,
175+ sizeof(ddb_entry->isid)) == 0) &&
176+ !QL_DDB_STATE_REMOVED(ddb_entry)) {
177 found = 1;
178
179 DEBUG6(dev_info(&ha->pdev->dev, "%s found target ddb = 0x%p"
180diff --git a/drivers/scsi/qla4xxx/ql4_inline.h b/drivers/scsi/qla4xxx/ql4_inline.h
181index bdf2475..a93b817 100644
182--- a/drivers/scsi/qla4xxx/ql4_inline.h
183+++ b/drivers/scsi/qla4xxx/ql4_inline.h
184@@ -55,8 +55,8 @@ static inline void qla4xxx_check_for_clear_ddb(struct scsi_qla_host *ha,
185 dev_info(&ha->pdev->dev, "%s: ddb[%d] os[%d] freed\n",
186 __func__, ddb_entry->fw_ddb_index,
187 ddb_entry->os_target_id);
188- set_bit(DF_DELETED, &ddb_entry->flags);
189- set_bit(DPC_DELETE_DEVICE, &ha->dpc_flags);
190+ set_bit(DF_REMOVE, &ddb_entry->flags);
191+ set_bit(DPC_REMOVE_DEVICE, &ha->dpc_flags);
192 queue_work(ha->dpc_thread, &ha->dpc_work);
193 }
194 }
195diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
196index bfe4d1e..67071d6 100644
197--- a/drivers/scsi/qla4xxx/ql4_iocb.c
198+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
199@@ -27,12 +27,6 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
200 cmd = srb->cmd;
201 ha = srb->ha;
202
203- if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
204- /* No data being transferred */
205- cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0);
206- return;
207- }
208-
209 avail_dsds = COMMAND_SEG;
210 cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]);
211
212@@ -43,6 +37,12 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
213 return;
214 }
215
216+ if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
217+ /* No data being transferred */
218+ cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0);
219+ return;
220+ }
221+
222 scsi_for_each_sg(cmd, sg, tot_dsds, i) {
223 dma_addr_t sle_dma;
224
225@@ -155,7 +155,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
226
227 int_to_scsilun(cmd->device->lun, &cmd_entry->lun);
228 cmd_entry->cmdSeqNum = cpu_to_le32(ddb_entry->CmdSn);
229- cmd_entry->ttlByteCnt = cpu_to_le32(scsi_bufflen(cmd));
230+
231 memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len);
232 cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds);
233 cmd_entry->hdr.entryCount = req_cnt;
234@@ -165,6 +165,9 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
235 * transferred, as the data direction bit is sometimed filled
236 * in when there is no data to be transferred */
237 cmd_entry->control_flags = CF_NO_DATA;
238+
239+ cmd_entry->ttlByteCnt = cpu_to_le32(scsi_bufflen(cmd));
240+
241 if (scsi_bufflen(cmd)) {
242 if (cmd->sc_data_direction == DMA_TO_DEVICE)
243 cmd_entry->control_flags = CF_WRITE;
244@@ -203,7 +206,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
245 wmb();
246
247 /*
248- * Check to see if adapter is online before placing request on
249+ * Check to see if adapter is online before placing request on
250 * request queue. If a reset occurs and a request is in the queue,
251 * the firmware will still attempt to process the request, retrieving
252 * garbage for pointers.
253@@ -243,4 +246,3 @@ queuing_error:
254
255 return QLA_ERROR;
256 }
257-
258diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
259index 2efcc20..a5cd40d 100644
260--- a/drivers/scsi/qla4xxx/ql4_os.c
261+++ b/drivers/scsi/qla4xxx/ql4_os.c
262@@ -111,6 +111,8 @@ static struct scsi_host_template qla4xxx_driver_template = {
263 .slave_alloc = qla4xxx_slave_alloc,
264 .slave_destroy = qla4xxx_slave_destroy,
265
266+ .target_destroy = qla4xxx_target_destroy,
267+
268 .this_id = -1,
269 .cmd_per_lun = 3,
270 .use_clustering = ENABLE_CLUSTERING,
271@@ -290,7 +292,8 @@ void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry)
272 if (ddb_entry->conn) {
273 QL_ISCSI_IF_DESTROY_SESSION_DONE(ddb_entry);
274 QL_ISCSI_DESTROY_CONN(ddb_entry);
275- iscsi_remove_session(ddb_entry->sess);
276+ if (!QL_DDB_STATE_REMOVED(ddb_entry))
277+ iscsi_remove_session(ddb_entry->sess);
278 }
279 iscsi_free_session(ddb_entry->sess);
280 }
281@@ -385,7 +388,8 @@ void qla4xxx_mark_device_missing(struct scsi_qla_host *ha,
282 dev_info(&ha->pdev->dev, "%s: ddb[%d] os[%d] marked MISSING\n",
283 __func__, ddb_entry->fw_ddb_index, ddb_entry->os_target_id);
284
285- qla4xxx_conn_stop(ddb_entry->conn, STOP_CONN_RECOVER);
286+ if (ddb_entry->conn)
287+ qla4xxx_conn_stop(ddb_entry->conn, STOP_CONN_RECOVER);
288 }
289
290 static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha,
291@@ -444,7 +448,8 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
292 int rval;
293
294 if (atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) {
295- if (atomic_read(&ddb_entry->state) == DDB_STATE_DEAD) {
296+ if ((atomic_read(&ddb_entry->state) == DDB_STATE_DEAD) ||
297+ QL_DDB_STATE_REMOVED(ddb_entry)) {
298 cmd->result = DID_NO_CONNECT << 16;
299 goto qc_fail_command;
300 }
301@@ -602,8 +607,9 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
302 list_for_each_entry_safe(ddb_entry, dtemp, &ha->ddb_list, list) {
303 /* Count down time between sending relogins */
304 if (adapter_up(ha) &&
305- !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
306- atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) {
307+ !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
308+ !QL_DDB_STATE_REMOVED(ddb_entry) &&
309+ atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) {
310 if (atomic_read(&ddb_entry->retry_relogin_timer) !=
311 INVALID_ENTRY) {
312 if (atomic_read(&ddb_entry->retry_relogin_timer)
313@@ -626,15 +632,16 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
314
315 /* Wait for relogin to timeout */
316 if (atomic_read(&ddb_entry->relogin_timer) &&
317- (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {
318+ (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {
319 /*
320 * If the relogin times out and the device is
321 * still NOT ONLINE then try and relogin again.
322 */
323 if (atomic_read(&ddb_entry->state) !=
324- DDB_STATE_ONLINE &&
325- ddb_entry->fw_ddb_device_state ==
326- DDB_DS_SESSION_FAILED) {
327+ DDB_STATE_ONLINE &&
328+ !QL_DDB_STATE_REMOVED(ddb_entry) &&
329+ ddb_entry->fw_ddb_device_state ==
330+ DDB_DS_SESSION_FAILED) {
331 /* Reset retry relogin timer */
332 atomic_inc(&ddb_entry->relogin_retry_count);
333 DEBUG2(printk("scsi%ld: index[%d] relogin"
334@@ -678,6 +685,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
335 test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) ||
336 test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
337 test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) ||
338+ test_bit(DPC_REMOVE_DEVICE, &ha->dpc_flags) ||
339 QL_DPC_OFFLINE_SET(ha) ||
340 test_bit(DPC_AEN, &ha->dpc_flags)) &&
341 ha->dpc_thread) {
342@@ -1061,31 +1069,7 @@ static QL_DECLARE_DPC(qla4xxx_do_dpc, data)
343
344 qla4xxx_check_dev_offline(ha);
345
346- if (test_and_clear_bit(DPC_DELETE_DEVICE, &ha->dpc_flags)) {
347- list_for_each_entry_safe(ddb_entry, dtemp,
348- &ha->ddb_list, list) {
349- if (test_and_clear_bit(DF_DELETED,
350- &ddb_entry->flags)) {
351- if (atomic_read(&ddb_entry->state) ==
352- DDB_STATE_DEAD) {
353- dev_info(&ha->pdev->dev,
354- "%s: ddb[%d] os[%d] - "
355- "delete\n",
356- __func__,
357- ddb_entry->fw_ddb_index,
358- ddb_entry->os_target_id);
359- } else {
360- dev_info(&ha->pdev->dev,
361- "%s: ddb[%d] os[%d] - "
362- "ddb state not dead but"
363- " marked for delete\n",
364- __func__,
365- ddb_entry->fw_ddb_index,
366- ddb_entry->os_target_id);
367- }
368- }
369- }
370- }
371+ qla4xxx_remove_device(ha);
372
373 /* ---- relogin device? --- */
374 if (adapter_up(ha) &&
375@@ -1093,6 +1077,7 @@ static QL_DECLARE_DPC(qla4xxx_do_dpc, data)
376 list_for_each_entry_safe(ddb_entry, dtemp,
377 &ha->ddb_list, list) {
378 if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) &&
379+ !QL_DDB_STATE_REMOVED(ddb_entry) &&
380 (atomic_read(&ddb_entry->state) !=
381 DDB_STATE_ONLINE))
382 qla4xxx_relogin_device(ha, ddb_entry);
383@@ -1181,7 +1166,6 @@ static int qla4xxx_iospace_config(struct scsi_qla_host *ha)
384 if (!(mmio_flags & IORESOURCE_MEM)) {
385 dev_err(&ha->pdev->dev,
386 "region #0 not an MMIO resource, aborting\n");
387-
388 goto iospace_error_exit;
389 }
390 if (mmio_len < MIN_IOBASE_LEN) {
391@@ -1336,7 +1320,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
392 /* Start timer thread. */
393 qla4xxx_start_timer(ha, qla4xxx_timer, 1);
394
395- set_bit(AF_INIT_DONE, &ha->flags);
396+// set_bit(AF_INIT_DONE, &ha->flags);
397
398 pci_set_drvdata(pdev, ha);
399
400@@ -1382,7 +1366,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
401 DEBUG2(dev_info(&ha->pdev->dev, "listhead=%p, done adding ha=%p i=%d\n",
402 &qla4xxx_hostlist, &ha->node, ha->instance));
403
404-// set_bit(AF_INIT_DONE, &ha->flags);
405+ set_bit(AF_INIT_DONE, &ha->flags);
406 dev_info(&ha->pdev->dev, "%s: AF_INIT_DONE\n", __func__);
407
408 return 0;
409@@ -1465,6 +1449,7 @@ static int qla4xxx_slave_alloc(struct scsi_device *sdev)
410
411 if (sess) {
412 sdev->hostdata = sess->dd_data;
413+ QL_SET_SDEV_HOSTDATA(sdev, sess);
414 return 0;
415 }
416 return FAILED;
417diff --git a/drivers/scsi/qla4xxx/ql4_os.h b/drivers/scsi/qla4xxx/ql4_os.h
418index 71c3da0..c96ab8f 100644
419--- a/drivers/scsi/qla4xxx/ql4_os.h
420+++ b/drivers/scsi/qla4xxx/ql4_os.h
421@@ -44,13 +44,16 @@
422 iscsi_unblock_session(ddb_entry->sess)
423 #define QL_ISCSI_ALLOC_SESSION(ha, trans) \
424 iscsi_alloc_session(ha->host, trans, sizeof(struct ddb_entry))
425+#define QL_SET_SDEV_HOSTDATA(sdev, sess)
426
427+#define QL_DDB_STATE_REMOVED(ddb_entry) 0
428
429 #define QL_MISC_INIT 0
430 #define QL_MISC_EXIT
431
432 #define qla4xxx_check_dev_offline(ha)
433 #define qla4xxx_proc_info NULL
434+#define qla4xxx_target_destroy NULL
435
436 #define QL_SET_SCSI_RESID(cmd, residual) scsi_set_resid(cmd, residual)
437 #define QL_SCSI_BUFFLEN(cmd) scsi_bufflen(cmd)
438@@ -69,10 +72,8 @@
439 void dpc_func(struct work_struct *data)
440
441 #define QL_INIT_SESSION_DATASIZE(sessiondata_size)
442-// .sessiondata_size = sizeof(struct ddb_entry),
443
444 #define QL_INIT_HOST_TEMPLATE(host_template)
445-// .host_template = &qla4xxx_driver_template,
446
447 QL_DECLARE_INTR_HANDLER(qla4xxx_intr_handler, irq, dev_id, regs);
448
449@@ -122,4 +123,22 @@ static inline void qla4xxx_srb_free_dma(struct scsi_qla_host *ha,
450 cmd->SCp.ptr = NULL;
451 }
452
453+static inline void qla4xxx_remove_device(struct scsi_qla_host *ha)
454+{
455+ struct ddb_entry *ddb_entry, *dtemp;
456+
457+ if (test_and_clear_bit(DPC_REMOVE_DEVICE, &ha->dpc_flags)) {
458+ list_for_each_entry_safe(ddb_entry, dtemp,
459+ &ha->ddb_list, list) {
460+ if (test_and_clear_bit(DF_REMOVE, &ddb_entry->flags)) {
461+ dev_info(&ha->pdev->dev,
462+ "%s: ddb[%d] os[%d] - removed\n",
463+ __func__, ddb_entry->fw_ddb_index,
464+ ddb_entry->os_target_id);
465+ qla4xxx_free_ddb(ha, ddb_entry);
466+ }
467+ }
468+ }
469+}
470+
471 #endif /* _QLA4x_OS_H */
472diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
473index d6ff1b7..073e401 100644
474--- a/drivers/scsi/qla4xxx/ql4_version.h
475+++ b/drivers/scsi/qla4xxx/ql4_version.h
476@@ -5,5 +5,5 @@
477 * See LICENSE.qla4xxx for copyright and licensing details.
478 */
479
480-#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-03"
481+#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-04"
482