2 * QLOGIC LINUX SOFTWARE
4 * QLogic ISP2x00 device driver for Linux 2.6.x
5 * Copyright (C) 2003-2005 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
);
334 fc_remote_port_unblock(fcport
->rport
);
339 * Mailbox IOCB commands.
343 * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
345 * @handle: handle to io descriptor
347 * Returns a pointer to the reqest entry, or NULL, if none were available.
349 static inline struct mbx_entry
*
350 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t
*ha
, uint32_t handle
)
353 struct device_reg_2xxx __iomem
*reg
= &ha
->iobase
->isp
;
354 struct mbx_entry
*mbxentry
;
358 if (ha
->req_q_cnt
< 3) {
359 cnt
= qla2x00_debounce_register(ISP_REQ_Q_OUT(ha
, reg
));
360 if (ha
->req_ring_index
< cnt
)
361 ha
->req_q_cnt
= cnt
- ha
->req_ring_index
;
363 ha
->req_q_cnt
= ha
->request_q_length
-
364 (ha
->req_ring_index
- cnt
);
366 if (ha
->req_q_cnt
>= 3) {
367 mbxentry
= (struct mbx_entry
*)ha
->request_ring_ptr
;
369 memset(mbxentry
, 0, sizeof(struct mbx_entry
));
370 mbxentry
->entry_type
= MBX_IOCB_TYPE
;
371 mbxentry
->entry_count
= 1;
372 mbxentry
->sys_define1
= SOURCE_ASYNC_IOCB
;
373 mbxentry
->handle
= handle
;
379 * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
381 * @iodesc: io descriptor
382 * @handle_to_abort: firmware handle to abort
383 * @ha_locked: is function called with the hardware lock
385 * Returns QLA_SUCCESS if the IOCB was issued.
388 qla2x00_send_abort_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
389 uint32_t handle_to_abort
, int ha_locked
)
391 unsigned long flags
= 0;
392 struct mbx_entry
*mbxentry
;
394 /* Send marker if required. */
395 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
396 return (QLA_FUNCTION_FAILED
);
399 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
401 /* Build abort mailbox IOCB. */
402 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
403 if (mbxentry
== NULL
) {
405 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
407 return (QLA_FUNCTION_FAILED
);
409 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_ABORT_COMMAND
);
410 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
411 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
412 mbxentry
->mb2
= LSW(handle_to_abort
);
413 mbxentry
->mb3
= MSW(handle_to_abort
);
416 qla2x00_add_iodesc_timer(iodesc
);
418 /* Issue command to ISP. */
422 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
424 DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
425 "%08x.\n", ha
->host_no
, iodesc
->signature
,
426 iodesc
->remote_fcport
->loop_id
, handle_to_abort
));
428 return (QLA_SUCCESS
);
432 * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
434 * @iodesc: io descriptor
435 * @mbxstat: mailbox status IOCB
437 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
438 * will be used for a retry.
441 qla2x00_send_abort_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
442 struct mbx_entry
*mbxstat
)
444 DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
445 "status=%x mb0=%x.\n", ha
->host_no
, iodesc
->remote_fcport
->loop_id
,
446 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
,
447 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
449 return (QLA_SUCCESS
);
454 * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
456 * @iodesc: io descriptor
457 * @ha_locked: is function called with the hardware lock
459 * Returns QLA_SUCCESS if the IOCB was issued.
462 qla2x00_send_adisc_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
465 unsigned long flags
= 0;
466 struct mbx_entry
*mbxentry
;
468 /* Send marker if required. */
469 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
470 return (QLA_FUNCTION_FAILED
);
473 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
475 /* Build Get Port Database IOCB. */
476 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
477 if (mbxentry
== NULL
) {
479 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
481 return (QLA_FUNCTION_FAILED
);
483 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_GET_PORT_DATABASE
);
484 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
485 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
486 mbxentry
->mb2
= cpu_to_le16(MSW(LSD(ha
->iodesc_pd_dma
)));
487 mbxentry
->mb3
= cpu_to_le16(LSW(LSD(ha
->iodesc_pd_dma
)));
488 mbxentry
->mb6
= cpu_to_le16(MSW(MSD(ha
->iodesc_pd_dma
)));
489 mbxentry
->mb7
= cpu_to_le16(LSW(MSD(ha
->iodesc_pd_dma
)));
490 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
493 qla2x00_add_iodesc_timer(iodesc
);
495 /* Issue command to ISP. */
499 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
501 DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
502 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
504 return (QLA_SUCCESS
);
508 * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
510 * @iodesc: io descriptor
511 * @mbxstat: mailbox status IOCB
513 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
514 * will be used for a retry.
517 qla2x00_send_adisc_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
518 struct mbx_entry
*mbxstat
)
520 fc_port_t
*remote_fcport
;
522 remote_fcport
= iodesc
->remote_fcport
;
524 /* Ensure the port IDs are consistent. */
525 if (remote_fcport
->d_id
.b24
!= iodesc
->d_id
.b24
) {
526 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
527 "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
528 ha
->host_no
, remote_fcport
->d_id
.b
.domain
,
529 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
530 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
531 iodesc
->d_id
.b
.al_pa
));
533 return (QLA_SUCCESS
);
536 /* Only process the last command. */
537 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
538 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
539 "[%02x%02x%02x], expected %x, received %x.\n", ha
->host_no
,
540 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
541 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
544 return (QLA_SUCCESS
);
547 if (le16_to_cpu(mbxstat
->status
) == CS_COMPLETE
) {
548 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
549 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
550 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
551 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
553 atomic_set(&remote_fcport
->state
, FCS_ONLINE
);
555 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
556 "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha
->host_no
,
557 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
558 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
559 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
561 if (atomic_read(&remote_fcport
->state
) != FCS_DEVICE_DEAD
)
562 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
564 remote_fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
566 return (QLA_SUCCESS
);
571 * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
573 * @iodesc: io descriptor
574 * @ha_locked: is function called with the hardware lock
576 * Returns QLA_SUCCESS if the IOCB was issued.
579 qla2x00_send_logout_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
582 unsigned long flags
= 0;
583 struct mbx_entry
*mbxentry
;
585 /* Send marker if required. */
586 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
587 return (QLA_FUNCTION_FAILED
);
590 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
592 /* Build fabric port logout mailbox IOCB. */
593 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
594 if (mbxentry
== NULL
) {
596 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
598 return (QLA_FUNCTION_FAILED
);
600 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT
);
601 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
602 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
605 qla2x00_add_iodesc_timer(iodesc
);
607 /* Issue command to ISP. */
611 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
613 DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
614 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
616 return (QLA_SUCCESS
);
620 * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
622 * @iodesc: io descriptor
623 * @mbxstat: mailbox status IOCB
625 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
626 * will be used for a retry.
629 qla2x00_send_logout_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
630 struct mbx_entry
*mbxstat
)
632 DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
633 "status=%x mb0=%x mb1=%x.\n", ha
->host_no
,
634 iodesc
->remote_fcport
->loop_id
,
635 iodesc
->remote_fcport
->d_id
.b
.domain
,
636 iodesc
->remote_fcport
->d_id
.b
.area
,
637 iodesc
->remote_fcport
->d_id
.b
.al_pa
, le16_to_cpu(mbxstat
->status
),
638 le16_to_cpu(mbxstat
->mb0
), le16_to_cpu(mbxstat
->mb1
)));
640 return (QLA_SUCCESS
);
645 * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
647 * @iodesc: io descriptor
648 * @d_id: port id for device
649 * @ha_locked: is function called with the hardware lock
651 * Returns QLA_SUCCESS if the IOCB was issued.
654 qla2x00_send_login_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
655 port_id_t
*d_id
, int ha_locked
)
657 unsigned long flags
= 0;
658 struct mbx_entry
*mbxentry
;
660 /* Send marker if required. */
661 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
662 return (QLA_FUNCTION_FAILED
);
665 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
667 /* Build fabric port login mailbox IOCB. */
668 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
669 if (mbxentry
== NULL
) {
671 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
673 return (QLA_FUNCTION_FAILED
);
675 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT
);
676 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
677 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
678 mbxentry
->mb2
= cpu_to_le16(d_id
->b
.domain
);
679 mbxentry
->mb3
= cpu_to_le16(d_id
->b
.area
<< 8 | d_id
->b
.al_pa
);
680 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
683 qla2x00_add_iodesc_timer(iodesc
);
685 /* Issue command to ISP. */
689 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
691 DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
692 "[%x/%02x%02x%02x].\n", ha
->host_no
, iodesc
->signature
,
693 iodesc
->remote_fcport
->loop_id
, d_id
->b
.domain
, d_id
->b
.area
,
696 return (QLA_SUCCESS
);
700 * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
702 * @iodesc: io descriptor
703 * @mbxstat: mailbox status IOCB
705 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
706 * will be used for a retry.
709 qla2x00_send_login_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
710 struct mbx_entry
*mbxstat
)
713 fc_port_t
*fcport
, *remote_fcport
, *exist_fcport
;
714 struct io_descriptor
*abort_iodesc
, *login_iodesc
;
715 uint16_t status
, mb
[8];
717 uint16_t remote_loopid
;
718 port_id_t remote_did
, inuse_did
;
720 remote_fcport
= iodesc
->remote_fcport
;
722 /* Only process the last command. */
723 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
724 DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
725 "[%02x%02x%02x], expected %x, received %x.\n",
726 ha
->host_no
, iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
727 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
730 /* Free RSCN fcport resources. */
731 if (remote_fcport
->port_type
== FCT_RSCN
) {
732 DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
733 "fcport %p [%x/%02x%02x%02x] given ignored Login "
734 "IOCB.\n", ha
->host_no
, remote_fcport
,
735 remote_fcport
->loop_id
,
736 remote_fcport
->d_id
.b
.domain
,
737 remote_fcport
->d_id
.b
.area
,
738 remote_fcport
->d_id
.b
.al_pa
));
740 list_del(&remote_fcport
->list
);
741 kfree(remote_fcport
);
743 return (QLA_SUCCESS
);
746 status
= le16_to_cpu(mbxstat
->status
);
747 mb
[0] = le16_to_cpu(mbxstat
->mb0
);
748 mb
[1] = le16_to_cpu(mbxstat
->mb1
);
749 mb
[2] = le16_to_cpu(mbxstat
->mb2
);
750 mb
[6] = le16_to_cpu(mbxstat
->mb6
);
751 mb
[7] = le16_to_cpu(mbxstat
->mb7
);
754 if ((status
== CS_COMPLETE
|| status
== CS_COMPLETE_CHKCOND
) &&
755 mb
[0] == MBS_COMMAND_COMPLETE
) {
757 DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
758 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha
->host_no
, status
,
759 mb
[1], mbxstat
->port_name
[0], mbxstat
->port_name
[1],
760 mbxstat
->port_name
[2], mbxstat
->port_name
[3],
761 mbxstat
->port_name
[4], mbxstat
->port_name
[5],
762 mbxstat
->port_name
[6], mbxstat
->port_name
[7]));
764 memcpy(remote_fcport
->node_name
, mbxstat
->node_name
, WWN_SIZE
);
765 memcpy(remote_fcport
->port_name
, mbxstat
->port_name
, WWN_SIZE
);
767 /* Is the device already in our fcports list? */
768 if (remote_fcport
->port_type
!= FCT_RSCN
) {
769 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
770 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
771 remote_fcport
->loop_id
,
772 remote_fcport
->d_id
.b
.domain
,
773 remote_fcport
->d_id
.b
.area
,
774 remote_fcport
->d_id
.b
.al_pa
));
776 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
778 return (QLA_SUCCESS
);
781 /* Does the RSCN portname already exist in our fcports list? */
783 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
784 if (memcmp(remote_fcport
->port_name
, fcport
->port_name
,
786 exist_fcport
= fcport
;
790 if (exist_fcport
!= NULL
) {
791 DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
792 "fcport in fcports list [%p].\n", ha
->host_no
,
795 /* Abort any ADISC that could have been sent. */
796 if (exist_fcport
->iodesc_idx_sent
!= iodesc
->idx
&&
797 exist_fcport
->iodesc_idx_sent
<
798 MAX_IO_DESCRIPTORS
&&
799 ha
->io_descriptors
[exist_fcport
->iodesc_idx_sent
].
800 cb_idx
== ADISC_PORT_IOCB_CB
) {
802 abort_iodesc
= qla2x00_alloc_iodesc(ha
);
804 DEBUG14(printk("scsi(%ld): Login IOCB "
805 "-- issuing abort to outstanding "
806 "Adisc [%x/%02x%02x%02x].\n",
807 ha
->host_no
, remote_fcport
->loop_id
,
808 exist_fcport
->d_id
.b
.domain
,
809 exist_fcport
->d_id
.b
.area
,
810 exist_fcport
->d_id
.b
.al_pa
));
812 abort_iodesc
->cb_idx
= ABORT_IOCB_CB
;
813 abort_iodesc
->d_id
.b24
=
814 exist_fcport
->d_id
.b24
;
815 abort_iodesc
->remote_fcport
=
817 exist_fcport
->iodesc_idx_sent
=
819 qla2x00_send_abort_iocb(ha
,
820 abort_iodesc
, ha
->io_descriptors
[
821 exist_fcport
->iodesc_idx_sent
].
824 DEBUG14(printk("scsi(%ld): Login IOCB "
825 "-- unable to abort outstanding "
826 "Adisc [%x/%02x%02x%02x].\n",
827 ha
->host_no
, remote_fcport
->loop_id
,
828 exist_fcport
->d_id
.b
.domain
,
829 exist_fcport
->d_id
.b
.area
,
830 exist_fcport
->d_id
.b
.al_pa
));
835 * If the existing fcport is waiting to send an ADISC
836 * or LOGIN, then reuse remote fcport (RSCN) to
840 remote_loopid
= remote_fcport
->loop_id
;
841 remote_did
.b24
= remote_fcport
->d_id
.b24
;
842 if (exist_fcport
->iodesc_idx_sent
==
843 IODESC_ADISC_NEEDED
||
844 exist_fcport
->iodesc_idx_sent
==
845 IODESC_LOGIN_NEEDED
) {
846 DEBUG14(printk("scsi(%ld): Login IOCB -- "
847 "existing fcport [%x/%02x%02x%02x] "
848 "waiting for IO descriptor, reuse RSCN "
849 "fcport.\n", ha
->host_no
,
850 exist_fcport
->loop_id
,
851 exist_fcport
->d_id
.b
.domain
,
852 exist_fcport
->d_id
.b
.area
,
853 exist_fcport
->d_id
.b
.al_pa
));
856 remote_fcport
->iodesc_idx_sent
=
857 exist_fcport
->iodesc_idx_sent
;
858 exist_fcport
->iodesc_idx_sent
=
859 IODESC_INVALID_INDEX
;
860 remote_fcport
->loop_id
= exist_fcport
->loop_id
;
861 remote_fcport
->d_id
.b24
=
862 exist_fcport
->d_id
.b24
;
865 /* Logout the old loopid. */
867 exist_fcport
->loop_id
!= remote_fcport
->loop_id
&&
868 exist_fcport
->loop_id
!= FC_NO_LOOP_ID
) {
869 login_iodesc
= qla2x00_alloc_iodesc(ha
);
871 DEBUG14(printk("scsi(%ld): Login IOCB "
872 "-- issuing logout to free old "
873 "loop id [%x/%02x%02x%02x].\n",
874 ha
->host_no
, 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
));
879 login_iodesc
->cb_idx
=
881 login_iodesc
->d_id
.b24
=
882 exist_fcport
->d_id
.b24
;
883 login_iodesc
->remote_fcport
=
885 exist_fcport
->iodesc_idx_sent
=
887 qla2x00_send_logout_iocb(ha
,
890 /* Ran out of IO descriptiors. */
891 DEBUG14(printk("scsi(%ld): Login IOCB "
892 "-- unable to logout to free old "
893 "loop id [%x/%02x%02x%02x].\n",
894 ha
->host_no
, exist_fcport
->loop_id
,
895 exist_fcport
->d_id
.b
.domain
,
896 exist_fcport
->d_id
.b
.area
,
897 exist_fcport
->d_id
.b
.al_pa
));
899 exist_fcport
->iodesc_idx_sent
=
900 IODESC_INVALID_INDEX
;
905 /* Update existing fcport with remote fcport info. */
906 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
907 "existing fcport [%x/%02x%02x%02x] online.\n",
908 ha
->host_no
, remote_loopid
, remote_did
.b
.domain
,
909 remote_did
.b
.area
, remote_did
.b
.al_pa
));
911 memcpy(exist_fcport
->node_name
,
912 remote_fcport
->node_name
, WWN_SIZE
);
913 exist_fcport
->loop_id
= remote_loopid
;
914 exist_fcport
->d_id
.b24
= remote_did
.b24
;
915 qla2x00_update_login_fcport(ha
, mbxstat
, exist_fcport
);
917 /* Finally, free the remote (RSCN) fcport. */
919 DEBUG14(printk("scsi(%ld): Login IOCB -- "
920 "Freeing RSCN fcport %p "
921 "[%x/%02x%02x%02x].\n", ha
->host_no
,
922 remote_fcport
, remote_fcport
->loop_id
,
923 remote_fcport
->d_id
.b
.domain
,
924 remote_fcport
->d_id
.b
.area
,
925 remote_fcport
->d_id
.b
.al_pa
));
927 list_del(&remote_fcport
->list
);
928 kfree(remote_fcport
);
931 return (QLA_SUCCESS
);
935 * A new device has been added, move the RSCN fcport to our
938 DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
939 "[%x/%02x%02x%02x] to fcports list.\n", ha
->host_no
,
940 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
941 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
943 list_del(&remote_fcport
->list
);
944 remote_fcport
->flags
= (FCF_RLC_SUPPORT
| FCF_RESCAN_NEEDED
);
945 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
946 list_add_tail(&remote_fcport
->list
, &ha
->fcports
);
947 set_bit(FCPORT_RESCAN_NEEDED
, &ha
->dpc_flags
);
949 /* Handle login failure. */
950 if (remote_fcport
->login_retry
!= 0) {
951 if (mb
[0] == MBS_LOOP_ID_USED
) {
952 inuse_did
.b
.domain
= LSB(mb
[1]);
953 inuse_did
.b
.area
= MSB(mb
[2]);
954 inuse_did
.b
.al_pa
= LSB(mb
[2]);
956 DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
957 "id [%x] used by port id [%02x%02x%02x].\n",
958 ha
->host_no
, remote_fcport
->loop_id
,
959 inuse_did
.b
.domain
, inuse_did
.b
.area
,
962 if (remote_fcport
->d_id
.b24
==
965 * Invalid port id means we are trying
966 * to login to a remote port with just
967 * a loop id without knowing about the
968 * port id. Copy the port id and try
971 remote_fcport
->d_id
.b24
= inuse_did
.b24
;
972 iodesc
->d_id
.b24
= inuse_did
.b24
;
974 remote_fcport
->loop_id
++;
975 rval
= qla2x00_find_new_loop_id(ha
,
977 if (rval
== QLA_FUNCTION_FAILED
) {
978 /* No more loop ids. */
979 return (QLA_SUCCESS
);
982 } else if (mb
[0] == MBS_PORT_ID_USED
) {
984 * Device has another loop ID. The firmware
985 * group recommends the driver perform an
986 * implicit login with the specified ID.
988 DEBUG14(printk("scsi(%ld): Login IOCB -- port "
989 "id [%02x%02x%02x] already assigned to "
990 "loop id [%x].\n", ha
->host_no
,
991 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
992 iodesc
->d_id
.b
.al_pa
, mb
[1]));
994 remote_fcport
->loop_id
= mb
[1];
997 /* Unable to perform login, try again. */
998 DEBUG14(printk("scsi(%ld): Login IOCB -- "
999 "failed login [%x/%02x%02x%02x], status=%x "
1000 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1001 ha
->host_no
, remote_fcport
->loop_id
,
1002 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1003 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
1004 mb
[2], mb
[6], mb
[7]));
1007 /* Reissue Login with the same IO descriptor. */
1009 qla2x00_iodesc_to_handle(iodesc
);
1010 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
1011 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
1012 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1013 remote_fcport
->login_retry
--;
1015 DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
1016 "login to [%x/%02x%02x%02x] (%d).\n", ha
->host_no
,
1017 remote_fcport
->loop_id
,
1018 remote_fcport
->d_id
.b
.domain
,
1019 remote_fcport
->d_id
.b
.area
,
1020 remote_fcport
->d_id
.b
.al_pa
,
1021 remote_fcport
->login_retry
));
1023 qla2x00_send_login_iocb(ha
, iodesc
,
1024 &remote_fcport
->d_id
, 1);
1026 return (QLA_FUNCTION_FAILED
);
1028 /* No more logins, mark device dead. */
1029 DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
1030 "login [%x/%02x%02x%02x] after retries, status=%x "
1031 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1032 ha
->host_no
, remote_fcport
->loop_id
,
1033 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1034 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
1035 mb
[2], mb
[6], mb
[7]));
1037 atomic_set(&remote_fcport
->state
, FCS_DEVICE_DEAD
);
1038 if (remote_fcport
->port_type
== FCT_RSCN
) {
1039 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1040 "Freeing dead RSCN fcport %p "
1041 "[%x/%02x%02x%02x].\n", ha
->host_no
,
1042 remote_fcport
, remote_fcport
->loop_id
,
1043 remote_fcport
->d_id
.b
.domain
,
1044 remote_fcport
->d_id
.b
.area
,
1045 remote_fcport
->d_id
.b
.al_pa
));
1047 list_del(&remote_fcport
->list
);
1048 kfree(remote_fcport
);
1053 return (QLA_SUCCESS
);
1058 * IO descriptor processing routines.
1062 * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
1064 * @flags: allocation flags
1066 * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
1069 qla2x00_alloc_rscn_fcport(scsi_qla_host_t
*ha
, int flags
)
1073 fcport
= qla2x00_alloc_fcport(ha
, flags
);
1077 /* Setup RSCN fcport structure. */
1078 fcport
->port_type
= FCT_RSCN
;
1084 * qla2x00_handle_port_rscn() - Handle port RSCN.
1086 * @rscn_entry: RSCN entry
1087 * @fcport: fcport entry to updated
1089 * Returns QLA_SUCCESS if the port RSCN was handled.
1092 qla2x00_handle_port_rscn(scsi_qla_host_t
*ha
, uint32_t rscn_entry
,
1093 fc_port_t
*known_fcport
, int ha_locked
)
1097 fc_port_t
*fcport
, *remote_fcport
, *rscn_fcport
;
1098 struct io_descriptor
*iodesc
;
1100 remote_fcport
= NULL
;
1103 /* Prepare port id based on incoming entries. */
1105 rscn_pid
.b24
= known_fcport
->d_id
.b24
;
1106 remote_fcport
= known_fcport
;
1108 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1109 "fcport [%02x%02x%02x].\n", ha
->host_no
,
1110 remote_fcport
->d_id
.b
.domain
, remote_fcport
->d_id
.b
.area
,
1111 remote_fcport
->d_id
.b
.al_pa
));
1113 rscn_pid
.b
.domain
= LSB(MSW(rscn_entry
));
1114 rscn_pid
.b
.area
= MSB(LSW(rscn_entry
));
1115 rscn_pid
.b
.al_pa
= LSB(LSW(rscn_entry
));
1117 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1118 "port id [%02x%02x%02x].\n", ha
->host_no
,
1119 rscn_pid
.b
.domain
, rscn_pid
.b
.area
, rscn_pid
.b
.al_pa
));
1122 * Search fcport lists for a known entry at the specified port
1125 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1126 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1127 remote_fcport
= fcport
;
1131 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1132 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1133 rscn_fcport
= fcport
;
1137 if (remote_fcport
== NULL
)
1138 remote_fcport
= rscn_fcport
;
1142 * If the port is already in our fcport list and online, send an ADISC
1143 * to see if it's still alive. Issue login if a new fcport or the known
1144 * fcport is currently offline.
1146 if (remote_fcport
) {
1148 * No need to send request if the remote fcport is currently
1149 * waiting for an available io descriptor.
1151 if (known_fcport
== NULL
&&
1152 (remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1153 remote_fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
)) {
1155 * If previous waiting io descriptor is an ADISC, then
1156 * the new RSCN may come from a new remote fcport being
1157 * plugged into the same location.
1159 if (remote_fcport
->port_type
== FCT_RSCN
) {
1160 remote_fcport
->iodesc_idx_sent
=
1161 IODESC_LOGIN_NEEDED
;
1162 } else if (remote_fcport
->iodesc_idx_sent
==
1163 IODESC_ADISC_NEEDED
) {
1164 fc_port_t
*new_fcport
;
1166 remote_fcport
->iodesc_idx_sent
=
1167 IODESC_INVALID_INDEX
;
1169 /* Create new fcport for later login. */
1170 new_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1171 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1173 DEBUG14(printk("scsi(%ld): Handle RSCN "
1174 "-- creating RSCN fcport %p for "
1175 "future login.\n", ha
->host_no
,
1178 new_fcport
->d_id
.b24
=
1179 remote_fcport
->d_id
.b24
;
1180 new_fcport
->iodesc_idx_sent
=
1181 IODESC_LOGIN_NEEDED
;
1183 list_add_tail(&new_fcport
->list
,
1185 set_bit(IODESC_PROCESS_NEEDED
,
1188 DEBUG14(printk("scsi(%ld): Handle RSCN "
1189 "-- unable to allocate RSCN fcport "
1190 "for future login.\n",
1194 return (QLA_SUCCESS
);
1197 /* Send ADISC if the fcport is online */
1198 if (atomic_read(&remote_fcport
->state
) == FCS_ONLINE
||
1199 remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
) {
1201 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1203 iodesc
= qla2x00_alloc_iodesc(ha
);
1204 if (iodesc
== NULL
) {
1205 /* Mark fcport for later adisc processing */
1206 DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
1207 "enough IO descriptors for Adisc, flag "
1208 "for later processing.\n", ha
->host_no
));
1210 remote_fcport
->iodesc_idx_sent
=
1211 IODESC_ADISC_NEEDED
;
1212 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1214 return (QLA_SUCCESS
);
1217 iodesc
->cb_idx
= ADISC_PORT_IOCB_CB
;
1218 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1219 iodesc
->remote_fcport
= remote_fcport
;
1220 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1221 qla2x00_send_adisc_iocb(ha
, iodesc
, ha_locked
);
1223 return (QLA_SUCCESS
);
1224 } else if (remote_fcport
->iodesc_idx_sent
<
1225 MAX_IO_DESCRIPTORS
&&
1226 ha
->io_descriptors
[remote_fcport
->iodesc_idx_sent
].cb_idx
==
1227 ADISC_PORT_IOCB_CB
) {
1229 * Receiving another RSCN while an ADISC is pending,
1230 * abort the IOCB. Use the same descriptor for the
1233 uint32_t handle_to_abort
;
1235 iodesc
= &ha
->io_descriptors
[
1236 remote_fcport
->iodesc_idx_sent
];
1237 qla2x00_remove_iodesc_timer(iodesc
);
1238 handle_to_abort
= iodesc
->signature
;
1239 iodesc
->signature
= qla2x00_iodesc_to_handle(iodesc
);
1240 iodesc
->cb_idx
= ABORT_IOCB_CB
;
1241 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
1242 iodesc
->remote_fcport
= remote_fcport
;
1243 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1245 DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
1246 "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
1247 ha
->host_no
, remote_fcport
->loop_id
,
1248 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1249 iodesc
->d_id
.b
.al_pa
));
1251 qla2x00_send_abort_iocb(ha
, iodesc
, handle_to_abort
,
1256 /* We need to login to the remote port, find it. */
1258 remote_fcport
= known_fcport
;
1259 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1260 rscn_fcport
->iodesc_idx_sent
< MAX_IO_DESCRIPTORS
&&
1261 ha
->io_descriptors
[rscn_fcport
->iodesc_idx_sent
].cb_idx
==
1262 LOGIN_PORT_IOCB_CB
) {
1264 * Ignore duplicate RSCN on fcport which has already
1265 * initiated a login IOCB.
1267 DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
1268 "already sent to [%02x%02x%02x].\n", ha
->host_no
,
1269 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1270 rscn_fcport
->d_id
.b
.al_pa
));
1272 return (QLA_SUCCESS
);
1273 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1274 rscn_fcport
!= remote_fcport
) {
1275 /* Reuse same rscn fcport. */
1276 DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
1277 "[%02x%02x%02x].\n", ha
->host_no
,
1278 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1279 rscn_fcport
->d_id
.b
.al_pa
));
1281 remote_fcport
= rscn_fcport
;
1283 /* Create new fcport for later login. */
1284 remote_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1285 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1286 list_add_tail(&remote_fcport
->list
, &ha
->rscn_fcports
);
1288 if (remote_fcport
== NULL
)
1289 return (QLA_SUCCESS
);
1291 /* Prepare fcport for login. */
1292 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1293 remote_fcport
->login_retry
= 3; /* ha->login_retry_count; */
1294 remote_fcport
->d_id
.b24
= rscn_pid
.b24
;
1296 iodesc
= qla2x00_alloc_iodesc(ha
);
1297 if (iodesc
== NULL
) {
1298 /* Mark fcport for later adisc processing. */
1299 DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
1300 "descriptors for Login, flag for later processing.\n",
1303 remote_fcport
->iodesc_idx_sent
= IODESC_LOGIN_NEEDED
;
1304 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1306 return (QLA_SUCCESS
);
1309 if (known_fcport
== NULL
|| rscn_pid
.b24
!= INVALID_PORT_ID
) {
1310 remote_fcport
->loop_id
= ha
->min_external_loopid
;
1312 rval
= qla2x00_find_new_loop_id(ha
, remote_fcport
);
1313 if (rval
== QLA_FUNCTION_FAILED
) {
1314 /* No more loop ids, failed. */
1315 DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
1316 "loop id to perform Login, failed.\n",
1323 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
1324 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1325 iodesc
->remote_fcport
= remote_fcport
;
1326 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1328 DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
1329 "[%x/%02x%02x%02x].\n", ha
->host_no
, remote_fcport
->loop_id
,
1330 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
));
1332 qla2x00_send_login_iocb(ha
, iodesc
, &rscn_pid
, ha_locked
);
1334 return (QLA_SUCCESS
);
1338 * qla2x00_process_iodesc() - Complete IO descriptor processing.
1340 * @mbxstat: Mailbox IOCB status
1343 qla2x00_process_iodesc(scsi_qla_host_t
*ha
, struct mbx_entry
*mbxstat
)
1348 struct io_descriptor
*iodesc
;
1350 signature
= mbxstat
->handle
;
1352 DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
1353 ha
->host_no
, signature
));
1355 /* Retrieve proper IO descriptor. */
1356 iodesc
= qla2x00_handle_to_iodesc(ha
, signature
);
1357 if (iodesc
== NULL
) {
1358 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1359 "incorrect signature %08x.\n", ha
->host_no
, signature
));
1364 /* Stop IO descriptor timer. */
1365 qla2x00_remove_iodesc_timer(iodesc
);
1367 /* Verify signature match. */
1368 if (iodesc
->signature
!= signature
) {
1369 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1370 "signature mismatch, sent %08x, received %08x.\n",
1371 ha
->host_no
, iodesc
->signature
, signature
));
1376 /* Go with IOCB callback. */
1377 rval
= iocb_function_cb_list
[iodesc
->cb_idx
](ha
, iodesc
, mbxstat
);
1378 if (rval
!= QLA_SUCCESS
) {
1379 /* IO descriptor reused by callback. */
1383 qla2x00_free_iodesc(iodesc
);
1385 if (test_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
)) {
1386 /* Scan our fcports list for any RSCN requests. */
1387 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1388 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1389 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1390 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1395 /* Scan our RSCN fcports list for any RSCN requests. */
1396 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1397 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1398 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1399 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1404 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1408 * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
1411 * This routine will also delete any RSCN entries related to the outstanding
1415 qla2x00_cancel_io_descriptors(scsi_qla_host_t
*ha
)
1417 fc_port_t
*fcport
, *fcptemp
;
1419 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1421 /* Abort all IO descriptors. */
1422 qla2x00_init_io_descriptors(ha
);
1424 /* Reset all pending IO descriptors in fcports list. */
1425 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1426 fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
1429 /* Reset all pending IO descriptors in rscn fcports list. */
1430 list_for_each_entry_safe(fcport
, fcptemp
, &ha
->rscn_fcports
, list
) {
1431 DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
1432 "%p [%x/%02x%02x%02x].\n", ha
->host_no
, fcport
,
1433 fcport
->loop_id
, fcport
->d_id
.b
.domain
, fcport
->d_id
.b
.area
,
1434 fcport
->d_id
.b
.al_pa
));
1436 list_del(&fcport
->list
);