diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2007-11-12 13:30:58 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:22:45 -0500 |
commit | eb66dc60be5a72bc940458a5adfd400e4d810d49 (patch) | |
tree | 677baf5655d9ae312e877cab4adb33a1319e9993 /drivers/scsi/qla2xxx | |
parent | 06e23b7470ca7974b0ca8150c5415b55b5ea2a99 (diff) |
[SCSI] qla2xxx: Correct NPIV support for recent ISPs.
Firmware will export to software the maximum number of vports
supported for any given firmware version and ISP type. Use this
information rather than the current hardcoding of limitations
within the driver.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 10 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 19 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 33 |
6 files changed, 33 insertions, 51 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index fb388b8c07cf..745283fcbf2c 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1124,7 +1124,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
1124 | 1124 | ||
1125 | down(&ha->vport_sem); | 1125 | down(&ha->vport_sem); |
1126 | ha->cur_vport_count--; | 1126 | ha->cur_vport_count--; |
1127 | clear_bit(vha->vp_idx, (unsigned long *)ha->vp_idx_map); | 1127 | clear_bit(vha->vp_idx, ha->vp_idx_map); |
1128 | up(&ha->vport_sem); | 1128 | up(&ha->vport_sem); |
1129 | 1129 | ||
1130 | kfree(vha->node_name); | 1130 | kfree(vha->node_name); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 04e8cbca4c0d..fe8f7828f592 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2116,14 +2116,6 @@ struct qla_msix_entry { | |||
2116 | 2116 | ||
2117 | #define WATCH_INTERVAL 1 /* number of seconds */ | 2117 | #define WATCH_INTERVAL 1 /* number of seconds */ |
2118 | 2118 | ||
2119 | /* NPIV */ | ||
2120 | #define MAX_MULTI_ID_LOOP 126 | ||
2121 | #define MAX_MULTI_ID_FABRIC 64 | ||
2122 | #define MAX_NUM_VPORT_LOOP (MAX_MULTI_ID_LOOP - 1) | ||
2123 | #define MAX_NUM_VPORT_FABRIC (MAX_MULTI_ID_FABRIC - 1) | ||
2124 | #define MAX_NUM_VHBA_LOOP (MAX_MULTI_ID_LOOP - 1) | ||
2125 | #define MAX_NUM_VHBA_FABRIC (MAX_MULTI_ID_FABRIC - 1) | ||
2126 | |||
2127 | /* | 2119 | /* |
2128 | * Linux Host Adapter structure | 2120 | * Linux Host Adapter structure |
2129 | */ | 2121 | */ |
@@ -2507,7 +2499,7 @@ typedef struct scsi_qla_host { | |||
2507 | 2499 | ||
2508 | struct list_head vp_list; /* list of VP */ | 2500 | struct list_head vp_list; /* list of VP */ |
2509 | struct fc_vport *fc_vport; /* holds fc_vport * for each vport */ | 2501 | struct fc_vport *fc_vport; /* holds fc_vport * for each vport */ |
2510 | uint8_t vp_idx_map[16]; | 2502 | unsigned long vp_idx_map[(MAX_MULTI_ID_FABRIC / 8) / sizeof(unsigned long)]; |
2511 | uint16_t num_vhosts; /* number of vports created */ | 2503 | uint16_t num_vhosts; /* number of vports created */ |
2512 | uint16_t num_vsans; /* number of vsan created */ | 2504 | uint16_t num_vsans; /* number of vsan created */ |
2513 | uint16_t vp_idx; /* vport ID */ | 2505 | uint16_t vp_idx; /* vport ID */ |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 25364b1aaf12..69a5e31dd93a 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -954,7 +954,15 @@ struct device_reg_24xx { | |||
954 | 954 | ||
955 | /* MID Support ***************************************************************/ | 955 | /* MID Support ***************************************************************/ |
956 | 956 | ||
957 | #define MAX_MID_VPS 125 | 957 | #define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */ |
958 | #define MAX_MULTI_ID_FABRIC 256 /* ... */ | ||
959 | |||
960 | #define for_each_mapped_vp_idx(_ha, _idx) \ | ||
961 | for (_idx = find_next_bit((_ha)->vp_idx_map, \ | ||
962 | (_ha)->max_npiv_vports + 1, 1); \ | ||
963 | _idx <= (_ha)->max_npiv_vports; \ | ||
964 | _idx = find_next_bit((_ha)->vp_idx_map, \ | ||
965 | (_ha)->max_npiv_vports + 1, _idx + 1)) \ | ||
958 | 966 | ||
959 | struct mid_conf_entry_24xx { | 967 | struct mid_conf_entry_24xx { |
960 | uint16_t reserved_1; | 968 | uint16_t reserved_1; |
@@ -982,7 +990,7 @@ struct mid_init_cb_24xx { | |||
982 | uint16_t count; | 990 | uint16_t count; |
983 | uint16_t options; | 991 | uint16_t options; |
984 | 992 | ||
985 | struct mid_conf_entry_24xx entries[MAX_MID_VPS]; | 993 | struct mid_conf_entry_24xx entries[MAX_MULTI_ID_FABRIC]; |
986 | }; | 994 | }; |
987 | 995 | ||
988 | 996 | ||
@@ -1002,10 +1010,6 @@ struct mid_db_entry_24xx { | |||
1002 | uint8_t reserved_1; | 1010 | uint8_t reserved_1; |
1003 | }; | 1011 | }; |
1004 | 1012 | ||
1005 | struct mid_db_24xx { | ||
1006 | struct mid_db_entry_24xx entries[MAX_MID_VPS]; | ||
1007 | }; | ||
1008 | |||
1009 | /* | 1013 | /* |
1010 | * Virtual Fabric ID type definition. | 1014 | * Virtual Fabric ID type definition. |
1011 | */ | 1015 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 191dafd89be0..03444d6e4d26 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -922,9 +922,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
922 | ha->flags.npiv_supported = 1; | 922 | ha->flags.npiv_supported = 1; |
923 | if ((!ha->max_npiv_vports) || | 923 | if ((!ha->max_npiv_vports) || |
924 | ((ha->max_npiv_vports + 1) % | 924 | ((ha->max_npiv_vports + 1) % |
925 | MAX_MULTI_ID_FABRIC)) | 925 | MIN_MULTI_ID_FABRIC)) |
926 | ha->max_npiv_vports = | 926 | ha->max_npiv_vports = |
927 | MAX_NUM_VPORT_FABRIC; | 927 | MIN_MULTI_ID_FABRIC - 1; |
928 | } | 928 | } |
929 | 929 | ||
930 | if (ql2xallocfwdump) | 930 | if (ql2xallocfwdump) |
@@ -1162,7 +1162,8 @@ qla2x00_init_rings(scsi_qla_host_t *ha) | |||
1162 | 1162 | ||
1163 | DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); | 1163 | DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); |
1164 | 1164 | ||
1165 | mid_init_cb->count = ha->max_npiv_vports; | 1165 | mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports); |
1166 | mid_init_cb->options = __constant_cpu_to_le16(BIT_1); | ||
1166 | 1167 | ||
1167 | rval = qla2x00_init_firmware(ha, ha->init_cb_size); | 1168 | rval = qla2x00_init_firmware(ha, ha->init_cb_size); |
1168 | if (rval) { | 1169 | if (rval) { |
@@ -2566,14 +2567,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2566 | 2567 | ||
2567 | /* Bypass virtual ports of the same host. */ | 2568 | /* Bypass virtual ports of the same host. */ |
2568 | if (pha->num_vhosts) { | 2569 | if (pha->num_vhosts) { |
2569 | vp_index = find_next_bit( | 2570 | for_each_mapped_vp_idx(pha, vp_index) { |
2570 | (unsigned long *)pha->vp_idx_map, | ||
2571 | MAX_MULTI_ID_FABRIC + 1, 1); | ||
2572 | |||
2573 | for (;vp_index <= MAX_MULTI_ID_FABRIC; | ||
2574 | vp_index = find_next_bit( | ||
2575 | (unsigned long *)pha->vp_idx_map, | ||
2576 | MAX_MULTI_ID_FABRIC + 1, vp_index + 1)) { | ||
2577 | empty_vp_index = 1; | 2571 | empty_vp_index = 1; |
2578 | found_vp = 0; | 2572 | found_vp = 0; |
2579 | list_for_each_entry(vha, &pha->vp_list, | 2573 | list_for_each_entry(vha, &pha->vp_list, |
@@ -2592,7 +2586,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2592 | new_fcport->d_id.b24 == vha->d_id.b24) | 2586 | new_fcport->d_id.b24 == vha->d_id.b24) |
2593 | break; | 2587 | break; |
2594 | } | 2588 | } |
2595 | if (vp_index <= MAX_MULTI_ID_FABRIC) | 2589 | |
2590 | if (vp_index <= pha->max_npiv_vports) | ||
2596 | continue; | 2591 | continue; |
2597 | } | 2592 | } |
2598 | 2593 | ||
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index ccd662a6f5dc..031f269149b1 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -905,7 +905,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
905 | 905 | ||
906 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; | 906 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; |
907 | mcp->mb[9] = ha->vp_idx; | 907 | mcp->mb[9] = ha->vp_idx; |
908 | mcp->out_mb = MBX_0; | 908 | mcp->out_mb = MBX_9|MBX_0; |
909 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 909 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
910 | mcp->tov = 30; | 910 | mcp->tov = 30; |
911 | mcp->flags = 0; | 911 | mcp->flags = 0; |
@@ -2873,7 +2873,7 @@ qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) | |||
2873 | DEBUG11(printk("%s(%ld): entered. Enabling index %d\n", __func__, | 2873 | DEBUG11(printk("%s(%ld): entered. Enabling index %d\n", __func__, |
2874 | ha->host_no, vp_index)); | 2874 | ha->host_no, vp_index)); |
2875 | 2875 | ||
2876 | if (vp_index == 0 || vp_index >= MAX_MULTI_ID_LOOP) | 2876 | if (vp_index == 0 || vp_index >= ha->max_npiv_vports) |
2877 | return QLA_PARAMETER_ERROR; | 2877 | return QLA_PARAMETER_ERROR; |
2878 | 2878 | ||
2879 | vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma); | 2879 | vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma); |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 821ee74aadc6..74096aaa693c 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -47,16 +47,15 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) | |||
47 | 47 | ||
48 | /* Find an empty slot and assign an vp_id */ | 48 | /* Find an empty slot and assign an vp_id */ |
49 | down(&ha->vport_sem); | 49 | down(&ha->vport_sem); |
50 | vp_id = find_first_zero_bit((unsigned long *)ha->vp_idx_map, | 50 | vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1); |
51 | MAX_MULTI_ID_FABRIC); | 51 | if (vp_id > ha->max_npiv_vports) { |
52 | if (vp_id > MAX_MULTI_ID_FABRIC) { | 52 | DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n", |
53 | DEBUG15(printk ("vp_id %d is bigger than MAX_MULTI_ID_FABRID\n", | 53 | vp_id, ha->max_npiv_vports)); |
54 | vp_id)); | ||
55 | up(&ha->vport_sem); | 54 | up(&ha->vport_sem); |
56 | return vp_id; | 55 | return vp_id; |
57 | } | 56 | } |
58 | 57 | ||
59 | set_bit(vp_id, (unsigned long *)ha->vp_idx_map); | 58 | set_bit(vp_id, ha->vp_idx_map); |
60 | ha->num_vhosts++; | 59 | ha->num_vhosts++; |
61 | vha->vp_idx = vp_id; | 60 | vha->vp_idx = vp_id; |
62 | list_add_tail(&vha->vp_list, &ha->vp_list); | 61 | list_add_tail(&vha->vp_list, &ha->vp_list); |
@@ -73,7 +72,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) | |||
73 | down(&ha->vport_sem); | 72 | down(&ha->vport_sem); |
74 | vp_id = vha->vp_idx; | 73 | vp_id = vha->vp_idx; |
75 | ha->num_vhosts--; | 74 | ha->num_vhosts--; |
76 | clear_bit(vp_id, (unsigned long *)ha->vp_idx_map); | 75 | clear_bit(vp_id, ha->vp_idx_map); |
77 | list_del(&vha->vp_list); | 76 | list_del(&vha->vp_list); |
78 | up(&ha->vport_sem); | 77 | up(&ha->vport_sem); |
79 | } | 78 | } |
@@ -216,11 +215,7 @@ qla2x00_alert_all_vps(scsi_qla_host_t *ha, uint16_t *mb) | |||
216 | if (ha->parent) | 215 | if (ha->parent) |
217 | return; | 216 | return; |
218 | 217 | ||
219 | i = find_next_bit((unsigned long *)ha->vp_idx_map, | 218 | for_each_mapped_vp_idx(ha, i) { |
220 | MAX_MULTI_ID_FABRIC + 1, 1); | ||
221 | for (;i <= MAX_MULTI_ID_FABRIC; | ||
222 | i = find_next_bit((unsigned long *)ha->vp_idx_map, | ||
223 | MAX_MULTI_ID_FABRIC + 1, i + 1)) { | ||
224 | vp_idx_matched = 0; | 219 | vp_idx_matched = 0; |
225 | 220 | ||
226 | list_for_each_entry(vha, &ha->vp_list, vp_list) { | 221 | list_for_each_entry(vha, &ha->vp_list, vp_list) { |
@@ -311,11 +306,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *ha) | |||
311 | 306 | ||
312 | clear_bit(VP_DPC_NEEDED, &ha->dpc_flags); | 307 | clear_bit(VP_DPC_NEEDED, &ha->dpc_flags); |
313 | 308 | ||
314 | i = find_next_bit((unsigned long *)ha->vp_idx_map, | 309 | for_each_mapped_vp_idx(ha, i) { |
315 | MAX_MULTI_ID_FABRIC + 1, 1); | ||
316 | for (;i <= MAX_MULTI_ID_FABRIC; | ||
317 | i = find_next_bit((unsigned long *)ha->vp_idx_map, | ||
318 | MAX_MULTI_ID_FABRIC + 1, i + 1)) { | ||
319 | vp_idx_matched = 0; | 310 | vp_idx_matched = 0; |
320 | 311 | ||
321 | list_for_each_entry(vha, &ha->vp_list, vp_list) { | 312 | list_for_each_entry(vha, &ha->vp_list, vp_list) { |
@@ -356,9 +347,9 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) | |||
356 | 347 | ||
357 | /* Check up max-npiv-supports */ | 348 | /* Check up max-npiv-supports */ |
358 | if (ha->num_vhosts > ha->max_npiv_vports) { | 349 | if (ha->num_vhosts > ha->max_npiv_vports) { |
359 | DEBUG15(printk("scsi(%ld): num_vhosts %d is bigger than " | 350 | DEBUG15(printk("scsi(%ld): num_vhosts %ud is bigger than " |
360 | "max_npv_vports %d.\n", ha->host_no, | 351 | "max_npv_vports %ud.\n", ha->host_no, |
361 | (uint16_t) ha->num_vhosts, (int) ha->max_npiv_vports)); | 352 | ha->num_vhosts, ha->max_npiv_vports)); |
362 | return VPCERR_UNSUPPORTED; | 353 | return VPCERR_UNSUPPORTED; |
363 | } | 354 | } |
364 | return 0; | 355 | return 0; |
@@ -450,7 +441,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
450 | num_hosts++; | 441 | num_hosts++; |
451 | 442 | ||
452 | down(&ha->vport_sem); | 443 | down(&ha->vport_sem); |
453 | set_bit(vha->vp_idx, (unsigned long *)ha->vp_idx_map); | 444 | set_bit(vha->vp_idx, ha->vp_idx_map); |
454 | ha->cur_vport_count++; | 445 | ha->cur_vport_count++; |
455 | up(&ha->vport_sem); | 446 | up(&ha->vport_sem); |
456 | 447 | ||