diff options
author | Arun Easi <arun.easi@qlogic.com> | 2012-02-09 14:15:39 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:16:44 -0500 |
commit | b3b02e6e9512636d5a1839b325e4722e80cda90d (patch) | |
tree | 2506fd856cac230170d13ba87f9e28384c091573 /drivers/scsi/qla2xxx | |
parent | 18f509dfa21a69b8de4145edc794172ed55a84a5 (diff) |
[SCSI] qla2xxx: Handle change notifications based on switch scan results.
Instead of processing each RSCN individually, use only the name server results
from the switch to tell the existance of a given fcport.
Signed-off-by: Arun Easi <arun.easi@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 136 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 12 |
3 files changed, 13 insertions, 144 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6704ef84c450..7a224b710ad4 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -127,7 +127,6 @@ | |||
127 | #define WWN_SIZE 8 /* Size of WWPN, WWN & WWNN */ | 127 | #define WWN_SIZE 8 /* Size of WWPN, WWN & WWNN */ |
128 | #define MAX_FIBRE_DEVICES 512 | 128 | #define MAX_FIBRE_DEVICES 512 |
129 | #define MAX_FIBRE_LUNS 0xFFFF | 129 | #define MAX_FIBRE_LUNS 0xFFFF |
130 | #define MAX_RSCN_COUNT 32 | ||
131 | #define MAX_HOST_COUNT 16 | 130 | #define MAX_HOST_COUNT 16 |
132 | 131 | ||
133 | /* | 132 | /* |
@@ -1720,6 +1719,7 @@ typedef struct fc_port { | |||
1720 | 1719 | ||
1721 | uint16_t vp_idx; | 1720 | uint16_t vp_idx; |
1722 | uint8_t fc4_type; | 1721 | uint8_t fc4_type; |
1722 | uint8_t scan_state; | ||
1723 | } fc_port_t; | 1723 | } fc_port_t; |
1724 | 1724 | ||
1725 | /* | 1725 | /* |
@@ -2877,7 +2877,6 @@ typedef struct scsi_qla_host { | |||
2877 | volatile struct { | 2877 | volatile struct { |
2878 | uint32_t init_done :1; | 2878 | uint32_t init_done :1; |
2879 | uint32_t online :1; | 2879 | uint32_t online :1; |
2880 | uint32_t rscn_queue_overflow :1; | ||
2881 | uint32_t reset_active :1; | 2880 | uint32_t reset_active :1; |
2882 | 2881 | ||
2883 | uint32_t management_server_logged_in :1; | 2882 | uint32_t management_server_logged_in :1; |
@@ -2931,11 +2930,6 @@ typedef struct scsi_qla_host { | |||
2931 | 2930 | ||
2932 | 2931 | ||
2933 | 2932 | ||
2934 | /* RSCN queue. */ | ||
2935 | uint32_t rscn_queue[MAX_RSCN_COUNT]; | ||
2936 | uint8_t rscn_in_ptr; | ||
2937 | uint8_t rscn_out_ptr; | ||
2938 | |||
2939 | /* Timeout timers. */ | 2933 | /* Timeout timers. */ |
2940 | uint8_t loop_down_abort_time; /* port down timer */ | 2934 | uint8_t loop_down_abort_time; /* port down timer */ |
2941 | atomic_t loop_down_timer; /* loop down timer */ | 2935 | atomic_t loop_down_timer; /* loop down timer */ |
@@ -3031,7 +3025,6 @@ typedef struct scsi_qla_host { | |||
3031 | #define QLA_ABORTED 0x105 | 3025 | #define QLA_ABORTED 0x105 |
3032 | #define QLA_SUSPENDED 0x106 | 3026 | #define QLA_SUSPENDED 0x106 |
3033 | #define QLA_BUSY 0x107 | 3027 | #define QLA_BUSY 0x107 |
3034 | #define QLA_RSCNS_HANDLED 0x108 | ||
3035 | #define QLA_ALREADY_REGISTERED 0x109 | 3028 | #define QLA_ALREADY_REGISTERED 0x109 |
3036 | 3029 | ||
3037 | #define NVRAM_DELAY() udelay(10) | 3030 | #define NVRAM_DELAY() udelay(10) |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 4837b5872cde..ff841d7172f2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -29,7 +29,6 @@ static int qla2x00_configure_loop(scsi_qla_host_t *); | |||
29 | static int qla2x00_configure_local_loop(scsi_qla_host_t *); | 29 | static int qla2x00_configure_local_loop(scsi_qla_host_t *); |
30 | static int qla2x00_configure_fabric(scsi_qla_host_t *); | 30 | static int qla2x00_configure_fabric(scsi_qla_host_t *); |
31 | static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *); | 31 | static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *); |
32 | static int qla2x00_device_resync(scsi_qla_host_t *); | ||
33 | static int qla2x00_fabric_dev_login(scsi_qla_host_t *, fc_port_t *, | 32 | static int qla2x00_fabric_dev_login(scsi_qla_host_t *, fc_port_t *, |
34 | uint16_t *); | 33 | uint16_t *); |
35 | 34 | ||
@@ -1755,7 +1754,6 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
1755 | struct qla_hw_data *ha = vha->hw; | 1754 | struct qla_hw_data *ha = vha->hw; |
1756 | struct req_que *req; | 1755 | struct req_que *req; |
1757 | struct rsp_que *rsp; | 1756 | struct rsp_que *rsp; |
1758 | struct scsi_qla_host *vp; | ||
1759 | struct mid_init_cb_24xx *mid_init_cb = | 1757 | struct mid_init_cb_24xx *mid_init_cb = |
1760 | (struct mid_init_cb_24xx *) ha->init_cb; | 1758 | (struct mid_init_cb_24xx *) ha->init_cb; |
1761 | 1759 | ||
@@ -1786,11 +1784,6 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
1786 | } | 1784 | } |
1787 | 1785 | ||
1788 | spin_lock(&ha->vport_slock); | 1786 | spin_lock(&ha->vport_slock); |
1789 | /* Clear RSCN queue. */ | ||
1790 | list_for_each_entry(vp, &ha->vp_list, list) { | ||
1791 | vp->rscn_in_ptr = 0; | ||
1792 | vp->rscn_out_ptr = 0; | ||
1793 | } | ||
1794 | 1787 | ||
1795 | spin_unlock(&ha->vport_slock); | 1788 | spin_unlock(&ha->vport_slock); |
1796 | 1789 | ||
@@ -2551,13 +2544,11 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
2551 | if (ha->current_topology == ISP_CFG_FL && | 2544 | if (ha->current_topology == ISP_CFG_FL && |
2552 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { | 2545 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { |
2553 | 2546 | ||
2554 | vha->flags.rscn_queue_overflow = 1; | ||
2555 | set_bit(RSCN_UPDATE, &flags); | 2547 | set_bit(RSCN_UPDATE, &flags); |
2556 | 2548 | ||
2557 | } else if (ha->current_topology == ISP_CFG_F && | 2549 | } else if (ha->current_topology == ISP_CFG_F && |
2558 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { | 2550 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { |
2559 | 2551 | ||
2560 | vha->flags.rscn_queue_overflow = 1; | ||
2561 | set_bit(RSCN_UPDATE, &flags); | 2552 | set_bit(RSCN_UPDATE, &flags); |
2562 | clear_bit(LOCAL_LOOP_UPDATE, &flags); | 2553 | clear_bit(LOCAL_LOOP_UPDATE, &flags); |
2563 | 2554 | ||
@@ -2567,7 +2558,6 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
2567 | } else if (!vha->flags.online || | 2558 | } else if (!vha->flags.online || |
2568 | (test_bit(ABORT_ISP_ACTIVE, &flags))) { | 2559 | (test_bit(ABORT_ISP_ACTIVE, &flags))) { |
2569 | 2560 | ||
2570 | vha->flags.rscn_queue_overflow = 1; | ||
2571 | set_bit(RSCN_UPDATE, &flags); | 2561 | set_bit(RSCN_UPDATE, &flags); |
2572 | set_bit(LOCAL_LOOP_UPDATE, &flags); | 2562 | set_bit(LOCAL_LOOP_UPDATE, &flags); |
2573 | } | 2563 | } |
@@ -2617,8 +2607,6 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
2617 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 2607 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
2618 | if (test_bit(RSCN_UPDATE, &save_flags)) { | 2608 | if (test_bit(RSCN_UPDATE, &save_flags)) { |
2619 | set_bit(RSCN_UPDATE, &vha->dpc_flags); | 2609 | set_bit(RSCN_UPDATE, &vha->dpc_flags); |
2620 | if (!IS_ALOGIO_CAPABLE(ha)) | ||
2621 | vha->flags.rscn_queue_overflow = 1; | ||
2622 | } | 2610 | } |
2623 | } | 2611 | } |
2624 | 2612 | ||
@@ -2926,7 +2914,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
2926 | static int | 2914 | static int |
2927 | qla2x00_configure_fabric(scsi_qla_host_t *vha) | 2915 | qla2x00_configure_fabric(scsi_qla_host_t *vha) |
2928 | { | 2916 | { |
2929 | int rval, rval2; | 2917 | int rval; |
2930 | fc_port_t *fcport, *fcptemp; | 2918 | fc_port_t *fcport, *fcptemp; |
2931 | uint16_t next_loopid; | 2919 | uint16_t next_loopid; |
2932 | uint16_t mb[MAILBOX_REGISTER_COUNT]; | 2920 | uint16_t mb[MAILBOX_REGISTER_COUNT]; |
@@ -2950,12 +2938,6 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2950 | } | 2938 | } |
2951 | vha->device_flags |= SWITCH_FOUND; | 2939 | vha->device_flags |= SWITCH_FOUND; |
2952 | 2940 | ||
2953 | /* Mark devices that need re-synchronization. */ | ||
2954 | rval2 = qla2x00_device_resync(vha); | ||
2955 | if (rval2 == QLA_RSCNS_HANDLED) { | ||
2956 | /* No point doing the scan, just continue. */ | ||
2957 | return (QLA_SUCCESS); | ||
2958 | } | ||
2959 | do { | 2941 | do { |
2960 | /* FDMI support. */ | 2942 | /* FDMI support. */ |
2961 | if (ql2xfdmienable && | 2943 | if (ql2xfdmienable && |
@@ -2999,6 +2981,13 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2999 | } | 2981 | } |
3000 | } | 2982 | } |
3001 | 2983 | ||
2984 | #define QLA_FCPORT_SCAN 1 | ||
2985 | #define QLA_FCPORT_FOUND 2 | ||
2986 | |||
2987 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | ||
2988 | fcport->scan_state = QLA_FCPORT_SCAN; | ||
2989 | } | ||
2990 | |||
3002 | rval = qla2x00_find_all_fabric_devs(vha, &new_fcports); | 2991 | rval = qla2x00_find_all_fabric_devs(vha, &new_fcports); |
3003 | if (rval != QLA_SUCCESS) | 2992 | if (rval != QLA_SUCCESS) |
3004 | break; | 2993 | break; |
@@ -3014,7 +3003,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
3014 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) | 3003 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) |
3015 | continue; | 3004 | continue; |
3016 | 3005 | ||
3017 | if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { | 3006 | if (fcport->scan_state == QLA_FCPORT_SCAN && |
3007 | atomic_read(&fcport->state) == FCS_ONLINE) { | ||
3018 | qla2x00_mark_device_lost(vha, fcport, | 3008 | qla2x00_mark_device_lost(vha, fcport, |
3019 | ql2xplogiabsentdevice, 0); | 3009 | ql2xplogiabsentdevice, 0); |
3020 | if (fcport->loop_id != FC_NO_LOOP_ID && | 3010 | if (fcport->loop_id != FC_NO_LOOP_ID && |
@@ -3287,6 +3277,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, | |||
3287 | WWN_SIZE)) | 3277 | WWN_SIZE)) |
3288 | continue; | 3278 | continue; |
3289 | 3279 | ||
3280 | fcport->scan_state = QLA_FCPORT_FOUND; | ||
3281 | |||
3290 | found++; | 3282 | found++; |
3291 | 3283 | ||
3292 | /* Update port state. */ | 3284 | /* Update port state. */ |
@@ -3443,110 +3435,6 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) | |||
3443 | } | 3435 | } |
3444 | 3436 | ||
3445 | /* | 3437 | /* |
3446 | * qla2x00_device_resync | ||
3447 | * Marks devices in the database that needs resynchronization. | ||
3448 | * | ||
3449 | * Input: | ||
3450 | * ha = adapter block pointer. | ||
3451 | * | ||
3452 | * Context: | ||
3453 | * Kernel context. | ||
3454 | */ | ||
3455 | static int | ||
3456 | qla2x00_device_resync(scsi_qla_host_t *vha) | ||
3457 | { | ||
3458 | int rval; | ||
3459 | uint32_t mask; | ||
3460 | fc_port_t *fcport; | ||
3461 | uint32_t rscn_entry; | ||
3462 | uint8_t rscn_out_iter; | ||
3463 | uint8_t format; | ||
3464 | port_id_t d_id = {}; | ||
3465 | |||
3466 | rval = QLA_RSCNS_HANDLED; | ||
3467 | |||
3468 | while (vha->rscn_out_ptr != vha->rscn_in_ptr || | ||
3469 | vha->flags.rscn_queue_overflow) { | ||
3470 | |||
3471 | rscn_entry = vha->rscn_queue[vha->rscn_out_ptr]; | ||
3472 | format = MSB(MSW(rscn_entry)); | ||
3473 | d_id.b.domain = LSB(MSW(rscn_entry)); | ||
3474 | d_id.b.area = MSB(LSW(rscn_entry)); | ||
3475 | d_id.b.al_pa = LSB(LSW(rscn_entry)); | ||
3476 | |||
3477 | ql_dbg(ql_dbg_disc, vha, 0x2020, | ||
3478 | "RSCN queue entry[%d] = [%02x/%02x%02x%02x].\n", | ||
3479 | vha->rscn_out_ptr, format, d_id.b.domain, d_id.b.area, | ||
3480 | d_id.b.al_pa); | ||
3481 | |||
3482 | vha->rscn_out_ptr++; | ||
3483 | if (vha->rscn_out_ptr == MAX_RSCN_COUNT) | ||
3484 | vha->rscn_out_ptr = 0; | ||
3485 | |||
3486 | /* Skip duplicate entries. */ | ||
3487 | for (rscn_out_iter = vha->rscn_out_ptr; | ||
3488 | !vha->flags.rscn_queue_overflow && | ||
3489 | rscn_out_iter != vha->rscn_in_ptr; | ||
3490 | rscn_out_iter = (rscn_out_iter == | ||
3491 | (MAX_RSCN_COUNT - 1)) ? 0: rscn_out_iter + 1) { | ||
3492 | |||
3493 | if (rscn_entry != vha->rscn_queue[rscn_out_iter]) | ||
3494 | break; | ||
3495 | |||
3496 | ql_dbg(ql_dbg_disc, vha, 0x2021, | ||
3497 | "Skipping duplicate RSCN queue entry found at " | ||
3498 | "[%d].\n", rscn_out_iter); | ||
3499 | |||
3500 | vha->rscn_out_ptr = rscn_out_iter; | ||
3501 | } | ||
3502 | |||
3503 | /* Queue overflow, set switch default case. */ | ||
3504 | if (vha->flags.rscn_queue_overflow) { | ||
3505 | ql_dbg(ql_dbg_disc, vha, 0x2022, | ||
3506 | "device_resync: rscn overflow.\n"); | ||
3507 | |||
3508 | format = 3; | ||
3509 | vha->flags.rscn_queue_overflow = 0; | ||
3510 | } | ||
3511 | |||
3512 | switch (format) { | ||
3513 | case 0: | ||
3514 | mask = 0xffffff; | ||
3515 | break; | ||
3516 | case 1: | ||
3517 | mask = 0xffff00; | ||
3518 | break; | ||
3519 | case 2: | ||
3520 | mask = 0xff0000; | ||
3521 | break; | ||
3522 | default: | ||
3523 | mask = 0x0; | ||
3524 | d_id.b24 = 0; | ||
3525 | vha->rscn_out_ptr = vha->rscn_in_ptr; | ||
3526 | break; | ||
3527 | } | ||
3528 | |||
3529 | rval = QLA_SUCCESS; | ||
3530 | |||
3531 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | ||
3532 | if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || | ||
3533 | (fcport->d_id.b24 & mask) != d_id.b24 || | ||
3534 | fcport->port_type == FCT_BROADCAST) | ||
3535 | continue; | ||
3536 | |||
3537 | if (atomic_read(&fcport->state) == FCS_ONLINE) { | ||
3538 | if (format != 3 || | ||
3539 | fcport->port_type != FCT_INITIATOR) { | ||
3540 | qla2x00_mark_device_lost(vha, fcport, | ||
3541 | 0, 0); | ||
3542 | } | ||
3543 | } | ||
3544 | } | ||
3545 | } | ||
3546 | return (rval); | ||
3547 | } | ||
3548 | |||
3549 | /* | ||
3550 | * qla2x00_fabric_dev_login | 3438 | * qla2x00_fabric_dev_login |
3551 | * Login fabric target device and update FC port database. | 3439 | * Login fabric target device and update FC port database. |
3552 | * | 3440 | * |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d4c0b337a0a6..39a0584889f9 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -328,7 +328,6 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) | |||
328 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; | 328 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; |
329 | struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; | 329 | struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; |
330 | uint32_t rscn_entry, host_pid; | 330 | uint32_t rscn_entry, host_pid; |
331 | uint8_t rscn_queue_index; | ||
332 | unsigned long flags; | 331 | unsigned long flags; |
333 | 332 | ||
334 | /* Setup to process RIO completion. */ | 333 | /* Setup to process RIO completion. */ |
@@ -685,8 +684,6 @@ skip_rio: | |||
685 | 684 | ||
686 | qla2x00_mark_all_devices_lost(vha, 1); | 685 | qla2x00_mark_all_devices_lost(vha, 1); |
687 | 686 | ||
688 | vha->flags.rscn_queue_overflow = 1; | ||
689 | |||
690 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | 687 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
691 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 688 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
692 | break; | 689 | break; |
@@ -715,15 +712,6 @@ skip_rio: | |||
715 | 712 | ||
716 | /* Ignore reserved bits from RSCN-payload. */ | 713 | /* Ignore reserved bits from RSCN-payload. */ |
717 | rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2]; | 714 | rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2]; |
718 | rscn_queue_index = vha->rscn_in_ptr + 1; | ||
719 | if (rscn_queue_index == MAX_RSCN_COUNT) | ||
720 | rscn_queue_index = 0; | ||
721 | if (rscn_queue_index != vha->rscn_out_ptr) { | ||
722 | vha->rscn_queue[vha->rscn_in_ptr] = rscn_entry; | ||
723 | vha->rscn_in_ptr = rscn_queue_index; | ||
724 | } else { | ||
725 | vha->flags.rscn_queue_overflow = 1; | ||
726 | } | ||
727 | 715 | ||
728 | atomic_set(&vha->loop_down_timer, 0); | 716 | atomic_set(&vha->loop_down_timer, 0); |
729 | vha->flags.management_server_logged_in = 0; | 717 | vha->flags.management_server_logged_in = 0; |