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.
22 * IO descriptor handle definitions.
26 * |31------28|27-------------------12|11-------0|
27 * | Type | Rolling Signature | Index |
28 * |----------|-----------------------|----------|
32 #define HDL_TYPE_SCSI 0
33 #define HDL_TYPE_ASYNC_IOCB 0x0A
35 #define HDL_INDEX_BITS 12
36 #define HDL_ITER_BITS 16
37 #define HDL_TYPE_BITS 4
39 #define HDL_INDEX_MASK ((1UL << HDL_INDEX_BITS) - 1)
40 #define HDL_ITER_MASK ((1UL << HDL_ITER_BITS) - 1)
41 #define HDL_TYPE_MASK ((1UL << HDL_TYPE_BITS) - 1)
43 #define HDL_INDEX_SHIFT 0
44 #define HDL_ITER_SHIFT (HDL_INDEX_SHIFT + HDL_INDEX_BITS)
45 #define HDL_TYPE_SHIFT (HDL_ITER_SHIFT + HDL_ITER_BITS)
47 /* Local Prototypes. */
48 static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t);
49 static inline uint16_t qla2x00_handle_to_idx(uint32_t);
50 static inline uint16_t qla2x00_handle_to_iter(uint32_t);
51 static inline uint16_t qla2x00_handle_to_type(uint32_t);
52 static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor *);
53 static inline struct io_descriptor *qla2x00_handle_to_iodesc(scsi_qla_host_t *,
56 static inline struct io_descriptor *qla2x00_alloc_iodesc(scsi_qla_host_t *);
57 static inline void qla2x00_free_iodesc(struct io_descriptor *);
58 static inline void qla2x00_init_io_descriptors(scsi_qla_host_t *);
60 static void qla2x00_iodesc_timeout(unsigned long);
61 static inline void qla2x00_add_iodesc_timer(struct io_descriptor *);
62 static inline void qla2x00_remove_iodesc_timer(struct io_descriptor *);
64 static inline void qla2x00_update_login_fcport(scsi_qla_host_t *,
65 struct mbx_entry *, fc_port_t *);
67 static int qla2x00_send_abort_iocb(scsi_qla_host_t *, struct io_descriptor *,
69 static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
72 static int qla2x00_send_adisc_iocb(scsi_qla_host_t *, struct io_descriptor *,
74 static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
77 static int qla2x00_send_logout_iocb(scsi_qla_host_t *, struct io_descriptor *,
79 static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t *,
80 struct io_descriptor *, struct mbx_entry *);
82 static int qla2x00_send_login_iocb(scsi_qla_host_t *, struct io_descriptor *,
84 static int qla2x00_send_login_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
88 * Mailbox IOCB callback array.
90 int (*iocb_function_cb_list[LAST_IOCB_CB])
91 (scsi_qla_host_t *, struct io_descriptor *, struct mbx_entry *) = {
93 qla2x00_send_abort_iocb_cb,
94 qla2x00_send_adisc_iocb_cb,
95 qla2x00_send_logout_iocb_cb,
96 qla2x00_send_login_iocb_cb,
101 * Generic IO descriptor handle routines.
105 * qla2x00_to_handle() - Create a descriptor handle.
106 * @type: descriptor type
107 * @iter: descriptor rolling signature
108 * @idx: index to the descriptor array
110 * Returns a composite handle based in the @type, @iter, and @idx.
112 static inline uint32_t
113 qla2x00_to_handle(uint16_t type, uint16_t iter, uint16_t idx)
115 return ((uint32_t)(((uint32_t)type << HDL_TYPE_SHIFT) |
116 ((uint32_t)iter << HDL_ITER_SHIFT) |
117 ((uint32_t)idx << HDL_INDEX_SHIFT)));
121 * qla2x00_handle_to_idx() - Retrive the index for a given handle.
122 * @handle: descriptor handle
124 * Returns the index specified by the @handle.
126 static inline uint16_t
127 qla2x00_handle_to_idx(uint32_t handle)
129 return ((uint16_t)(((handle) >> HDL_INDEX_SHIFT) & HDL_INDEX_MASK));
133 * qla2x00_handle_to_type() - Retrive the descriptor type for a given handle.
134 * @handle: descriptor handle
136 * Returns the descriptor type specified by the @handle.
138 static inline uint16_t
139 qla2x00_handle_to_type(uint32_t handle)
141 return ((uint16_t)(((handle) >> HDL_TYPE_SHIFT) & HDL_TYPE_MASK));
145 * qla2x00_handle_to_iter() - Retrive the rolling signature for a given handle.
146 * @handle: descriptor handle
148 * Returns the signature specified by the @handle.
150 static inline uint16_t
151 qla2x00_handle_to_iter(uint32_t handle)
153 return ((uint16_t)(((handle) >> HDL_ITER_SHIFT) & HDL_ITER_MASK));
157 * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
158 * @iodesc: io descriptor
160 * Returns a unique handle for @iodesc.
162 static inline uint32_t
163 qla2x00_iodesc_to_handle(struct io_descriptor *iodesc)
167 handle = qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB,
168 ++iodesc->ha->iodesc_signature, iodesc->idx);
169 iodesc->signature = handle;
175 * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
177 * @handle: handle to io descriptor
179 * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
180 * not exist or the io descriptors signature does not @handle.
182 static inline struct io_descriptor *
183 qla2x00_handle_to_iodesc(scsi_qla_host_t *ha, uint32_t handle)
186 struct io_descriptor *iodesc;
188 idx = qla2x00_handle_to_idx(handle);
189 iodesc = &ha->io_descriptors[idx];
191 if (iodesc->signature != handle)
199 * IO descriptor allocation routines.
203 * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
206 * Returns a pointer to the allocated io descriptor, or NULL, if none available.
208 static inline struct io_descriptor *
209 qla2x00_alloc_iodesc(scsi_qla_host_t *ha)
212 struct io_descriptor *iodesc;
215 for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
216 if (ha->io_descriptors[iter].used)
219 iodesc = &ha->io_descriptors[iter];
222 init_timer(&iodesc->timer);
224 iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
232 * qla2x00_free_iodesc() - Free an IO descriptor.
233 * @iodesc: io descriptor
235 * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
238 qla2x00_free_iodesc(struct io_descriptor *iodesc)
241 iodesc->signature = 0;
245 * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
246 * @iodesc: io descriptor
249 qla2x00_remove_iodesc_timer(struct io_descriptor *iodesc)
251 if (iodesc->timer.function != NULL) {
252 del_timer_sync(&iodesc->timer);
253 iodesc->timer.data = (unsigned long) NULL;
254 iodesc->timer.function = NULL;
259 * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
263 qla2x00_init_io_descriptors(scsi_qla_host_t *ha)
267 for (iter = 0; iter < MAX_IO_DESCRIPTORS; iter++) {
268 if (!ha->io_descriptors[iter].used)
271 qla2x00_remove_iodesc_timer(&ha->io_descriptors[iter]);
272 qla2x00_free_iodesc(&ha->io_descriptors[iter]);
278 * IO descriptor timer routines.
282 * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
283 * @data: io descriptor
286 qla2x00_iodesc_timeout(unsigned long data)
288 struct io_descriptor *iodesc;
290 iodesc = (struct io_descriptor *) data;
292 DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
293 "signature=%08x, scheduling ISP abort.\n", iodesc->ha->host_no,
294 iodesc->idx, iodesc->signature));
296 qla2x00_free_iodesc(iodesc);
298 qla_printk(KERN_WARNING, iodesc->ha,
299 "IO descriptor timeout. Scheduling ISP abort.\n");
300 set_bit(ISP_ABORT_NEEDED, &iodesc->ha->dpc_flags);
304 * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
305 * @iodesc: io descriptor
308 * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
309 * tenths of a second) after it hits the wire. But, if there are any request
310 * resource contraints (i.e. during heavy I/O), exchanges can be held off for
311 * at most R_A_TOV. Therefore, the driver will wait 4 * R_A_TOV before
312 * scheduling a recovery (big hammer).
315 qla2x00_add_iodesc_timer(struct io_descriptor *iodesc)
317 unsigned long timeout;
319 timeout = (iodesc->ha->r_a_tov * 4) / 10;
320 init_timer(&iodesc->timer);
321 iodesc->timer.data = (unsigned long) iodesc;
322 iodesc->timer.expires = jiffies + (timeout * HZ);
323 iodesc->timer.function =
324 (void (*) (unsigned long)) qla2x00_iodesc_timeout;
325 add_timer(&iodesc->timer);
329 * IO descriptor support routines.
333 * qla2x00_update_login_fcport() - Update fcport data after login processing.
335 * @mbxstat: Mailbox command status IOCB
336 * @fcport: port to update
339 qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
342 if (le16_to_cpu(mbxstat->mb1) & BIT_0) {
343 fcport->port_type = FCT_INITIATOR;
345 fcport->port_type = FCT_TARGET;
346 if (le16_to_cpu(mbxstat->mb1) & BIT_1) {
347 fcport->flags |= FCF_TAPE_PRESENT;
350 fcport->login_retry = 0;
351 fcport->port_login_retry_count = ha->port_down_retry_count *
353 atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
355 fcport->flags |= FCF_FABRIC_DEVICE;
356 fcport->flags &= ~FCF_FAILOVER_NEEDED;
357 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
358 atomic_set(&fcport->state, FCS_ONLINE);
363 * Mailbox IOCB commands.
367 * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
369 * @handle: handle to io descriptor
371 * Returns a pointer to the reqest entry, or NULL, if none were available.
373 static inline struct mbx_entry *
374 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle)
377 device_reg_t __iomem *reg = ha->iobase;
378 struct mbx_entry *mbxentry;
382 if (ha->req_q_cnt < 3) {
383 cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg));
384 if (ha->req_ring_index < cnt)
385 ha->req_q_cnt = cnt - ha->req_ring_index;
387 ha->req_q_cnt = ha->request_q_length -
388 (ha->req_ring_index - cnt);
390 if (ha->req_q_cnt >= 3) {
391 mbxentry = (struct mbx_entry *)ha->request_ring_ptr;
393 memset(mbxentry, 0, sizeof(struct mbx_entry));
394 mbxentry->entry_type = MBX_IOCB_TYPE;
395 mbxentry->entry_count = 1;
396 mbxentry->sys_define1 = SOURCE_ASYNC_IOCB;
397 mbxentry->handle = handle;
403 * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
405 * @iodesc: io descriptor
406 * @handle_to_abort: firmware handle to abort
407 * @ha_locked: is function called with the hardware lock
409 * Returns QLA_SUCCESS if the IOCB was issued.
412 qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
413 uint32_t handle_to_abort, int ha_locked)
415 unsigned long flags = 0;
416 struct mbx_entry *mbxentry;
418 /* Send marker if required. */
419 if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
420 return (QLA_FUNCTION_FAILED);
423 spin_lock_irqsave(&ha->hardware_lock, flags);
425 /* Build abort mailbox IOCB. */
426 mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
427 if (mbxentry == NULL) {
429 spin_unlock_irqrestore(&ha->hardware_lock, flags);
431 return (QLA_FUNCTION_FAILED);
433 mbxentry->mb0 = __constant_cpu_to_le16(MBC_ABORT_COMMAND);
434 mbxentry->mb1 = mbxentry->loop_id.extended =
435 cpu_to_le16(iodesc->remote_fcport->loop_id);
436 mbxentry->mb2 = LSW(handle_to_abort);
437 mbxentry->mb3 = MSW(handle_to_abort);
440 qla2x00_add_iodesc_timer(iodesc);
442 /* Issue command to ISP. */
446 spin_unlock_irqrestore(&ha->hardware_lock, flags);
448 DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
449 "%08x.\n", ha->host_no, iodesc->signature,
450 iodesc->remote_fcport->loop_id, handle_to_abort));
452 return (QLA_SUCCESS);
456 * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
458 * @iodesc: io descriptor
459 * @mbxstat: mailbox status IOCB
461 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
462 * will be used for a retry.
465 qla2x00_send_abort_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
466 struct mbx_entry *mbxstat)
468 DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
469 "status=%x mb0=%x.\n", ha->host_no, iodesc->remote_fcport->loop_id,
470 iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa,
471 le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
473 return (QLA_SUCCESS);
478 * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
480 * @iodesc: io descriptor
481 * @ha_locked: is function called with the hardware lock
483 * Returns QLA_SUCCESS if the IOCB was issued.
486 qla2x00_send_adisc_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
489 unsigned long flags = 0;
490 struct mbx_entry *mbxentry;
492 /* Send marker if required. */
493 if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
494 return (QLA_FUNCTION_FAILED);
497 spin_lock_irqsave(&ha->hardware_lock, flags);
499 /* Build Get Port Database IOCB. */
500 mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
501 if (mbxentry == NULL) {
503 spin_unlock_irqrestore(&ha->hardware_lock, flags);
505 return (QLA_FUNCTION_FAILED);
507 mbxentry->mb0 = __constant_cpu_to_le16(MBC_GET_PORT_DATABASE);
508 mbxentry->mb1 = mbxentry->loop_id.extended =
509 cpu_to_le16(iodesc->remote_fcport->loop_id);
510 mbxentry->mb2 = cpu_to_le16(MSW(LSD(ha->iodesc_pd_dma)));
511 mbxentry->mb3 = cpu_to_le16(LSW(LSD(ha->iodesc_pd_dma)));
512 mbxentry->mb6 = cpu_to_le16(MSW(MSD(ha->iodesc_pd_dma)));
513 mbxentry->mb7 = cpu_to_le16(LSW(MSD(ha->iodesc_pd_dma)));
514 mbxentry->mb10 = __constant_cpu_to_le16(BIT_0);
517 qla2x00_add_iodesc_timer(iodesc);
519 /* Issue command to ISP. */
523 spin_unlock_irqrestore(&ha->hardware_lock, flags);
525 DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
526 ha->host_no, iodesc->signature, iodesc->remote_fcport->loop_id));
528 return (QLA_SUCCESS);
532 * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
534 * @iodesc: io descriptor
535 * @mbxstat: mailbox status IOCB
537 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
538 * will be used for a retry.
541 qla2x00_send_adisc_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
542 struct mbx_entry *mbxstat)
544 fc_port_t *remote_fcport;
546 remote_fcport = iodesc->remote_fcport;
548 /* Ensure the port IDs are consistent. */
549 if (remote_fcport->d_id.b24 != iodesc->d_id.b24) {
550 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
551 "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
552 ha->host_no, remote_fcport->d_id.b.domain,
553 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
554 iodesc->d_id.b.domain, iodesc->d_id.b.area,
555 iodesc->d_id.b.al_pa));
557 return (QLA_SUCCESS);
560 /* Only process the last command. */
561 if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
562 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
563 "[%02x%02x%02x], expected %x, received %x.\n", ha->host_no,
564 iodesc->d_id.b.domain, iodesc->d_id.b.area,
565 iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
568 return (QLA_SUCCESS);
571 if (le16_to_cpu(mbxstat->status) == CS_COMPLETE) {
572 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
573 "[%x/%02x%02x%02x] online.\n", ha->host_no,
574 remote_fcport->loop_id, remote_fcport->d_id.b.domain,
575 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
577 atomic_set(&remote_fcport->state, FCS_ONLINE);
579 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
580 "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha->host_no,
581 remote_fcport->loop_id, remote_fcport->d_id.b.domain,
582 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa,
583 le16_to_cpu(mbxstat->status), le16_to_cpu(mbxstat->mb0)));
585 if (atomic_read(&remote_fcport->state) != FCS_DEVICE_DEAD)
586 atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
588 remote_fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
590 return (QLA_SUCCESS);
595 * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
597 * @iodesc: io descriptor
598 * @ha_locked: is function called with the hardware lock
600 * Returns QLA_SUCCESS if the IOCB was issued.
603 qla2x00_send_logout_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
606 unsigned long flags = 0;
607 struct mbx_entry *mbxentry;
609 /* Send marker if required. */
610 if (qla2x00_issue_marker(ha, ha_locked) != QLA_SUCCESS)
611 return (QLA_FUNCTION_FAILED);
614 spin_lock_irqsave(&ha->hardware_lock, flags);
616 /* Build fabric port logout mailbox IOCB. */
617 mbxentry = qla2x00_get_mbx_iocb_entry(ha, iodesc->signature);
618 if (mbxentry == NULL) {
620 spin_unlock_irqrestore(&ha->hardware_lock, flags);
622 return (QLA_FUNCTION_FAILED);
624 mbxentry->mb0 = __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
625 mbxentry->mb1 = mbxentry->loop_id.extended =
626 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);
707 qla2x00_add_iodesc_timer(iodesc);
709 /* Issue command to ISP. */
713 spin_unlock_irqrestore(&ha->hardware_lock, flags);
715 DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
716 "[%x/%02x%02x%02x].\n", ha->host_no, iodesc->signature,
717 iodesc->remote_fcport->loop_id, d_id->b.domain, d_id->b.area,
720 return (QLA_SUCCESS);
724 * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
726 * @iodesc: io descriptor
727 * @mbxstat: mailbox status IOCB
729 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
730 * will be used for a retry.
733 qla2x00_send_login_iocb_cb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
734 struct mbx_entry *mbxstat)
737 fc_port_t *fcport, *remote_fcport, *exist_fcport;
738 struct io_descriptor *abort_iodesc, *login_iodesc;
739 uint16_t status, mb[8];
741 uint16_t remote_loopid;
742 port_id_t remote_did, inuse_did;
744 remote_fcport = iodesc->remote_fcport;
746 /* Only process the last command. */
747 if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
748 DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
749 "[%02x%02x%02x], expected %x, received %x.\n",
750 ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,
751 iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
754 /* Free RSCN fcport resources. */
755 if (remote_fcport->port_type == FCT_RSCN) {
756 DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
757 "fcport %p [%x/%02x%02x%02x] given ignored Login "
758 "IOCB.\n", ha->host_no, remote_fcport,
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));
764 list_del(&remote_fcport->list);
765 kfree(remote_fcport);
767 return (QLA_SUCCESS);
770 status = le16_to_cpu(mbxstat->status);
771 mb[0] = le16_to_cpu(mbxstat->mb0);
772 mb[1] = le16_to_cpu(mbxstat->mb1);
773 mb[2] = le16_to_cpu(mbxstat->mb2);
774 mb[6] = le16_to_cpu(mbxstat->mb6);
775 mb[7] = le16_to_cpu(mbxstat->mb7);
778 if ((status == CS_COMPLETE || status == CS_COMPLETE_CHKCOND) &&
779 mb[0] == MBS_COMMAND_COMPLETE) {
781 DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
782 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,
783 mb[1], mbxstat->port_name[0], mbxstat->port_name[1],
784 mbxstat->port_name[2], mbxstat->port_name[3],
785 mbxstat->port_name[4], mbxstat->port_name[5],
786 mbxstat->port_name[6], mbxstat->port_name[7]));
788 memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);
789 memcpy(remote_fcport->port_name, mbxstat->port_name, WWN_SIZE);
791 /* Is the device already in our fcports list? */
792 if (remote_fcport->port_type != FCT_RSCN) {
793 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
794 "[%x/%02x%02x%02x] online.\n", ha->host_no,
795 remote_fcport->loop_id,
796 remote_fcport->d_id.b.domain,
797 remote_fcport->d_id.b.area,
798 remote_fcport->d_id.b.al_pa));
800 qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
802 return (QLA_SUCCESS);
805 /* Does the RSCN portname already exist in our fcports list? */
807 list_for_each_entry(fcport, &ha->fcports, list) {
808 if (memcmp(remote_fcport->port_name, fcport->port_name,
810 exist_fcport = fcport;
814 if (exist_fcport != NULL) {
815 DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
816 "fcport in fcports list [%p].\n", ha->host_no,
819 /* Abort any ADISC that could have been sent. */
820 if (exist_fcport->iodesc_idx_sent != iodesc->idx &&
821 exist_fcport->iodesc_idx_sent <
822 MAX_IO_DESCRIPTORS &&
823 ha->io_descriptors[exist_fcport->iodesc_idx_sent].
824 cb_idx == ADISC_PORT_IOCB_CB) {
826 abort_iodesc = qla2x00_alloc_iodesc(ha);
828 DEBUG14(printk("scsi(%ld): Login IOCB "
829 "-- issuing abort to outstanding "
830 "Adisc [%x/%02x%02x%02x].\n",
831 ha->host_no, remote_fcport->loop_id,
832 exist_fcport->d_id.b.domain,
833 exist_fcport->d_id.b.area,
834 exist_fcport->d_id.b.al_pa));
836 abort_iodesc->cb_idx = ABORT_IOCB_CB;
837 abort_iodesc->d_id.b24 =
838 exist_fcport->d_id.b24;
839 abort_iodesc->remote_fcport =
841 exist_fcport->iodesc_idx_sent =
843 qla2x00_send_abort_iocb(ha,
844 abort_iodesc, ha->io_descriptors[
845 exist_fcport->iodesc_idx_sent].
848 DEBUG14(printk("scsi(%ld): Login IOCB "
849 "-- unable to abort outstanding "
850 "Adisc [%x/%02x%02x%02x].\n",
851 ha->host_no, remote_fcport->loop_id,
852 exist_fcport->d_id.b.domain,
853 exist_fcport->d_id.b.area,
854 exist_fcport->d_id.b.al_pa));
859 * If the existing fcport is waiting to send an ADISC
860 * or LOGIN, then reuse remote fcport (RSCN) to
864 remote_loopid = remote_fcport->loop_id;
865 remote_did.b24 = remote_fcport->d_id.b24;
866 if (exist_fcport->iodesc_idx_sent ==
867 IODESC_ADISC_NEEDED ||
868 exist_fcport->iodesc_idx_sent ==
869 IODESC_LOGIN_NEEDED) {
870 DEBUG14(printk("scsi(%ld): Login IOCB -- "
871 "existing fcport [%x/%02x%02x%02x] "
872 "waiting for IO descriptor, reuse RSCN "
873 "fcport.\n", ha->host_no,
874 exist_fcport->loop_id,
875 exist_fcport->d_id.b.domain,
876 exist_fcport->d_id.b.area,
877 exist_fcport->d_id.b.al_pa));
880 remote_fcport->iodesc_idx_sent =
881 exist_fcport->iodesc_idx_sent;
882 exist_fcport->iodesc_idx_sent =
883 IODESC_INVALID_INDEX;
884 remote_fcport->loop_id = exist_fcport->loop_id;
885 remote_fcport->d_id.b24 =
886 exist_fcport->d_id.b24;
889 /* Logout the old loopid. */
891 exist_fcport->loop_id != remote_fcport->loop_id &&
892 exist_fcport->loop_id != FC_NO_LOOP_ID) {
893 login_iodesc = qla2x00_alloc_iodesc(ha);
895 DEBUG14(printk("scsi(%ld): Login IOCB "
896 "-- issuing logout to free old "
897 "loop id [%x/%02x%02x%02x].\n",
898 ha->host_no, exist_fcport->loop_id,
899 exist_fcport->d_id.b.domain,
900 exist_fcport->d_id.b.area,
901 exist_fcport->d_id.b.al_pa));
903 login_iodesc->cb_idx =
905 login_iodesc->d_id.b24 =
906 exist_fcport->d_id.b24;
907 login_iodesc->remote_fcport =
909 exist_fcport->iodesc_idx_sent =
911 qla2x00_send_logout_iocb(ha,
914 /* Ran out of IO descriptiors. */
915 DEBUG14(printk("scsi(%ld): Login IOCB "
916 "-- unable to logout to free old "
917 "loop id [%x/%02x%02x%02x].\n",
918 ha->host_no, exist_fcport->loop_id,
919 exist_fcport->d_id.b.domain,
920 exist_fcport->d_id.b.area,
921 exist_fcport->d_id.b.al_pa));
923 exist_fcport->iodesc_idx_sent =
924 IODESC_INVALID_INDEX;
929 /* Update existing fcport with remote fcport info. */
930 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
931 "existing fcport [%x/%02x%02x%02x] online.\n",
932 ha->host_no, remote_loopid, remote_did.b.domain,
933 remote_did.b.area, remote_did.b.al_pa));
935 memcpy(exist_fcport->node_name,
936 remote_fcport->node_name, WWN_SIZE);
937 exist_fcport->loop_id = remote_loopid;
938 exist_fcport->d_id.b24 = remote_did.b24;
939 qla2x00_update_login_fcport(ha, mbxstat, exist_fcport);
941 /* Finally, free the remote (RSCN) fcport. */
943 DEBUG14(printk("scsi(%ld): Login IOCB -- "
944 "Freeing RSCN fcport %p "
945 "[%x/%02x%02x%02x].\n", ha->host_no,
946 remote_fcport, remote_fcport->loop_id,
947 remote_fcport->d_id.b.domain,
948 remote_fcport->d_id.b.area,
949 remote_fcport->d_id.b.al_pa));
951 list_del(&remote_fcport->list);
952 kfree(remote_fcport);
955 return (QLA_SUCCESS);
959 * A new device has been added, move the RSCN fcport to our
962 DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
963 "[%x/%02x%02x%02x] to fcports list.\n", ha->host_no,
964 remote_fcport->loop_id, remote_fcport->d_id.b.domain,
965 remote_fcport->d_id.b.area, remote_fcport->d_id.b.al_pa));
967 list_del(&remote_fcport->list);
968 remote_fcport->flags = (FCF_RLC_SUPPORT | FCF_RESCAN_NEEDED);
969 qla2x00_update_login_fcport(ha, mbxstat, remote_fcport);
970 list_add_tail(&remote_fcport->list, &ha->fcports);
971 set_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags);
973 /* Handle login failure. */
974 if (remote_fcport->login_retry != 0) {
975 if (mb[0] == MBS_LOOP_ID_USED) {
976 inuse_did.b.domain = LSB(mb[1]);
977 inuse_did.b.area = MSB(mb[2]);
978 inuse_did.b.al_pa = LSB(mb[2]);
980 DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
981 "id [%x] used by port id [%02x%02x%02x].\n",
982 ha->host_no, remote_fcport->loop_id,
983 inuse_did.b.domain, inuse_did.b.area,
986 if (remote_fcport->d_id.b24 ==
989 * Invalid port id means we are trying
990 * to login to a remote port with just
991 * a loop id without knowing about the
992 * port id. Copy the port id and try
995 remote_fcport->d_id.b24 = inuse_did.b24;
996 iodesc->d_id.b24 = inuse_did.b24;
998 remote_fcport->loop_id++;
999 rval = qla2x00_find_new_loop_id(ha,
1001 if (rval == QLA_FUNCTION_FAILED) {
1002 /* No more loop ids. */
1003 return (QLA_SUCCESS);
1006 } else if (mb[0] == MBS_PORT_ID_USED) {
1008 * Device has another loop ID. The firmware
1009 * group recommends the driver perform an
1010 * implicit login with the specified ID.
1012 DEBUG14(printk("scsi(%ld): Login IOCB -- port "
1013 "id [%02x%02x%02x] already assigned to "
1014 "loop id [%x].\n", ha->host_no,
1015 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1016 iodesc->d_id.b.al_pa, mb[1]));
1018 remote_fcport->loop_id = mb[1];
1021 /* Unable to perform login, try again. */
1022 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1023 "failed login [%x/%02x%02x%02x], status=%x "
1024 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1025 ha->host_no, remote_fcport->loop_id,
1026 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1027 iodesc->d_id.b.al_pa, status, mb[0], mb[1],
1028 mb[2], mb[6], mb[7]));
1031 /* Reissue Login with the same IO descriptor. */
1033 qla2x00_iodesc_to_handle(iodesc);
1034 iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
1035 iodesc->d_id.b24 = remote_fcport->d_id.b24;
1036 remote_fcport->iodesc_idx_sent = iodesc->idx;
1037 remote_fcport->login_retry--;
1039 DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
1040 "login to [%x/%02x%02x%02x] (%d).\n", ha->host_no,
1041 remote_fcport->loop_id,
1042 remote_fcport->d_id.b.domain,
1043 remote_fcport->d_id.b.area,
1044 remote_fcport->d_id.b.al_pa,
1045 remote_fcport->login_retry));
1047 qla2x00_send_login_iocb(ha, iodesc,
1048 &remote_fcport->d_id, 1);
1050 return (QLA_FUNCTION_FAILED);
1052 /* No more logins, mark device dead. */
1053 DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
1054 "login [%x/%02x%02x%02x] after retries, status=%x "
1055 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1056 ha->host_no, remote_fcport->loop_id,
1057 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1058 iodesc->d_id.b.al_pa, status, mb[0], mb[1],
1059 mb[2], mb[6], mb[7]));
1061 atomic_set(&remote_fcport->state, FCS_DEVICE_DEAD);
1062 if (remote_fcport->port_type == FCT_RSCN) {
1063 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1064 "Freeing dead RSCN fcport %p "
1065 "[%x/%02x%02x%02x].\n", ha->host_no,
1066 remote_fcport, remote_fcport->loop_id,
1067 remote_fcport->d_id.b.domain,
1068 remote_fcport->d_id.b.area,
1069 remote_fcport->d_id.b.al_pa));
1071 list_del(&remote_fcport->list);
1072 kfree(remote_fcport);
1077 return (QLA_SUCCESS);
1082 * IO descriptor processing routines.
1086 * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
1088 * @flags: allocation flags
1090 * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
1093 qla2x00_alloc_rscn_fcport(scsi_qla_host_t *ha, int flags)
1097 fcport = qla2x00_alloc_fcport(ha, flags);
1101 /* Setup RSCN fcport structure. */
1102 fcport->port_type = FCT_RSCN;
1108 * qla2x00_handle_port_rscn() - Handle port RSCN.
1110 * @rscn_entry: RSCN entry
1111 * @fcport: fcport entry to updated
1113 * Returns QLA_SUCCESS if the port RSCN was handled.
1116 qla2x00_handle_port_rscn(scsi_qla_host_t *ha, uint32_t rscn_entry,
1117 fc_port_t *known_fcport, int ha_locked)
1121 fc_port_t *fcport, *remote_fcport, *rscn_fcport;
1122 struct io_descriptor *iodesc;
1124 remote_fcport = NULL;
1127 /* Prepare port id based on incoming entries. */
1129 rscn_pid.b24 = known_fcport->d_id.b24;
1130 remote_fcport = known_fcport;
1132 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1133 "fcport [%02x%02x%02x].\n", ha->host_no,
1134 remote_fcport->d_id.b.domain, remote_fcport->d_id.b.area,
1135 remote_fcport->d_id.b.al_pa));
1137 rscn_pid.b.domain = LSB(MSW(rscn_entry));
1138 rscn_pid.b.area = MSB(LSW(rscn_entry));
1139 rscn_pid.b.al_pa = LSB(LSW(rscn_entry));
1141 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1142 "port id [%02x%02x%02x].\n", ha->host_no,
1143 rscn_pid.b.domain, rscn_pid.b.area, rscn_pid.b.al_pa));
1146 * Search fcport lists for a known entry at the specified port
1149 list_for_each_entry(fcport, &ha->fcports, list) {
1150 if (rscn_pid.b24 == fcport->d_id.b24) {
1151 remote_fcport = fcport;
1155 list_for_each_entry(fcport, &ha->rscn_fcports, list) {
1156 if (rscn_pid.b24 == fcport->d_id.b24) {
1157 rscn_fcport = fcport;
1161 if (remote_fcport == NULL)
1162 remote_fcport = rscn_fcport;
1166 * If the port is already in our fcport list and online, send an ADISC
1167 * to see if it's still alive. Issue login if a new fcport or the known
1168 * fcport is currently offline.
1170 if (remote_fcport) {
1172 * No need to send request if the remote fcport is currently
1173 * waiting for an available io descriptor.
1175 if (known_fcport == NULL &&
1176 (remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1177 remote_fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED)) {
1179 * If previous waiting io descriptor is an ADISC, then
1180 * the new RSCN may come from a new remote fcport being
1181 * plugged into the same location.
1183 if (remote_fcport->port_type == FCT_RSCN) {
1184 remote_fcport->iodesc_idx_sent =
1185 IODESC_LOGIN_NEEDED;
1186 } else if (remote_fcport->iodesc_idx_sent ==
1187 IODESC_ADISC_NEEDED) {
1188 fc_port_t *new_fcport;
1190 remote_fcport->iodesc_idx_sent =
1191 IODESC_INVALID_INDEX;
1193 /* Create new fcport for later login. */
1194 new_fcport = qla2x00_alloc_rscn_fcport(ha,
1195 ha_locked ? GFP_ATOMIC: GFP_KERNEL);
1197 DEBUG14(printk("scsi(%ld): Handle RSCN "
1198 "-- creating RSCN fcport %p for "
1199 "future login.\n", ha->host_no,
1202 new_fcport->d_id.b24 =
1203 remote_fcport->d_id.b24;
1204 new_fcport->iodesc_idx_sent =
1205 IODESC_LOGIN_NEEDED;
1207 list_add_tail(&new_fcport->list,
1209 set_bit(IODESC_PROCESS_NEEDED,
1212 DEBUG14(printk("scsi(%ld): Handle RSCN "
1213 "-- unable to allocate RSCN fcport "
1214 "for future login.\n",
1218 return (QLA_SUCCESS);
1221 /* Send ADISC if the fcport is online */
1222 if (atomic_read(&remote_fcport->state) == FCS_ONLINE ||
1223 remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) {
1225 atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
1227 iodesc = qla2x00_alloc_iodesc(ha);
1228 if (iodesc == NULL) {
1229 /* Mark fcport for later adisc processing */
1230 DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
1231 "enough IO descriptors for Adisc, flag "
1232 "for later processing.\n", ha->host_no));
1234 remote_fcport->iodesc_idx_sent =
1235 IODESC_ADISC_NEEDED;
1236 set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1238 return (QLA_SUCCESS);
1241 iodesc->cb_idx = ADISC_PORT_IOCB_CB;
1242 iodesc->d_id.b24 = rscn_pid.b24;
1243 iodesc->remote_fcport = remote_fcport;
1244 remote_fcport->iodesc_idx_sent = iodesc->idx;
1245 qla2x00_send_adisc_iocb(ha, iodesc, ha_locked);
1247 return (QLA_SUCCESS);
1248 } else if (remote_fcport->iodesc_idx_sent <
1249 MAX_IO_DESCRIPTORS &&
1250 ha->io_descriptors[remote_fcport->iodesc_idx_sent].cb_idx ==
1251 ADISC_PORT_IOCB_CB) {
1253 * Receiving another RSCN while an ADISC is pending,
1254 * abort the IOCB. Use the same descriptor for the
1257 uint32_t handle_to_abort;
1259 iodesc = &ha->io_descriptors[
1260 remote_fcport->iodesc_idx_sent];
1261 qla2x00_remove_iodesc_timer(iodesc);
1262 handle_to_abort = iodesc->signature;
1263 iodesc->signature = qla2x00_iodesc_to_handle(iodesc);
1264 iodesc->cb_idx = ABORT_IOCB_CB;
1265 iodesc->d_id.b24 = remote_fcport->d_id.b24;
1266 iodesc->remote_fcport = remote_fcport;
1267 remote_fcport->iodesc_idx_sent = iodesc->idx;
1269 DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
1270 "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
1271 ha->host_no, remote_fcport->loop_id,
1272 iodesc->d_id.b.domain, iodesc->d_id.b.area,
1273 iodesc->d_id.b.al_pa));
1275 qla2x00_send_abort_iocb(ha, iodesc, handle_to_abort,
1280 /* We need to login to the remote port, find it. */
1282 remote_fcport = known_fcport;
1283 } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
1284 rscn_fcport->iodesc_idx_sent < MAX_IO_DESCRIPTORS &&
1285 ha->io_descriptors[rscn_fcport->iodesc_idx_sent].cb_idx ==
1286 LOGIN_PORT_IOCB_CB) {
1288 * Ignore duplicate RSCN on fcport which has already
1289 * initiated a login IOCB.
1291 DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
1292 "already sent to [%02x%02x%02x].\n", ha->host_no,
1293 rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
1294 rscn_fcport->d_id.b.al_pa));
1296 return (QLA_SUCCESS);
1297 } else if (rscn_fcport && rscn_fcport->d_id.b24 != INVALID_PORT_ID &&
1298 rscn_fcport != remote_fcport) {
1299 /* Reuse same rscn fcport. */
1300 DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
1301 "[%02x%02x%02x].\n", ha->host_no,
1302 rscn_fcport->d_id.b.domain, rscn_fcport->d_id.b.area,
1303 rscn_fcport->d_id.b.al_pa));
1305 remote_fcport = rscn_fcport;
1307 /* Create new fcport for later login. */
1308 remote_fcport = qla2x00_alloc_rscn_fcport(ha,
1309 ha_locked ? GFP_ATOMIC: GFP_KERNEL);
1310 list_add_tail(&remote_fcport->list, &ha->rscn_fcports);
1312 if (remote_fcport == NULL)
1313 return (QLA_SUCCESS);
1315 /* Prepare fcport for login. */
1316 atomic_set(&remote_fcport->state, FCS_DEVICE_LOST);
1317 remote_fcport->login_retry = 3; /* ha->login_retry_count; */
1318 remote_fcport->d_id.b24 = rscn_pid.b24;
1320 iodesc = qla2x00_alloc_iodesc(ha);
1321 if (iodesc == NULL) {
1322 /* Mark fcport for later adisc processing. */
1323 DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
1324 "descriptors for Login, flag for later processing.\n",
1327 remote_fcport->iodesc_idx_sent = IODESC_LOGIN_NEEDED;
1328 set_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1330 return (QLA_SUCCESS);
1333 if (known_fcport == NULL || rscn_pid.b24 != INVALID_PORT_ID) {
1334 remote_fcport->loop_id = ha->min_external_loopid;
1336 rval = qla2x00_find_new_loop_id(ha, remote_fcport);
1337 if (rval == QLA_FUNCTION_FAILED) {
1338 /* No more loop ids, failed. */
1339 DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
1340 "loop id to perform Login, failed.\n",
1347 iodesc->cb_idx = LOGIN_PORT_IOCB_CB;
1348 iodesc->d_id.b24 = rscn_pid.b24;
1349 iodesc->remote_fcport = remote_fcport;
1350 remote_fcport->iodesc_idx_sent = iodesc->idx;
1352 DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
1353 "[%x/%02x%02x%02x].\n", ha->host_no, remote_fcport->loop_id,
1354 iodesc->d_id.b.domain, iodesc->d_id.b.area, iodesc->d_id.b.al_pa));
1356 qla2x00_send_login_iocb(ha, iodesc, &rscn_pid, ha_locked);
1358 return (QLA_SUCCESS);
1362 * qla2x00_process_iodesc() - Complete IO descriptor processing.
1364 * @mbxstat: Mailbox IOCB status
1367 qla2x00_process_iodesc(scsi_qla_host_t *ha, struct mbx_entry *mbxstat)
1372 struct io_descriptor *iodesc;
1374 signature = mbxstat->handle;
1376 DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
1377 ha->host_no, signature));
1379 /* Retrieve proper IO descriptor. */
1380 iodesc = qla2x00_handle_to_iodesc(ha, signature);
1381 if (iodesc == NULL) {
1382 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1383 "incorrect signature %08x.\n", ha->host_no, signature));
1388 /* Stop IO descriptor timer. */
1389 qla2x00_remove_iodesc_timer(iodesc);
1391 /* Verify signature match. */
1392 if (iodesc->signature != signature) {
1393 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1394 "signature mismatch, sent %08x, received %08x.\n",
1395 ha->host_no, iodesc->signature, signature));
1400 /* Go with IOCB callback. */
1401 rval = iocb_function_cb_list[iodesc->cb_idx](ha, iodesc, mbxstat);
1402 if (rval != QLA_SUCCESS) {
1403 /* IO descriptor reused by callback. */
1407 qla2x00_free_iodesc(iodesc);
1409 if (test_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags)) {
1410 /* Scan our fcports list for any RSCN requests. */
1411 list_for_each_entry(fcport, &ha->fcports, list) {
1412 if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1413 fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
1414 qla2x00_handle_port_rscn(ha, 0, fcport, 1);
1419 /* Scan our RSCN fcports list for any RSCN requests. */
1420 list_for_each_entry(fcport, &ha->rscn_fcports, list) {
1421 if (fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED ||
1422 fcport->iodesc_idx_sent == IODESC_LOGIN_NEEDED) {
1423 qla2x00_handle_port_rscn(ha, 0, fcport, 1);
1428 clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1432 * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
1435 * This routine will also delete any RSCN entries related to the outstanding
1439 qla2x00_cancel_io_descriptors(scsi_qla_host_t *ha)
1441 fc_port_t *fcport, *fcptemp;
1443 clear_bit(IODESC_PROCESS_NEEDED, &ha->dpc_flags);
1445 /* Abort all IO descriptors. */
1446 qla2x00_init_io_descriptors(ha);
1448 /* Reset all pending IO descriptors in fcports list. */
1449 list_for_each_entry(fcport, &ha->fcports, list) {
1450 fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
1453 /* Reset all pending IO descriptors in rscn fcports list. */
1454 list_for_each_entry_safe(fcport, fcptemp, &ha->rscn_fcports, list) {
1455 DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
1456 "%p [%x/%02x%02x%02x].\n", ha->host_no, fcport,
1457 fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
1458 fcport->d_id.b.al_pa));
1460 list_del(&fcport->list);