]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/scsi/qla2xxx/qla_rscn.c
[SCSI] Add an 'Issue LIP' device attribute in fc_transport class
[linux-2.6-omap-h63xx.git] / drivers / scsi / qla2xxx / qla_rscn.c
1 /*
2  * QLogic Fibre Channel HBA Driver
3  * Copyright (c)  2003-2005 QLogic Corporation
4  *
5  * See LICENSE.qla2xxx for copyright and licensing details.
6  */
7 #include "qla_def.h"
8
9 #include <scsi/scsi_transport_fc.h>
10
11 /**
12  * IO descriptor handle definitions.
13  *
14  * Signature form:
15  *
16  *      |31------28|27-------------------12|11-------0|
17  *      |   Type   |   Rolling Signature   |   Index  |
18  *      |----------|-----------------------|----------|
19  *
20  **/
21
22 #define HDL_TYPE_SCSI           0
23 #define HDL_TYPE_ASYNC_IOCB     0x0A
24
25 #define HDL_INDEX_BITS  12
26 #define HDL_ITER_BITS   16
27 #define HDL_TYPE_BITS   4
28
29 #define HDL_INDEX_MASK  ((1UL << HDL_INDEX_BITS) - 1)
30 #define HDL_ITER_MASK   ((1UL << HDL_ITER_BITS) - 1)
31 #define HDL_TYPE_MASK   ((1UL << HDL_TYPE_BITS) - 1)
32
33 #define HDL_INDEX_SHIFT 0
34 #define HDL_ITER_SHIFT  (HDL_INDEX_SHIFT + HDL_INDEX_BITS)
35 #define HDL_TYPE_SHIFT  (HDL_ITER_SHIFT + HDL_ITER_BITS)
36
37 /* Local Prototypes. */
38 static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t);
39 static inline uint16_t qla2x00_handle_to_idx(uint32_t);
40 static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor *);
41 static inline struct io_descriptor *qla2x00_handle_to_iodesc(scsi_qla_host_t *,
42     uint32_t);
43
44 static inline struct io_descriptor *qla2x00_alloc_iodesc(scsi_qla_host_t *);
45 static inline void qla2x00_free_iodesc(struct io_descriptor *);
46 static inline void qla2x00_init_io_descriptors(scsi_qla_host_t *);
47
48 static void qla2x00_iodesc_timeout(unsigned long);
49 static inline void qla2x00_add_iodesc_timer(struct io_descriptor *);
50 static inline void qla2x00_remove_iodesc_timer(struct io_descriptor *);
51
52 static inline void qla2x00_update_login_fcport(scsi_qla_host_t *,
53     struct mbx_entry *, fc_port_t *);
54
55 static int qla2x00_send_abort_iocb(scsi_qla_host_t *, struct io_descriptor *,
56     uint32_t, int);
57 static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
58     struct mbx_entry *);
59
60 static int qla2x00_send_adisc_iocb(scsi_qla_host_t *, struct io_descriptor *,
61     int);
62 static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
63     struct mbx_entry *);
64
65 static int qla2x00_send_logout_iocb(scsi_qla_host_t *, struct io_descriptor *,
66     int);
67 static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t *,
68     struct io_descriptor *, struct mbx_entry *);
69
70 static int qla2x00_send_login_iocb(scsi_qla_host_t *, struct io_descriptor *,
71     port_id_t *, int);
72 static int qla2x00_send_login_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
73     struct mbx_entry *);
74
75 /**
76  * Mailbox IOCB callback array.
77  **/
78 static int (*iocb_function_cb_list[LAST_IOCB_CB])
79         (scsi_qla_host_t *, struct io_descriptor *, struct mbx_entry *) = {
80
81         qla2x00_send_abort_iocb_cb,
82         qla2x00_send_adisc_iocb_cb,
83         qla2x00_send_logout_iocb_cb,
84         qla2x00_send_login_iocb_cb,
85 };
86
87
88 /**
89  * Generic IO descriptor handle routines.
90  **/
91
92 /**
93  * qla2x00_to_handle() - Create a descriptor handle.
94  * @type: descriptor type
95  * @iter: descriptor rolling signature
96  * @idx: index to the descriptor array
97  *
98  * Returns a composite handle based in the @type, @iter, and @idx.
99  */
100 static inline uint32_t
101 qla2x00_to_handle(uint16_t type, uint16_t iter, uint16_t idx)
102 {
103         return ((uint32_t)(((uint32_t)type << HDL_TYPE_SHIFT) |
104             ((uint32_t)iter << HDL_ITER_SHIFT) |
105             ((uint32_t)idx << HDL_INDEX_SHIFT)));
106 }
107
108 /**
109  * qla2x00_handle_to_idx() - Retrive the index for a given handle.
110  * @handle: descriptor handle
111  *
112  * Returns the index specified by the @handle.
113  */
114 static inline uint16_t
115 qla2x00_handle_to_idx(uint32_t handle)
116 {
117         return ((uint16_t)(((handle) >> HDL_INDEX_SHIFT) & HDL_INDEX_MASK));
118 }
119
120 /**
121  * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
122  * @iodesc: io descriptor
123  *
124  * Returns a unique handle for @iodesc.
125  */
126 static inline uint32_t
127 qla2x00_iodesc_to_handle(struct io_descriptor *iodesc)
128 {
129         uint32_t handle;
130
131         handle = qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB,
132             ++iodesc->ha->iodesc_signature, iodesc->idx);
133         iodesc->signature = handle;
134
135         return (handle);
136 }
137
138 /**
139  * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
140  * @ha: HA context
141  * @handle: handle to io descriptor
142  *
143  * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
144  * not exist or the io descriptors signature does not @handle.
145  */
146 static inline struct io_descriptor *
147 qla2x00_handle_to_iodesc(scsi_qla_host_t *ha, uint32_t handle)
148 {
149         uint16_t idx;
150         struct io_descriptor *iodesc;
151
152         idx = qla2x00_handle_to_idx(handle);
153         iodesc = &ha->io_descriptors[idx];
154         if (iodesc)
155                 if (iodesc->signature != handle)
156                         iodesc = NULL;
157
158         return (iodesc);
159 }
160
161
162 /**
163  * IO descriptor allocation routines.
164  **/
165
166 /**
167  * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
168  * @ha: HA context
169  *
170  * Returns a pointer to the allocated io descriptor, or NULL, if none available.
171  */
172 static inline struct io_descriptor *
173 qla2x00_alloc_iodesc(scsi_qla_host_t *ha)
174 {
175         uint16_t iter;
176         struct io_descriptor *iodesc;
177
178         iodesc = NULL;
179         for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
180                 if (ha->io_descriptors[iter].used)
181                         continue;
182
183                 iodesc = &ha->io_descriptors[iter];
184                 iodesc->used = 1;
185                 iodesc->idx = iter;
186                 init_timer(&iodesc->timer);
187                 iodesc->ha = ha;
188                 iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
189                 break;
190         }
191
192         return (iodesc);
193 }
194
195 /**
196  * qla2x00_free_iodesc() - Free an IO descriptor.
197  * @iodesc: io descriptor
198  *
199  * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
200  */
201 static inline void
202 qla2x00_free_iodesc(struct io_descriptor *iodesc)
203 {
204         iodesc->used = 0;
205         iodesc->signature = 0;
206 }
207
208 /**
209  * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
210  * @iodesc: io descriptor
211  */
212 static inline void
213 qla2x00_remove_iodesc_timer(struct io_descriptor *iodesc)
214 {
215         if (iodesc->timer.function != NULL) {
216                 del_timer_sync(&iodesc->timer);
217                 iodesc->timer.data = (unsigned long) NULL;
218                 iodesc->timer.function = NULL;
219         }
220 }
221
222 /**
223  * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
224  * @ha: HA context
225  */
226 static inline void
227 qla2x00_init_io_descriptors(scsi_qla_host_t *ha)
228 {
229         uint16_t iter;
230
231         for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
232                 if (!ha->io_descriptors[iter].used)
233                         continue;
234
235                 qla2x00_remove_iodesc_timer(&ha->io_descriptors[iter]);
236                 qla2x00_free_iodesc(&ha->io_descriptors[iter]);
237         }
238 }
239
240
241 /**
242  * IO descriptor timer routines.
243  **/
244
245 /**
246  * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
247  * @data: io descriptor
248  */
249 static void
250 qla2x00_iodesc_timeout(unsigned long data)
251 {
252         struct io_descriptor *iodesc;
253
254         iodesc = (struct io_descriptor *) data;
255
256         DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
257             "signature=%08x, scheduling ISP abort.\n", iodesc->ha->host_no,
258             iodesc->idx, iodesc->signature));
259
260         qla2x00_free_iodesc(iodesc);
261
262         qla_printk(KERN_WARNING, iodesc->ha,
263             "IO descriptor timeout. Scheduling ISP abort.\n");
264         set_bit(ISP_ABORT_NEEDED, &iodesc->ha->dpc_flags);
265 }
266
267 /**
268  * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
269  * @iodesc: io descriptor
270  *
271  * NOTE:
272  * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
273  * tenths of a second) after it hits the wire.  But, if there are any request
274  * resource contraints (i.e. during heavy I/O), exchanges can be held off for
275  * at most R_A_TOV.  Therefore, the driver will wait 4 * R_A_TOV before
276  * scheduling a recovery (big hammer).
277  */
278 static inline void
279 qla2x00_add_iodesc_timer(struct io_descriptor *iodesc)
280 {
281         unsigned long timeout;
282
283         timeout = (iodesc->ha->r_a_tov * 4) / 10;
284         init_timer(&iodesc->timer);
285         iodesc->timer.data = (unsigned long) iodesc;
286         iodesc->timer.expires = jiffies + (timeout * HZ);
287         iodesc->timer.function =
288             (void (*) (unsigned long)) qla2x00_iodesc_timeout;
289         add_timer(&iodesc->timer);
290 }
291
292 /**
293  * IO descriptor support routines.
294  **/
295
296 /**
297  * qla2x00_update_login_fcport() - Update fcport data after login processing.
298  * @ha: HA context
299  * @mbxstat: Mailbox command status IOCB
300  * @fcport: port to update
301  */
302 static inline void
303 qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
304     fc_port_t *fcport)
305 {
306         if (le16_to_cpu(mbxstat->mb1) & BIT_0) {
307                 fcport->port_type = FCT_INITIATOR;
308         } else {
309                 fcport->port_type = FCT_TARGET;
310                 if (le16_to_cpu(mbxstat->mb1) & BIT_1) {
311                         fcport->flags |= FCF_TAPE_PRESENT;
312                 }
313         }
314         fcport->login_retry = 0;
315         fcport->port_login_retry_count = ha->port_down_retry_count *
316             PORT_RETRY_TIME;
317         atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
318             PORT_RETRY_TIME);
319         fcport->flags |= FCF_FABRIC_DEVICE;
320         fcport->flags &= ~FCF_FAILOVER_NEEDED;
321         fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
322         atomic_set(&fcport->state, FCS_ONLINE);
323         if (fcport->rport)
324                 fc_remote_port_unblock(fcport->rport);
325 }
326
327
328 /**
329  * Mailbox IOCB commands.
330  **/
331
332 /**
333  * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
334  * @ha: HA context
335  * @handle: handle to io descriptor
336  *
337  * Returns a pointer to the reqest entry, or NULL, if none were available.
338  */
339 static inline struct mbx_entry *
340 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle)
341 {
342         uint16_t cnt;
343         struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
344         struct mbx_entry *mbxentry;
345
346         mbxentry = NULL;
347
348         if (ha->req_q_cnt < 3) {
349                 cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg));
350                 if  (ha->req_ring_index < cnt)
351                         ha->req_q_cnt = cnt - ha->req_ring_index;
352                 else
353                         ha->req_q_cnt = ha->request_q_length -
354                             (ha->req_ring_index - cnt);
355         }
356         if (ha->req_q_cnt >= 3) {
357                 mbxentry = (struct mbx_entry *)ha->request_ring_ptr;
358
359                 memset(mbxentry, 0, sizeof(struct mbx_entry));
360                 mbxentry->entry_type = MBX_IOCB_TYPE;
361                 mbxentry->entry_count = 1;
362                 mbxentry->sys_define1 = SOURCE_ASYNC_IOCB;
363                 mbxentry->handle = handle;
364         }
365         return (mbxentry);
366 }
367
368 /**
369  * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
370  * @ha: HA context
371  * @iodesc: io descriptor
372  * @handle_to_abort: firmware handle to abort
373  * @ha_locked: is function called with the hardware lock
374  *
375  * Returns QLA_SUCCESS if the IOCB was issued.
376  */
377 static int
378 qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
379     uint32_t handle_to_abort, int ha_locked)
380 {
381         unsigned long flags = 0;
382         struct mbx_entry *mbxentry;
383
384         /* Send marker if required. */
385         if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
386                 return (QLA_FUNCTION_FAILED);
387
388         if (!ha_locked)
389                 spin_lock_irqsave(&ha->hardware_lock, flags);
390
391         /* Build abort mailbox IOCB. */
392         mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
393         if (mbxentry == NULL) {
394                 if (!ha_locked)
395                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
396
397                 return (QLA_FUNCTION_FAILED);
398         }
399         mbxentry->mb0 = __constant_cpu_to_le16(MBC_ABORT_COMMAND);
400         mbxentry->mb1 = mbxentry->loop_id.extended =
401             cpu_to_le16(iodesc->remote_fcport->loop_id);
402         mbxentry->mb2 = LSW(handle_to_abort);
403         mbxentry->mb3 = MSW(handle_to_abort);
404         wmb();
405
406         qla2x00_add_iodesc_timer(iodesc);
407
408         /* Issue command to ISP. */
409         qla2x00_isp_cmd(ha);
410
411         if (!ha_locked)
412                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
413
414         DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
415             "%08x.\n", ha->host_no, iodesc->signature,
416             iodesc->remote_fcport->loop_id, handle_to_abort));
417
418         return (QLA_SUCCESS);
419 }
420
421 /**
422  * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
423  * @ha: HA context
424  * @iodesc: io descriptor
425  * @mbxstat: mailbox status IOCB
426  *
427  * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
428  * will be used for a retry.
429  */
430 static int
431 qla2x00_send_abort_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
432     struct mbx_entry *mbxstat)
433 {
434         DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
435             "status=%x mb0=%x.\n", ha->host_no, iodesc->remote_fcport->loop_id,
436             iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa,
437             le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
438
439         return (QLA_SUCCESS);
440 }
441
442
443 /**
444  * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
445  * @ha: HA context
446  * @iodesc: io descriptor
447  * @ha_locked: is function called with the hardware lock
448  *
449  * Returns QLA_SUCCESS if the IOCB was issued.
450  */
451 static int
452 qla2x00_send_adisc_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
453     int ha_locked)
454 {
455         unsigned long flags = 0;
456         struct mbx_entry *mbxentry;
457
458         /* Send marker if required. */
459         if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
460                 return (QLA_FUNCTION_FAILED);
461
462         if (!ha_locked)
463                 spin_lock_irqsave(&ha->hardware_lock, flags);
464
465         /* Build Get Port Database IOCB. */
466         mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
467         if (mbxentry == NULL) {
468                 if (!ha_locked)
469                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
470
471                 return (QLA_FUNCTION_FAILED);
472         }
473         mbxentry->mb0 = __constant_cpu_to_le16(MBC_GET_PORT_DATABASE);
474         mbxentry->mb1 = mbxentry->loop_id.extended =
475             cpu_to_le16(iodesc->remote_fcport->loop_id);
476         mbxentry->mb2 = cpu_to_le16(MSW(LSD(ha->iodesc_pd_dma)));
477         mbxentry->mb3 = cpu_to_le16(LSW(LSD(ha->iodesc_pd_dma)));
478         mbxentry->mb6 = cpu_to_le16(MSW(MSD(ha->iodesc_pd_dma)));
479         mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma)));
480         mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
481         wmb();
482
483         qla2x00_add_iodesc_timer(iodesc);
484
485         /* Issue command to ISP. */
486         qla2x00_isp_cmd(ha);
487
488         if (!ha_locked)
489                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
490
491         DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
492             ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
493
494         return (QLA_SUCCESS);
495 }
496
497 /**
498  * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
499  * @ha: HA context
500  * @iodesc: io descriptor
501  * @mbxstat: mailbox status IOCB
502  *
503  * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
504  * will be used for a retry.
505  */
506 static int
507 qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
508     struct mbx_entry *mbxstat)
509 {
510         fc_port_t *remote_fcport;
511
512         remote_fcport = iodesc->remote_fcport;
513
514         /* Ensure the port IDs are consistent. */
515         if (remote_fcport->d_id.b24 != iodesc->d_id.b24) {
516                 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
517                     "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
518                     ha->host_no, remote_fcport->d_id.b.domain,
519                     remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
520                     iodesc->d_id.b.domain, iodesc->d_id.b.area,
521                     iodesc->d_id.b.al_pa));
522
523                 return (QLA_SUCCESS);
524         }
525
526         /* Only process the last command. */
527         if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
528                 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
529                     "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no,
530                     iodesc->d_id.b.domain, iodesc->d_id.b.area,
531                     iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
532                     iodesc->idx));
533
534                 return (QLA_SUCCESS);
535         }
536
537         if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) {
538                 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
539                     "[%x/%02x%02x%02x] online.\n", ha->host_no,
540                     remote_fcport->loop_id, remote_fcport->d_id.b.domain,
541                     remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
542
543                 atomic_set(&remote_fcport->state, FCS_ONLINE);
544         } else {
545                 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
546                     "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no,
547                     remote_fcport->loop_id, remote_fcport->d_id.b.domain,
548                     remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
549                     le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
550
551                 if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD)
552                         atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
553         }
554         remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
555
556         return (QLA_SUCCESS);
557 }
558
559
560 /**
561  * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
562  * @ha: HA context
563  * @iodesc: io descriptor
564  * @ha_locked: is function called with the hardware lock
565  *
566  * Returns QLA_SUCCESS if the IOCB was issued.
567  */
568 static int
569 qla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
570     int ha_locked)
571 {
572         unsigned long flags = 0;
573         struct mbx_entry *mbxentry;
574
575         /* Send marker if required. */
576         if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
577                 return (QLA_FUNCTION_FAILED);
578
579         if (!ha_locked)
580                 spin_lock_irqsave(&ha->hardware_lock, flags);
581
582         /* Build fabric port logout mailbox IOCB. */
583         mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
584         if (mbxentry == NULL) {
585                 if (!ha_locked)
586                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
587
588                 return (QLA_FUNCTION_FAILED);
589         }
590         mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
591         mbxentry->mb1 = mbxentry->loop_id.extended =
592             cpu_to_le16(iodesc->remote_fcport->loop_id);
593         wmb();
594
595         qla2x00_add_iodesc_timer(iodesc);
596
597         /* Issue command to ISP. */
598         qla2x00_isp_cmd(ha);
599
600         if (!ha_locked)
601                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
602
603         DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
604             ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
605
606         return (QLA_SUCCESS);
607 }
608
609 /**
610  * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
611  * @ha: HA context
612  * @iodesc: io descriptor
613  * @mbxstat: mailbox status IOCB
614  *
615  * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
616  * will be used for a retry.
617  */
618 static int
619 qla2x00_send_logout_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
620     struct mbx_entry *mbxstat)
621 {
622         DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
623             "status=%x mb0=%x mb1=%x.\n", ha->host_no,
624             iodesc->remote_fcport->loop_id,
625             iodesc->remote_fcport->d_id.b.domain,
626             iodesc->remote_fcport->d_id.b.area,
627             iodesc->remote_fcport->d_id.b.al_pa, le16_to_cpu(mbxstat->status),
628             le16_to_cpu(mbxstat->mb0), le16_to_cpu(mbxstat->mb1)));
629
630         return (QLA_SUCCESS);
631 }
632
633
634 /**
635  * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
636  * @ha: HA context
637  * @iodesc: io descriptor
638  * @d_id: port id for device
639  * @ha_locked: is function called with the hardware lock
640  *
641  * Returns QLA_SUCCESS if the IOCB was issued.
642  */
643 static int
644 qla2x00_send_login_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
645     port_id_t *d_id, int ha_locked)
646 {
647         unsigned long flags = 0;
648         struct mbx_entry *mbxentry;
649
650         /* Send marker if required. */
651         if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
652                 return (QLA_FUNCTION_FAILED);
653
654         if (!ha_locked)
655                 spin_lock_irqsave(&ha->hardware_lock, flags);
656
657         /* Build fabric port login mailbox IOCB. */
658         mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
659         if (mbxentry == NULL) {
660                 if (!ha_locked)
661                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
662
663                 return (QLA_FUNCTION_FAILED);
664         }
665         mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
666         mbxentry->mb1 = mbxentry->loop_id.extended =
667             cpu_to_le16(iodesc->remote_fcport->loop_id);
668         mbxentry->mb2 = cpu_to_le16(d_id->b.domain);
669         mbxentry->mb3 = cpu_to_le16(d_id->b.area << 8 | d_id->b.al_pa);
670         mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
671         wmb();
672
673         qla2x00_add_iodesc_timer(iodesc);
674
675         /* Issue command to ISP. */
676         qla2x00_isp_cmd(ha);
677
678         if (!ha_locked)
679                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
680
681         DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
682             "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature,
683             iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area,
684             d_id->b.al_pa));
685
686         return (QLA_SUCCESS);
687 }
688
689 /**
690  * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
691  * @ha: HA context
692  * @iodesc: io descriptor
693  * @mbxstat: mailbox status IOCB
694  *
695  * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
696  * will be used for a retry.
697  */
698 static int
699 qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
700     struct mbx_entry *mbxstat)
701 {
702         int rval;
703         fc_port_t *fcport, *remote_fcport, *exist_fcport;
704         struct io_descriptor *abort_iodesc, *login_iodesc;
705         uint16_t status, mb[8];
706         uint16_t reuse;
707         uint16_t remote_loopid;
708         port_id_t remote_did, inuse_did;
709
710         remote_fcport = iodesc->remote_fcport;
711
712         /* Only process the last command. */
713         if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
714                 DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
715                     "[%02x%02x%02x], expected %x, received %x.\n",
716                     ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,
717                     iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
718                     iodesc->idx));
719
720                 /* Free RSCN fcport resources. */
721                 if (remote_fcport->port_type == FCT_RSCN) {
722                         DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
723                             "fcport %p [%x/%02x%02x%02x] given ignored Login "
724                             "IOCB.\n", ha->host_no, remote_fcport,
725                             remote_fcport->loop_id,
726                             remote_fcport->d_id.b.domain,
727                             remote_fcport->d_id.b.area,
728                             remote_fcport->d_id.b.al_pa));
729
730                         list_del(&remote_fcport->list);
731                         kfree(remote_fcport);
732                 }
733                 return (QLA_SUCCESS);
734         }
735
736         status = le16_to_cpu(mbxstat->status);
737         mb[0] = le16_to_cpu(mbxstat->mb0);
738         mb[1] = le16_to_cpu(mbxstat->mb1);
739         mb[2] = le16_to_cpu(mbxstat->mb2);
740         mb[6] = le16_to_cpu(mbxstat->mb6);
741         mb[7] = le16_to_cpu(mbxstat->mb7);
742
743         /* Good status? */
744         if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) &&
745             mb[0] == MBS_COMMAND_COMPLETE) {
746
747                 DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
748                     "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,
749                     mb[1], mbxstat->port_name[0], mbxstat->port_name[1],
750                     mbxstat->port_name[2], mbxstat->port_name[3],
751                     mbxstat->port_name[4], mbxstat->port_name[5],
752                     mbxstat->port_name[6], mbxstat->port_name[7]));
753
754                 memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);
755                 memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE);
756
757                 /* Is the device already in our fcports list? */
758                 if (remote_fcport->port_type != FCT_RSCN) {
759                         DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
760                             "[%x/%02x%02x%02x] online.\n", ha->host_no,
761                             remote_fcport->loop_id,
762                             remote_fcport->d_id.b.domain,
763                             remote_fcport->d_id.b.area,
764                             remote_fcport->d_id.b.al_pa));
765
766                         qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
767
768                         return (QLA_SUCCESS);
769                 }
770
771                 /* Does the RSCN portname already exist in our fcports list? */
772                 exist_fcport = NULL;
773                 list_for_each_entry(fcport, &ha->fcports, list) {
774                         if (memcmp(remote_fcport->port_name, fcport->port_name,
775                             WWN_SIZE) == 0) {
776                                 exist_fcport = fcport;
777                                 break;
778                         }
779                 }
780                 if (exist_fcport != NULL) {
781                         DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
782                             "fcport in fcports list [%p].\n", ha->host_no,
783                             exist_fcport));
784
785                         /* Abort any ADISC that could have been sent. */
786                         if (exist_fcport->iodesc_idx_sent != iodesc->idx &&
787                             exist_fcport->iodesc_idx_sent <
788                             MAX_IO_DESCRIPTORS &&
789                             ha->io_descriptors[exist_fcport->iodesc_idx_sent].
790                             cb_idx == ADISC_PORT_IOCB_CB) {
791
792                                 abort_iodesc = qla2x00_alloc_iodesc(ha);
793                                 if (abort_iodesc) {
794                                         DEBUG14(printk("scsi(%ld): Login IOCB "
795                                             "-- issuing abort to outstanding "
796                                             "Adisc [%x/%02x%02x%02x].\n",
797                                             ha->host_no, remote_fcport->loop_id,
798                                             exist_fcport->d_id.b.domain,
799                                             exist_fcport->d_id.b.area,
800                                             exist_fcport->d_id.b.al_pa));
801
802                                         abort_iodesc->cb_idx = ABORT_IOCB_CB;
803                                         abort_iodesc->d_id.b24 =
804                                             exist_fcport->d_id.b24;
805                                         abort_iodesc->remote_fcport =
806                                             exist_fcport;
807                                         exist_fcport->iodesc_idx_sent =
808                                             abort_iodesc->idx;
809                                         qla2x00_send_abort_iocb(ha,
810                                             abort_iodesc, ha->io_descriptors[
811                                              exist_fcport->iodesc_idx_sent].
812                                               signature, 1);
813                                 } else {
814                                         DEBUG14(printk("scsi(%ld): Login IOCB "
815                                             "-- unable to abort outstanding "
816                                             "Adisc [%x/%02x%02x%02x].\n",
817                                             ha->host_no, remote_fcport->loop_id,
818                                             exist_fcport->d_id.b.domain,
819                                             exist_fcport->d_id.b.area,
820                                             exist_fcport->d_id.b.al_pa));
821                                 }
822                         }
823
824                         /*
825                          * If the existing fcport is waiting to send an ADISC
826                          * or LOGIN, then reuse remote fcport (RSCN) to
827                          * continue waiting.
828                          */
829                         reuse = 0;
830                         remote_loopid = remote_fcport->loop_id;
831                         remote_did.b24 = remote_fcport->d_id.b24;
832                         if (exist_fcport->iodesc_idx_sent ==
833                             IODESC_ADISC_NEEDED ||
834                             exist_fcport->iodesc_idx_sent ==
835                             IODESC_LOGIN_NEEDED) {
836                                 DEBUG14(printk("scsi(%ld): Login IOCB -- "
837                                     "existing fcport [%x/%02x%02x%02x] "
838                                     "waiting for IO descriptor, reuse RSCN "
839                                     "fcport.\n", ha->host_no,
840                                     exist_fcport->loop_id,
841                                     exist_fcport->d_id.b.domain,
842                                     exist_fcport->d_id.b.area,
843                                     exist_fcport->d_id.b.al_pa));
844
845                                 reuse++;
846                                 remote_fcport->iodesc_idx_sent =
847                                     exist_fcport->iodesc_idx_sent;
848                                 exist_fcport->iodesc_idx_sent =
849                                     IODESC_INVALID_INDEX;
850                                 remote_fcport->loop_id = exist_fcport->loop_id;
851                                 remote_fcport->d_id.b24 =
852                                     exist_fcport->d_id.b24;
853                         }
854
855                         /* Logout the old loopid. */
856                         if (!reuse &&
857                             exist_fcport->loop_id != remote_fcport->loop_id &&
858                             exist_fcport->loop_id != FC_NO_LOOP_ID) {
859                                 login_iodesc = qla2x00_alloc_iodesc(ha);
860                                 if (login_iodesc) {
861                                         DEBUG14(printk("scsi(%ld): Login IOCB "
862                                             "-- issuing logout to free old "
863                                             "loop id [%x/%02x%02x%02x].\n",
864                                             ha->host_no, exist_fcport->loop_id,
865                                             exist_fcport->d_id.b.domain,
866                                             exist_fcport->d_id.b.area,
867                                             exist_fcport->d_id.b.al_pa));
868
869                                         login_iodesc->cb_idx =
870                                             LOGOUT_PORT_IOCB_CB;
871                                         login_iodesc->d_id.b24 =
872                                             exist_fcport->d_id.b24;
873                                         login_iodesc->remote_fcport =
874                                             exist_fcport;
875                                         exist_fcport->iodesc_idx_sent =
876                                             login_iodesc->idx;
877                                         qla2x00_send_logout_iocb(ha,
878                                             login_iodesc, 1);
879                                 } else {
880                                         /* Ran out of IO descriptiors. */
881                                         DEBUG14(printk("scsi(%ld): Login IOCB "
882                                             "-- unable to logout to free old "
883                                             "loop id [%x/%02x%02x%02x].\n",
884                                             ha->host_no, exist_fcport->loop_id,
885                                             exist_fcport->d_id.b.domain,
886                                             exist_fcport->d_id.b.area,
887                                             exist_fcport->d_id.b.al_pa));
888
889                                         exist_fcport->iodesc_idx_sent =
890                                             IODESC_INVALID_INDEX;
891                                 }
892
893                         }
894
895                         /* Update existing fcport with remote fcport info. */
896                         DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
897                             "existing fcport [%x/%02x%02x%02x] online.\n",
898                             ha->host_no, remote_loopid, remote_did.b.domain,
899                             remote_did.b.area, remote_did.b.al_pa));
900
901                         memcpy(exist_fcport->node_name,
902                             remote_fcport->node_name, WWN_SIZE);
903                         exist_fcport->loop_id = remote_loopid;
904                         exist_fcport->d_id.b24 = remote_did.b24;
905                         qla2x00_update_login_fcport(ha, mbxstat, exist_fcport);
906
907                         /* Finally, free the remote (RSCN) fcport. */
908                         if (!reuse) {
909                                 DEBUG14(printk("scsi(%ld): Login IOCB -- "
910                                     "Freeing RSCN fcport %p "
911                                     "[%x/%02x%02x%02x].\n", ha->host_no,
912                                     remote_fcport, remote_fcport->loop_id,
913                                     remote_fcport->d_id.b.domain,
914                                     remote_fcport->d_id.b.area,
915                                     remote_fcport->d_id.b.al_pa));
916
917                                 list_del(&remote_fcport->list);
918                                 kfree(remote_fcport);
919                         }
920
921                         return (QLA_SUCCESS);
922                 }
923
924                 /*
925                  * A new device has been added, move the RSCN fcport to our
926                  * fcports list.
927                  */
928                 DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
929                     "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no,
930                     remote_fcport->loop_id, remote_fcport->d_id.b.domain,
931                     remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
932
933                 list_del(&remote_fcport->list);
934                 remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED);
935                 qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
936                 list_add_tail(&remote_fcport->list, &ha->fcports);
937                 set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags);
938         } else {
939                 /* Handle login failure. */
940                 if (remote_fcport->login_retry != 0) {
941                         if (mb[0] == MBS_LOOP_ID_USED) {
942                                 inuse_did.b.domain = LSB(mb[1]);
943                                 inuse_did.b.area = MSB(mb[2]);
944                                 inuse_did.b.al_pa = LSB(mb[2]);
945
946                                 DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
947                                     "id [%x] used by port id [%02x%02x%02x].\n",
948                                     ha->host_no, remote_fcport->loop_id,
949                                     inuse_did.b.domain, inuse_did.b.area,
950                                     inuse_did.b.al_pa));
951
952                                 if (remote_fcport->d_id.b24 ==
953                                     INVALID_PORT_ID) {
954                                         /*
955                                          * Invalid port id means we are trying
956                                          * to login to a remote port with just
957                                          * a loop id without knowing about the
958                                          * port id.  Copy the port id and try
959                                          * again.
960                                          */
961                                         remote_fcport->d_id.b24 = inuse_did.b24;
962                                         iodesc->d_id.b24 = inuse_did.b24;
963                                 } else {
964                                         remote_fcport->loop_id++;
965                                         rval = qla2x00_find_new_loop_id(ha,
966                                             remote_fcport);
967                                         if (rval == QLA_FUNCTION_FAILED) {
968                                                 /* No more loop ids. */
969                                                 return (QLA_SUCCESS);
970                                         }
971                                 }
972                         } else if (mb[0] == MBS_PORT_ID_USED) {
973                                 /*
974                                  * Device has another loop ID.  The firmware
975                                  * group recommends the driver perform an
976                                  * implicit login with the specified ID.
977                                  */
978                                 DEBUG14(printk("scsi(%ld): Login IOCB -- port "
979                                     "id [%02x%02x%02x] already assigned to "
980                                     "loop id [%x].\n", ha->host_no,
981                                     iodesc->d_id.b.domain, iodesc->d_id.b.area,
982                                     iodesc->d_id.b.al_pa, mb[1]));
983
984                                 remote_fcport->loop_id = mb[1];
985
986                         } else {
987                                 /* Unable to perform login, try again. */
988                                 DEBUG14(printk("scsi(%ld): Login IOCB -- "
989                                     "failed login [%x/%02x%02x%02x], status=%x "
990                                     "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
991                                     ha->host_no, remote_fcport->loop_id,
992                                     iodesc->d_id.b.domain, iodesc->d_id.b.area,
993                                     iodesc->d_id.b.al_pa, status, mb[0], mb[1],
994                                     mb[2], mb[6], mb[7]));
995                         }
996
997                         /* Reissue Login with the same IO descriptor. */
998                         iodesc->signature =
999                             qla2x00_iodesc_to_handle(iodesc);
1000                         iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
1001                         iodesc->d_id.b24 = remote_fcport->d_id.b24;
1002                         remote_fcport->iodesc_idx_sent = iodesc->idx;
1003                         remote_fcport->login_retry--;
1004
1005                         DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
1006                             "login to [%x/%02x%02x%02x] (%d).\n", ha->host_no,
1007                             remote_fcport->loop_id,
1008                             remote_fcport->d_id.b.domain,
1009                             remote_fcport->d_id.b.area,
1010                             remote_fcport->d_id.b.al_pa,
1011                             remote_fcport->login_retry));
1012
1013                         qla2x00_send_login_iocb(ha, iodesc,
1014                             &remote_fcport->d_id, 1);
1015
1016                         return (QLA_FUNCTION_FAILED);
1017                 } else {
1018                         /* No more logins, mark device dead. */
1019                         DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
1020                             "login [%x/%02x%02x%02x] after retries, status=%x "
1021                             "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1022                             ha->host_no, remote_fcport->loop_id,
1023                             iodesc->d_id.b.domain, iodesc->d_id.b.area,
1024                             iodesc->d_id.b.al_pa, status, mb[0], mb[1],
1025                             mb[2], mb[6], mb[7]));
1026
1027                         atomic_set(&remote_fcport->state, FCS_DEVICE_DEAD);
1028                         if (remote_fcport->port_type == FCT_RSCN) {
1029                                 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1030                                     "Freeing dead RSCN fcport %p "
1031                                     "[%x/%02x%02x%02x].\n", ha->host_no,
1032                                     remote_fcport, remote_fcport->loop_id,
1033                                     remote_fcport->d_id.b.domain,
1034                                     remote_fcport->d_id.b.area,
1035                                     remote_fcport->d_id.b.al_pa));
1036
1037                                 list_del(&remote_fcport->list);
1038                                 kfree(remote_fcport);
1039                         }
1040                 }
1041         }
1042
1043         return (QLA_SUCCESS);
1044 }
1045
1046
1047 /**
1048  * IO descriptor processing routines.
1049  **/
1050
1051 /**
1052  * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
1053  * @ha: HA context
1054  * @flags: allocation flags
1055  *
1056  * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
1057  */
1058 fc_port_t *
1059 qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, gfp_t flags)
1060 {
1061         fc_port_t *fcport;
1062
1063         fcport = qla2x00_alloc_fcport(ha, flags);
1064         if (fcport == NULL)
1065                 return (fcport);
1066
1067         /* Setup RSCN fcport structure. */
1068         fcport->port_type = FCT_RSCN;
1069
1070         return (fcport);
1071 }
1072
1073 /**
1074  * qla2x00_handle_port_rscn() - Handle port RSCN.
1075  * @ha: HA context
1076  * @rscn_entry: RSCN entry
1077  * @fcport: fcport entry to updated
1078  *
1079  * Returns QLA_SUCCESS if the port RSCN was handled.
1080  */
1081 int
1082 qla2x00_handle_port_rscn(scsi_qla_host_t *ha, uint32_t rscn_entry,
1083     fc_port_t *known_fcport, int ha_locked)
1084 {
1085         int     rval;
1086         port_id_t rscn_pid;
1087         fc_port_t *fcport, *remote_fcport, *rscn_fcport;
1088         struct io_descriptor *iodesc;
1089
1090         remote_fcport = NULL;
1091         rscn_fcport = NULL;
1092
1093         /* Prepare port id based on incoming entries. */
1094         if (known_fcport) {
1095                 rscn_pid.b24 = known_fcport->d_id.b24;
1096                 remote_fcport = known_fcport;
1097
1098                 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1099                     "fcport [%02x%02x%02x].\n", ha->host_no,
1100                     remote_fcport->d_id.b.domain, remote_fcport->d_id.b.area,
1101                     remote_fcport->d_id.b.al_pa));
1102         } else {
1103                 rscn_pid.b.domain = LSB(MSW(rscn_entry));
1104                 rscn_pid.b.area = MSB(LSW(rscn_entry));
1105                 rscn_pid.b.al_pa = LSB(LSW(rscn_entry));
1106
1107                 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1108                     "port id [%02x%02x%02x].\n", ha->host_no,
1109                     rscn_pid.b.domain, rscn_pid.b.area, rscn_pid.b.al_pa));
1110
1111                 /*
1112                  * Search fcport lists for a known entry at the specified port
1113                  * ID.
1114                  */
1115                 list_for_each_entry(fcport, &ha->fcports, list) {
1116                     if (rscn_pid.b24 == fcport->d_id.b24) {
1117                             remote_fcport = fcport;
1118                             break;
1119                     }
1120                 }
1121                 list_for_each_entry(fcport, &ha->rscn_fcports, list) {
1122                     if (rscn_pid.b24 == fcport->d_id.b24) {
1123                             rscn_fcport = fcport;
1124                             break;
1125                     }
1126                 }
1127                 if (remote_fcport == NULL)
1128                     remote_fcport = rscn_fcport;
1129         }
1130
1131         /*
1132          * If the port is already in our fcport list and online, send an ADISC
1133          * to see if it's still alive.  Issue login if a new fcport or the known
1134          * fcport is currently offline.
1135          */
1136         if (remote_fcport) {
1137                 /*
1138                  * No need to send request if the remote fcport is currently
1139                  * waiting for an available io descriptor.
1140                  */
1141                 if (known_fcport == NULL &&
1142                     (remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1143                     remote_fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED)) {
1144                         /*
1145                          * If previous waiting io descriptor is an ADISC, then
1146                          * the new RSCN may come from a new remote fcport being
1147                          * plugged into the same location.
1148                          */
1149                         if (remote_fcport->port_type == FCT_RSCN) {
1150                             remote_fcport->iodesc_idx_sent =
1151                                 IODESC_LOGIN_NEEDED;
1152                         } else if (remote_fcport->iodesc_idx_sent ==
1153                             IODESC_ADISC_NEEDED) {
1154                                 fc_port_t *new_fcport;
1155
1156                                 remote_fcport->iodesc_idx_sent =
1157                                     IODESC_INVALID_INDEX;
1158
1159                                 /* Create new fcport for later login. */
1160                                 new_fcport = qla2x00_alloc_rscn_fcport(ha,
1161                                     ha_locked ? GFP_ATOMIC: GFP_KERNEL);
1162                                 if (new_fcport) {
1163                                         DEBUG14(printk("scsi(%ld): Handle RSCN "
1164                                             "-- creating RSCN fcport %p for "
1165                                             "future login.\n", ha->host_no,
1166                                             new_fcport));
1167
1168                                         new_fcport->d_id.b24 =
1169                                             remote_fcport->d_id.b24;
1170                                         new_fcport->iodesc_idx_sent =
1171                                             IODESC_LOGIN_NEEDED;
1172
1173                                         list_add_tail(&new_fcport->list,
1174                                             &ha->rscn_fcports);
1175                                         set_bit(IODESC_PROCESS_NEEDED,
1176                                             &ha->dpc_flags);
1177                                 } else {
1178                                         DEBUG14(printk("scsi(%ld): Handle RSCN "
1179                                             "-- unable to allocate RSCN fcport "
1180                                             "for future login.\n",
1181                                             ha->host_no));
1182                                 }
1183                         }
1184                         return (QLA_SUCCESS);
1185                 }
1186
1187                 /* Send ADISC if the fcport is online */
1188                 if (atomic_read(&remote_fcport->state) == FCS_ONLINE ||
1189                     remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) {
1190
1191                         atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
1192
1193                         iodesc = qla2x00_alloc_iodesc(ha);
1194                         if (iodesc == NULL) {
1195                                 /* Mark fcport for later adisc processing */
1196                                 DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
1197                                     "enough IO descriptors for Adisc, flag "
1198                                     "for later processing.\n", ha->host_no));
1199
1200                                 remote_fcport->iodesc_idx_sent =
1201                                     IODESC_ADISC_NEEDED;
1202                                 set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1203
1204                                 return (QLA_SUCCESS);
1205                         }
1206
1207                         iodesc->cb_idx = ADISC_PORT_IOCB_CB;
1208                         iodesc->d_id.b24 = rscn_pid.b24;
1209                         iodesc->remote_fcport = remote_fcport;
1210                         remote_fcport->iodesc_idx_sent = iodesc->idx;
1211                         qla2x00_send_adisc_iocb(ha, iodesc, ha_locked);
1212
1213                         return (QLA_SUCCESS);
1214                 } else if (remote_fcport->iodesc_idx_sent <
1215                     MAX_IO_DESCRIPTORS &&
1216                     ha->io_descriptors[remote_fcport->iodesc_idx_sent].cb_idx ==
1217                     ADISC_PORT_IOCB_CB) {
1218                         /*
1219                          * Receiving another RSCN while an ADISC is pending,
1220                          * abort the IOCB.  Use the same descriptor for the
1221                          * abort.
1222                          */
1223                         uint32_t handle_to_abort;
1224
1225                         iodesc = &ha->io_descriptors[
1226                                 remote_fcport->iodesc_idx_sent];
1227                         qla2x00_remove_iodesc_timer(iodesc);
1228                         handle_to_abort = iodesc->signature;
1229                         iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
1230                         iodesc->cb_idx = ABORT_IOCB_CB;
1231                         iodesc->d_id.b24 = remote_fcport->d_id.b24;
1232                         iodesc->remote_fcport = remote_fcport;
1233                         remote_fcport->iodesc_idx_sent = iodesc->idx;
1234
1235                         DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
1236                             "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
1237                             ha->host_no, remote_fcport->loop_id,
1238                             iodesc->d_id.b.domain, iodesc->d_id.b.area,
1239                             iodesc->d_id.b.al_pa));
1240
1241                         qla2x00_send_abort_iocb(ha, iodesc, handle_to_abort,
1242                             ha_locked);
1243                 }
1244         }
1245
1246         /* We need to login to the remote port, find it. */
1247         if (known_fcport) {
1248                 remote_fcport = known_fcport;
1249         } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
1250             rscn_fcport->iodesc_idx_sent < MAX_IO_DESCRIPTORS &&
1251             ha->io_descriptors[rscn_fcport->iodesc_idx_sent].cb_idx ==
1252             LOGIN_PORT_IOCB_CB) {
1253                 /*
1254                  * Ignore duplicate RSCN on fcport which has already
1255                  * initiated a login IOCB.
1256                  */
1257                 DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
1258                     "already sent to [%02x%02x%02x].\n", ha->host_no,
1259                     rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
1260                     rscn_fcport->d_id.b.al_pa));
1261
1262                 return (QLA_SUCCESS);
1263         } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
1264             rscn_fcport != remote_fcport) {
1265                 /* Reuse same rscn fcport. */
1266                 DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
1267                     "[%02x%02x%02x].\n", ha->host_no,
1268                     rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
1269                     rscn_fcport->d_id.b.al_pa));
1270
1271                 remote_fcport = rscn_fcport;
1272         } else {
1273                 /* Create new fcport for later login. */
1274                 remote_fcport = qla2x00_alloc_rscn_fcport(ha,
1275                     ha_locked ? GFP_ATOMIC: GFP_KERNEL);
1276                 list_add_tail(&remote_fcport->list, &ha->rscn_fcports);
1277         }
1278         if (remote_fcport == NULL)
1279                 return (QLA_SUCCESS);
1280
1281         /* Prepare fcport for login. */
1282         atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
1283         remote_fcport->login_retry = 3; /* ha->login_retry_count; */
1284         remote_fcport->d_id.b24 = rscn_pid.b24;
1285
1286         iodesc = qla2x00_alloc_iodesc(ha);
1287         if (iodesc == NULL) {
1288                 /* Mark fcport for later adisc processing. */
1289                 DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
1290                     "descriptors for Login, flag for later processing.\n",
1291                     ha->host_no));
1292
1293                 remote_fcport->iodesc_idx_sent = IODESC_LOGIN_NEEDED;
1294                 set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1295
1296                 return (QLA_SUCCESS);
1297         }
1298
1299         if (known_fcport == NULL || rscn_pid.b24 != INVALID_PORT_ID) {
1300                 remote_fcport->loop_id = ha->min_external_loopid;
1301
1302                 rval = qla2x00_find_new_loop_id(ha, remote_fcport);
1303                 if (rval == QLA_FUNCTION_FAILED) {
1304                         /* No more loop ids, failed. */
1305                         DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
1306                             "loop id to perform Login, failed.\n",
1307                             ha->host_no));
1308
1309                         return (rval);
1310                 }
1311         }
1312
1313         iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
1314         iodesc->d_id.b24 = rscn_pid.b24;
1315         iodesc->remote_fcport = remote_fcport;
1316         remote_fcport->iodesc_idx_sent = iodesc->idx;
1317
1318         DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
1319             "[%x/%02x%02x%02x].\n", ha->host_no, remote_fcport->loop_id,
1320             iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa));
1321
1322         qla2x00_send_login_iocb(ha, iodesc, &rscn_pid, ha_locked);
1323
1324         return (QLA_SUCCESS);
1325 }
1326
1327 /**
1328  * qla2x00_process_iodesc() - Complete IO descriptor processing.
1329  * @ha: HA context
1330  * @mbxstat: Mailbox IOCB status
1331  */
1332 void
1333 qla2x00_process_iodesc(scsi_qla_host_t *ha, struct mbx_entry *mbxstat)
1334 {
1335         int rval;
1336         uint32_t signature;
1337         fc_port_t *fcport;
1338         struct io_descriptor *iodesc;
1339
1340         signature = mbxstat->handle;
1341
1342         DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
1343             ha->host_no, signature));
1344
1345         /* Retrieve proper IO descriptor. */
1346         iodesc = qla2x00_handle_to_iodesc(ha, signature);
1347         if (iodesc == NULL) {
1348                 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1349                     "incorrect signature %08x.\n", ha->host_no, signature));
1350
1351                 return;
1352         }
1353
1354         /* Stop IO descriptor timer. */
1355         qla2x00_remove_iodesc_timer(iodesc);
1356
1357         /* Verify signature match. */
1358         if (iodesc->signature != signature) {
1359                 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1360                     "signature mismatch, sent %08x, received %08x.\n",
1361                     ha->host_no, iodesc->signature, signature));
1362
1363                 return;
1364         }
1365
1366         /* Go with IOCB callback. */
1367         rval = iocb_function_cb_list[iodesc->cb_idx](ha, iodesc, mbxstat);
1368         if (rval != QLA_SUCCESS) {
1369                 /* IO descriptor reused by callback. */
1370                 return;
1371         }
1372
1373         qla2x00_free_iodesc(iodesc);
1374
1375         if (test_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags)) {
1376                 /* Scan our fcports list for any RSCN requests. */
1377                 list_for_each_entry(fcport, &ha->fcports, list) {
1378                         if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1379                             fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
1380                                 qla2x00_handle_port_rscn(ha, 0, fcport, 1);
1381                                 return;
1382                         }
1383                 }
1384
1385                 /* Scan our RSCN fcports list for any RSCN requests. */
1386                 list_for_each_entry(fcport, &ha->rscn_fcports, list) {
1387                         if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1388                             fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
1389                                 qla2x00_handle_port_rscn(ha, 0, fcport, 1);
1390                                 return;
1391                         }
1392                 }
1393         }
1394         clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1395 }
1396
1397 /**
1398  * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
1399  * @ha: HA context
1400  *
1401  * This routine will also delete any RSCN entries related to the outstanding
1402  * IO descriptors.
1403  */
1404 void
1405 qla2x00_cancel_io_descriptors(scsi_qla_host_t *ha)
1406 {
1407         fc_port_t *fcport, *fcptemp;
1408
1409         clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1410
1411         /* Abort all IO descriptors. */
1412         qla2x00_init_io_descriptors(ha);
1413
1414         /* Reset all pending IO descriptors in fcports list. */
1415         list_for_each_entry(fcport, &ha->fcports, list) {
1416                 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
1417         }
1418
1419         /* Reset all pending IO descriptors in rscn fcports list. */
1420         list_for_each_entry_safe(fcport, fcptemp, &ha->rscn_fcports, list) {
1421                 DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
1422                     "%p [%x/%02x%02x%02x].\n", ha->host_no, fcport,
1423                     fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
1424                     fcport->d_id.b.al_pa));
1425
1426                 list_del(&fcport->list);
1427                 kfree(fcport);
1428         }
1429 }