2 * QLOGIC LINUX SOFTWARE
4 * QLogic ISP2x00 device driver for Linux 2.6.x
5 * Copyright (C) 2003-2004 QLogic Corporation
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
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.
24 * IO descriptor handle definitions.
28 * |31------28|27-------------------12|11-------0|
29 * | Type | Rolling Signature | Index |
30 * |----------|-----------------------|----------|
34 #define HDL_TYPE_SCSI 0
35 #define HDL_TYPE_ASYNC_IOCB 0x0A
37 #define HDL_INDEX_BITS 12
38 #define HDL_ITER_BITS 16
39 #define HDL_TYPE_BITS 4
41 #define HDL_INDEX_MASK ((1UL << HDL_INDEX_BITS) - 1)
42 #define HDL_ITER_MASK ((1UL << HDL_ITER_BITS) - 1)
43 #define HDL_TYPE_MASK ((1UL << HDL_TYPE_BITS) - 1)
45 #define HDL_INDEX_SHIFT 0
46 #define HDL_ITER_SHIFT (HDL_INDEX_SHIFT + HDL_INDEX_BITS)
47 #define HDL_TYPE_SHIFT (HDL_ITER_SHIFT + HDL_ITER_BITS)
49 /* Local Prototypes. */
50 static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t);
51 static inline uint16_t qla2x00_handle_to_idx(uint32_t);
52 static inline uint16_t qla2x00_handle_to_iter(uint32_t);
53 static inline uint16_t qla2x00_handle_to_type(uint32_t);
54 static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor *);
55 static inline struct io_descriptor *qla2x00_handle_to_iodesc(scsi_qla_host_t *,
58 static inline struct io_descriptor *qla2x00_alloc_iodesc(scsi_qla_host_t *);
59 static inline void qla2x00_free_iodesc(struct io_descriptor *);
60 static inline void qla2x00_init_io_descriptors(scsi_qla_host_t *);
62 static void qla2x00_iodesc_timeout(unsigned long);
63 static inline void qla2x00_add_iodesc_timer(struct io_descriptor *);
64 static inline void qla2x00_remove_iodesc_timer(struct io_descriptor *);
66 static inline void qla2x00_update_login_fcport(scsi_qla_host_t *,
67 struct mbx_entry *, fc_port_t *);
69 static int qla2x00_send_abort_iocb(scsi_qla_host_t *, struct io_descriptor *,
71 static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
74 static int qla2x00_send_adisc_iocb(scsi_qla_host_t *, struct io_descriptor *,
76 static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
79 static int qla2x00_send_logout_iocb(scsi_qla_host_t *, struct io_descriptor *,
81 static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t *,
82 struct io_descriptor *, struct mbx_entry *);
84 static int qla2x00_send_login_iocb(scsi_qla_host_t *, struct io_descriptor *,
86 static int qla2x00_send_login_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
90 * Mailbox IOCB callback array.
92 int (*iocb_function_cb_list[LAST_IOCB_CB])
93 (scsi_qla_host_t *, struct io_descriptor *, struct mbx_entry *) = {
95 qla2x00_send_abort_iocb_cb,
96 qla2x00_send_adisc_iocb_cb,
97 qla2x00_send_logout_iocb_cb,
98 qla2x00_send_login_iocb_cb,
103 * Generic IO descriptor handle routines.
107 * qla2x00_to_handle() - Create a descriptor handle.
108 * @type: descriptor type
109 * @iter: descriptor rolling signature
110 * @idx: index to the descriptor array
112 * Returns a composite handle based in the @type, @iter, and @idx.
114 static inline uint32_t
115 qla2x00_to_handle(uint16_t type, uint16_t iter, uint16_t idx)
117 return ((uint32_t)(((uint32_t)type << HDL_TYPE_SHIFT) |
118 ((uint32_t)iter << HDL_ITER_SHIFT) |
119 ((uint32_t)idx << HDL_INDEX_SHIFT)));
123 * qla2x00_handle_to_idx() - Retrive the index for a given handle.
124 * @handle: descriptor handle
126 * Returns the index specified by the @handle.
128 static inline uint16_t
129 qla2x00_handle_to_idx(uint32_t handle)
131 return ((uint16_t)(((handle) >> HDL_INDEX_SHIFT) & HDL_INDEX_MASK));
135 * qla2x00_handle_to_type() - Retrive the descriptor type for a given handle.
136 * @handle: descriptor handle
138 * Returns the descriptor type specified by the @handle.
140 static inline uint16_t
141 qla2x00_handle_to_type(uint32_t handle)
143 return ((uint16_t)(((handle) >> HDL_TYPE_SHIFT) & HDL_TYPE_MASK));
147 * qla2x00_handle_to_iter() - Retrive the rolling signature for a given handle.
148 * @handle: descriptor handle
150 * Returns the signature specified by the @handle.
152 static inline uint16_t
153 qla2x00_handle_to_iter(uint32_t handle)
155 return ((uint16_t)(((handle) >> HDL_ITER_SHIFT) & HDL_ITER_MASK));
159 * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
160 * @iodesc: io descriptor
162 * Returns a unique handle for @iodesc.
164 static inline uint32_t
165 qla2x00_iodesc_to_handle(struct io_descriptor *iodesc)
169 handle = qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB,
170 ++iodesc->ha->iodesc_signature, iodesc->idx);
171 iodesc->signature = handle;
177 * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
179 * @handle: handle to io descriptor
181 * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
182 * not exist or the io descriptors signature does not @handle.
184 static inline struct io_descriptor *
185 qla2x00_handle_to_iodesc(scsi_qla_host_t *ha, uint32_t handle)
188 struct io_descriptor *iodesc;
190 idx = qla2x00_handle_to_idx(handle);
191 iodesc = &ha->io_descriptors[idx];
193 if (iodesc->signature != handle)
201 * IO descriptor allocation routines.
205 * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
208 * Returns a pointer to the allocated io descriptor, or NULL, if none available.
210 static inline struct io_descriptor *
211 qla2x00_alloc_iodesc(scsi_qla_host_t *ha)
214 struct io_descriptor *iodesc;
217 for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
218 if (ha->io_descriptors[iter].used)
221 iodesc = &ha->io_descriptors[iter];
224 init_timer(&iodesc->timer);
226 iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
234 * qla2x00_free_iodesc() - Free an IO descriptor.
235 * @iodesc: io descriptor
237 * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
240 qla2x00_free_iodesc(struct io_descriptor *iodesc)
243 iodesc->signature = 0;
247 * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
251 qla2x00_init_io_descriptors(scsi_qla_host_t *ha)
255 for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
256 if (!ha->io_descriptors[iter].used)
259 qla2x00_remove_iodesc_timer(&ha->io_descriptors[iter]);
260 qla2x00_free_iodesc(&ha->io_descriptors[iter]);
266 * IO descriptor timer routines.
270 * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
271 * @data: io descriptor
274 qla2x00_iodesc_timeout(unsigned long data)
276 struct io_descriptor *iodesc;
278 iodesc = (struct io_descriptor *) data;
280 DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
281 "signature=%08x, scheduling ISP abort.\n", iodesc->ha->host_no,
282 iodesc->idx, iodesc->signature));
284 qla2x00_free_iodesc(iodesc);
286 qla_printk(KERN_WARNING, iodesc->ha,
287 "IO descriptor timeout. Scheduling ISP abort.\n");
288 set_bit(ISP_ABORT_NEEDED, &iodesc->ha->dpc_flags);
292 * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
293 * @iodesc: io descriptor
296 * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
297 * tenths of a second) after it hits the wire. But, if there are any request
298 * resource contraints (i.e. during heavy I/O), exchanges can be held off for
299 * at most R_A_TOV. Therefore, the driver will wait 4 * R_A_TOV before
300 * scheduling a recovery (big hammer).
303 qla2x00_add_iodesc_timer(struct io_descriptor *iodesc)
305 unsigned long timeout;
307 timeout = (iodesc->ha->r_a_tov * 4) / 10;
308 init_timer(&iodesc->timer);
309 iodesc->timer.data = (unsigned long) iodesc;
310 iodesc->timer.expires = jiffies + (timeout * HZ);
311 iodesc->timer.function =
312 (void (*) (unsigned long)) qla2x00_iodesc_timeout;
313 add_timer(&iodesc->timer);
317 * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
318 * @iodesc: io descriptor
321 qla2x00_remove_iodesc_timer(struct io_descriptor *iodesc)
323 if (iodesc->timer.function != NULL) {
324 del_timer_sync(&iodesc->timer);
325 iodesc->timer.data = (unsigned long) NULL;
326 iodesc->timer.function = NULL;
331 * IO descriptor support routines.
335 * qla2x00_update_login_fcport() - Update fcport data after login processing.
337 * @mbxstat: Mailbox command status IOCB
338 * @fcport: port to update
341 qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
344 if (le16_to_cpu(mbxstat->mb1) & BIT_0) {
345 fcport->port_type = FCT_INITIATOR;
347 fcport->port_type = FCT_TARGET;
348 if (le16_to_cpu(mbxstat->mb1) & BIT_1) {
349 fcport->flags |= FCF_TAPE_PRESENT;
352 fcport->login_retry = 0;
353 fcport->port_login_retry_count = ha->port_down_retry_count *
355 atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
357 fcport->flags |= FCF_FABRIC_DEVICE;
358 fcport->flags &= ~FCF_FAILOVER_NEEDED;
359 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
360 atomic_set(&fcport->state, FCS_ONLINE);
365 * Mailbox IOCB commands.
369 * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
371 * @handle: handle to io descriptor
373 * Returns a pointer to the reqest entry, or NULL, if none were available.
375 static inline struct mbx_entry *
376 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle)
380 struct mbx_entry *mbxentry;
385 if (ha->req_q_cnt < 3) {
386 cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg));
387 if (ha->req_ring_index < cnt)
388 ha->req_q_cnt = cnt - ha->req_ring_index;
390 ha->req_q_cnt = ha->request_q_length -
391 (ha->req_ring_index - cnt);
393 if (ha->req_q_cnt >= 3) {
394 mbxentry = (struct mbx_entry *)ha->request_ring_ptr;
396 memset(mbxentry, 0, sizeof(struct mbx_entry));
397 mbxentry->entry_type = MBX_IOCB_TYPE;
398 mbxentry->entry_count = 1;
399 mbxentry->sys_define1 = SOURCE_ASYNC_IOCB;
400 mbxentry->handle = handle;
406 * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
408 * @iodesc: io descriptor
409 * @handle_to_abort: firmware handle to abort
410 * @ha_locked: is function called with the hardware lock
412 * Returns QLA_SUCCESS if the IOCB was issued.
415 qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
416 uint32_t handle_to_abort, int ha_locked)
418 unsigned long flags = 0;
419 struct mbx_entry *mbxentry;
421 /* Send marker if required. */
422 if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
423 return (QLA_FUNCTION_FAILED);
426 spin_lock_irqsave(&ha->hardware_lock, flags);
428 /* Build abort mailbox IOCB. */
429 mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
430 if (mbxentry == NULL) {
432 spin_unlock_irqrestore(&ha->hardware_lock, flags);
434 return (QLA_FUNCTION_FAILED);
436 mbxentry->mb0 = __constant_cpu_to_le16(MBC_ABORT_COMMAND);
437 mbxentry->mb1 = mbxentry->loop_id.extended =
438 cpu_to_le16(iodesc->remote_fcport->loop_id);
439 mbxentry->mb2 = LSW(handle_to_abort);
440 mbxentry->mb3 = MSW(handle_to_abort);
442 qla2x00_add_iodesc_timer(iodesc);
444 /* Issue command to ISP. */
448 spin_unlock_irqrestore(&ha->hardware_lock, flags);
450 DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
451 "%08x.\n", ha->host_no, iodesc->signature,
452 iodesc->remote_fcport->loop_id, handle_to_abort));
454 return (QLA_SUCCESS);
458 * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
460 * @iodesc: io descriptor
461 * @mbxstat: mailbox status IOCB
463 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
464 * will be used for a retry.
467 qla2x00_send_abort_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
468 struct mbx_entry *mbxstat)
470 DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
471 "status=%x mb0=%x.\n", ha->host_no, iodesc->remote_fcport->loop_id,
472 iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa,
473 le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
475 return (QLA_SUCCESS);
480 * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
482 * @iodesc: io descriptor
483 * @ha_locked: is function called with the hardware lock
485 * Returns QLA_SUCCESS if the IOCB was issued.
488 qla2x00_send_adisc_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
491 unsigned long flags = 0;
492 struct mbx_entry *mbxentry;
494 /* Send marker if required. */
495 if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
496 return (QLA_FUNCTION_FAILED);
499 spin_lock_irqsave(&ha->hardware_lock, flags);
501 /* Build Get Port Database IOCB. */
502 mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
503 if (mbxentry == NULL) {
505 spin_unlock_irqrestore(&ha->hardware_lock, flags);
507 return (QLA_FUNCTION_FAILED);
509 mbxentry->mb0 = __constant_cpu_to_le16(MBC_GET_PORT_DATABASE);
510 mbxentry->mb1 = mbxentry->loop_id.extended =
511 cpu_to_le16(iodesc->remote_fcport->loop_id);
512 mbxentry->mb2 = cpu_to_le16(MSW(LSD(ha->iodesc_pd_dma)));
513 mbxentry->mb3 = cpu_to_le16(LSW(LSD(ha->iodesc_pd_dma)));
514 mbxentry->mb6 = cpu_to_le16(MSW(MSD(ha->iodesc_pd_dma)));
515 mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma)));
516 mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
518 qla2x00_add_iodesc_timer(iodesc);
520 /* Issue command to ISP. */
524 spin_unlock_irqrestore(&ha->hardware_lock, flags);
526 DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
527 ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
529 return (QLA_SUCCESS);
533 * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
535 * @iodesc: io descriptor
536 * @mbxstat: mailbox status IOCB
538 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
539 * will be used for a retry.
542 qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
543 struct mbx_entry *mbxstat)
545 fc_port_t *remote_fcport;
547 remote_fcport = iodesc->remote_fcport;
549 /* Ensure the port IDs are consistent. */
550 if (remote_fcport->d_id.b24 != iodesc->d_id.b24) {
551 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
552 "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
553 ha->host_no, remote_fcport->d_id.b.domain,
554 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
555 iodesc->d_id.b.domain, iodesc->d_id.b.area,
556 iodesc->d_id.b.al_pa));
558 return (QLA_SUCCESS);
561 /* Only process the last command. */
562 if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
563 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
564 "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no,
565 iodesc->d_id.b.domain, iodesc->d_id.b.area,
566 iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
569 return (QLA_SUCCESS);
572 if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) {
573 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
574 "[%x/%02x%02x%02x] online.\n", ha->host_no,
575 remote_fcport->loop_id, remote_fcport->d_id.b.domain,
576 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
578 atomic_set(&remote_fcport->state, FCS_ONLINE);
580 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
581 "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no,
582 remote_fcport->loop_id, remote_fcport->d_id.b.domain,
583 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
584 le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
586 if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD)
587 atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
589 remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
591 return (QLA_SUCCESS);
596 * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
598 * @iodesc: io descriptor
599 * @ha_locked: is function called with the hardware lock
601 * Returns QLA_SUCCESS if the IOCB was issued.
604 qla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
607 unsigned long flags = 0;
608 struct mbx_entry *mbxentry;
610 /* Send marker if required. */
611 if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
612 return (QLA_FUNCTION_FAILED);
615 spin_lock_irqsave(&ha->hardware_lock, flags);
617 /* Build fabric port logout mailbox IOCB. */
618 mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
619 if (mbxentry == NULL) {
621 spin_unlock_irqrestore(&ha->hardware_lock, flags);
623 return (QLA_FUNCTION_FAILED);
625 mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
626 mbxentry->mb1 = mbxentry->loop_id.extended =
627 cpu_to_le16(iodesc->remote_fcport->loop_id);
629 qla2x00_add_iodesc_timer(iodesc);
631 /* Issue command to ISP. */
635 spin_unlock_irqrestore(&ha->hardware_lock, flags);
637 DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
638 ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
640 return (QLA_SUCCESS);
644 * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
646 * @iodesc: io descriptor
647 * @mbxstat: mailbox status IOCB
649 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
650 * will be used for a retry.
653 qla2x00_send_logout_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
654 struct mbx_entry *mbxstat)
656 DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
657 "status=%x mb0=%x mb1=%x.\n", ha->host_no,
658 iodesc->remote_fcport->loop_id,
659 iodesc->remote_fcport->d_id.b.domain,
660 iodesc->remote_fcport->d_id.b.area,
661 iodesc->remote_fcport->d_id.b.al_pa, le16_to_cpu(mbxstat->status),
662 le16_to_cpu(mbxstat->mb0), le16_to_cpu(mbxstat->mb1)));
664 return (QLA_SUCCESS);
669 * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
671 * @iodesc: io descriptor
672 * @d_id: port id for device
673 * @ha_locked: is function called with the hardware lock
675 * Returns QLA_SUCCESS if the IOCB was issued.
678 qla2x00_send_login_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
679 port_id_t *d_id, int ha_locked)
681 unsigned long flags = 0;
682 struct mbx_entry *mbxentry;
684 /* Send marker if required. */
685 if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
686 return (QLA_FUNCTION_FAILED);
689 spin_lock_irqsave(&ha->hardware_lock, flags);
691 /* Build fabric port login mailbox IOCB. */
692 mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
693 if (mbxentry == NULL) {
695 spin_unlock_irqrestore(&ha->hardware_lock, flags);
697 return (QLA_FUNCTION_FAILED);
699 mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
700 mbxentry->mb1 = mbxentry->loop_id.extended =
701 cpu_to_le16(iodesc->remote_fcport->loop_id);
702 mbxentry->mb2 = cpu_to_le16(d_id->b.domain);
703 mbxentry->mb3 = cpu_to_le16(d_id->b.area << 8 | d_id->b.al_pa);
704 mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
706 qla2x00_add_iodesc_timer(iodesc);
708 /* Issue command to ISP. */
712 spin_unlock_irqrestore(&ha->hardware_lock, flags);
714 DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
715 "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature,
716 iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area,
719 return (QLA_SUCCESS);
723 * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
725 * @iodesc: io descriptor
726 * @mbxstat: mailbox status IOCB
728 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
729 * will be used for a retry.
732 qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
733 struct mbx_entry *mbxstat)
736 fc_port_t *fcport, *remote_fcport, *exist_fcport;
737 struct io_descriptor *abort_iodesc, *login_iodesc;
738 uint16_t status, mb[8];
740 uint16_t remote_loopid;
741 port_id_t remote_did, inuse_did;
743 remote_fcport = iodesc->remote_fcport;
745 /* Only process the last command. */
746 if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
747 DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
748 "[%02x%02x%02x], expected %x, received %x.\n",
749 ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,
750 iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
753 /* Free RSCN fcport resources. */
754 if (remote_fcport->port_type == FCT_RSCN) {
755 DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
756 "fcport %p [%x/%02x%02x%02x] given ignored Login "
757 "IOCB.\n", ha->host_no, remote_fcport,
758 remote_fcport->loop_id,
759 remote_fcport->d_id.b.domain,
760 remote_fcport->d_id.b.area,
761 remote_fcport->d_id.b.al_pa));
763 list_del(&remote_fcport->list);
764 kfree(remote_fcport);
766 return (QLA_SUCCESS);
769 status = le16_to_cpu(mbxstat->status);
770 mb[0] = le16_to_cpu(mbxstat->mb0);
771 mb[1] = le16_to_cpu(mbxstat->mb1);
772 mb[2] = le16_to_cpu(mbxstat->mb2);
773 mb[6] = le16_to_cpu(mbxstat->mb6);
774 mb[7] = le16_to_cpu(mbxstat->mb7);
777 if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) &&
778 mb[0] == MBS_COMMAND_COMPLETE) {
780 DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
781 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,
782 mb[1], mbxstat->port_name[0], mbxstat->port_name[1],
783 mbxstat->port_name[2], mbxstat->port_name[3],
784 mbxstat->port_name[4], mbxstat->port_name[5],
785 mbxstat->port_name[6], mbxstat->port_name[7]));
787 memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);
788 memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE);
790 /* Is the device already in our fcports list? */
791 if (remote_fcport->port_type != FCT_RSCN) {
792 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
793 "[%x/%02x%02x%02x] online.\n", ha->host_no,
794 remote_fcport->loop_id,
795 remote_fcport->d_id.b.domain,
796 remote_fcport->d_id.b.area,
797 remote_fcport->d_id.b.al_pa));
799 qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
801 return (QLA_SUCCESS);
804 /* Does the RSCN portname already exist in our fcports list? */
806 list_for_each_entry(fcport, &ha->fcports, list) {
807 if (memcmp(remote_fcport->port_name, fcport->port_name,
809 exist_fcport = fcport;
813 if (exist_fcport != NULL) {
814 DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
815 "fcport in fcports list [%p].\n", ha->host_no,
818 /* Abort any ADISC that could have been sent. */
819 if (exist_fcport->iodesc_idx_sent != iodesc->idx &&
820 exist_fcport->iodesc_idx_sent <
821 MAX_IO_DESCRIPTORS &&
822 ha->io_descriptors[exist_fcport->iodesc_idx_sent].
823 cb_idx == ADISC_PORT_IOCB_CB) {
825 abort_iodesc = qla2x00_alloc_iodesc(ha);
827 DEBUG14(printk("scsi(%ld): Login IOCB "
828 "-- issuing abort to outstanding "
829 "Adisc [%x/%02x%02x%02x].\n",
830 ha->host_no, remote_fcport->loop_id,
831 exist_fcport->d_id.b.domain,
832 exist_fcport->d_id.b.area,
833 exist_fcport->d_id.b.al_pa));
835 abort_iodesc->cb_idx = ABORT_IOCB_CB;
836 abort_iodesc->d_id.b24 =
837 exist_fcport->d_id.b24;
838 abort_iodesc->remote_fcport =
840 exist_fcport->iodesc_idx_sent =
842 qla2x00_send_abort_iocb(ha,
843 abort_iodesc, ha->io_descriptors[
844 exist_fcport->iodesc_idx_sent].
847 DEBUG14(printk("scsi(%ld): Login IOCB "
848 "-- unable to abort outstanding "
849 "Adisc [%x/%02x%02x%02x].\n",
850 ha->host_no, remote_fcport->loop_id,
851 exist_fcport->d_id.b.domain,
852 exist_fcport->d_id.b.area,
853 exist_fcport->d_id.b.al_pa));
858 * If the existing fcport is waiting to send an ADISC
859 * or LOGIN, then reuse remote fcport (RSCN) to
863 remote_loopid = remote_fcport->loop_id;
864 remote_did.b24 = remote_fcport->d_id.b24;
865 if (exist_fcport->iodesc_idx_sent ==
866 IODESC_ADISC_NEEDED ||
867 exist_fcport->iodesc_idx_sent ==
868 IODESC_LOGIN_NEEDED) {
869 DEBUG14(printk("scsi(%ld): Login IOCB -- "
870 "existing fcport [%x/%02x%02x%02x] "
871 "waiting for IO descriptor, reuse RSCN "
872 "fcport.\n", ha->host_no,
873 exist_fcport->loop_id,
874 exist_fcport->d_id.b.domain,
875 exist_fcport->d_id.b.area,
876 exist_fcport->d_id.b.al_pa));
879 remote_fcport->iodesc_idx_sent =
880 exist_fcport->iodesc_idx_sent;
881 exist_fcport->iodesc_idx_sent =
882 IODESC_INVALID_INDEX;
883 remote_fcport->loop_id = exist_fcport->loop_id;
884 remote_fcport->d_id.b24 =
885 exist_fcport->d_id.b24;
888 /* Logout the old loopid. */
890 exist_fcport->loop_id != remote_fcport->loop_id &&
891 exist_fcport->loop_id != FC_NO_LOOP_ID) {
892 login_iodesc = qla2x00_alloc_iodesc(ha);
894 DEBUG14(printk("scsi(%ld): Login IOCB "
895 "-- issuing logout to free old "
896 "loop id [%x/%02x%02x%02x].\n",
897 ha->host_no, exist_fcport->loop_id,
898 exist_fcport->d_id.b.domain,
899 exist_fcport->d_id.b.area,
900 exist_fcport->d_id.b.al_pa));
902 login_iodesc->cb_idx =
904 login_iodesc->d_id.b24 =
905 exist_fcport->d_id.b24;
906 login_iodesc->remote_fcport =
908 exist_fcport->iodesc_idx_sent =
910 qla2x00_send_logout_iocb(ha,
913 /* Ran out of IO descriptiors. */
914 DEBUG14(printk("scsi(%ld): Login IOCB "
915 "-- unable to logout to free old "
916 "loop id [%x/%02x%02x%02x].\n",
917 ha->host_no, exist_fcport->loop_id,
918 exist_fcport->d_id.b.domain,
919 exist_fcport->d_id.b.area,
920 exist_fcport->d_id.b.al_pa));
922 exist_fcport->iodesc_idx_sent =
923 IODESC_INVALID_INDEX;
928 /* Update existing fcport with remote fcport info. */
929 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
930 "existing fcport [%x/%02x%02x%02x] online.\n",
931 ha->host_no, remote_loopid, remote_did.b.domain,
932 remote_did.b.area, remote_did.b.al_pa));
934 memcpy(exist_fcport->node_name,
935 remote_fcport->node_name, WWN_SIZE);
936 exist_fcport->loop_id = remote_loopid;
937 exist_fcport->d_id.b24 = remote_did.b24;
938 qla2x00_update_login_fcport(ha, mbxstat, exist_fcport);
940 /* Finally, free the remote (RSCN) fcport. */
942 DEBUG14(printk("scsi(%ld): Login IOCB -- "
943 "Freeing RSCN fcport %p "
944 "[%x/%02x%02x%02x].\n", ha->host_no,
945 remote_fcport, remote_fcport->loop_id,
946 remote_fcport->d_id.b.domain,
947 remote_fcport->d_id.b.area,
948 remote_fcport->d_id.b.al_pa));
950 list_del(&remote_fcport->list);
951 kfree(remote_fcport);
954 return (QLA_SUCCESS);
958 * A new device has been added, move the RSCN fcport to our
961 DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
962 "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no,
963 remote_fcport->loop_id, remote_fcport->d_id.b.domain,
964 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
966 list_del(&remote_fcport->list);
967 remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED);
968 qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
969 list_add_tail(&remote_fcport->list, &ha->fcports);
970 set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags);
972 /* Handle login failure. */
973 if (remote_fcport->login_retry != 0) {
974 if (mb[0] == MBS_LOOP_ID_USED) {
975 inuse_did.b.domain = LSB(mb[1]);
976 inuse_did.b.area = MSB(mb[2]);
977 inuse_did.b.al_pa = LSB(mb[2]);
979 DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
980 "id [%x] used by port id [%02x%02x%02x].\n",
981 ha->host_no, remote_fcport->loop_id,
982 inuse_did.b.domain, inuse_did.b.area,
985 if (remote_fcport->d_id.b24 ==
988 * Invalid port id means we are trying
989 * to login to a remote port with just
990 * a loop id without knowing about the
991 * port id. Copy the port id and try
994 remote_fcport->d_id.b24 = inuse_did.b24;
995 iodesc->d_id.b24 = inuse_did.b24;
997 remote_fcport->loop_id++;
998 rval = qla2x00_find_new_loop_id(ha,
1000 if (rval == QLA_FUNCTION_FAILED) {
1001 /* No more loop ids. */
1002 return (QLA_SUCCESS);
1005 } else if (mb[0] == MBS_PORT_ID_USED) {
1007 * Device has another loop ID. The firmware
1008 * group recommends the driver perform an
1009 * implicit login with the specified ID.
1011 DEBUG14(printk("scsi(%ld): Login IOCB -- port "
1012 "id [%02x%02x%02x] already assigned to "
1013 "loop id [%x].\n", ha->host_no,
1014 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1015 iodesc->d_id.b.al_pa, mb[1]));
1017 remote_fcport->loop_id = mb[1];
1020 /* Unable to perform login, try again. */
1021 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1022 "failed login [%x/%02x%02x%02x], status=%x "
1023 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1024 ha->host_no, remote_fcport->loop_id,
1025 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1026 iodesc->d_id.b.al_pa, status, mb[0], mb[1],
1027 mb[2], mb[6], mb[7]));
1030 /* Reissue Login with the same IO descriptor. */
1032 qla2x00_iodesc_to_handle(iodesc);
1033 iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
1034 iodesc->d_id.b24 = remote_fcport->d_id.b24;
1035 remote_fcport->iodesc_idx_sent = iodesc->idx;
1036 remote_fcport->login_retry--;
1038 DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
1039 "login to [%x/%02x%02x%02x] (%d).\n", ha->host_no,
1040 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 remote_fcport->login_retry));
1046 qla2x00_send_login_iocb(ha, iodesc,
1047 &remote_fcport->d_id, 1);
1049 return (QLA_FUNCTION_FAILED);
1051 /* No more logins, mark device dead. */
1052 DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
1053 "login [%x/%02x%02x%02x] after retries, status=%x "
1054 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1055 ha->host_no, remote_fcport->loop_id,
1056 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1057 iodesc->d_id.b.al_pa, status, mb[0], mb[1],
1058 mb[2], mb[6], mb[7]));
1060 atomic_set(&remote_fcport->state, FCS_DEVICE_DEAD);
1061 if (remote_fcport->port_type == FCT_RSCN) {
1062 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1063 "Freeing dead RSCN fcport %p "
1064 "[%x/%02x%02x%02x].\n", ha->host_no,
1065 remote_fcport, remote_fcport->loop_id,
1066 remote_fcport->d_id.b.domain,
1067 remote_fcport->d_id.b.area,
1068 remote_fcport->d_id.b.al_pa));
1070 list_del(&remote_fcport->list);
1071 kfree(remote_fcport);
1076 return (QLA_SUCCESS);
1081 * IO descriptor processing routines.
1085 * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
1087 * @flags: allocation flags
1089 * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
1092 qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, int flags)
1096 fcport = qla2x00_alloc_fcport(ha, flags);
1100 /* Setup RSCN fcport structure. */
1101 fcport->port_type = FCT_RSCN;
1107 * qla2x00_handle_port_rscn() - Handle port RSCN.
1109 * @rscn_entry: RSCN entry
1110 * @fcport: fcport entry to updated
1112 * Returns QLA_SUCCESS if the port RSCN was handled.
1115 qla2x00_handle_port_rscn(scsi_qla_host_t *ha, uint32_t rscn_entry,
1116 fc_port_t *known_fcport, int ha_locked)
1120 fc_port_t *fcport, *remote_fcport, *rscn_fcport;
1121 struct io_descriptor *iodesc;
1123 remote_fcport = NULL;
1126 /* Prepare port id based on incoming entries. */
1128 rscn_pid.b24 = known_fcport->d_id.b24;
1129 remote_fcport = known_fcport;
1131 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1132 "fcport [%02x%02x%02x].\n", ha->host_no,
1133 remote_fcport->d_id.b.domain, remote_fcport->d_id.b.area,
1134 remote_fcport->d_id.b.al_pa));
1136 rscn_pid.b.domain = LSB(MSW(rscn_entry));
1137 rscn_pid.b.area = MSB(LSW(rscn_entry));
1138 rscn_pid.b.al_pa = LSB(LSW(rscn_entry));
1140 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1141 "port id [%02x%02x%02x].\n", ha->host_no,
1142 rscn_pid.b.domain, rscn_pid.b.area, rscn_pid.b.al_pa));
1145 * Search fcport lists for a known entry at the specified port
1148 list_for_each_entry(fcport, &ha->fcports, list) {
1149 if (rscn_pid.b24 == fcport->d_id.b24) {
1150 remote_fcport = fcport;
1154 list_for_each_entry(fcport, &ha->rscn_fcports, list) {
1155 if (rscn_pid.b24 == fcport->d_id.b24) {
1156 rscn_fcport = fcport;
1160 if (remote_fcport == NULL)
1161 remote_fcport = rscn_fcport;
1165 * If the port is already in our fcport list and online, send an ADISC
1166 * to see if it's still alive. Issue login if a new fcport or the known
1167 * fcport is currently offline.
1169 if (remote_fcport) {
1171 * No need to send request if the remote fcport is currently
1172 * waiting for an available io descriptor.
1174 if (known_fcport == NULL &&
1175 (remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1176 remote_fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED)) {
1178 * If previous waiting io descriptor is an ADISC, then
1179 * the new RSCN may come from a new remote fcport being
1180 * plugged into the same location.
1182 if (remote_fcport->port_type == FCT_RSCN) {
1183 remote_fcport->iodesc_idx_sent =
1184 IODESC_LOGIN_NEEDED;
1185 } else if (remote_fcport->iodesc_idx_sent ==
1186 IODESC_ADISC_NEEDED) {
1187 fc_port_t *new_fcport;
1189 remote_fcport->iodesc_idx_sent =
1190 IODESC_INVALID_INDEX;
1192 /* Create new fcport for later login. */
1193 new_fcport = qla2x00_alloc_rscn_fcport(ha,
1194 ha_locked ? GFP_ATOMIC: GFP_KERNEL);
1196 DEBUG14(printk("scsi(%ld): Handle RSCN "
1197 "-- creating RSCN fcport %p for "
1198 "future login.\n", ha->host_no,
1201 new_fcport->d_id.b24 =
1202 remote_fcport->d_id.b24;
1203 new_fcport->iodesc_idx_sent =
1204 IODESC_LOGIN_NEEDED;
1206 list_add_tail(&new_fcport->list,
1208 set_bit(IODESC_PROCESS_NEEDED,
1211 DEBUG14(printk("scsi(%ld): Handle RSCN "
1212 "-- unable to allocate RSCN fcport "
1213 "for future login.\n",
1217 return (QLA_SUCCESS);
1220 /* Send ADISC if the fcport is online */
1221 if (atomic_read(&remote_fcport->state) == FCS_ONLINE ||
1222 remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) {
1224 atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
1226 iodesc = qla2x00_alloc_iodesc(ha);
1227 if (iodesc == NULL) {
1228 /* Mark fcport for later adisc processing */
1229 DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
1230 "enough IO descriptors for Adisc, flag "
1231 "for later processing.\n", ha->host_no));
1233 remote_fcport->iodesc_idx_sent =
1234 IODESC_ADISC_NEEDED;
1235 set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1237 return (QLA_SUCCESS);
1240 iodesc->cb_idx = ADISC_PORT_IOCB_CB;
1241 iodesc->d_id.b24 = rscn_pid.b24;
1242 iodesc->remote_fcport = remote_fcport;
1243 remote_fcport->iodesc_idx_sent = iodesc->idx;
1244 qla2x00_send_adisc_iocb(ha, iodesc, ha_locked);
1246 return (QLA_SUCCESS);
1247 } else if (remote_fcport->iodesc_idx_sent <
1248 MAX_IO_DESCRIPTORS &&
1249 ha->io_descriptors[remote_fcport->iodesc_idx_sent].cb_idx ==
1250 ADISC_PORT_IOCB_CB) {
1252 * Receiving another RSCN while an ADISC is pending,
1253 * abort the IOCB. Use the same descriptor for the
1256 uint32_t handle_to_abort;
1258 iodesc = &ha->io_descriptors[
1259 remote_fcport->iodesc_idx_sent];
1260 qla2x00_remove_iodesc_timer(iodesc);
1261 handle_to_abort = iodesc->signature;
1262 iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
1263 iodesc->cb_idx = ABORT_IOCB_CB;
1264 iodesc->d_id.b24 = remote_fcport->d_id.b24;
1265 iodesc->remote_fcport = remote_fcport;
1266 remote_fcport->iodesc_idx_sent = iodesc->idx;
1268 DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
1269 "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
1270 ha->host_no, remote_fcport->loop_id,
1271 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1272 iodesc->d_id.b.al_pa));
1274 qla2x00_send_abort_iocb(ha, iodesc, handle_to_abort,
1279 /* We need to login to the remote port, find it. */
1281 remote_fcport = known_fcport;
1282 } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
1283 rscn_fcport->iodesc_idx_sent < MAX_IO_DESCRIPTORS &&
1284 ha->io_descriptors[rscn_fcport->iodesc_idx_sent].cb_idx ==
1285 LOGIN_PORT_IOCB_CB) {
1287 * Ignore duplicate RSCN on fcport which has already
1288 * initiated a login IOCB.
1290 DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
1291 "already sent to [%02x%02x%02x].\n", ha->host_no,
1292 rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
1293 rscn_fcport->d_id.b.al_pa));
1295 return (QLA_SUCCESS);
1296 } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
1297 rscn_fcport != remote_fcport) {
1298 /* Reuse same rscn fcport. */
1299 DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
1300 "[%02x%02x%02x].\n", ha->host_no,
1301 rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
1302 rscn_fcport->d_id.b.al_pa));
1304 remote_fcport = rscn_fcport;
1306 /* Create new fcport for later login. */
1307 remote_fcport = qla2x00_alloc_rscn_fcport(ha,
1308 ha_locked ? GFP_ATOMIC: GFP_KERNEL);
1309 list_add_tail(&remote_fcport->list, &ha->rscn_fcports);
1311 if (remote_fcport == NULL)
1312 return (QLA_SUCCESS);
1314 /* Prepare fcport for login. */
1315 atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
1316 remote_fcport->login_retry = 3; /* ha->login_retry_count; */
1317 remote_fcport->d_id.b24 = rscn_pid.b24;
1319 iodesc = qla2x00_alloc_iodesc(ha);
1320 if (iodesc == NULL) {
1321 /* Mark fcport for later adisc processing. */
1322 DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
1323 "descriptors for Login, flag for later processing.\n",
1326 remote_fcport->iodesc_idx_sent = IODESC_LOGIN_NEEDED;
1327 set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1329 return (QLA_SUCCESS);
1332 if (known_fcport == NULL || rscn_pid.b24 != INVALID_PORT_ID) {
1333 remote_fcport->loop_id = ha->min_external_loopid;
1335 rval = qla2x00_find_new_loop_id(ha, remote_fcport);
1336 if (rval == QLA_FUNCTION_FAILED) {
1337 /* No more loop ids, failed. */
1338 DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
1339 "loop id to perform Login, failed.\n",
1346 iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
1347 iodesc->d_id.b24 = rscn_pid.b24;
1348 iodesc->remote_fcport = remote_fcport;
1349 remote_fcport->iodesc_idx_sent = iodesc->idx;
1351 DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
1352 "[%x/%02x%02x%02x].\n", ha->host_no, remote_fcport->loop_id,
1353 iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa));
1355 qla2x00_send_login_iocb(ha, iodesc, &rscn_pid, ha_locked);
1357 return (QLA_SUCCESS);
1361 * qla2x00_process_iodesc() - Complete IO descriptor processing.
1363 * @mbxstat: Mailbox IOCB status
1366 qla2x00_process_iodesc(scsi_qla_host_t *ha, struct mbx_entry *mbxstat)
1371 struct io_descriptor *iodesc;
1373 signature = mbxstat->handle;
1375 DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
1376 ha->host_no, signature));
1378 /* Retrieve proper IO descriptor. */
1379 iodesc = qla2x00_handle_to_iodesc(ha, signature);
1380 if (iodesc == NULL) {
1381 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1382 "incorrect signature %08x.\n", ha->host_no, signature));
1387 /* Stop IO descriptor timer. */
1388 qla2x00_remove_iodesc_timer(iodesc);
1390 /* Verify signature match. */
1391 if (iodesc->signature != signature) {
1392 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1393 "signature mismatch, sent %08x, received %08x.\n",
1394 ha->host_no, iodesc->signature, signature));
1399 /* Go with IOCB callback. */
1400 rval = iocb_function_cb_list[iodesc->cb_idx](ha, iodesc, mbxstat);
1401 if (rval != QLA_SUCCESS) {
1402 /* IO descriptor reused by callback. */
1406 qla2x00_free_iodesc(iodesc);
1408 if (test_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags)) {
1409 /* Scan our fcports list for any RSCN requests. */
1410 list_for_each_entry(fcport, &ha->fcports, list) {
1411 if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1412 fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
1413 qla2x00_handle_port_rscn(ha, 0, fcport, 1);
1418 /* Scan our RSCN fcports list for any RSCN requests. */
1419 list_for_each_entry(fcport, &ha->rscn_fcports, list) {
1420 if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1421 fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
1422 qla2x00_handle_port_rscn(ha, 0, fcport, 1);
1427 clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1431 * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
1434 * This routine will also delete any RSCN entries related to the outstanding
1438 qla2x00_cancel_io_descriptors(scsi_qla_host_t *ha)
1440 fc_port_t *fcport, *fcptemp;
1442 clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1444 /* Abort all IO descriptors. */
1445 qla2x00_init_io_descriptors(ha);
1447 /* Reset all pending IO descriptors in fcports list. */
1448 list_for_each_entry(fcport, &ha->fcports, list) {
1449 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
1452 /* Reset all pending IO descriptors in rscn fcports list. */
1453 list_for_each_entry_safe(fcport, fcptemp, &ha->rscn_fcports, list) {
1454 DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
1455 "%p [%x/%02x%02x%02x].\n", ha->host_no, fcport,
1456 fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
1457 fcport->d_id.b.al_pa));
1459 list_del(&fcport->list);