2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2005 QLogic Corporation
5 * See LICENSE.qla2xxx for copyright and licensing details.
9 #include <scsi/scsi_transport_fc.h>
12 * IO descriptor handle definitions.
16 * |31------28|27-------------------12|11-------0|
17 * | Type | Rolling Signature | Index |
18 * |----------|-----------------------|----------|
22 #define HDL_TYPE_SCSI 0
23 #define HDL_TYPE_ASYNC_IOCB 0x0A
25 #define HDL_INDEX_BITS 12
26 #define HDL_ITER_BITS 16
27 #define HDL_TYPE_BITS 4
29 #define HDL_INDEX_MASK ((1UL << HDL_INDEX_BITS) - 1)
30 #define HDL_ITER_MASK ((1UL << HDL_ITER_BITS) - 1)
31 #define HDL_TYPE_MASK ((1UL << HDL_TYPE_BITS) - 1)
33 #define HDL_INDEX_SHIFT 0
34 #define HDL_ITER_SHIFT (HDL_INDEX_SHIFT + HDL_INDEX_BITS)
35 #define HDL_TYPE_SHIFT (HDL_ITER_SHIFT + HDL_ITER_BITS)
37 /* Local Prototypes. */
38 static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t);
39 static inline uint16_t qla2x00_handle_to_idx(uint32_t);
40 static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor
*);
41 static inline struct io_descriptor
*qla2x00_handle_to_iodesc(scsi_qla_host_t
*,
44 static inline struct io_descriptor
*qla2x00_alloc_iodesc(scsi_qla_host_t
*);
45 static inline void qla2x00_free_iodesc(struct io_descriptor
*);
46 static inline void qla2x00_init_io_descriptors(scsi_qla_host_t
*);
48 static void qla2x00_iodesc_timeout(unsigned long);
49 static inline void qla2x00_add_iodesc_timer(struct io_descriptor
*);
50 static inline void qla2x00_remove_iodesc_timer(struct io_descriptor
*);
52 static inline void qla2x00_update_login_fcport(scsi_qla_host_t
*,
53 struct mbx_entry
*, fc_port_t
*);
55 static int qla2x00_send_abort_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
57 static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
60 static int qla2x00_send_adisc_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
62 static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
65 static int qla2x00_send_logout_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
67 static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t
*,
68 struct io_descriptor
*, struct mbx_entry
*);
70 static int qla2x00_send_login_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
72 static int qla2x00_send_login_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
76 * Mailbox IOCB callback array.
78 static int (*iocb_function_cb_list
[LAST_IOCB_CB
])
79 (scsi_qla_host_t
*, struct io_descriptor
*, struct mbx_entry
*) = {
81 qla2x00_send_abort_iocb_cb
,
82 qla2x00_send_adisc_iocb_cb
,
83 qla2x00_send_logout_iocb_cb
,
84 qla2x00_send_login_iocb_cb
,
89 * Generic IO descriptor handle routines.
93 * qla2x00_to_handle() - Create a descriptor handle.
94 * @type: descriptor type
95 * @iter: descriptor rolling signature
96 * @idx: index to the descriptor array
98 * Returns a composite handle based in the @type, @iter, and @idx.
100 static inline uint32_t
101 qla2x00_to_handle(uint16_t type
, uint16_t iter
, uint16_t idx
)
103 return ((uint32_t)(((uint32_t)type
<< HDL_TYPE_SHIFT
) |
104 ((uint32_t)iter
<< HDL_ITER_SHIFT
) |
105 ((uint32_t)idx
<< HDL_INDEX_SHIFT
)));
109 * qla2x00_handle_to_idx() - Retrive the index for a given handle.
110 * @handle: descriptor handle
112 * Returns the index specified by the @handle.
114 static inline uint16_t
115 qla2x00_handle_to_idx(uint32_t handle
)
117 return ((uint16_t)(((handle
) >> HDL_INDEX_SHIFT
) & HDL_INDEX_MASK
));
121 * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
122 * @iodesc: io descriptor
124 * Returns a unique handle for @iodesc.
126 static inline uint32_t
127 qla2x00_iodesc_to_handle(struct io_descriptor
*iodesc
)
131 handle
= qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB
,
132 ++iodesc
->ha
->iodesc_signature
, iodesc
->idx
);
133 iodesc
->signature
= handle
;
139 * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
141 * @handle: handle to io descriptor
143 * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
144 * not exist or the io descriptors signature does not @handle.
146 static inline struct io_descriptor
*
147 qla2x00_handle_to_iodesc(scsi_qla_host_t
*ha
, uint32_t handle
)
150 struct io_descriptor
*iodesc
;
152 idx
= qla2x00_handle_to_idx(handle
);
153 iodesc
= &ha
->io_descriptors
[idx
];
155 if (iodesc
->signature
!= handle
)
163 * IO descriptor allocation routines.
167 * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
170 * Returns a pointer to the allocated io descriptor, or NULL, if none available.
172 static inline struct io_descriptor
*
173 qla2x00_alloc_iodesc(scsi_qla_host_t
*ha
)
176 struct io_descriptor
*iodesc
;
179 for (iter
= 0; iter
< MAX_IO_DESCRIPTORS
; iter
++) {
180 if (ha
->io_descriptors
[iter
].used
)
183 iodesc
= &ha
->io_descriptors
[iter
];
186 init_timer(&iodesc
->timer
);
188 iodesc
->signature
= qla2x00_iodesc_to_handle(iodesc
);
196 * qla2x00_free_iodesc() - Free an IO descriptor.
197 * @iodesc: io descriptor
199 * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
202 qla2x00_free_iodesc(struct io_descriptor
*iodesc
)
205 iodesc
->signature
= 0;
209 * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
210 * @iodesc: io descriptor
213 qla2x00_remove_iodesc_timer(struct io_descriptor
*iodesc
)
215 if (iodesc
->timer
.function
!= NULL
) {
216 del_timer_sync(&iodesc
->timer
);
217 iodesc
->timer
.data
= (unsigned long) NULL
;
218 iodesc
->timer
.function
= NULL
;
223 * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
227 qla2x00_init_io_descriptors(scsi_qla_host_t
*ha
)
231 for (iter
= 0; iter
< MAX_IO_DESCRIPTORS
; iter
++) {
232 if (!ha
->io_descriptors
[iter
].used
)
235 qla2x00_remove_iodesc_timer(&ha
->io_descriptors
[iter
]);
236 qla2x00_free_iodesc(&ha
->io_descriptors
[iter
]);
242 * IO descriptor timer routines.
246 * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
247 * @data: io descriptor
250 qla2x00_iodesc_timeout(unsigned long data
)
252 struct io_descriptor
*iodesc
;
254 iodesc
= (struct io_descriptor
*) data
;
256 DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
257 "signature=%08x, scheduling ISP abort.\n", iodesc
->ha
->host_no
,
258 iodesc
->idx
, iodesc
->signature
));
260 qla2x00_free_iodesc(iodesc
);
262 qla_printk(KERN_WARNING
, iodesc
->ha
,
263 "IO descriptor timeout. Scheduling ISP abort.\n");
264 set_bit(ISP_ABORT_NEEDED
, &iodesc
->ha
->dpc_flags
);
268 * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
269 * @iodesc: io descriptor
272 * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
273 * tenths of a second) after it hits the wire. But, if there are any request
274 * resource contraints (i.e. during heavy I/O), exchanges can be held off for
275 * at most R_A_TOV. Therefore, the driver will wait 4 * R_A_TOV before
276 * scheduling a recovery (big hammer).
279 qla2x00_add_iodesc_timer(struct io_descriptor
*iodesc
)
281 unsigned long timeout
;
283 timeout
= (iodesc
->ha
->r_a_tov
* 4) / 10;
284 init_timer(&iodesc
->timer
);
285 iodesc
->timer
.data
= (unsigned long) iodesc
;
286 iodesc
->timer
.expires
= jiffies
+ (timeout
* HZ
);
287 iodesc
->timer
.function
=
288 (void (*) (unsigned long)) qla2x00_iodesc_timeout
;
289 add_timer(&iodesc
->timer
);
293 * IO descriptor support routines.
297 * qla2x00_update_login_fcport() - Update fcport data after login processing.
299 * @mbxstat: Mailbox command status IOCB
300 * @fcport: port to update
303 qla2x00_update_login_fcport(scsi_qla_host_t
*ha
, struct mbx_entry
*mbxstat
,
306 if (le16_to_cpu(mbxstat
->mb1
) & BIT_0
) {
307 fcport
->port_type
= FCT_INITIATOR
;
309 fcport
->port_type
= FCT_TARGET
;
310 if (le16_to_cpu(mbxstat
->mb1
) & BIT_1
) {
311 fcport
->flags
|= FCF_TAPE_PRESENT
;
314 fcport
->login_retry
= 0;
315 fcport
->port_login_retry_count
= ha
->port_down_retry_count
*
317 atomic_set(&fcport
->port_down_timer
, ha
->port_down_retry_count
*
319 fcport
->flags
|= FCF_FABRIC_DEVICE
;
320 fcport
->flags
&= ~FCF_FAILOVER_NEEDED
;
321 fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
322 atomic_set(&fcport
->state
, FCS_ONLINE
);
323 schedule_work(&fcport
->rport_add_work
);
328 * Mailbox IOCB commands.
332 * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
334 * @handle: handle to io descriptor
336 * Returns a pointer to the reqest entry, or NULL, if none were available.
338 static inline struct mbx_entry
*
339 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t
*ha
, uint32_t handle
)
342 struct device_reg_2xxx __iomem
*reg
= &ha
->iobase
->isp
;
343 struct mbx_entry
*mbxentry
;
347 if (ha
->req_q_cnt
< 3) {
348 cnt
= qla2x00_debounce_register(ISP_REQ_Q_OUT(ha
, reg
));
349 if (ha
->req_ring_index
< cnt
)
350 ha
->req_q_cnt
= cnt
- ha
->req_ring_index
;
352 ha
->req_q_cnt
= ha
->request_q_length
-
353 (ha
->req_ring_index
- cnt
);
355 if (ha
->req_q_cnt
>= 3) {
356 mbxentry
= (struct mbx_entry
*)ha
->request_ring_ptr
;
358 memset(mbxentry
, 0, sizeof(struct mbx_entry
));
359 mbxentry
->entry_type
= MBX_IOCB_TYPE
;
360 mbxentry
->entry_count
= 1;
361 mbxentry
->sys_define1
= SOURCE_ASYNC_IOCB
;
362 mbxentry
->handle
= handle
;
368 * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
370 * @iodesc: io descriptor
371 * @handle_to_abort: firmware handle to abort
372 * @ha_locked: is function called with the hardware lock
374 * Returns QLA_SUCCESS if the IOCB was issued.
377 qla2x00_send_abort_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
378 uint32_t handle_to_abort
, int ha_locked
)
380 unsigned long flags
= 0;
381 struct mbx_entry
*mbxentry
;
383 /* Send marker if required. */
384 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
385 return (QLA_FUNCTION_FAILED
);
388 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
390 /* Build abort mailbox IOCB. */
391 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
392 if (mbxentry
== NULL
) {
394 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
396 return (QLA_FUNCTION_FAILED
);
398 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_ABORT_COMMAND
);
399 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
400 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
401 mbxentry
->mb2
= LSW(handle_to_abort
);
402 mbxentry
->mb3
= MSW(handle_to_abort
);
405 qla2x00_add_iodesc_timer(iodesc
);
407 /* Issue command to ISP. */
411 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
413 DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
414 "%08x.\n", ha
->host_no
, iodesc
->signature
,
415 iodesc
->remote_fcport
->loop_id
, handle_to_abort
));
417 return (QLA_SUCCESS
);
421 * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
423 * @iodesc: io descriptor
424 * @mbxstat: mailbox status IOCB
426 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
427 * will be used for a retry.
430 qla2x00_send_abort_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
431 struct mbx_entry
*mbxstat
)
433 DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
434 "status=%x mb0=%x.\n", ha
->host_no
, iodesc
->remote_fcport
->loop_id
,
435 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
,
436 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
438 return (QLA_SUCCESS
);
443 * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
445 * @iodesc: io descriptor
446 * @ha_locked: is function called with the hardware lock
448 * Returns QLA_SUCCESS if the IOCB was issued.
451 qla2x00_send_adisc_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
454 unsigned long flags
= 0;
455 struct mbx_entry
*mbxentry
;
457 /* Send marker if required. */
458 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
459 return (QLA_FUNCTION_FAILED
);
462 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
464 /* Build Get Port Database IOCB. */
465 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
466 if (mbxentry
== NULL
) {
468 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
470 return (QLA_FUNCTION_FAILED
);
472 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_GET_PORT_DATABASE
);
473 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
474 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
475 mbxentry
->mb2
= cpu_to_le16(MSW(LSD(ha
->iodesc_pd_dma
)));
476 mbxentry
->mb3
= cpu_to_le16(LSW(LSD(ha
->iodesc_pd_dma
)));
477 mbxentry
->mb6
= cpu_to_le16(MSW(MSD(ha
->iodesc_pd_dma
)));
478 mbxentry
->mb7
= cpu_to_le16(LSW(MSD(ha
->iodesc_pd_dma
)));
479 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
482 qla2x00_add_iodesc_timer(iodesc
);
484 /* Issue command to ISP. */
488 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
490 DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
491 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
493 return (QLA_SUCCESS
);
497 * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
499 * @iodesc: io descriptor
500 * @mbxstat: mailbox status IOCB
502 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
503 * will be used for a retry.
506 qla2x00_send_adisc_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
507 struct mbx_entry
*mbxstat
)
509 fc_port_t
*remote_fcport
;
511 remote_fcport
= iodesc
->remote_fcport
;
513 /* Ensure the port IDs are consistent. */
514 if (remote_fcport
->d_id
.b24
!= iodesc
->d_id
.b24
) {
515 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
516 "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
517 ha
->host_no
, remote_fcport
->d_id
.b
.domain
,
518 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
519 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
520 iodesc
->d_id
.b
.al_pa
));
522 return (QLA_SUCCESS
);
525 /* Only process the last command. */
526 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
527 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
528 "[%02x%02x%02x], expected %x, received %x.\n", ha
->host_no
,
529 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
530 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
533 return (QLA_SUCCESS
);
536 if (le16_to_cpu(mbxstat
->status
) == CS_COMPLETE
) {
537 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
538 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
539 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
540 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
542 atomic_set(&remote_fcport
->state
, FCS_ONLINE
);
544 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
545 "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha
->host_no
,
546 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
547 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
548 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
550 if (atomic_read(&remote_fcport
->state
) != FCS_DEVICE_DEAD
)
551 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
553 remote_fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
555 return (QLA_SUCCESS
);
560 * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
562 * @iodesc: io descriptor
563 * @ha_locked: is function called with the hardware lock
565 * Returns QLA_SUCCESS if the IOCB was issued.
568 qla2x00_send_logout_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
571 unsigned long flags
= 0;
572 struct mbx_entry
*mbxentry
;
574 /* Send marker if required. */
575 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
576 return (QLA_FUNCTION_FAILED
);
579 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
581 /* Build fabric port logout mailbox IOCB. */
582 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
583 if (mbxentry
== NULL
) {
585 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
587 return (QLA_FUNCTION_FAILED
);
589 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT
);
590 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
591 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
594 qla2x00_add_iodesc_timer(iodesc
);
596 /* Issue command to ISP. */
600 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
602 DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
603 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
605 return (QLA_SUCCESS
);
609 * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
611 * @iodesc: io descriptor
612 * @mbxstat: mailbox status IOCB
614 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
615 * will be used for a retry.
618 qla2x00_send_logout_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
619 struct mbx_entry
*mbxstat
)
621 DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
622 "status=%x mb0=%x mb1=%x.\n", ha
->host_no
,
623 iodesc
->remote_fcport
->loop_id
,
624 iodesc
->remote_fcport
->d_id
.b
.domain
,
625 iodesc
->remote_fcport
->d_id
.b
.area
,
626 iodesc
->remote_fcport
->d_id
.b
.al_pa
, le16_to_cpu(mbxstat
->status
),
627 le16_to_cpu(mbxstat
->mb0
), le16_to_cpu(mbxstat
->mb1
)));
629 return (QLA_SUCCESS
);
634 * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
636 * @iodesc: io descriptor
637 * @d_id: port id for device
638 * @ha_locked: is function called with the hardware lock
640 * Returns QLA_SUCCESS if the IOCB was issued.
643 qla2x00_send_login_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
644 port_id_t
*d_id
, int ha_locked
)
646 unsigned long flags
= 0;
647 struct mbx_entry
*mbxentry
;
649 /* Send marker if required. */
650 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
651 return (QLA_FUNCTION_FAILED
);
654 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
656 /* Build fabric port login mailbox IOCB. */
657 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
658 if (mbxentry
== NULL
) {
660 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
662 return (QLA_FUNCTION_FAILED
);
664 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT
);
665 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
666 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
667 mbxentry
->mb2
= cpu_to_le16(d_id
->b
.domain
);
668 mbxentry
->mb3
= cpu_to_le16(d_id
->b
.area
<< 8 | d_id
->b
.al_pa
);
669 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
672 qla2x00_add_iodesc_timer(iodesc
);
674 /* Issue command to ISP. */
678 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
680 DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
681 "[%x/%02x%02x%02x].\n", ha
->host_no
, iodesc
->signature
,
682 iodesc
->remote_fcport
->loop_id
, d_id
->b
.domain
, d_id
->b
.area
,
685 return (QLA_SUCCESS
);
689 * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
691 * @iodesc: io descriptor
692 * @mbxstat: mailbox status IOCB
694 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
695 * will be used for a retry.
698 qla2x00_send_login_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
699 struct mbx_entry
*mbxstat
)
702 fc_port_t
*fcport
, *remote_fcport
, *exist_fcport
;
703 struct io_descriptor
*abort_iodesc
, *login_iodesc
;
704 uint16_t status
, mb
[8];
706 uint16_t remote_loopid
;
707 port_id_t remote_did
, inuse_did
;
709 remote_fcport
= iodesc
->remote_fcport
;
711 /* Only process the last command. */
712 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
713 DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
714 "[%02x%02x%02x], expected %x, received %x.\n",
715 ha
->host_no
, iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
716 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
719 /* Free RSCN fcport resources. */
720 if (remote_fcport
->port_type
== FCT_RSCN
) {
721 DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
722 "fcport %p [%x/%02x%02x%02x] given ignored Login "
723 "IOCB.\n", ha
->host_no
, remote_fcport
,
724 remote_fcport
->loop_id
,
725 remote_fcport
->d_id
.b
.domain
,
726 remote_fcport
->d_id
.b
.area
,
727 remote_fcport
->d_id
.b
.al_pa
));
729 list_del(&remote_fcport
->list
);
730 kfree(remote_fcport
);
732 return (QLA_SUCCESS
);
735 status
= le16_to_cpu(mbxstat
->status
);
736 mb
[0] = le16_to_cpu(mbxstat
->mb0
);
737 mb
[1] = le16_to_cpu(mbxstat
->mb1
);
738 mb
[2] = le16_to_cpu(mbxstat
->mb2
);
739 mb
[6] = le16_to_cpu(mbxstat
->mb6
);
740 mb
[7] = le16_to_cpu(mbxstat
->mb7
);
743 if ((status
== CS_COMPLETE
|| status
== CS_COMPLETE_CHKCOND
) &&
744 mb
[0] == MBS_COMMAND_COMPLETE
) {
746 DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
747 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha
->host_no
, status
,
748 mb
[1], mbxstat
->port_name
[0], mbxstat
->port_name
[1],
749 mbxstat
->port_name
[2], mbxstat
->port_name
[3],
750 mbxstat
->port_name
[4], mbxstat
->port_name
[5],
751 mbxstat
->port_name
[6], mbxstat
->port_name
[7]));
753 memcpy(remote_fcport
->node_name
, mbxstat
->node_name
, WWN_SIZE
);
754 memcpy(remote_fcport
->port_name
, mbxstat
->port_name
, WWN_SIZE
);
756 /* Is the device already in our fcports list? */
757 if (remote_fcport
->port_type
!= FCT_RSCN
) {
758 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
759 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
760 remote_fcport
->loop_id
,
761 remote_fcport
->d_id
.b
.domain
,
762 remote_fcport
->d_id
.b
.area
,
763 remote_fcport
->d_id
.b
.al_pa
));
765 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
767 return (QLA_SUCCESS
);
770 /* Does the RSCN portname already exist in our fcports list? */
772 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
773 if (memcmp(remote_fcport
->port_name
, fcport
->port_name
,
775 exist_fcport
= fcport
;
779 if (exist_fcport
!= NULL
) {
780 DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
781 "fcport in fcports list [%p].\n", ha
->host_no
,
784 /* Abort any ADISC that could have been sent. */
785 if (exist_fcport
->iodesc_idx_sent
!= iodesc
->idx
&&
786 exist_fcport
->iodesc_idx_sent
<
787 MAX_IO_DESCRIPTORS
&&
788 ha
->io_descriptors
[exist_fcport
->iodesc_idx_sent
].
789 cb_idx
== ADISC_PORT_IOCB_CB
) {
791 abort_iodesc
= qla2x00_alloc_iodesc(ha
);
793 DEBUG14(printk("scsi(%ld): Login IOCB "
794 "-- issuing abort to outstanding "
795 "Adisc [%x/%02x%02x%02x].\n",
796 ha
->host_no
, remote_fcport
->loop_id
,
797 exist_fcport
->d_id
.b
.domain
,
798 exist_fcport
->d_id
.b
.area
,
799 exist_fcport
->d_id
.b
.al_pa
));
801 abort_iodesc
->cb_idx
= ABORT_IOCB_CB
;
802 abort_iodesc
->d_id
.b24
=
803 exist_fcport
->d_id
.b24
;
804 abort_iodesc
->remote_fcport
=
806 exist_fcport
->iodesc_idx_sent
=
808 qla2x00_send_abort_iocb(ha
,
809 abort_iodesc
, ha
->io_descriptors
[
810 exist_fcport
->iodesc_idx_sent
].
813 DEBUG14(printk("scsi(%ld): Login IOCB "
814 "-- unable to abort outstanding "
815 "Adisc [%x/%02x%02x%02x].\n",
816 ha
->host_no
, remote_fcport
->loop_id
,
817 exist_fcport
->d_id
.b
.domain
,
818 exist_fcport
->d_id
.b
.area
,
819 exist_fcport
->d_id
.b
.al_pa
));
824 * If the existing fcport is waiting to send an ADISC
825 * or LOGIN, then reuse remote fcport (RSCN) to
829 remote_loopid
= remote_fcport
->loop_id
;
830 remote_did
.b24
= remote_fcport
->d_id
.b24
;
831 if (exist_fcport
->iodesc_idx_sent
==
832 IODESC_ADISC_NEEDED
||
833 exist_fcport
->iodesc_idx_sent
==
834 IODESC_LOGIN_NEEDED
) {
835 DEBUG14(printk("scsi(%ld): Login IOCB -- "
836 "existing fcport [%x/%02x%02x%02x] "
837 "waiting for IO descriptor, reuse RSCN "
838 "fcport.\n", ha
->host_no
,
839 exist_fcport
->loop_id
,
840 exist_fcport
->d_id
.b
.domain
,
841 exist_fcport
->d_id
.b
.area
,
842 exist_fcport
->d_id
.b
.al_pa
));
845 remote_fcport
->iodesc_idx_sent
=
846 exist_fcport
->iodesc_idx_sent
;
847 exist_fcport
->iodesc_idx_sent
=
848 IODESC_INVALID_INDEX
;
849 remote_fcport
->loop_id
= exist_fcport
->loop_id
;
850 remote_fcport
->d_id
.b24
=
851 exist_fcport
->d_id
.b24
;
854 /* Logout the old loopid. */
856 exist_fcport
->loop_id
!= remote_fcport
->loop_id
&&
857 exist_fcport
->loop_id
!= FC_NO_LOOP_ID
) {
858 login_iodesc
= qla2x00_alloc_iodesc(ha
);
860 DEBUG14(printk("scsi(%ld): Login IOCB "
861 "-- issuing logout to free old "
862 "loop id [%x/%02x%02x%02x].\n",
863 ha
->host_no
, exist_fcport
->loop_id
,
864 exist_fcport
->d_id
.b
.domain
,
865 exist_fcport
->d_id
.b
.area
,
866 exist_fcport
->d_id
.b
.al_pa
));
868 login_iodesc
->cb_idx
=
870 login_iodesc
->d_id
.b24
=
871 exist_fcport
->d_id
.b24
;
872 login_iodesc
->remote_fcport
=
874 exist_fcport
->iodesc_idx_sent
=
876 qla2x00_send_logout_iocb(ha
,
879 /* Ran out of IO descriptiors. */
880 DEBUG14(printk("scsi(%ld): Login IOCB "
881 "-- unable to logout to free old "
882 "loop id [%x/%02x%02x%02x].\n",
883 ha
->host_no
, exist_fcport
->loop_id
,
884 exist_fcport
->d_id
.b
.domain
,
885 exist_fcport
->d_id
.b
.area
,
886 exist_fcport
->d_id
.b
.al_pa
));
888 exist_fcport
->iodesc_idx_sent
=
889 IODESC_INVALID_INDEX
;
894 /* Update existing fcport with remote fcport info. */
895 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
896 "existing fcport [%x/%02x%02x%02x] online.\n",
897 ha
->host_no
, remote_loopid
, remote_did
.b
.domain
,
898 remote_did
.b
.area
, remote_did
.b
.al_pa
));
900 memcpy(exist_fcport
->node_name
,
901 remote_fcport
->node_name
, WWN_SIZE
);
902 exist_fcport
->loop_id
= remote_loopid
;
903 exist_fcport
->d_id
.b24
= remote_did
.b24
;
904 qla2x00_update_login_fcport(ha
, mbxstat
, exist_fcport
);
906 /* Finally, free the remote (RSCN) fcport. */
908 DEBUG14(printk("scsi(%ld): Login IOCB -- "
909 "Freeing RSCN fcport %p "
910 "[%x/%02x%02x%02x].\n", ha
->host_no
,
911 remote_fcport
, remote_fcport
->loop_id
,
912 remote_fcport
->d_id
.b
.domain
,
913 remote_fcport
->d_id
.b
.area
,
914 remote_fcport
->d_id
.b
.al_pa
));
916 list_del(&remote_fcport
->list
);
917 kfree(remote_fcport
);
920 return (QLA_SUCCESS
);
924 * A new device has been added, move the RSCN fcport to our
927 DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
928 "[%x/%02x%02x%02x] to fcports list.\n", ha
->host_no
,
929 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
930 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
932 list_del(&remote_fcport
->list
);
933 remote_fcport
->flags
= (FCF_RLC_SUPPORT
| FCF_RESCAN_NEEDED
);
934 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
935 list_add_tail(&remote_fcport
->list
, &ha
->fcports
);
936 set_bit(FCPORT_RESCAN_NEEDED
, &ha
->dpc_flags
);
938 /* Handle login failure. */
939 if (remote_fcport
->login_retry
!= 0) {
940 if (mb
[0] == MBS_LOOP_ID_USED
) {
941 inuse_did
.b
.domain
= LSB(mb
[1]);
942 inuse_did
.b
.area
= MSB(mb
[2]);
943 inuse_did
.b
.al_pa
= LSB(mb
[2]);
945 DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
946 "id [%x] used by port id [%02x%02x%02x].\n",
947 ha
->host_no
, remote_fcport
->loop_id
,
948 inuse_did
.b
.domain
, inuse_did
.b
.area
,
951 if (remote_fcport
->d_id
.b24
==
954 * Invalid port id means we are trying
955 * to login to a remote port with just
956 * a loop id without knowing about the
957 * port id. Copy the port id and try
960 remote_fcport
->d_id
.b24
= inuse_did
.b24
;
961 iodesc
->d_id
.b24
= inuse_did
.b24
;
963 remote_fcport
->loop_id
++;
964 rval
= qla2x00_find_new_loop_id(ha
,
966 if (rval
== QLA_FUNCTION_FAILED
) {
967 /* No more loop ids. */
968 return (QLA_SUCCESS
);
971 } else if (mb
[0] == MBS_PORT_ID_USED
) {
973 * Device has another loop ID. The firmware
974 * group recommends the driver perform an
975 * implicit login with the specified ID.
977 DEBUG14(printk("scsi(%ld): Login IOCB -- port "
978 "id [%02x%02x%02x] already assigned to "
979 "loop id [%x].\n", ha
->host_no
,
980 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
981 iodesc
->d_id
.b
.al_pa
, mb
[1]));
983 remote_fcport
->loop_id
= mb
[1];
986 /* Unable to perform login, try again. */
987 DEBUG14(printk("scsi(%ld): Login IOCB -- "
988 "failed login [%x/%02x%02x%02x], status=%x "
989 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
990 ha
->host_no
, remote_fcport
->loop_id
,
991 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
992 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
993 mb
[2], mb
[6], mb
[7]));
996 /* Reissue Login with the same IO descriptor. */
998 qla2x00_iodesc_to_handle(iodesc
);
999 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
1000 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
1001 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1002 remote_fcport
->login_retry
--;
1004 DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
1005 "login to [%x/%02x%02x%02x] (%d).\n", ha
->host_no
,
1006 remote_fcport
->loop_id
,
1007 remote_fcport
->d_id
.b
.domain
,
1008 remote_fcport
->d_id
.b
.area
,
1009 remote_fcport
->d_id
.b
.al_pa
,
1010 remote_fcport
->login_retry
));
1012 qla2x00_send_login_iocb(ha
, iodesc
,
1013 &remote_fcport
->d_id
, 1);
1015 return (QLA_FUNCTION_FAILED
);
1017 /* No more logins, mark device dead. */
1018 DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
1019 "login [%x/%02x%02x%02x] after retries, status=%x "
1020 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1021 ha
->host_no
, remote_fcport
->loop_id
,
1022 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1023 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
1024 mb
[2], mb
[6], mb
[7]));
1026 atomic_set(&remote_fcport
->state
, FCS_DEVICE_DEAD
);
1027 if (remote_fcport
->port_type
== FCT_RSCN
) {
1028 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1029 "Freeing dead RSCN fcport %p "
1030 "[%x/%02x%02x%02x].\n", ha
->host_no
,
1031 remote_fcport
, remote_fcport
->loop_id
,
1032 remote_fcport
->d_id
.b
.domain
,
1033 remote_fcport
->d_id
.b
.area
,
1034 remote_fcport
->d_id
.b
.al_pa
));
1036 list_del(&remote_fcport
->list
);
1037 kfree(remote_fcport
);
1042 return (QLA_SUCCESS
);
1047 * IO descriptor processing routines.
1051 * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
1053 * @flags: allocation flags
1055 * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
1058 qla2x00_alloc_rscn_fcport(scsi_qla_host_t
*ha
, gfp_t flags
)
1062 fcport
= qla2x00_alloc_fcport(ha
, flags
);
1066 /* Setup RSCN fcport structure. */
1067 fcport
->port_type
= FCT_RSCN
;
1073 * qla2x00_handle_port_rscn() - Handle port RSCN.
1075 * @rscn_entry: RSCN entry
1076 * @fcport: fcport entry to updated
1078 * Returns QLA_SUCCESS if the port RSCN was handled.
1081 qla2x00_handle_port_rscn(scsi_qla_host_t
*ha
, uint32_t rscn_entry
,
1082 fc_port_t
*known_fcport
, int ha_locked
)
1086 fc_port_t
*fcport
, *remote_fcport
, *rscn_fcport
;
1087 struct io_descriptor
*iodesc
;
1089 remote_fcport
= NULL
;
1092 /* Prepare port id based on incoming entries. */
1094 rscn_pid
.b24
= known_fcport
->d_id
.b24
;
1095 remote_fcport
= known_fcport
;
1097 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1098 "fcport [%02x%02x%02x].\n", ha
->host_no
,
1099 remote_fcport
->d_id
.b
.domain
, remote_fcport
->d_id
.b
.area
,
1100 remote_fcport
->d_id
.b
.al_pa
));
1102 rscn_pid
.b
.domain
= LSB(MSW(rscn_entry
));
1103 rscn_pid
.b
.area
= MSB(LSW(rscn_entry
));
1104 rscn_pid
.b
.al_pa
= LSB(LSW(rscn_entry
));
1106 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1107 "port id [%02x%02x%02x].\n", ha
->host_no
,
1108 rscn_pid
.b
.domain
, rscn_pid
.b
.area
, rscn_pid
.b
.al_pa
));
1111 * Search fcport lists for a known entry at the specified port
1114 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1115 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1116 remote_fcport
= fcport
;
1120 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1121 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1122 rscn_fcport
= fcport
;
1126 if (remote_fcport
== NULL
)
1127 remote_fcport
= rscn_fcport
;
1131 * If the port is already in our fcport list and online, send an ADISC
1132 * to see if it's still alive. Issue login if a new fcport or the known
1133 * fcport is currently offline.
1135 if (remote_fcport
) {
1137 * No need to send request if the remote fcport is currently
1138 * waiting for an available io descriptor.
1140 if (known_fcport
== NULL
&&
1141 (remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1142 remote_fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
)) {
1144 * If previous waiting io descriptor is an ADISC, then
1145 * the new RSCN may come from a new remote fcport being
1146 * plugged into the same location.
1148 if (remote_fcport
->port_type
== FCT_RSCN
) {
1149 remote_fcport
->iodesc_idx_sent
=
1150 IODESC_LOGIN_NEEDED
;
1151 } else if (remote_fcport
->iodesc_idx_sent
==
1152 IODESC_ADISC_NEEDED
) {
1153 fc_port_t
*new_fcport
;
1155 remote_fcport
->iodesc_idx_sent
=
1156 IODESC_INVALID_INDEX
;
1158 /* Create new fcport for later login. */
1159 new_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1160 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1162 DEBUG14(printk("scsi(%ld): Handle RSCN "
1163 "-- creating RSCN fcport %p for "
1164 "future login.\n", ha
->host_no
,
1167 new_fcport
->d_id
.b24
=
1168 remote_fcport
->d_id
.b24
;
1169 new_fcport
->iodesc_idx_sent
=
1170 IODESC_LOGIN_NEEDED
;
1172 list_add_tail(&new_fcport
->list
,
1174 set_bit(IODESC_PROCESS_NEEDED
,
1177 DEBUG14(printk("scsi(%ld): Handle RSCN "
1178 "-- unable to allocate RSCN fcport "
1179 "for future login.\n",
1183 return (QLA_SUCCESS
);
1186 /* Send ADISC if the fcport is online */
1187 if (atomic_read(&remote_fcport
->state
) == FCS_ONLINE
||
1188 remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
) {
1190 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1192 iodesc
= qla2x00_alloc_iodesc(ha
);
1193 if (iodesc
== NULL
) {
1194 /* Mark fcport for later adisc processing */
1195 DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
1196 "enough IO descriptors for Adisc, flag "
1197 "for later processing.\n", ha
->host_no
));
1199 remote_fcport
->iodesc_idx_sent
=
1200 IODESC_ADISC_NEEDED
;
1201 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1203 return (QLA_SUCCESS
);
1206 iodesc
->cb_idx
= ADISC_PORT_IOCB_CB
;
1207 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1208 iodesc
->remote_fcport
= remote_fcport
;
1209 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1210 qla2x00_send_adisc_iocb(ha
, iodesc
, ha_locked
);
1212 return (QLA_SUCCESS
);
1213 } else if (remote_fcport
->iodesc_idx_sent
<
1214 MAX_IO_DESCRIPTORS
&&
1215 ha
->io_descriptors
[remote_fcport
->iodesc_idx_sent
].cb_idx
==
1216 ADISC_PORT_IOCB_CB
) {
1218 * Receiving another RSCN while an ADISC is pending,
1219 * abort the IOCB. Use the same descriptor for the
1222 uint32_t handle_to_abort
;
1224 iodesc
= &ha
->io_descriptors
[
1225 remote_fcport
->iodesc_idx_sent
];
1226 qla2x00_remove_iodesc_timer(iodesc
);
1227 handle_to_abort
= iodesc
->signature
;
1228 iodesc
->signature
= qla2x00_iodesc_to_handle(iodesc
);
1229 iodesc
->cb_idx
= ABORT_IOCB_CB
;
1230 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
1231 iodesc
->remote_fcport
= remote_fcport
;
1232 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1234 DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
1235 "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
1236 ha
->host_no
, remote_fcport
->loop_id
,
1237 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1238 iodesc
->d_id
.b
.al_pa
));
1240 qla2x00_send_abort_iocb(ha
, iodesc
, handle_to_abort
,
1245 /* We need to login to the remote port, find it. */
1247 remote_fcport
= known_fcport
;
1248 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1249 rscn_fcport
->iodesc_idx_sent
< MAX_IO_DESCRIPTORS
&&
1250 ha
->io_descriptors
[rscn_fcport
->iodesc_idx_sent
].cb_idx
==
1251 LOGIN_PORT_IOCB_CB
) {
1253 * Ignore duplicate RSCN on fcport which has already
1254 * initiated a login IOCB.
1256 DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
1257 "already sent to [%02x%02x%02x].\n", ha
->host_no
,
1258 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1259 rscn_fcport
->d_id
.b
.al_pa
));
1261 return (QLA_SUCCESS
);
1262 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1263 rscn_fcport
!= remote_fcport
) {
1264 /* Reuse same rscn fcport. */
1265 DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
1266 "[%02x%02x%02x].\n", ha
->host_no
,
1267 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1268 rscn_fcport
->d_id
.b
.al_pa
));
1270 remote_fcport
= rscn_fcport
;
1272 /* Create new fcport for later login. */
1273 remote_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1274 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1275 list_add_tail(&remote_fcport
->list
, &ha
->rscn_fcports
);
1277 if (remote_fcport
== NULL
)
1278 return (QLA_SUCCESS
);
1280 /* Prepare fcport for login. */
1281 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1282 remote_fcport
->login_retry
= 3; /* ha->login_retry_count; */
1283 remote_fcport
->d_id
.b24
= rscn_pid
.b24
;
1285 iodesc
= qla2x00_alloc_iodesc(ha
);
1286 if (iodesc
== NULL
) {
1287 /* Mark fcport for later adisc processing. */
1288 DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
1289 "descriptors for Login, flag for later processing.\n",
1292 remote_fcport
->iodesc_idx_sent
= IODESC_LOGIN_NEEDED
;
1293 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1295 return (QLA_SUCCESS
);
1298 if (known_fcport
== NULL
|| rscn_pid
.b24
!= INVALID_PORT_ID
) {
1299 remote_fcport
->loop_id
= ha
->min_external_loopid
;
1301 rval
= qla2x00_find_new_loop_id(ha
, remote_fcport
);
1302 if (rval
== QLA_FUNCTION_FAILED
) {
1303 /* No more loop ids, failed. */
1304 DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
1305 "loop id to perform Login, failed.\n",
1312 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
1313 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1314 iodesc
->remote_fcport
= remote_fcport
;
1315 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1317 DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
1318 "[%x/%02x%02x%02x].\n", ha
->host_no
, remote_fcport
->loop_id
,
1319 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
));
1321 qla2x00_send_login_iocb(ha
, iodesc
, &rscn_pid
, ha_locked
);
1323 return (QLA_SUCCESS
);
1327 * qla2x00_process_iodesc() - Complete IO descriptor processing.
1329 * @mbxstat: Mailbox IOCB status
1332 qla2x00_process_iodesc(scsi_qla_host_t
*ha
, struct mbx_entry
*mbxstat
)
1337 struct io_descriptor
*iodesc
;
1339 signature
= mbxstat
->handle
;
1341 DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
1342 ha
->host_no
, signature
));
1344 /* Retrieve proper IO descriptor. */
1345 iodesc
= qla2x00_handle_to_iodesc(ha
, signature
);
1346 if (iodesc
== NULL
) {
1347 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1348 "incorrect signature %08x.\n", ha
->host_no
, signature
));
1353 /* Stop IO descriptor timer. */
1354 qla2x00_remove_iodesc_timer(iodesc
);
1356 /* Verify signature match. */
1357 if (iodesc
->signature
!= signature
) {
1358 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1359 "signature mismatch, sent %08x, received %08x.\n",
1360 ha
->host_no
, iodesc
->signature
, signature
));
1365 /* Go with IOCB callback. */
1366 rval
= iocb_function_cb_list
[iodesc
->cb_idx
](ha
, iodesc
, mbxstat
);
1367 if (rval
!= QLA_SUCCESS
) {
1368 /* IO descriptor reused by callback. */
1372 qla2x00_free_iodesc(iodesc
);
1374 if (test_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
)) {
1375 /* Scan our fcports list for any RSCN requests. */
1376 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1377 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1378 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1379 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1384 /* Scan our RSCN fcports list for any RSCN requests. */
1385 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1386 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1387 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1388 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1393 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1397 * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
1400 * This routine will also delete any RSCN entries related to the outstanding
1404 qla2x00_cancel_io_descriptors(scsi_qla_host_t
*ha
)
1406 fc_port_t
*fcport
, *fcptemp
;
1408 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1410 /* Abort all IO descriptors. */
1411 qla2x00_init_io_descriptors(ha
);
1413 /* Reset all pending IO descriptors in fcports list. */
1414 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1415 fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
1418 /* Reset all pending IO descriptors in rscn fcports list. */
1419 list_for_each_entry_safe(fcport
, fcptemp
, &ha
->rscn_fcports
, list
) {
1420 DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
1421 "%p [%x/%02x%02x%02x].\n", ha
->host_no
, fcport
,
1422 fcport
->loop_id
, fcport
->d_id
.b
.domain
, fcport
->d_id
.b
.area
,
1423 fcport
->d_id
.b
.al_pa
));
1425 list_del(&fcport
->list
);