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