aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2007-11-12 13:30:58 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:45 -0500
commiteb66dc60be5a72bc940458a5adfd400e4d810d49 (patch)
tree677baf5655d9ae312e877cab4adb33a1319e9993 /drivers/scsi/qla2xxx
parent06e23b7470ca7974b0ca8150c5415b55b5ea2a99 (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.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h16
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c19
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c33
6 files changed, 33 insertions, 51 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index fb388b8c07c..745283fcbf2 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 04e8cbca4c0..fe8f7828f59 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 25364b1aaf1..69a5e31dd93 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
959struct mid_conf_entry_24xx { 967struct 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
1005struct 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 191dafd89be..03444d6e4d2 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 ccd662a6f5d..031f269149b 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 821ee74aadc..74096aaa693 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