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