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 uint32_t qla2x00_iodesc_to_handle(struct io_descriptor
*);
51 static inline struct io_descriptor
*qla2x00_handle_to_iodesc(scsi_qla_host_t
*,
54 static inline struct io_descriptor
*qla2x00_alloc_iodesc(scsi_qla_host_t
*);
55 static inline void qla2x00_free_iodesc(struct io_descriptor
*);
56 static inline void qla2x00_init_io_descriptors(scsi_qla_host_t
*);
58 static void qla2x00_iodesc_timeout(unsigned long);
59 static inline void qla2x00_add_iodesc_timer(struct io_descriptor
*);
60 static inline void qla2x00_remove_iodesc_timer(struct io_descriptor
*);
62 static inline void qla2x00_update_login_fcport(scsi_qla_host_t
*,
63 struct mbx_entry
*, fc_port_t
*);
65 static int qla2x00_send_abort_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
67 static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
70 static int qla2x00_send_adisc_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
72 static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
75 static int qla2x00_send_logout_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
77 static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t
*,
78 struct io_descriptor
*, struct mbx_entry
*);
80 static int qla2x00_send_login_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
82 static int qla2x00_send_login_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
86 * Mailbox IOCB callback array.
88 static int (*iocb_function_cb_list
[LAST_IOCB_CB
])
89 (scsi_qla_host_t
*, struct io_descriptor
*, struct mbx_entry
*) = {
91 qla2x00_send_abort_iocb_cb
,
92 qla2x00_send_adisc_iocb_cb
,
93 qla2x00_send_logout_iocb_cb
,
94 qla2x00_send_login_iocb_cb
,
99 * Generic IO descriptor handle routines.
103 * qla2x00_to_handle() - Create a descriptor handle.
104 * @type: descriptor type
105 * @iter: descriptor rolling signature
106 * @idx: index to the descriptor array
108 * Returns a composite handle based in the @type, @iter, and @idx.
110 static inline uint32_t
111 qla2x00_to_handle(uint16_t type
, uint16_t iter
, uint16_t idx
)
113 return ((uint32_t)(((uint32_t)type
<< HDL_TYPE_SHIFT
) |
114 ((uint32_t)iter
<< HDL_ITER_SHIFT
) |
115 ((uint32_t)idx
<< HDL_INDEX_SHIFT
)));
119 * qla2x00_handle_to_idx() - Retrive the index for a given handle.
120 * @handle: descriptor handle
122 * Returns the index specified by the @handle.
124 static inline uint16_t
125 qla2x00_handle_to_idx(uint32_t handle
)
127 return ((uint16_t)(((handle
) >> HDL_INDEX_SHIFT
) & HDL_INDEX_MASK
));
131 * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
132 * @iodesc: io descriptor
134 * Returns a unique handle for @iodesc.
136 static inline uint32_t
137 qla2x00_iodesc_to_handle(struct io_descriptor
*iodesc
)
141 handle
= qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB
,
142 ++iodesc
->ha
->iodesc_signature
, iodesc
->idx
);
143 iodesc
->signature
= handle
;
149 * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
151 * @handle: handle to io descriptor
153 * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
154 * not exist or the io descriptors signature does not @handle.
156 static inline struct io_descriptor
*
157 qla2x00_handle_to_iodesc(scsi_qla_host_t
*ha
, uint32_t handle
)
160 struct io_descriptor
*iodesc
;
162 idx
= qla2x00_handle_to_idx(handle
);
163 iodesc
= &ha
->io_descriptors
[idx
];
165 if (iodesc
->signature
!= handle
)
173 * IO descriptor allocation routines.
177 * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
180 * Returns a pointer to the allocated io descriptor, or NULL, if none available.
182 static inline struct io_descriptor
*
183 qla2x00_alloc_iodesc(scsi_qla_host_t
*ha
)
186 struct io_descriptor
*iodesc
;
189 for (iter
= 0; iter
< MAX_IO_DESCRIPTORS
; iter
++) {
190 if (ha
->io_descriptors
[iter
].used
)
193 iodesc
= &ha
->io_descriptors
[iter
];
196 init_timer(&iodesc
->timer
);
198 iodesc
->signature
= qla2x00_iodesc_to_handle(iodesc
);
206 * qla2x00_free_iodesc() - Free an IO descriptor.
207 * @iodesc: io descriptor
209 * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
212 qla2x00_free_iodesc(struct io_descriptor
*iodesc
)
215 iodesc
->signature
= 0;
219 * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
220 * @iodesc: io descriptor
223 qla2x00_remove_iodesc_timer(struct io_descriptor
*iodesc
)
225 if (iodesc
->timer
.function
!= NULL
) {
226 del_timer_sync(&iodesc
->timer
);
227 iodesc
->timer
.data
= (unsigned long) NULL
;
228 iodesc
->timer
.function
= NULL
;
233 * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
237 qla2x00_init_io_descriptors(scsi_qla_host_t
*ha
)
241 for (iter
= 0; iter
< MAX_IO_DESCRIPTORS
; iter
++) {
242 if (!ha
->io_descriptors
[iter
].used
)
245 qla2x00_remove_iodesc_timer(&ha
->io_descriptors
[iter
]);
246 qla2x00_free_iodesc(&ha
->io_descriptors
[iter
]);
252 * IO descriptor timer routines.
256 * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
257 * @data: io descriptor
260 qla2x00_iodesc_timeout(unsigned long data
)
262 struct io_descriptor
*iodesc
;
264 iodesc
= (struct io_descriptor
*) data
;
266 DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
267 "signature=%08x, scheduling ISP abort.\n", iodesc
->ha
->host_no
,
268 iodesc
->idx
, iodesc
->signature
));
270 qla2x00_free_iodesc(iodesc
);
272 qla_printk(KERN_WARNING
, iodesc
->ha
,
273 "IO descriptor timeout. Scheduling ISP abort.\n");
274 set_bit(ISP_ABORT_NEEDED
, &iodesc
->ha
->dpc_flags
);
278 * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
279 * @iodesc: io descriptor
282 * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
283 * tenths of a second) after it hits the wire. But, if there are any request
284 * resource contraints (i.e. during heavy I/O), exchanges can be held off for
285 * at most R_A_TOV. Therefore, the driver will wait 4 * R_A_TOV before
286 * scheduling a recovery (big hammer).
289 qla2x00_add_iodesc_timer(struct io_descriptor
*iodesc
)
291 unsigned long timeout
;
293 timeout
= (iodesc
->ha
->r_a_tov
* 4) / 10;
294 init_timer(&iodesc
->timer
);
295 iodesc
->timer
.data
= (unsigned long) iodesc
;
296 iodesc
->timer
.expires
= jiffies
+ (timeout
* HZ
);
297 iodesc
->timer
.function
=
298 (void (*) (unsigned long)) qla2x00_iodesc_timeout
;
299 add_timer(&iodesc
->timer
);
303 * IO descriptor support routines.
307 * qla2x00_update_login_fcport() - Update fcport data after login processing.
309 * @mbxstat: Mailbox command status IOCB
310 * @fcport: port to update
313 qla2x00_update_login_fcport(scsi_qla_host_t
*ha
, struct mbx_entry
*mbxstat
,
316 if (le16_to_cpu(mbxstat
->mb1
) & BIT_0
) {
317 fcport
->port_type
= FCT_INITIATOR
;
319 fcport
->port_type
= FCT_TARGET
;
320 if (le16_to_cpu(mbxstat
->mb1
) & BIT_1
) {
321 fcport
->flags
|= FCF_TAPE_PRESENT
;
324 fcport
->login_retry
= 0;
325 fcport
->port_login_retry_count
= ha
->port_down_retry_count
*
327 atomic_set(&fcport
->port_down_timer
, ha
->port_down_retry_count
*
329 fcport
->flags
|= FCF_FABRIC_DEVICE
;
330 fcport
->flags
&= ~FCF_FAILOVER_NEEDED
;
331 fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
332 atomic_set(&fcport
->state
, FCS_ONLINE
);
337 * Mailbox IOCB commands.
341 * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
343 * @handle: handle to io descriptor
345 * Returns a pointer to the reqest entry, or NULL, if none were available.
347 static inline struct mbx_entry
*
348 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t
*ha
, uint32_t handle
)
351 device_reg_t __iomem
*reg
= ha
->iobase
;
352 struct mbx_entry
*mbxentry
;
356 if (ha
->req_q_cnt
< 3) {
357 cnt
= qla2x00_debounce_register(ISP_REQ_Q_OUT(ha
, reg
));
358 if (ha
->req_ring_index
< cnt
)
359 ha
->req_q_cnt
= cnt
- ha
->req_ring_index
;
361 ha
->req_q_cnt
= ha
->request_q_length
-
362 (ha
->req_ring_index
- cnt
);
364 if (ha
->req_q_cnt
>= 3) {
365 mbxentry
= (struct mbx_entry
*)ha
->request_ring_ptr
;
367 memset(mbxentry
, 0, sizeof(struct mbx_entry
));
368 mbxentry
->entry_type
= MBX_IOCB_TYPE
;
369 mbxentry
->entry_count
= 1;
370 mbxentry
->sys_define1
= SOURCE_ASYNC_IOCB
;
371 mbxentry
->handle
= handle
;
377 * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
379 * @iodesc: io descriptor
380 * @handle_to_abort: firmware handle to abort
381 * @ha_locked: is function called with the hardware lock
383 * Returns QLA_SUCCESS if the IOCB was issued.
386 qla2x00_send_abort_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
387 uint32_t handle_to_abort
, int ha_locked
)
389 unsigned long flags
= 0;
390 struct mbx_entry
*mbxentry
;
392 /* Send marker if required. */
393 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
394 return (QLA_FUNCTION_FAILED
);
397 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
399 /* Build abort mailbox IOCB. */
400 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
401 if (mbxentry
== NULL
) {
403 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
405 return (QLA_FUNCTION_FAILED
);
407 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_ABORT_COMMAND
);
408 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
409 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
410 mbxentry
->mb2
= LSW(handle_to_abort
);
411 mbxentry
->mb3
= MSW(handle_to_abort
);
414 qla2x00_add_iodesc_timer(iodesc
);
416 /* Issue command to ISP. */
420 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
422 DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
423 "%08x.\n", ha
->host_no
, iodesc
->signature
,
424 iodesc
->remote_fcport
->loop_id
, handle_to_abort
));
426 return (QLA_SUCCESS
);
430 * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
432 * @iodesc: io descriptor
433 * @mbxstat: mailbox status IOCB
435 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
436 * will be used for a retry.
439 qla2x00_send_abort_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
440 struct mbx_entry
*mbxstat
)
442 DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
443 "status=%x mb0=%x.\n", ha
->host_no
, iodesc
->remote_fcport
->loop_id
,
444 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
,
445 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
447 return (QLA_SUCCESS
);
452 * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
454 * @iodesc: io descriptor
455 * @ha_locked: is function called with the hardware lock
457 * Returns QLA_SUCCESS if the IOCB was issued.
460 qla2x00_send_adisc_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
463 unsigned long flags
= 0;
464 struct mbx_entry
*mbxentry
;
466 /* Send marker if required. */
467 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
468 return (QLA_FUNCTION_FAILED
);
471 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
473 /* Build Get Port Database IOCB. */
474 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
475 if (mbxentry
== NULL
) {
477 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
479 return (QLA_FUNCTION_FAILED
);
481 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_GET_PORT_DATABASE
);
482 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
483 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
484 mbxentry
->mb2
= cpu_to_le16(MSW(LSD(ha
->iodesc_pd_dma
)));
485 mbxentry
->mb3
= cpu_to_le16(LSW(LSD(ha
->iodesc_pd_dma
)));
486 mbxentry
->mb6
= cpu_to_le16(MSW(MSD(ha
->iodesc_pd_dma
)));
487 mbxentry
->mb7
= cpu_to_le16(LSW(MSD(ha
->iodesc_pd_dma
)));
488 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
491 qla2x00_add_iodesc_timer(iodesc
);
493 /* Issue command to ISP. */
497 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
499 DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
500 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
502 return (QLA_SUCCESS
);
506 * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
508 * @iodesc: io descriptor
509 * @mbxstat: mailbox status IOCB
511 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
512 * will be used for a retry.
515 qla2x00_send_adisc_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
516 struct mbx_entry
*mbxstat
)
518 fc_port_t
*remote_fcport
;
520 remote_fcport
= iodesc
->remote_fcport
;
522 /* Ensure the port IDs are consistent. */
523 if (remote_fcport
->d_id
.b24
!= iodesc
->d_id
.b24
) {
524 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
525 "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
526 ha
->host_no
, remote_fcport
->d_id
.b
.domain
,
527 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
528 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
529 iodesc
->d_id
.b
.al_pa
));
531 return (QLA_SUCCESS
);
534 /* Only process the last command. */
535 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
536 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
537 "[%02x%02x%02x], expected %x, received %x.\n", ha
->host_no
,
538 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
539 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
542 return (QLA_SUCCESS
);
545 if (le16_to_cpu(mbxstat
->status
) == CS_COMPLETE
) {
546 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
547 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
548 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
549 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
551 atomic_set(&remote_fcport
->state
, FCS_ONLINE
);
553 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
554 "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha
->host_no
,
555 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
556 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
557 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
559 if (atomic_read(&remote_fcport
->state
) != FCS_DEVICE_DEAD
)
560 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
562 remote_fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
564 return (QLA_SUCCESS
);
569 * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
571 * @iodesc: io descriptor
572 * @ha_locked: is function called with the hardware lock
574 * Returns QLA_SUCCESS if the IOCB was issued.
577 qla2x00_send_logout_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
580 unsigned long flags
= 0;
581 struct mbx_entry
*mbxentry
;
583 /* Send marker if required. */
584 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
585 return (QLA_FUNCTION_FAILED
);
588 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
590 /* Build fabric port logout mailbox IOCB. */
591 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
592 if (mbxentry
== NULL
) {
594 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
596 return (QLA_FUNCTION_FAILED
);
598 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT
);
599 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
600 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
603 qla2x00_add_iodesc_timer(iodesc
);
605 /* Issue command to ISP. */
609 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
611 DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
612 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
614 return (QLA_SUCCESS
);
618 * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
620 * @iodesc: io descriptor
621 * @mbxstat: mailbox status IOCB
623 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
624 * will be used for a retry.
627 qla2x00_send_logout_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
628 struct mbx_entry
*mbxstat
)
630 DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
631 "status=%x mb0=%x mb1=%x.\n", ha
->host_no
,
632 iodesc
->remote_fcport
->loop_id
,
633 iodesc
->remote_fcport
->d_id
.b
.domain
,
634 iodesc
->remote_fcport
->d_id
.b
.area
,
635 iodesc
->remote_fcport
->d_id
.b
.al_pa
, le16_to_cpu(mbxstat
->status
),
636 le16_to_cpu(mbxstat
->mb0
), le16_to_cpu(mbxstat
->mb1
)));
638 return (QLA_SUCCESS
);
643 * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
645 * @iodesc: io descriptor
646 * @d_id: port id for device
647 * @ha_locked: is function called with the hardware lock
649 * Returns QLA_SUCCESS if the IOCB was issued.
652 qla2x00_send_login_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
653 port_id_t
*d_id
, int ha_locked
)
655 unsigned long flags
= 0;
656 struct mbx_entry
*mbxentry
;
658 /* Send marker if required. */
659 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
660 return (QLA_FUNCTION_FAILED
);
663 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
665 /* Build fabric port login mailbox IOCB. */
666 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
667 if (mbxentry
== NULL
) {
669 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
671 return (QLA_FUNCTION_FAILED
);
673 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT
);
674 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
675 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
676 mbxentry
->mb2
= cpu_to_le16(d_id
->b
.domain
);
677 mbxentry
->mb3
= cpu_to_le16(d_id
->b
.area
<< 8 | d_id
->b
.al_pa
);
678 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
681 qla2x00_add_iodesc_timer(iodesc
);
683 /* Issue command to ISP. */
687 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
689 DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
690 "[%x/%02x%02x%02x].\n", ha
->host_no
, iodesc
->signature
,
691 iodesc
->remote_fcport
->loop_id
, d_id
->b
.domain
, d_id
->b
.area
,
694 return (QLA_SUCCESS
);
698 * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
700 * @iodesc: io descriptor
701 * @mbxstat: mailbox status IOCB
703 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
704 * will be used for a retry.
707 qla2x00_send_login_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
708 struct mbx_entry
*mbxstat
)
711 fc_port_t
*fcport
, *remote_fcport
, *exist_fcport
;
712 struct io_descriptor
*abort_iodesc
, *login_iodesc
;
713 uint16_t status
, mb
[8];
715 uint16_t remote_loopid
;
716 port_id_t remote_did
, inuse_did
;
718 remote_fcport
= iodesc
->remote_fcport
;
720 /* Only process the last command. */
721 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
722 DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
723 "[%02x%02x%02x], expected %x, received %x.\n",
724 ha
->host_no
, iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
725 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
728 /* Free RSCN fcport resources. */
729 if (remote_fcport
->port_type
== FCT_RSCN
) {
730 DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
731 "fcport %p [%x/%02x%02x%02x] given ignored Login "
732 "IOCB.\n", ha
->host_no
, remote_fcport
,
733 remote_fcport
->loop_id
,
734 remote_fcport
->d_id
.b
.domain
,
735 remote_fcport
->d_id
.b
.area
,
736 remote_fcport
->d_id
.b
.al_pa
));
738 list_del(&remote_fcport
->list
);
739 kfree(remote_fcport
);
741 return (QLA_SUCCESS
);
744 status
= le16_to_cpu(mbxstat
->status
);
745 mb
[0] = le16_to_cpu(mbxstat
->mb0
);
746 mb
[1] = le16_to_cpu(mbxstat
->mb1
);
747 mb
[2] = le16_to_cpu(mbxstat
->mb2
);
748 mb
[6] = le16_to_cpu(mbxstat
->mb6
);
749 mb
[7] = le16_to_cpu(mbxstat
->mb7
);
752 if ((status
== CS_COMPLETE
|| status
== CS_COMPLETE_CHKCOND
) &&
753 mb
[0] == MBS_COMMAND_COMPLETE
) {
755 DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
756 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha
->host_no
, status
,
757 mb
[1], mbxstat
->port_name
[0], mbxstat
->port_name
[1],
758 mbxstat
->port_name
[2], mbxstat
->port_name
[3],
759 mbxstat
->port_name
[4], mbxstat
->port_name
[5],
760 mbxstat
->port_name
[6], mbxstat
->port_name
[7]));
762 memcpy(remote_fcport
->node_name
, mbxstat
->node_name
, WWN_SIZE
);
763 memcpy(remote_fcport
->port_name
, mbxstat
->port_name
, WWN_SIZE
);
765 /* Is the device already in our fcports list? */
766 if (remote_fcport
->port_type
!= FCT_RSCN
) {
767 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
768 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
769 remote_fcport
->loop_id
,
770 remote_fcport
->d_id
.b
.domain
,
771 remote_fcport
->d_id
.b
.area
,
772 remote_fcport
->d_id
.b
.al_pa
));
774 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
776 return (QLA_SUCCESS
);
779 /* Does the RSCN portname already exist in our fcports list? */
781 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
782 if (memcmp(remote_fcport
->port_name
, fcport
->port_name
,
784 exist_fcport
= fcport
;
788 if (exist_fcport
!= NULL
) {
789 DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
790 "fcport in fcports list [%p].\n", ha
->host_no
,
793 /* Abort any ADISC that could have been sent. */
794 if (exist_fcport
->iodesc_idx_sent
!= iodesc
->idx
&&
795 exist_fcport
->iodesc_idx_sent
<
796 MAX_IO_DESCRIPTORS
&&
797 ha
->io_descriptors
[exist_fcport
->iodesc_idx_sent
].
798 cb_idx
== ADISC_PORT_IOCB_CB
) {
800 abort_iodesc
= qla2x00_alloc_iodesc(ha
);
802 DEBUG14(printk("scsi(%ld): Login IOCB "
803 "-- issuing abort to outstanding "
804 "Adisc [%x/%02x%02x%02x].\n",
805 ha
->host_no
, remote_fcport
->loop_id
,
806 exist_fcport
->d_id
.b
.domain
,
807 exist_fcport
->d_id
.b
.area
,
808 exist_fcport
->d_id
.b
.al_pa
));
810 abort_iodesc
->cb_idx
= ABORT_IOCB_CB
;
811 abort_iodesc
->d_id
.b24
=
812 exist_fcport
->d_id
.b24
;
813 abort_iodesc
->remote_fcport
=
815 exist_fcport
->iodesc_idx_sent
=
817 qla2x00_send_abort_iocb(ha
,
818 abort_iodesc
, ha
->io_descriptors
[
819 exist_fcport
->iodesc_idx_sent
].
822 DEBUG14(printk("scsi(%ld): Login IOCB "
823 "-- unable to abort outstanding "
824 "Adisc [%x/%02x%02x%02x].\n",
825 ha
->host_no
, remote_fcport
->loop_id
,
826 exist_fcport
->d_id
.b
.domain
,
827 exist_fcport
->d_id
.b
.area
,
828 exist_fcport
->d_id
.b
.al_pa
));
833 * If the existing fcport is waiting to send an ADISC
834 * or LOGIN, then reuse remote fcport (RSCN) to
838 remote_loopid
= remote_fcport
->loop_id
;
839 remote_did
.b24
= remote_fcport
->d_id
.b24
;
840 if (exist_fcport
->iodesc_idx_sent
==
841 IODESC_ADISC_NEEDED
||
842 exist_fcport
->iodesc_idx_sent
==
843 IODESC_LOGIN_NEEDED
) {
844 DEBUG14(printk("scsi(%ld): Login IOCB -- "
845 "existing fcport [%x/%02x%02x%02x] "
846 "waiting for IO descriptor, reuse RSCN "
847 "fcport.\n", ha
->host_no
,
848 exist_fcport
->loop_id
,
849 exist_fcport
->d_id
.b
.domain
,
850 exist_fcport
->d_id
.b
.area
,
851 exist_fcport
->d_id
.b
.al_pa
));
854 remote_fcport
->iodesc_idx_sent
=
855 exist_fcport
->iodesc_idx_sent
;
856 exist_fcport
->iodesc_idx_sent
=
857 IODESC_INVALID_INDEX
;
858 remote_fcport
->loop_id
= exist_fcport
->loop_id
;
859 remote_fcport
->d_id
.b24
=
860 exist_fcport
->d_id
.b24
;
863 /* Logout the old loopid. */
865 exist_fcport
->loop_id
!= remote_fcport
->loop_id
&&
866 exist_fcport
->loop_id
!= FC_NO_LOOP_ID
) {
867 login_iodesc
= qla2x00_alloc_iodesc(ha
);
869 DEBUG14(printk("scsi(%ld): Login IOCB "
870 "-- issuing logout to free old "
871 "loop id [%x/%02x%02x%02x].\n",
872 ha
->host_no
, exist_fcport
->loop_id
,
873 exist_fcport
->d_id
.b
.domain
,
874 exist_fcport
->d_id
.b
.area
,
875 exist_fcport
->d_id
.b
.al_pa
));
877 login_iodesc
->cb_idx
=
879 login_iodesc
->d_id
.b24
=
880 exist_fcport
->d_id
.b24
;
881 login_iodesc
->remote_fcport
=
883 exist_fcport
->iodesc_idx_sent
=
885 qla2x00_send_logout_iocb(ha
,
888 /* Ran out of IO descriptiors. */
889 DEBUG14(printk("scsi(%ld): Login IOCB "
890 "-- unable to logout to free old "
891 "loop id [%x/%02x%02x%02x].\n",
892 ha
->host_no
, exist_fcport
->loop_id
,
893 exist_fcport
->d_id
.b
.domain
,
894 exist_fcport
->d_id
.b
.area
,
895 exist_fcport
->d_id
.b
.al_pa
));
897 exist_fcport
->iodesc_idx_sent
=
898 IODESC_INVALID_INDEX
;
903 /* Update existing fcport with remote fcport info. */
904 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
905 "existing fcport [%x/%02x%02x%02x] online.\n",
906 ha
->host_no
, remote_loopid
, remote_did
.b
.domain
,
907 remote_did
.b
.area
, remote_did
.b
.al_pa
));
909 memcpy(exist_fcport
->node_name
,
910 remote_fcport
->node_name
, WWN_SIZE
);
911 exist_fcport
->loop_id
= remote_loopid
;
912 exist_fcport
->d_id
.b24
= remote_did
.b24
;
913 qla2x00_update_login_fcport(ha
, mbxstat
, exist_fcport
);
915 /* Finally, free the remote (RSCN) fcport. */
917 DEBUG14(printk("scsi(%ld): Login IOCB -- "
918 "Freeing RSCN fcport %p "
919 "[%x/%02x%02x%02x].\n", ha
->host_no
,
920 remote_fcport
, remote_fcport
->loop_id
,
921 remote_fcport
->d_id
.b
.domain
,
922 remote_fcport
->d_id
.b
.area
,
923 remote_fcport
->d_id
.b
.al_pa
));
925 list_del(&remote_fcport
->list
);
926 kfree(remote_fcport
);
929 return (QLA_SUCCESS
);
933 * A new device has been added, move the RSCN fcport to our
936 DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
937 "[%x/%02x%02x%02x] to fcports list.\n", ha
->host_no
,
938 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
939 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
941 list_del(&remote_fcport
->list
);
942 remote_fcport
->flags
= (FCF_RLC_SUPPORT
| FCF_RESCAN_NEEDED
);
943 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
944 list_add_tail(&remote_fcport
->list
, &ha
->fcports
);
945 set_bit(FCPORT_RESCAN_NEEDED
, &ha
->dpc_flags
);
947 /* Handle login failure. */
948 if (remote_fcport
->login_retry
!= 0) {
949 if (mb
[0] == MBS_LOOP_ID_USED
) {
950 inuse_did
.b
.domain
= LSB(mb
[1]);
951 inuse_did
.b
.area
= MSB(mb
[2]);
952 inuse_did
.b
.al_pa
= LSB(mb
[2]);
954 DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
955 "id [%x] used by port id [%02x%02x%02x].\n",
956 ha
->host_no
, remote_fcport
->loop_id
,
957 inuse_did
.b
.domain
, inuse_did
.b
.area
,
960 if (remote_fcport
->d_id
.b24
==
963 * Invalid port id means we are trying
964 * to login to a remote port with just
965 * a loop id without knowing about the
966 * port id. Copy the port id and try
969 remote_fcport
->d_id
.b24
= inuse_did
.b24
;
970 iodesc
->d_id
.b24
= inuse_did
.b24
;
972 remote_fcport
->loop_id
++;
973 rval
= qla2x00_find_new_loop_id(ha
,
975 if (rval
== QLA_FUNCTION_FAILED
) {
976 /* No more loop ids. */
977 return (QLA_SUCCESS
);
980 } else if (mb
[0] == MBS_PORT_ID_USED
) {
982 * Device has another loop ID. The firmware
983 * group recommends the driver perform an
984 * implicit login with the specified ID.
986 DEBUG14(printk("scsi(%ld): Login IOCB -- port "
987 "id [%02x%02x%02x] already assigned to "
988 "loop id [%x].\n", ha
->host_no
,
989 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
990 iodesc
->d_id
.b
.al_pa
, mb
[1]));
992 remote_fcport
->loop_id
= mb
[1];
995 /* Unable to perform login, try again. */
996 DEBUG14(printk("scsi(%ld): Login IOCB -- "
997 "failed login [%x/%02x%02x%02x], status=%x "
998 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
999 ha
->host_no
, remote_fcport
->loop_id
,
1000 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1001 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
1002 mb
[2], mb
[6], mb
[7]));
1005 /* Reissue Login with the same IO descriptor. */
1007 qla2x00_iodesc_to_handle(iodesc
);
1008 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
1009 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
1010 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1011 remote_fcport
->login_retry
--;
1013 DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
1014 "login to [%x/%02x%02x%02x] (%d).\n", ha
->host_no
,
1015 remote_fcport
->loop_id
,
1016 remote_fcport
->d_id
.b
.domain
,
1017 remote_fcport
->d_id
.b
.area
,
1018 remote_fcport
->d_id
.b
.al_pa
,
1019 remote_fcport
->login_retry
));
1021 qla2x00_send_login_iocb(ha
, iodesc
,
1022 &remote_fcport
->d_id
, 1);
1024 return (QLA_FUNCTION_FAILED
);
1026 /* No more logins, mark device dead. */
1027 DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
1028 "login [%x/%02x%02x%02x] after retries, status=%x "
1029 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1030 ha
->host_no
, remote_fcport
->loop_id
,
1031 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1032 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
1033 mb
[2], mb
[6], mb
[7]));
1035 atomic_set(&remote_fcport
->state
, FCS_DEVICE_DEAD
);
1036 if (remote_fcport
->port_type
== FCT_RSCN
) {
1037 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1038 "Freeing dead RSCN fcport %p "
1039 "[%x/%02x%02x%02x].\n", ha
->host_no
,
1040 remote_fcport
, remote_fcport
->loop_id
,
1041 remote_fcport
->d_id
.b
.domain
,
1042 remote_fcport
->d_id
.b
.area
,
1043 remote_fcport
->d_id
.b
.al_pa
));
1045 list_del(&remote_fcport
->list
);
1046 kfree(remote_fcport
);
1051 return (QLA_SUCCESS
);
1056 * IO descriptor processing routines.
1060 * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
1062 * @flags: allocation flags
1064 * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
1067 qla2x00_alloc_rscn_fcport(scsi_qla_host_t
*ha
, int flags
)
1071 fcport
= qla2x00_alloc_fcport(ha
, flags
);
1075 /* Setup RSCN fcport structure. */
1076 fcport
->port_type
= FCT_RSCN
;
1082 * qla2x00_handle_port_rscn() - Handle port RSCN.
1084 * @rscn_entry: RSCN entry
1085 * @fcport: fcport entry to updated
1087 * Returns QLA_SUCCESS if the port RSCN was handled.
1090 qla2x00_handle_port_rscn(scsi_qla_host_t
*ha
, uint32_t rscn_entry
,
1091 fc_port_t
*known_fcport
, int ha_locked
)
1095 fc_port_t
*fcport
, *remote_fcport
, *rscn_fcport
;
1096 struct io_descriptor
*iodesc
;
1098 remote_fcport
= NULL
;
1101 /* Prepare port id based on incoming entries. */
1103 rscn_pid
.b24
= known_fcport
->d_id
.b24
;
1104 remote_fcport
= known_fcport
;
1106 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1107 "fcport [%02x%02x%02x].\n", ha
->host_no
,
1108 remote_fcport
->d_id
.b
.domain
, remote_fcport
->d_id
.b
.area
,
1109 remote_fcport
->d_id
.b
.al_pa
));
1111 rscn_pid
.b
.domain
= LSB(MSW(rscn_entry
));
1112 rscn_pid
.b
.area
= MSB(LSW(rscn_entry
));
1113 rscn_pid
.b
.al_pa
= LSB(LSW(rscn_entry
));
1115 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1116 "port id [%02x%02x%02x].\n", ha
->host_no
,
1117 rscn_pid
.b
.domain
, rscn_pid
.b
.area
, rscn_pid
.b
.al_pa
));
1120 * Search fcport lists for a known entry at the specified port
1123 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1124 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1125 remote_fcport
= fcport
;
1129 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1130 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1131 rscn_fcport
= fcport
;
1135 if (remote_fcport
== NULL
)
1136 remote_fcport
= rscn_fcport
;
1140 * If the port is already in our fcport list and online, send an ADISC
1141 * to see if it's still alive. Issue login if a new fcport or the known
1142 * fcport is currently offline.
1144 if (remote_fcport
) {
1146 * No need to send request if the remote fcport is currently
1147 * waiting for an available io descriptor.
1149 if (known_fcport
== NULL
&&
1150 (remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1151 remote_fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
)) {
1153 * If previous waiting io descriptor is an ADISC, then
1154 * the new RSCN may come from a new remote fcport being
1155 * plugged into the same location.
1157 if (remote_fcport
->port_type
== FCT_RSCN
) {
1158 remote_fcport
->iodesc_idx_sent
=
1159 IODESC_LOGIN_NEEDED
;
1160 } else if (remote_fcport
->iodesc_idx_sent
==
1161 IODESC_ADISC_NEEDED
) {
1162 fc_port_t
*new_fcport
;
1164 remote_fcport
->iodesc_idx_sent
=
1165 IODESC_INVALID_INDEX
;
1167 /* Create new fcport for later login. */
1168 new_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1169 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1171 DEBUG14(printk("scsi(%ld): Handle RSCN "
1172 "-- creating RSCN fcport %p for "
1173 "future login.\n", ha
->host_no
,
1176 new_fcport
->d_id
.b24
=
1177 remote_fcport
->d_id
.b24
;
1178 new_fcport
->iodesc_idx_sent
=
1179 IODESC_LOGIN_NEEDED
;
1181 list_add_tail(&new_fcport
->list
,
1183 set_bit(IODESC_PROCESS_NEEDED
,
1186 DEBUG14(printk("scsi(%ld): Handle RSCN "
1187 "-- unable to allocate RSCN fcport "
1188 "for future login.\n",
1192 return (QLA_SUCCESS
);
1195 /* Send ADISC if the fcport is online */
1196 if (atomic_read(&remote_fcport
->state
) == FCS_ONLINE
||
1197 remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
) {
1199 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1201 iodesc
= qla2x00_alloc_iodesc(ha
);
1202 if (iodesc
== NULL
) {
1203 /* Mark fcport for later adisc processing */
1204 DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
1205 "enough IO descriptors for Adisc, flag "
1206 "for later processing.\n", ha
->host_no
));
1208 remote_fcport
->iodesc_idx_sent
=
1209 IODESC_ADISC_NEEDED
;
1210 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1212 return (QLA_SUCCESS
);
1215 iodesc
->cb_idx
= ADISC_PORT_IOCB_CB
;
1216 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1217 iodesc
->remote_fcport
= remote_fcport
;
1218 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1219 qla2x00_send_adisc_iocb(ha
, iodesc
, ha_locked
);
1221 return (QLA_SUCCESS
);
1222 } else if (remote_fcport
->iodesc_idx_sent
<
1223 MAX_IO_DESCRIPTORS
&&
1224 ha
->io_descriptors
[remote_fcport
->iodesc_idx_sent
].cb_idx
==
1225 ADISC_PORT_IOCB_CB
) {
1227 * Receiving another RSCN while an ADISC is pending,
1228 * abort the IOCB. Use the same descriptor for the
1231 uint32_t handle_to_abort
;
1233 iodesc
= &ha
->io_descriptors
[
1234 remote_fcport
->iodesc_idx_sent
];
1235 qla2x00_remove_iodesc_timer(iodesc
);
1236 handle_to_abort
= iodesc
->signature
;
1237 iodesc
->signature
= qla2x00_iodesc_to_handle(iodesc
);
1238 iodesc
->cb_idx
= ABORT_IOCB_CB
;
1239 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
1240 iodesc
->remote_fcport
= remote_fcport
;
1241 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1243 DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
1244 "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
1245 ha
->host_no
, remote_fcport
->loop_id
,
1246 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1247 iodesc
->d_id
.b
.al_pa
));
1249 qla2x00_send_abort_iocb(ha
, iodesc
, handle_to_abort
,
1254 /* We need to login to the remote port, find it. */
1256 remote_fcport
= known_fcport
;
1257 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1258 rscn_fcport
->iodesc_idx_sent
< MAX_IO_DESCRIPTORS
&&
1259 ha
->io_descriptors
[rscn_fcport
->iodesc_idx_sent
].cb_idx
==
1260 LOGIN_PORT_IOCB_CB
) {
1262 * Ignore duplicate RSCN on fcport which has already
1263 * initiated a login IOCB.
1265 DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
1266 "already sent to [%02x%02x%02x].\n", ha
->host_no
,
1267 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1268 rscn_fcport
->d_id
.b
.al_pa
));
1270 return (QLA_SUCCESS
);
1271 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1272 rscn_fcport
!= remote_fcport
) {
1273 /* Reuse same rscn fcport. */
1274 DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
1275 "[%02x%02x%02x].\n", ha
->host_no
,
1276 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1277 rscn_fcport
->d_id
.b
.al_pa
));
1279 remote_fcport
= rscn_fcport
;
1281 /* Create new fcport for later login. */
1282 remote_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1283 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1284 list_add_tail(&remote_fcport
->list
, &ha
->rscn_fcports
);
1286 if (remote_fcport
== NULL
)
1287 return (QLA_SUCCESS
);
1289 /* Prepare fcport for login. */
1290 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1291 remote_fcport
->login_retry
= 3; /* ha->login_retry_count; */
1292 remote_fcport
->d_id
.b24
= rscn_pid
.b24
;
1294 iodesc
= qla2x00_alloc_iodesc(ha
);
1295 if (iodesc
== NULL
) {
1296 /* Mark fcport for later adisc processing. */
1297 DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
1298 "descriptors for Login, flag for later processing.\n",
1301 remote_fcport
->iodesc_idx_sent
= IODESC_LOGIN_NEEDED
;
1302 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1304 return (QLA_SUCCESS
);
1307 if (known_fcport
== NULL
|| rscn_pid
.b24
!= INVALID_PORT_ID
) {
1308 remote_fcport
->loop_id
= ha
->min_external_loopid
;
1310 rval
= qla2x00_find_new_loop_id(ha
, remote_fcport
);
1311 if (rval
== QLA_FUNCTION_FAILED
) {
1312 /* No more loop ids, failed. */
1313 DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
1314 "loop id to perform Login, failed.\n",
1321 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
1322 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1323 iodesc
->remote_fcport
= remote_fcport
;
1324 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1326 DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
1327 "[%x/%02x%02x%02x].\n", ha
->host_no
, remote_fcport
->loop_id
,
1328 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
));
1330 qla2x00_send_login_iocb(ha
, iodesc
, &rscn_pid
, ha_locked
);
1332 return (QLA_SUCCESS
);
1336 * qla2x00_process_iodesc() - Complete IO descriptor processing.
1338 * @mbxstat: Mailbox IOCB status
1341 qla2x00_process_iodesc(scsi_qla_host_t
*ha
, struct mbx_entry
*mbxstat
)
1346 struct io_descriptor
*iodesc
;
1348 signature
= mbxstat
->handle
;
1350 DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
1351 ha
->host_no
, signature
));
1353 /* Retrieve proper IO descriptor. */
1354 iodesc
= qla2x00_handle_to_iodesc(ha
, signature
);
1355 if (iodesc
== NULL
) {
1356 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1357 "incorrect signature %08x.\n", ha
->host_no
, signature
));
1362 /* Stop IO descriptor timer. */
1363 qla2x00_remove_iodesc_timer(iodesc
);
1365 /* Verify signature match. */
1366 if (iodesc
->signature
!= signature
) {
1367 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1368 "signature mismatch, sent %08x, received %08x.\n",
1369 ha
->host_no
, iodesc
->signature
, signature
));
1374 /* Go with IOCB callback. */
1375 rval
= iocb_function_cb_list
[iodesc
->cb_idx
](ha
, iodesc
, mbxstat
);
1376 if (rval
!= QLA_SUCCESS
) {
1377 /* IO descriptor reused by callback. */
1381 qla2x00_free_iodesc(iodesc
);
1383 if (test_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
)) {
1384 /* Scan our fcports list for any RSCN requests. */
1385 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1386 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1387 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1388 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1393 /* Scan our RSCN fcports list for any RSCN requests. */
1394 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1395 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1396 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1397 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1402 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1406 * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
1409 * This routine will also delete any RSCN entries related to the outstanding
1413 qla2x00_cancel_io_descriptors(scsi_qla_host_t
*ha
)
1415 fc_port_t
*fcport
, *fcptemp
;
1417 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1419 /* Abort all IO descriptors. */
1420 qla2x00_init_io_descriptors(ha
);
1422 /* Reset all pending IO descriptors in fcports list. */
1423 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1424 fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
1427 /* Reset all pending IO descriptors in rscn fcports list. */
1428 list_for_each_entry_safe(fcport
, fcptemp
, &ha
->rscn_fcports
, list
) {
1429 DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
1430 "%p [%x/%02x%02x%02x].\n", ha
->host_no
, fcport
,
1431 fcport
->loop_id
, fcport
->d_id
.b
.domain
, fcport
->d_id
.b
.area
,
1432 fcport
->d_id
.b
.al_pa
));
1434 list_del(&fcport
->list
);