2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2005 QLogic Corporation
5 * See LICENSE.qla2xxx for copyright and licensing details.
10 * IO descriptor handle definitions.
14 * |31------28|27-------------------12|11-------0|
15 * | Type | Rolling Signature | Index |
16 * |----------|-----------------------|----------|
20 #define HDL_TYPE_SCSI 0
21 #define HDL_TYPE_ASYNC_IOCB 0x0A
23 #define HDL_INDEX_BITS 12
24 #define HDL_ITER_BITS 16
25 #define HDL_TYPE_BITS 4
27 #define HDL_INDEX_MASK ((1UL << HDL_INDEX_BITS) - 1)
28 #define HDL_ITER_MASK ((1UL << HDL_ITER_BITS) - 1)
29 #define HDL_TYPE_MASK ((1UL << HDL_TYPE_BITS) - 1)
31 #define HDL_INDEX_SHIFT 0
32 #define HDL_ITER_SHIFT (HDL_INDEX_SHIFT + HDL_INDEX_BITS)
33 #define HDL_TYPE_SHIFT (HDL_ITER_SHIFT + HDL_ITER_BITS)
35 /* Local Prototypes. */
36 static inline uint32_t qla2x00_to_handle(uint16_t, uint16_t, uint16_t);
37 static inline uint16_t qla2x00_handle_to_idx(uint32_t);
38 static inline uint32_t qla2x00_iodesc_to_handle(struct io_descriptor
*);
39 static inline struct io_descriptor
*qla2x00_handle_to_iodesc(scsi_qla_host_t
*,
42 static inline struct io_descriptor
*qla2x00_alloc_iodesc(scsi_qla_host_t
*);
43 static inline void qla2x00_free_iodesc(struct io_descriptor
*);
44 static inline void qla2x00_init_io_descriptors(scsi_qla_host_t
*);
46 static void qla2x00_iodesc_timeout(unsigned long);
47 static inline void qla2x00_add_iodesc_timer(struct io_descriptor
*);
48 static inline void qla2x00_remove_iodesc_timer(struct io_descriptor
*);
50 static inline void qla2x00_update_login_fcport(scsi_qla_host_t
*,
51 struct mbx_entry
*, fc_port_t
*);
53 static int qla2x00_send_abort_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
55 static int qla2x00_send_abort_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
58 static int qla2x00_send_adisc_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
60 static int qla2x00_send_adisc_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
63 static int qla2x00_send_logout_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
65 static int qla2x00_send_logout_iocb_cb(scsi_qla_host_t
*,
66 struct io_descriptor
*, struct mbx_entry
*);
68 static int qla2x00_send_login_iocb(scsi_qla_host_t
*, struct io_descriptor
*,
70 static int qla2x00_send_login_iocb_cb(scsi_qla_host_t
*, struct io_descriptor
*,
74 * Mailbox IOCB callback array.
76 static int (*iocb_function_cb_list
[LAST_IOCB_CB
])
77 (scsi_qla_host_t
*, struct io_descriptor
*, struct mbx_entry
*) = {
79 qla2x00_send_abort_iocb_cb
,
80 qla2x00_send_adisc_iocb_cb
,
81 qla2x00_send_logout_iocb_cb
,
82 qla2x00_send_login_iocb_cb
,
87 * Generic IO descriptor handle routines.
91 * qla2x00_to_handle() - Create a descriptor handle.
92 * @type: descriptor type
93 * @iter: descriptor rolling signature
94 * @idx: index to the descriptor array
96 * Returns a composite handle based in the @type, @iter, and @idx.
98 static inline uint32_t
99 qla2x00_to_handle(uint16_t type
, uint16_t iter
, uint16_t idx
)
101 return ((uint32_t)(((uint32_t)type
<< HDL_TYPE_SHIFT
) |
102 ((uint32_t)iter
<< HDL_ITER_SHIFT
) |
103 ((uint32_t)idx
<< HDL_INDEX_SHIFT
)));
107 * qla2x00_handle_to_idx() - Retrive the index for a given handle.
108 * @handle: descriptor handle
110 * Returns the index specified by the @handle.
112 static inline uint16_t
113 qla2x00_handle_to_idx(uint32_t handle
)
115 return ((uint16_t)(((handle
) >> HDL_INDEX_SHIFT
) & HDL_INDEX_MASK
));
119 * qla2x00_iodesc_to_handle() - Convert an IO descriptor to a unique handle.
120 * @iodesc: io descriptor
122 * Returns a unique handle for @iodesc.
124 static inline uint32_t
125 qla2x00_iodesc_to_handle(struct io_descriptor
*iodesc
)
129 handle
= qla2x00_to_handle(HDL_TYPE_ASYNC_IOCB
,
130 ++iodesc
->ha
->iodesc_signature
, iodesc
->idx
);
131 iodesc
->signature
= handle
;
137 * qla2x00_handle_to_iodesc() - Retrieve an IO descriptor given a unique handle.
139 * @handle: handle to io descriptor
141 * Returns a pointer to the io descriptor, or NULL, if the io descriptor does
142 * not exist or the io descriptors signature does not @handle.
144 static inline struct io_descriptor
*
145 qla2x00_handle_to_iodesc(scsi_qla_host_t
*ha
, uint32_t handle
)
148 struct io_descriptor
*iodesc
;
150 idx
= qla2x00_handle_to_idx(handle
);
151 iodesc
= &ha
->io_descriptors
[idx
];
153 if (iodesc
->signature
!= handle
)
161 * IO descriptor allocation routines.
165 * qla2x00_alloc_iodesc() - Allocate an IO descriptor from the pool.
168 * Returns a pointer to the allocated io descriptor, or NULL, if none available.
170 static inline struct io_descriptor
*
171 qla2x00_alloc_iodesc(scsi_qla_host_t
*ha
)
174 struct io_descriptor
*iodesc
;
177 for (iter
= 0; iter
< MAX_IO_DESCRIPTORS
; iter
++) {
178 if (ha
->io_descriptors
[iter
].used
)
181 iodesc
= &ha
->io_descriptors
[iter
];
184 init_timer(&iodesc
->timer
);
186 iodesc
->signature
= qla2x00_iodesc_to_handle(iodesc
);
194 * qla2x00_free_iodesc() - Free an IO descriptor.
195 * @iodesc: io descriptor
197 * NOTE: The io descriptors timer *must* be stopped before it can be free'd.
200 qla2x00_free_iodesc(struct io_descriptor
*iodesc
)
203 iodesc
->signature
= 0;
207 * qla2x00_remove_iodesc_timer() - Remove an active timer from an IO descriptor.
208 * @iodesc: io descriptor
211 qla2x00_remove_iodesc_timer(struct io_descriptor
*iodesc
)
213 if (iodesc
->timer
.function
!= NULL
) {
214 del_timer_sync(&iodesc
->timer
);
215 iodesc
->timer
.data
= (unsigned long) NULL
;
216 iodesc
->timer
.function
= NULL
;
221 * qla2x00_init_io_descriptors() - Initialize the pool of IO descriptors.
225 qla2x00_init_io_descriptors(scsi_qla_host_t
*ha
)
229 for (iter
= 0; iter
< MAX_IO_DESCRIPTORS
; iter
++) {
230 if (!ha
->io_descriptors
[iter
].used
)
233 qla2x00_remove_iodesc_timer(&ha
->io_descriptors
[iter
]);
234 qla2x00_free_iodesc(&ha
->io_descriptors
[iter
]);
240 * IO descriptor timer routines.
244 * qla2x00_iodesc_timeout() - Timeout IO descriptor handler.
245 * @data: io descriptor
248 qla2x00_iodesc_timeout(unsigned long data
)
250 struct io_descriptor
*iodesc
;
252 iodesc
= (struct io_descriptor
*) data
;
254 DEBUG14(printk("scsi(%ld): IO descriptor timeout, index=%x "
255 "signature=%08x, scheduling ISP abort.\n", iodesc
->ha
->host_no
,
256 iodesc
->idx
, iodesc
->signature
));
258 qla2x00_free_iodesc(iodesc
);
260 qla_printk(KERN_WARNING
, iodesc
->ha
,
261 "IO descriptor timeout. Scheduling ISP abort.\n");
262 set_bit(ISP_ABORT_NEEDED
, &iodesc
->ha
->dpc_flags
);
266 * qla2x00_add_iodesc_timer() - Add and start a timer for an IO descriptor.
267 * @iodesc: io descriptor
270 * The firmware shall timeout an outstanding mailbox IOCB in 2 * R_A_TOV (in
271 * tenths of a second) after it hits the wire. But, if there are any request
272 * resource contraints (i.e. during heavy I/O), exchanges can be held off for
273 * at most R_A_TOV. Therefore, the driver will wait 4 * R_A_TOV before
274 * scheduling a recovery (big hammer).
277 qla2x00_add_iodesc_timer(struct io_descriptor
*iodesc
)
279 unsigned long timeout
;
281 timeout
= (iodesc
->ha
->r_a_tov
* 4) / 10;
282 init_timer(&iodesc
->timer
);
283 iodesc
->timer
.data
= (unsigned long) iodesc
;
284 iodesc
->timer
.expires
= jiffies
+ (timeout
* HZ
);
285 iodesc
->timer
.function
=
286 (void (*) (unsigned long)) qla2x00_iodesc_timeout
;
287 add_timer(&iodesc
->timer
);
291 * IO descriptor support routines.
295 * qla2x00_update_login_fcport() - Update fcport data after login processing.
297 * @mbxstat: Mailbox command status IOCB
298 * @fcport: port to update
301 qla2x00_update_login_fcport(scsi_qla_host_t
*ha
, struct mbx_entry
*mbxstat
,
304 if (le16_to_cpu(mbxstat
->mb1
) & BIT_0
) {
305 fcport
->port_type
= FCT_INITIATOR
;
307 fcport
->port_type
= FCT_TARGET
;
308 if (le16_to_cpu(mbxstat
->mb1
) & BIT_1
) {
309 fcport
->flags
|= FCF_TAPE_PRESENT
;
312 fcport
->login_retry
= 0;
313 fcport
->port_login_retry_count
= ha
->port_down_retry_count
*
315 atomic_set(&fcport
->port_down_timer
, ha
->port_down_retry_count
*
317 fcport
->flags
|= FCF_FABRIC_DEVICE
;
318 fcport
->flags
&= ~FCF_FAILOVER_NEEDED
;
319 fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
320 atomic_set(&fcport
->state
, FCS_ONLINE
);
321 schedule_work(&fcport
->rport_add_work
);
326 * Mailbox IOCB commands.
330 * qla2x00_get_mbx_iocb_entry() - Retrieve an IOCB from the request queue.
332 * @handle: handle to io descriptor
334 * Returns a pointer to the reqest entry, or NULL, if none were available.
336 static inline struct mbx_entry
*
337 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t
*ha
, uint32_t handle
)
340 struct device_reg_2xxx __iomem
*reg
= &ha
->iobase
->isp
;
341 struct mbx_entry
*mbxentry
;
345 if (ha
->req_q_cnt
< 3) {
346 cnt
= qla2x00_debounce_register(ISP_REQ_Q_OUT(ha
, reg
));
347 if (ha
->req_ring_index
< cnt
)
348 ha
->req_q_cnt
= cnt
- ha
->req_ring_index
;
350 ha
->req_q_cnt
= ha
->request_q_length
-
351 (ha
->req_ring_index
- cnt
);
353 if (ha
->req_q_cnt
>= 3) {
354 mbxentry
= (struct mbx_entry
*)ha
->request_ring_ptr
;
356 memset(mbxentry
, 0, sizeof(struct mbx_entry
));
357 mbxentry
->entry_type
= MBX_IOCB_TYPE
;
358 mbxentry
->entry_count
= 1;
359 mbxentry
->sys_define1
= SOURCE_ASYNC_IOCB
;
360 mbxentry
->handle
= handle
;
366 * qla2x00_send_abort_iocb() - Issue an abort IOCB to the firmware.
368 * @iodesc: io descriptor
369 * @handle_to_abort: firmware handle to abort
370 * @ha_locked: is function called with the hardware lock
372 * Returns QLA_SUCCESS if the IOCB was issued.
375 qla2x00_send_abort_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
376 uint32_t handle_to_abort
, int ha_locked
)
378 unsigned long flags
= 0;
379 struct mbx_entry
*mbxentry
;
381 /* Send marker if required. */
382 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
383 return (QLA_FUNCTION_FAILED
);
386 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
388 /* Build abort mailbox IOCB. */
389 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
390 if (mbxentry
== NULL
) {
392 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
394 return (QLA_FUNCTION_FAILED
);
396 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_ABORT_COMMAND
);
397 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
398 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
399 mbxentry
->mb2
= LSW(handle_to_abort
);
400 mbxentry
->mb3
= MSW(handle_to_abort
);
403 qla2x00_add_iodesc_timer(iodesc
);
405 /* Issue command to ISP. */
409 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
411 DEBUG14(printk("scsi(%ld): Sending Abort IOCB (%08x) to [%x], aborting "
412 "%08x.\n", ha
->host_no
, iodesc
->signature
,
413 iodesc
->remote_fcport
->loop_id
, handle_to_abort
));
415 return (QLA_SUCCESS
);
419 * qla2x00_send_abort_iocb_cb() - Abort IOCB callback.
421 * @iodesc: io descriptor
422 * @mbxstat: mailbox status IOCB
424 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
425 * will be used for a retry.
428 qla2x00_send_abort_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
429 struct mbx_entry
*mbxstat
)
431 DEBUG14(printk("scsi(%ld): Abort IOCB -- sent to [%x/%02x%02x%02x], "
432 "status=%x mb0=%x.\n", ha
->host_no
, iodesc
->remote_fcport
->loop_id
,
433 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
,
434 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
436 return (QLA_SUCCESS
);
441 * qla2x00_send_adisc_iocb() - Issue a Get Port Database IOCB to the firmware.
443 * @iodesc: io descriptor
444 * @ha_locked: is function called with the hardware lock
446 * Returns QLA_SUCCESS if the IOCB was issued.
449 qla2x00_send_adisc_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
452 unsigned long flags
= 0;
453 struct mbx_entry
*mbxentry
;
455 /* Send marker if required. */
456 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
457 return (QLA_FUNCTION_FAILED
);
460 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
462 /* Build Get Port Database IOCB. */
463 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
464 if (mbxentry
== NULL
) {
466 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
468 return (QLA_FUNCTION_FAILED
);
470 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_GET_PORT_DATABASE
);
471 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
472 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
473 mbxentry
->mb2
= cpu_to_le16(MSW(LSD(ha
->iodesc_pd_dma
)));
474 mbxentry
->mb3
= cpu_to_le16(LSW(LSD(ha
->iodesc_pd_dma
)));
475 mbxentry
->mb6
= cpu_to_le16(MSW(MSD(ha
->iodesc_pd_dma
)));
476 mbxentry
->mb7
= cpu_to_le16(LSW(MSD(ha
->iodesc_pd_dma
)));
477 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
480 qla2x00_add_iodesc_timer(iodesc
);
482 /* Issue command to ISP. */
486 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
488 DEBUG14(printk("scsi(%ld): Sending Adisc IOCB (%08x) to [%x].\n",
489 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
491 return (QLA_SUCCESS
);
495 * qla2x00_send_adisc_iocb_cb() - Get Port Database IOCB callback.
497 * @iodesc: io descriptor
498 * @mbxstat: mailbox status IOCB
500 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
501 * will be used for a retry.
504 qla2x00_send_adisc_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
505 struct mbx_entry
*mbxstat
)
507 fc_port_t
*remote_fcport
;
509 remote_fcport
= iodesc
->remote_fcport
;
511 /* Ensure the port IDs are consistent. */
512 if (remote_fcport
->d_id
.b24
!= iodesc
->d_id
.b24
) {
513 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, remote port "
514 "id changed from [%02x%02x%02x] to [%02x%02x%02x].\n",
515 ha
->host_no
, remote_fcport
->d_id
.b
.domain
,
516 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
517 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
518 iodesc
->d_id
.b
.al_pa
));
520 return (QLA_SUCCESS
);
523 /* Only process the last command. */
524 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
525 DEBUG14(printk("scsi(%ld): Adisc IOCB -- ignoring, sent to "
526 "[%02x%02x%02x], expected %x, received %x.\n", ha
->host_no
,
527 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
528 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
531 return (QLA_SUCCESS
);
534 if (le16_to_cpu(mbxstat
->status
) == CS_COMPLETE
) {
535 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
536 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
537 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
538 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
540 atomic_set(&remote_fcport
->state
, FCS_ONLINE
);
542 DEBUG14(printk("scsi(%ld): Adisc IOCB -- marking "
543 "[%x/%02x%02x%02x] lost, status=%x mb0=%x.\n", ha
->host_no
,
544 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
545 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
,
546 le16_to_cpu(mbxstat
->status
), le16_to_cpu(mbxstat
->mb0
)));
548 if (atomic_read(&remote_fcport
->state
) != FCS_DEVICE_DEAD
)
549 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
551 remote_fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
553 return (QLA_SUCCESS
);
558 * qla2x00_send_logout_iocb() - Issue a fabric port logout IOCB to the firmware.
560 * @iodesc: io descriptor
561 * @ha_locked: is function called with the hardware lock
563 * Returns QLA_SUCCESS if the IOCB was issued.
566 qla2x00_send_logout_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
569 unsigned long flags
= 0;
570 struct mbx_entry
*mbxentry
;
572 /* Send marker if required. */
573 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
574 return (QLA_FUNCTION_FAILED
);
577 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
579 /* Build fabric port logout mailbox IOCB. */
580 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
581 if (mbxentry
== NULL
) {
583 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
585 return (QLA_FUNCTION_FAILED
);
587 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGOUT_FABRIC_PORT
);
588 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
589 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
592 qla2x00_add_iodesc_timer(iodesc
);
594 /* Issue command to ISP. */
598 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
600 DEBUG14(printk("scsi(%ld): Sending Logout IOCB (%08x) to [%x].\n",
601 ha
->host_no
, iodesc
->signature
, iodesc
->remote_fcport
->loop_id
));
603 return (QLA_SUCCESS
);
607 * qla2x00_send_logout_iocb_cb() - Fabric port logout IOCB callback.
609 * @iodesc: io descriptor
610 * @mbxstat: mailbox status IOCB
612 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
613 * will be used for a retry.
616 qla2x00_send_logout_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
617 struct mbx_entry
*mbxstat
)
619 DEBUG14(printk("scsi(%ld): Logout IOCB -- sent to [%x/%02x%02x%02x], "
620 "status=%x mb0=%x mb1=%x.\n", ha
->host_no
,
621 iodesc
->remote_fcport
->loop_id
,
622 iodesc
->remote_fcport
->d_id
.b
.domain
,
623 iodesc
->remote_fcport
->d_id
.b
.area
,
624 iodesc
->remote_fcport
->d_id
.b
.al_pa
, le16_to_cpu(mbxstat
->status
),
625 le16_to_cpu(mbxstat
->mb0
), le16_to_cpu(mbxstat
->mb1
)));
627 return (QLA_SUCCESS
);
632 * qla2x00_send_login_iocb() - Issue a fabric port login IOCB to the firmware.
634 * @iodesc: io descriptor
635 * @d_id: port id for device
636 * @ha_locked: is function called with the hardware lock
638 * Returns QLA_SUCCESS if the IOCB was issued.
641 qla2x00_send_login_iocb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
642 port_id_t
*d_id
, int ha_locked
)
644 unsigned long flags
= 0;
645 struct mbx_entry
*mbxentry
;
647 /* Send marker if required. */
648 if (qla2x00_issue_marker(ha
, ha_locked
) != QLA_SUCCESS
)
649 return (QLA_FUNCTION_FAILED
);
652 spin_lock_irqsave(&ha
->hardware_lock
, flags
);
654 /* Build fabric port login mailbox IOCB. */
655 mbxentry
= qla2x00_get_mbx_iocb_entry(ha
, iodesc
->signature
);
656 if (mbxentry
== NULL
) {
658 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
660 return (QLA_FUNCTION_FAILED
);
662 mbxentry
->mb0
= __constant_cpu_to_le16(MBC_LOGIN_FABRIC_PORT
);
663 mbxentry
->mb1
= mbxentry
->loop_id
.extended
=
664 cpu_to_le16(iodesc
->remote_fcport
->loop_id
);
665 mbxentry
->mb2
= cpu_to_le16(d_id
->b
.domain
);
666 mbxentry
->mb3
= cpu_to_le16(d_id
->b
.area
<< 8 | d_id
->b
.al_pa
);
667 mbxentry
->mb10
= __constant_cpu_to_le16(BIT_0
);
670 qla2x00_add_iodesc_timer(iodesc
);
672 /* Issue command to ISP. */
676 spin_unlock_irqrestore(&ha
->hardware_lock
, flags
);
678 DEBUG14(printk("scsi(%ld): Sending Login IOCB (%08x) to "
679 "[%x/%02x%02x%02x].\n", ha
->host_no
, iodesc
->signature
,
680 iodesc
->remote_fcport
->loop_id
, d_id
->b
.domain
, d_id
->b
.area
,
683 return (QLA_SUCCESS
);
687 * qla2x00_send_login_iocb_cb() - Fabric port logout IOCB callback.
689 * @iodesc: io descriptor
690 * @mbxstat: mailbox status IOCB
692 * Returns QLA_SUCCESS if @iodesc can be freed by the caller, else, @iodesc
693 * will be used for a retry.
696 qla2x00_send_login_iocb_cb(scsi_qla_host_t
*ha
, struct io_descriptor
*iodesc
,
697 struct mbx_entry
*mbxstat
)
700 fc_port_t
*fcport
, *remote_fcport
, *exist_fcport
;
701 struct io_descriptor
*abort_iodesc
, *login_iodesc
;
702 uint16_t status
, mb
[8];
704 uint16_t remote_loopid
;
705 port_id_t remote_did
, inuse_did
;
707 remote_fcport
= iodesc
->remote_fcport
;
709 /* Only process the last command. */
710 if (remote_fcport
->iodesc_idx_sent
!= iodesc
->idx
) {
711 DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
712 "[%02x%02x%02x], expected %x, received %x.\n",
713 ha
->host_no
, iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
714 iodesc
->d_id
.b
.al_pa
, remote_fcport
->iodesc_idx_sent
,
717 /* Free RSCN fcport resources. */
718 if (remote_fcport
->port_type
== FCT_RSCN
) {
719 DEBUG14(printk("scsi(%ld): Login IOCB -- Freeing RSCN "
720 "fcport %p [%x/%02x%02x%02x] given ignored Login "
721 "IOCB.\n", ha
->host_no
, remote_fcport
,
722 remote_fcport
->loop_id
,
723 remote_fcport
->d_id
.b
.domain
,
724 remote_fcport
->d_id
.b
.area
,
725 remote_fcport
->d_id
.b
.al_pa
));
727 list_del(&remote_fcport
->list
);
728 kfree(remote_fcport
);
730 return (QLA_SUCCESS
);
733 status
= le16_to_cpu(mbxstat
->status
);
734 mb
[0] = le16_to_cpu(mbxstat
->mb0
);
735 mb
[1] = le16_to_cpu(mbxstat
->mb1
);
736 mb
[2] = le16_to_cpu(mbxstat
->mb2
);
737 mb
[6] = le16_to_cpu(mbxstat
->mb6
);
738 mb
[7] = le16_to_cpu(mbxstat
->mb7
);
741 if ((status
== CS_COMPLETE
|| status
== CS_COMPLETE_CHKCOND
) &&
742 mb
[0] == MBS_COMMAND_COMPLETE
) {
744 DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
745 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha
->host_no
, status
,
746 mb
[1], mbxstat
->port_name
[0], mbxstat
->port_name
[1],
747 mbxstat
->port_name
[2], mbxstat
->port_name
[3],
748 mbxstat
->port_name
[4], mbxstat
->port_name
[5],
749 mbxstat
->port_name
[6], mbxstat
->port_name
[7]));
751 memcpy(remote_fcport
->node_name
, mbxstat
->node_name
, WWN_SIZE
);
752 memcpy(remote_fcport
->port_name
, mbxstat
->port_name
, WWN_SIZE
);
754 /* Is the device already in our fcports list? */
755 if (remote_fcport
->port_type
!= FCT_RSCN
) {
756 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
757 "[%x/%02x%02x%02x] online.\n", ha
->host_no
,
758 remote_fcport
->loop_id
,
759 remote_fcport
->d_id
.b
.domain
,
760 remote_fcport
->d_id
.b
.area
,
761 remote_fcport
->d_id
.b
.al_pa
));
763 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
765 return (QLA_SUCCESS
);
768 /* Does the RSCN portname already exist in our fcports list? */
770 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
771 if (memcmp(remote_fcport
->port_name
, fcport
->port_name
,
773 exist_fcport
= fcport
;
777 if (exist_fcport
!= NULL
) {
778 DEBUG14(printk("scsi(%ld): Login IOCB -- found RSCN "
779 "fcport in fcports list [%p].\n", ha
->host_no
,
782 /* Abort any ADISC that could have been sent. */
783 if (exist_fcport
->iodesc_idx_sent
!= iodesc
->idx
&&
784 exist_fcport
->iodesc_idx_sent
<
785 MAX_IO_DESCRIPTORS
&&
786 ha
->io_descriptors
[exist_fcport
->iodesc_idx_sent
].
787 cb_idx
== ADISC_PORT_IOCB_CB
) {
789 abort_iodesc
= qla2x00_alloc_iodesc(ha
);
791 DEBUG14(printk("scsi(%ld): Login IOCB "
792 "-- issuing abort to outstanding "
793 "Adisc [%x/%02x%02x%02x].\n",
794 ha
->host_no
, remote_fcport
->loop_id
,
795 exist_fcport
->d_id
.b
.domain
,
796 exist_fcport
->d_id
.b
.area
,
797 exist_fcport
->d_id
.b
.al_pa
));
799 abort_iodesc
->cb_idx
= ABORT_IOCB_CB
;
800 abort_iodesc
->d_id
.b24
=
801 exist_fcport
->d_id
.b24
;
802 abort_iodesc
->remote_fcport
=
804 exist_fcport
->iodesc_idx_sent
=
806 qla2x00_send_abort_iocb(ha
,
807 abort_iodesc
, ha
->io_descriptors
[
808 exist_fcport
->iodesc_idx_sent
].
811 DEBUG14(printk("scsi(%ld): Login IOCB "
812 "-- unable to abort outstanding "
813 "Adisc [%x/%02x%02x%02x].\n",
814 ha
->host_no
, remote_fcport
->loop_id
,
815 exist_fcport
->d_id
.b
.domain
,
816 exist_fcport
->d_id
.b
.area
,
817 exist_fcport
->d_id
.b
.al_pa
));
822 * If the existing fcport is waiting to send an ADISC
823 * or LOGIN, then reuse remote fcport (RSCN) to
827 remote_loopid
= remote_fcport
->loop_id
;
828 remote_did
.b24
= remote_fcport
->d_id
.b24
;
829 if (exist_fcport
->iodesc_idx_sent
==
830 IODESC_ADISC_NEEDED
||
831 exist_fcport
->iodesc_idx_sent
==
832 IODESC_LOGIN_NEEDED
) {
833 DEBUG14(printk("scsi(%ld): Login IOCB -- "
834 "existing fcport [%x/%02x%02x%02x] "
835 "waiting for IO descriptor, reuse RSCN "
836 "fcport.\n", ha
->host_no
,
837 exist_fcport
->loop_id
,
838 exist_fcport
->d_id
.b
.domain
,
839 exist_fcport
->d_id
.b
.area
,
840 exist_fcport
->d_id
.b
.al_pa
));
843 remote_fcport
->iodesc_idx_sent
=
844 exist_fcport
->iodesc_idx_sent
;
845 exist_fcport
->iodesc_idx_sent
=
846 IODESC_INVALID_INDEX
;
847 remote_fcport
->loop_id
= exist_fcport
->loop_id
;
848 remote_fcport
->d_id
.b24
=
849 exist_fcport
->d_id
.b24
;
852 /* Logout the old loopid. */
854 exist_fcport
->loop_id
!= remote_fcport
->loop_id
&&
855 exist_fcport
->loop_id
!= FC_NO_LOOP_ID
) {
856 login_iodesc
= qla2x00_alloc_iodesc(ha
);
858 DEBUG14(printk("scsi(%ld): Login IOCB "
859 "-- issuing logout to free old "
860 "loop id [%x/%02x%02x%02x].\n",
861 ha
->host_no
, exist_fcport
->loop_id
,
862 exist_fcport
->d_id
.b
.domain
,
863 exist_fcport
->d_id
.b
.area
,
864 exist_fcport
->d_id
.b
.al_pa
));
866 login_iodesc
->cb_idx
=
868 login_iodesc
->d_id
.b24
=
869 exist_fcport
->d_id
.b24
;
870 login_iodesc
->remote_fcport
=
872 exist_fcport
->iodesc_idx_sent
=
874 qla2x00_send_logout_iocb(ha
,
877 /* Ran out of IO descriptiors. */
878 DEBUG14(printk("scsi(%ld): Login IOCB "
879 "-- unable to logout to free old "
880 "loop id [%x/%02x%02x%02x].\n",
881 ha
->host_no
, exist_fcport
->loop_id
,
882 exist_fcport
->d_id
.b
.domain
,
883 exist_fcport
->d_id
.b
.area
,
884 exist_fcport
->d_id
.b
.al_pa
));
886 exist_fcport
->iodesc_idx_sent
=
887 IODESC_INVALID_INDEX
;
892 /* Update existing fcport with remote fcport info. */
893 DEBUG14(printk("scsi(%ld): Login IOCB -- marking "
894 "existing fcport [%x/%02x%02x%02x] online.\n",
895 ha
->host_no
, remote_loopid
, remote_did
.b
.domain
,
896 remote_did
.b
.area
, remote_did
.b
.al_pa
));
898 memcpy(exist_fcport
->node_name
,
899 remote_fcport
->node_name
, WWN_SIZE
);
900 exist_fcport
->loop_id
= remote_loopid
;
901 exist_fcport
->d_id
.b24
= remote_did
.b24
;
902 qla2x00_update_login_fcport(ha
, mbxstat
, exist_fcport
);
904 /* Finally, free the remote (RSCN) fcport. */
906 DEBUG14(printk("scsi(%ld): Login IOCB -- "
907 "Freeing RSCN fcport %p "
908 "[%x/%02x%02x%02x].\n", ha
->host_no
,
909 remote_fcport
, remote_fcport
->loop_id
,
910 remote_fcport
->d_id
.b
.domain
,
911 remote_fcport
->d_id
.b
.area
,
912 remote_fcport
->d_id
.b
.al_pa
));
914 list_del(&remote_fcport
->list
);
915 kfree(remote_fcport
);
918 return (QLA_SUCCESS
);
922 * A new device has been added, move the RSCN fcport to our
925 DEBUG14(printk("scsi(%ld): Login IOCB -- adding RSCN fcport "
926 "[%x/%02x%02x%02x] to fcports list.\n", ha
->host_no
,
927 remote_fcport
->loop_id
, remote_fcport
->d_id
.b
.domain
,
928 remote_fcport
->d_id
.b
.area
, remote_fcport
->d_id
.b
.al_pa
));
930 list_del(&remote_fcport
->list
);
931 remote_fcport
->flags
= (FCF_RLC_SUPPORT
| FCF_RESCAN_NEEDED
);
932 qla2x00_update_login_fcport(ha
, mbxstat
, remote_fcport
);
933 list_add_tail(&remote_fcport
->list
, &ha
->fcports
);
934 set_bit(FCPORT_RESCAN_NEEDED
, &ha
->dpc_flags
);
936 /* Handle login failure. */
937 if (remote_fcport
->login_retry
!= 0) {
938 if (mb
[0] == MBS_LOOP_ID_USED
) {
939 inuse_did
.b
.domain
= LSB(mb
[1]);
940 inuse_did
.b
.area
= MSB(mb
[2]);
941 inuse_did
.b
.al_pa
= LSB(mb
[2]);
943 DEBUG14(printk("scsi(%ld): Login IOCB -- loop "
944 "id [%x] used by port id [%02x%02x%02x].\n",
945 ha
->host_no
, remote_fcport
->loop_id
,
946 inuse_did
.b
.domain
, inuse_did
.b
.area
,
949 if (remote_fcport
->d_id
.b24
==
952 * Invalid port id means we are trying
953 * to login to a remote port with just
954 * a loop id without knowing about the
955 * port id. Copy the port id and try
958 remote_fcport
->d_id
.b24
= inuse_did
.b24
;
959 iodesc
->d_id
.b24
= inuse_did
.b24
;
961 remote_fcport
->loop_id
++;
962 rval
= qla2x00_find_new_loop_id(ha
,
964 if (rval
== QLA_FUNCTION_FAILED
) {
965 /* No more loop ids. */
966 return (QLA_SUCCESS
);
969 } else if (mb
[0] == MBS_PORT_ID_USED
) {
971 * Device has another loop ID. The firmware
972 * group recommends the driver perform an
973 * implicit login with the specified ID.
975 DEBUG14(printk("scsi(%ld): Login IOCB -- port "
976 "id [%02x%02x%02x] already assigned to "
977 "loop id [%x].\n", ha
->host_no
,
978 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
979 iodesc
->d_id
.b
.al_pa
, mb
[1]));
981 remote_fcport
->loop_id
= mb
[1];
984 /* Unable to perform login, try again. */
985 DEBUG14(printk("scsi(%ld): Login IOCB -- "
986 "failed login [%x/%02x%02x%02x], status=%x "
987 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
988 ha
->host_no
, remote_fcport
->loop_id
,
989 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
990 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
991 mb
[2], mb
[6], mb
[7]));
994 /* Reissue Login with the same IO descriptor. */
996 qla2x00_iodesc_to_handle(iodesc
);
997 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
998 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
999 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1000 remote_fcport
->login_retry
--;
1002 DEBUG14(printk("scsi(%ld): Login IOCB -- retrying "
1003 "login to [%x/%02x%02x%02x] (%d).\n", ha
->host_no
,
1004 remote_fcport
->loop_id
,
1005 remote_fcport
->d_id
.b
.domain
,
1006 remote_fcport
->d_id
.b
.area
,
1007 remote_fcport
->d_id
.b
.al_pa
,
1008 remote_fcport
->login_retry
));
1010 qla2x00_send_login_iocb(ha
, iodesc
,
1011 &remote_fcport
->d_id
, 1);
1013 return (QLA_FUNCTION_FAILED
);
1015 /* No more logins, mark device dead. */
1016 DEBUG14(printk("scsi(%ld): Login IOCB -- failed "
1017 "login [%x/%02x%02x%02x] after retries, status=%x "
1018 "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.\n",
1019 ha
->host_no
, remote_fcport
->loop_id
,
1020 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1021 iodesc
->d_id
.b
.al_pa
, status
, mb
[0], mb
[1],
1022 mb
[2], mb
[6], mb
[7]));
1024 atomic_set(&remote_fcport
->state
, FCS_DEVICE_DEAD
);
1025 if (remote_fcport
->port_type
== FCT_RSCN
) {
1026 DEBUG14(printk("scsi(%ld): Login IOCB -- "
1027 "Freeing dead RSCN fcport %p "
1028 "[%x/%02x%02x%02x].\n", ha
->host_no
,
1029 remote_fcport
, remote_fcport
->loop_id
,
1030 remote_fcport
->d_id
.b
.domain
,
1031 remote_fcport
->d_id
.b
.area
,
1032 remote_fcport
->d_id
.b
.al_pa
));
1034 list_del(&remote_fcport
->list
);
1035 kfree(remote_fcport
);
1040 return (QLA_SUCCESS
);
1045 * IO descriptor processing routines.
1049 * qla2x00_alloc_rscn_fcport() - Allocate an RSCN type fcport.
1051 * @flags: allocation flags
1053 * Returns a pointer to the allocated RSCN fcport, or NULL, if none available.
1056 qla2x00_alloc_rscn_fcport(scsi_qla_host_t
*ha
, gfp_t flags
)
1060 fcport
= qla2x00_alloc_fcport(ha
, flags
);
1064 /* Setup RSCN fcport structure. */
1065 fcport
->port_type
= FCT_RSCN
;
1071 * qla2x00_handle_port_rscn() - Handle port RSCN.
1073 * @rscn_entry: RSCN entry
1074 * @fcport: fcport entry to updated
1076 * Returns QLA_SUCCESS if the port RSCN was handled.
1079 qla2x00_handle_port_rscn(scsi_qla_host_t
*ha
, uint32_t rscn_entry
,
1080 fc_port_t
*known_fcport
, int ha_locked
)
1084 fc_port_t
*fcport
, *remote_fcport
, *rscn_fcport
;
1085 struct io_descriptor
*iodesc
;
1087 remote_fcport
= NULL
;
1090 /* Prepare port id based on incoming entries. */
1092 rscn_pid
.b24
= known_fcport
->d_id
.b24
;
1093 remote_fcport
= known_fcport
;
1095 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1096 "fcport [%02x%02x%02x].\n", ha
->host_no
,
1097 remote_fcport
->d_id
.b
.domain
, remote_fcport
->d_id
.b
.area
,
1098 remote_fcport
->d_id
.b
.al_pa
));
1100 rscn_pid
.b
.domain
= LSB(MSW(rscn_entry
));
1101 rscn_pid
.b
.area
= MSB(LSW(rscn_entry
));
1102 rscn_pid
.b
.al_pa
= LSB(LSW(rscn_entry
));
1104 DEBUG14(printk("scsi(%ld): Handle RSCN -- process RSCN for "
1105 "port id [%02x%02x%02x].\n", ha
->host_no
,
1106 rscn_pid
.b
.domain
, rscn_pid
.b
.area
, rscn_pid
.b
.al_pa
));
1109 * Search fcport lists for a known entry at the specified port
1112 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1113 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1114 remote_fcport
= fcport
;
1118 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1119 if (rscn_pid
.b24
== fcport
->d_id
.b24
) {
1120 rscn_fcport
= fcport
;
1124 if (remote_fcport
== NULL
)
1125 remote_fcport
= rscn_fcport
;
1129 * If the port is already in our fcport list and online, send an ADISC
1130 * to see if it's still alive. Issue login if a new fcport or the known
1131 * fcport is currently offline.
1133 if (remote_fcport
) {
1135 * No need to send request if the remote fcport is currently
1136 * waiting for an available io descriptor.
1138 if (known_fcport
== NULL
&&
1139 (remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1140 remote_fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
)) {
1142 * If previous waiting io descriptor is an ADISC, then
1143 * the new RSCN may come from a new remote fcport being
1144 * plugged into the same location.
1146 if (remote_fcport
->port_type
== FCT_RSCN
) {
1147 remote_fcport
->iodesc_idx_sent
=
1148 IODESC_LOGIN_NEEDED
;
1149 } else if (remote_fcport
->iodesc_idx_sent
==
1150 IODESC_ADISC_NEEDED
) {
1151 fc_port_t
*new_fcport
;
1153 remote_fcport
->iodesc_idx_sent
=
1154 IODESC_INVALID_INDEX
;
1156 /* Create new fcport for later login. */
1157 new_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1158 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1160 DEBUG14(printk("scsi(%ld): Handle RSCN "
1161 "-- creating RSCN fcport %p for "
1162 "future login.\n", ha
->host_no
,
1165 new_fcport
->d_id
.b24
=
1166 remote_fcport
->d_id
.b24
;
1167 new_fcport
->iodesc_idx_sent
=
1168 IODESC_LOGIN_NEEDED
;
1170 list_add_tail(&new_fcport
->list
,
1172 set_bit(IODESC_PROCESS_NEEDED
,
1175 DEBUG14(printk("scsi(%ld): Handle RSCN "
1176 "-- unable to allocate RSCN fcport "
1177 "for future login.\n",
1181 return (QLA_SUCCESS
);
1184 /* Send ADISC if the fcport is online */
1185 if (atomic_read(&remote_fcport
->state
) == FCS_ONLINE
||
1186 remote_fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
) {
1188 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1190 iodesc
= qla2x00_alloc_iodesc(ha
);
1191 if (iodesc
== NULL
) {
1192 /* Mark fcport for later adisc processing */
1193 DEBUG14(printk("scsi(%ld): Handle RSCN -- not "
1194 "enough IO descriptors for Adisc, flag "
1195 "for later processing.\n", ha
->host_no
));
1197 remote_fcport
->iodesc_idx_sent
=
1198 IODESC_ADISC_NEEDED
;
1199 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1201 return (QLA_SUCCESS
);
1204 iodesc
->cb_idx
= ADISC_PORT_IOCB_CB
;
1205 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1206 iodesc
->remote_fcport
= remote_fcport
;
1207 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1208 qla2x00_send_adisc_iocb(ha
, iodesc
, ha_locked
);
1210 return (QLA_SUCCESS
);
1211 } else if (remote_fcport
->iodesc_idx_sent
<
1212 MAX_IO_DESCRIPTORS
&&
1213 ha
->io_descriptors
[remote_fcport
->iodesc_idx_sent
].cb_idx
==
1214 ADISC_PORT_IOCB_CB
) {
1216 * Receiving another RSCN while an ADISC is pending,
1217 * abort the IOCB. Use the same descriptor for the
1220 uint32_t handle_to_abort
;
1222 iodesc
= &ha
->io_descriptors
[
1223 remote_fcport
->iodesc_idx_sent
];
1224 qla2x00_remove_iodesc_timer(iodesc
);
1225 handle_to_abort
= iodesc
->signature
;
1226 iodesc
->signature
= qla2x00_iodesc_to_handle(iodesc
);
1227 iodesc
->cb_idx
= ABORT_IOCB_CB
;
1228 iodesc
->d_id
.b24
= remote_fcport
->d_id
.b24
;
1229 iodesc
->remote_fcport
= remote_fcport
;
1230 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1232 DEBUG14(printk("scsi(%ld): Handle RSCN -- issuing "
1233 "abort to outstanding Adisc [%x/%02x%02x%02x].\n",
1234 ha
->host_no
, remote_fcport
->loop_id
,
1235 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
,
1236 iodesc
->d_id
.b
.al_pa
));
1238 qla2x00_send_abort_iocb(ha
, iodesc
, handle_to_abort
,
1243 /* We need to login to the remote port, find it. */
1245 remote_fcport
= known_fcport
;
1246 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1247 rscn_fcport
->iodesc_idx_sent
< MAX_IO_DESCRIPTORS
&&
1248 ha
->io_descriptors
[rscn_fcport
->iodesc_idx_sent
].cb_idx
==
1249 LOGIN_PORT_IOCB_CB
) {
1251 * Ignore duplicate RSCN on fcport which has already
1252 * initiated a login IOCB.
1254 DEBUG14(printk("scsi(%ld): Handle RSCN -- ignoring, login "
1255 "already sent to [%02x%02x%02x].\n", ha
->host_no
,
1256 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1257 rscn_fcport
->d_id
.b
.al_pa
));
1259 return (QLA_SUCCESS
);
1260 } else if (rscn_fcport
&& rscn_fcport
->d_id
.b24
!= INVALID_PORT_ID
&&
1261 rscn_fcport
!= remote_fcport
) {
1262 /* Reuse same rscn fcport. */
1263 DEBUG14(printk("scsi(%ld): Handle RSCN -- reusing RSCN fcport "
1264 "[%02x%02x%02x].\n", ha
->host_no
,
1265 rscn_fcport
->d_id
.b
.domain
, rscn_fcport
->d_id
.b
.area
,
1266 rscn_fcport
->d_id
.b
.al_pa
));
1268 remote_fcport
= rscn_fcport
;
1270 /* Create new fcport for later login. */
1271 remote_fcport
= qla2x00_alloc_rscn_fcport(ha
,
1272 ha_locked
? GFP_ATOMIC
: GFP_KERNEL
);
1273 list_add_tail(&remote_fcport
->list
, &ha
->rscn_fcports
);
1275 if (remote_fcport
== NULL
)
1276 return (QLA_SUCCESS
);
1278 /* Prepare fcport for login. */
1279 atomic_set(&remote_fcport
->state
, FCS_DEVICE_LOST
);
1280 remote_fcport
->login_retry
= 3; /* ha->login_retry_count; */
1281 remote_fcport
->d_id
.b24
= rscn_pid
.b24
;
1283 iodesc
= qla2x00_alloc_iodesc(ha
);
1284 if (iodesc
== NULL
) {
1285 /* Mark fcport for later adisc processing. */
1286 DEBUG14(printk("scsi(%ld): Handle RSCN -- not enough IO "
1287 "descriptors for Login, flag for later processing.\n",
1290 remote_fcport
->iodesc_idx_sent
= IODESC_LOGIN_NEEDED
;
1291 set_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1293 return (QLA_SUCCESS
);
1296 if (known_fcport
== NULL
|| rscn_pid
.b24
!= INVALID_PORT_ID
) {
1297 remote_fcport
->loop_id
= ha
->min_external_loopid
;
1299 rval
= qla2x00_find_new_loop_id(ha
, remote_fcport
);
1300 if (rval
== QLA_FUNCTION_FAILED
) {
1301 /* No more loop ids, failed. */
1302 DEBUG14(printk("scsi(%ld): Handle RSCN -- no available "
1303 "loop id to perform Login, failed.\n",
1310 iodesc
->cb_idx
= LOGIN_PORT_IOCB_CB
;
1311 iodesc
->d_id
.b24
= rscn_pid
.b24
;
1312 iodesc
->remote_fcport
= remote_fcport
;
1313 remote_fcport
->iodesc_idx_sent
= iodesc
->idx
;
1315 DEBUG14(printk("scsi(%ld): Handle RSCN -- attempting login to "
1316 "[%x/%02x%02x%02x].\n", ha
->host_no
, remote_fcport
->loop_id
,
1317 iodesc
->d_id
.b
.domain
, iodesc
->d_id
.b
.area
, iodesc
->d_id
.b
.al_pa
));
1319 qla2x00_send_login_iocb(ha
, iodesc
, &rscn_pid
, ha_locked
);
1321 return (QLA_SUCCESS
);
1325 * qla2x00_process_iodesc() - Complete IO descriptor processing.
1327 * @mbxstat: Mailbox IOCB status
1330 qla2x00_process_iodesc(scsi_qla_host_t
*ha
, struct mbx_entry
*mbxstat
)
1335 struct io_descriptor
*iodesc
;
1337 signature
= mbxstat
->handle
;
1339 DEBUG14(printk("scsi(%ld): Process IODesc -- processing %08x.\n",
1340 ha
->host_no
, signature
));
1342 /* Retrieve proper IO descriptor. */
1343 iodesc
= qla2x00_handle_to_iodesc(ha
, signature
);
1344 if (iodesc
== NULL
) {
1345 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1346 "incorrect signature %08x.\n", ha
->host_no
, signature
));
1351 /* Stop IO descriptor timer. */
1352 qla2x00_remove_iodesc_timer(iodesc
);
1354 /* Verify signature match. */
1355 if (iodesc
->signature
!= signature
) {
1356 DEBUG14(printk("scsi(%ld): Process IODesc -- ignoring, "
1357 "signature mismatch, sent %08x, received %08x.\n",
1358 ha
->host_no
, iodesc
->signature
, signature
));
1363 /* Go with IOCB callback. */
1364 rval
= iocb_function_cb_list
[iodesc
->cb_idx
](ha
, iodesc
, mbxstat
);
1365 if (rval
!= QLA_SUCCESS
) {
1366 /* IO descriptor reused by callback. */
1370 qla2x00_free_iodesc(iodesc
);
1372 if (test_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
)) {
1373 /* Scan our fcports list for any RSCN requests. */
1374 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1375 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1376 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1377 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1382 /* Scan our RSCN fcports list for any RSCN requests. */
1383 list_for_each_entry(fcport
, &ha
->rscn_fcports
, list
) {
1384 if (fcport
->iodesc_idx_sent
== IODESC_ADISC_NEEDED
||
1385 fcport
->iodesc_idx_sent
== IODESC_LOGIN_NEEDED
) {
1386 qla2x00_handle_port_rscn(ha
, 0, fcport
, 1);
1391 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1395 * qla2x00_cancel_io_descriptors() - Cancel all outstanding io descriptors.
1398 * This routine will also delete any RSCN entries related to the outstanding
1402 qla2x00_cancel_io_descriptors(scsi_qla_host_t
*ha
)
1404 fc_port_t
*fcport
, *fcptemp
;
1406 clear_bit(IODESC_PROCESS_NEEDED
, &ha
->dpc_flags
);
1408 /* Abort all IO descriptors. */
1409 qla2x00_init_io_descriptors(ha
);
1411 /* Reset all pending IO descriptors in fcports list. */
1412 list_for_each_entry(fcport
, &ha
->fcports
, list
) {
1413 fcport
->iodesc_idx_sent
= IODESC_INVALID_INDEX
;
1416 /* Reset all pending IO descriptors in rscn fcports list. */
1417 list_for_each_entry_safe(fcport
, fcptemp
, &ha
->rscn_fcports
, list
) {
1418 DEBUG14(printk("scsi(%ld): Cancel IOs -- Freeing RSCN fcport "
1419 "%p [%x/%02x%02x%02x].\n", ha
->host_no
, fcport
,
1420 fcport
->loop_id
, fcport
->d_id
.b
.domain
, fcport
->d_id
.b
.area
,
1421 fcport
->d_id
.b
.al_pa
));
1423 list_del(&fcport
->list
);