diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2008-11-06 13:40:19 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 12:24:15 -0500 |
commit | 7b867cf76fbcc8d77867cbec6f509f71dce8a98f (patch) | |
tree | ef5fcc1e21701ed1baa1b131c7c29f29cd41d5d6 /drivers/scsi/qla2xxx/qla_attr.c | |
parent | a9b589d90e3d7748dae459031c2d912cd9e83c88 (diff) |
[SCSI] qla2xxx: Refactor qla data structures
Following changes have been made to the qla2xxx FC driver in
preparation for the multi- queue and future SR IOV hardware.
1. scsi_qla_host structure has been changed to contain scsi host
specific data only.
2. A new structure, qla_hw_data is created to contain HBA specific
hardware data.
3. Request and response IO specific data strucures are created.
4. The global list of fcports for the hba is not maintained anymore,
instead a fcport list is construted on per scsi_qla_host.
Signed-of-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 298 |
1 files changed, 162 insertions, 136 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ed731968f15f..b22384229378 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -19,8 +19,9 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, | |||
19 | struct bin_attribute *bin_attr, | 19 | struct bin_attribute *bin_attr, |
20 | char *buf, loff_t off, size_t count) | 20 | char *buf, loff_t off, size_t count) |
21 | { | 21 | { |
22 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 22 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
23 | struct device, kobj))); | 23 | struct device, kobj))); |
24 | struct qla_hw_data *ha = vha->hw; | ||
24 | 25 | ||
25 | if (ha->fw_dump_reading == 0) | 26 | if (ha->fw_dump_reading == 0) |
26 | return 0; | 27 | return 0; |
@@ -34,8 +35,9 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, | |||
34 | struct bin_attribute *bin_attr, | 35 | struct bin_attribute *bin_attr, |
35 | char *buf, loff_t off, size_t count) | 36 | char *buf, loff_t off, size_t count) |
36 | { | 37 | { |
37 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 38 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
38 | struct device, kobj))); | 39 | struct device, kobj))); |
40 | struct qla_hw_data *ha = vha->hw; | ||
39 | int reading; | 41 | int reading; |
40 | 42 | ||
41 | if (off != 0) | 43 | if (off != 0) |
@@ -48,7 +50,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, | |||
48 | break; | 50 | break; |
49 | 51 | ||
50 | qla_printk(KERN_INFO, ha, | 52 | qla_printk(KERN_INFO, ha, |
51 | "Firmware dump cleared on (%ld).\n", ha->host_no); | 53 | "Firmware dump cleared on (%ld).\n", vha->host_no); |
52 | 54 | ||
53 | ha->fw_dump_reading = 0; | 55 | ha->fw_dump_reading = 0; |
54 | ha->fw_dumped = 0; | 56 | ha->fw_dumped = 0; |
@@ -59,14 +61,14 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, | |||
59 | 61 | ||
60 | qla_printk(KERN_INFO, ha, | 62 | qla_printk(KERN_INFO, ha, |
61 | "Raw firmware dump ready for read on (%ld).\n", | 63 | "Raw firmware dump ready for read on (%ld).\n", |
62 | ha->host_no); | 64 | vha->host_no); |
63 | } | 65 | } |
64 | break; | 66 | break; |
65 | case 2: | 67 | case 2: |
66 | qla2x00_alloc_fw_dump(ha); | 68 | qla2x00_alloc_fw_dump(vha); |
67 | break; | 69 | break; |
68 | case 3: | 70 | case 3: |
69 | qla2x00_system_error(ha); | 71 | qla2x00_system_error(vha); |
70 | break; | 72 | break; |
71 | } | 73 | } |
72 | return (count); | 74 | return (count); |
@@ -87,8 +89,9 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, | |||
87 | struct bin_attribute *bin_attr, | 89 | struct bin_attribute *bin_attr, |
88 | char *buf, loff_t off, size_t count) | 90 | char *buf, loff_t off, size_t count) |
89 | { | 91 | { |
90 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 92 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
91 | struct device, kobj))); | 93 | struct device, kobj))); |
94 | struct qla_hw_data *ha = vha->hw; | ||
92 | 95 | ||
93 | if (!capable(CAP_SYS_ADMIN)) | 96 | if (!capable(CAP_SYS_ADMIN)) |
94 | return 0; | 97 | return 0; |
@@ -103,8 +106,9 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
103 | struct bin_attribute *bin_attr, | 106 | struct bin_attribute *bin_attr, |
104 | char *buf, loff_t off, size_t count) | 107 | char *buf, loff_t off, size_t count) |
105 | { | 108 | { |
106 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 109 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
107 | struct device, kobj))); | 110 | struct device, kobj))); |
111 | struct qla_hw_data *ha = vha->hw; | ||
108 | uint16_t cnt; | 112 | uint16_t cnt; |
109 | 113 | ||
110 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) | 114 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) |
@@ -134,11 +138,11 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
134 | } | 138 | } |
135 | 139 | ||
136 | /* Write NVRAM. */ | 140 | /* Write NVRAM. */ |
137 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); | 141 | ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count); |
138 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->nvram, ha->nvram_base, | 142 | ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base, |
139 | count); | 143 | count); |
140 | 144 | ||
141 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 145 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
142 | 146 | ||
143 | return (count); | 147 | return (count); |
144 | } | 148 | } |
@@ -158,8 +162,9 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, | |||
158 | struct bin_attribute *bin_attr, | 162 | struct bin_attribute *bin_attr, |
159 | char *buf, loff_t off, size_t count) | 163 | char *buf, loff_t off, size_t count) |
160 | { | 164 | { |
161 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 165 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
162 | struct device, kobj))); | 166 | struct device, kobj))); |
167 | struct qla_hw_data *ha = vha->hw; | ||
163 | 168 | ||
164 | if (ha->optrom_state != QLA_SREADING) | 169 | if (ha->optrom_state != QLA_SREADING) |
165 | return 0; | 170 | return 0; |
@@ -173,8 +178,9 @@ qla2x00_sysfs_write_optrom(struct kobject *kobj, | |||
173 | struct bin_attribute *bin_attr, | 178 | struct bin_attribute *bin_attr, |
174 | char *buf, loff_t off, size_t count) | 179 | char *buf, loff_t off, size_t count) |
175 | { | 180 | { |
176 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 181 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
177 | struct device, kobj))); | 182 | struct device, kobj))); |
183 | struct qla_hw_data *ha = vha->hw; | ||
178 | 184 | ||
179 | if (ha->optrom_state != QLA_SWRITING) | 185 | if (ha->optrom_state != QLA_SWRITING) |
180 | return -EINVAL; | 186 | return -EINVAL; |
@@ -203,8 +209,10 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
203 | struct bin_attribute *bin_attr, | 209 | struct bin_attribute *bin_attr, |
204 | char *buf, loff_t off, size_t count) | 210 | char *buf, loff_t off, size_t count) |
205 | { | 211 | { |
206 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 212 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
207 | struct device, kobj))); | 213 | struct device, kobj))); |
214 | struct qla_hw_data *ha = vha->hw; | ||
215 | |||
208 | uint32_t start = 0; | 216 | uint32_t start = 0; |
209 | uint32_t size = ha->optrom_size; | 217 | uint32_t size = ha->optrom_size; |
210 | int val, valid; | 218 | int val, valid; |
@@ -262,7 +270,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
262 | ha->optrom_region_start, ha->optrom_region_size)); | 270 | ha->optrom_region_start, ha->optrom_region_size)); |
263 | 271 | ||
264 | memset(ha->optrom_buffer, 0, ha->optrom_region_size); | 272 | memset(ha->optrom_buffer, 0, ha->optrom_region_size); |
265 | ha->isp_ops->read_optrom(ha, ha->optrom_buffer, | 273 | ha->isp_ops->read_optrom(vha, ha->optrom_buffer, |
266 | ha->optrom_region_start, ha->optrom_region_size); | 274 | ha->optrom_region_start, ha->optrom_region_size); |
267 | break; | 275 | break; |
268 | case 2: | 276 | case 2: |
@@ -333,7 +341,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
333 | "Writing flash region -- 0x%x/0x%x.\n", | 341 | "Writing flash region -- 0x%x/0x%x.\n", |
334 | ha->optrom_region_start, ha->optrom_region_size)); | 342 | ha->optrom_region_start, ha->optrom_region_size)); |
335 | 343 | ||
336 | ha->isp_ops->write_optrom(ha, ha->optrom_buffer, | 344 | ha->isp_ops->write_optrom(vha, ha->optrom_buffer, |
337 | ha->optrom_region_start, ha->optrom_region_size); | 345 | ha->optrom_region_start, ha->optrom_region_size); |
338 | break; | 346 | break; |
339 | default: | 347 | default: |
@@ -356,8 +364,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
356 | struct bin_attribute *bin_attr, | 364 | struct bin_attribute *bin_attr, |
357 | char *buf, loff_t off, size_t count) | 365 | char *buf, loff_t off, size_t count) |
358 | { | 366 | { |
359 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 367 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
360 | struct device, kobj))); | 368 | struct device, kobj))); |
369 | struct qla_hw_data *ha = vha->hw; | ||
361 | 370 | ||
362 | if (!capable(CAP_SYS_ADMIN)) | 371 | if (!capable(CAP_SYS_ADMIN)) |
363 | return 0; | 372 | return 0; |
@@ -371,15 +380,16 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, | |||
371 | struct bin_attribute *bin_attr, | 380 | struct bin_attribute *bin_attr, |
372 | char *buf, loff_t off, size_t count) | 381 | char *buf, loff_t off, size_t count) |
373 | { | 382 | { |
374 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 383 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
375 | struct device, kobj))); | 384 | struct device, kobj))); |
385 | struct qla_hw_data *ha = vha->hw; | ||
376 | 386 | ||
377 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) | 387 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) |
378 | return 0; | 388 | return 0; |
379 | 389 | ||
380 | /* Write NVRAM. */ | 390 | /* Write NVRAM. */ |
381 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); | 391 | ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count); |
382 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count); | 392 | ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count); |
383 | 393 | ||
384 | return count; | 394 | return count; |
385 | } | 395 | } |
@@ -399,8 +409,9 @@ qla2x00_sysfs_read_sfp(struct kobject *kobj, | |||
399 | struct bin_attribute *bin_attr, | 409 | struct bin_attribute *bin_attr, |
400 | char *buf, loff_t off, size_t count) | 410 | char *buf, loff_t off, size_t count) |
401 | { | 411 | { |
402 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 412 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
403 | struct device, kobj))); | 413 | struct device, kobj))); |
414 | struct qla_hw_data *ha = vha->hw; | ||
404 | uint16_t iter, addr, offset; | 415 | uint16_t iter, addr, offset; |
405 | int rval; | 416 | int rval; |
406 | 417 | ||
@@ -429,7 +440,7 @@ do_read: | |||
429 | offset = 0; | 440 | offset = 0; |
430 | } | 441 | } |
431 | 442 | ||
432 | rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset, | 443 | rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, addr, offset, |
433 | SFP_BLOCK_SIZE); | 444 | SFP_BLOCK_SIZE); |
434 | if (rval != QLA_SUCCESS) { | 445 | if (rval != QLA_SUCCESS) { |
435 | qla_printk(KERN_WARNING, ha, | 446 | qla_printk(KERN_WARNING, ha, |
@@ -469,30 +480,31 @@ static struct sysfs_entry { | |||
469 | }; | 480 | }; |
470 | 481 | ||
471 | void | 482 | void |
472 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 483 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) |
473 | { | 484 | { |
474 | struct Scsi_Host *host = ha->host; | 485 | struct Scsi_Host *host = vha->host; |
475 | struct sysfs_entry *iter; | 486 | struct sysfs_entry *iter; |
476 | int ret; | 487 | int ret; |
477 | 488 | ||
478 | for (iter = bin_file_entries; iter->name; iter++) { | 489 | for (iter = bin_file_entries; iter->name; iter++) { |
479 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) | 490 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw)) |
480 | continue; | 491 | continue; |
481 | 492 | ||
482 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, | 493 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, |
483 | iter->attr); | 494 | iter->attr); |
484 | if (ret) | 495 | if (ret) |
485 | qla_printk(KERN_INFO, ha, | 496 | qla_printk(KERN_INFO, vha->hw, |
486 | "Unable to create sysfs %s binary attribute " | 497 | "Unable to create sysfs %s binary attribute " |
487 | "(%d).\n", iter->name, ret); | 498 | "(%d).\n", iter->name, ret); |
488 | } | 499 | } |
489 | } | 500 | } |
490 | 501 | ||
491 | void | 502 | void |
492 | qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | 503 | qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) |
493 | { | 504 | { |
494 | struct Scsi_Host *host = ha->host; | 505 | struct Scsi_Host *host = vha->host; |
495 | struct sysfs_entry *iter; | 506 | struct sysfs_entry *iter; |
507 | struct qla_hw_data *ha = vha->hw; | ||
496 | 508 | ||
497 | for (iter = bin_file_entries; iter->name; iter++) { | 509 | for (iter = bin_file_entries; iter->name; iter++) { |
498 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) | 510 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) |
@@ -503,7 +515,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
503 | } | 515 | } |
504 | 516 | ||
505 | if (ha->beacon_blink_led == 1) | 517 | if (ha->beacon_blink_led == 1) |
506 | ha->isp_ops->beacon_off(ha); | 518 | ha->isp_ops->beacon_off(vha); |
507 | } | 519 | } |
508 | 520 | ||
509 | /* Scsi_Host attributes. */ | 521 | /* Scsi_Host attributes. */ |
@@ -519,22 +531,24 @@ static ssize_t | |||
519 | qla2x00_fw_version_show(struct device *dev, | 531 | qla2x00_fw_version_show(struct device *dev, |
520 | struct device_attribute *attr, char *buf) | 532 | struct device_attribute *attr, char *buf) |
521 | { | 533 | { |
522 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 534 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
523 | char fw_str[30]; | 535 | struct qla_hw_data *ha = vha->hw; |
536 | char fw_str[128]; | ||
524 | 537 | ||
525 | return snprintf(buf, PAGE_SIZE, "%s\n", | 538 | return snprintf(buf, PAGE_SIZE, "%s\n", |
526 | ha->isp_ops->fw_version_str(ha, fw_str)); | 539 | ha->isp_ops->fw_version_str(vha, fw_str)); |
527 | } | 540 | } |
528 | 541 | ||
529 | static ssize_t | 542 | static ssize_t |
530 | qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr, | 543 | qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr, |
531 | char *buf) | 544 | char *buf) |
532 | { | 545 | { |
533 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 546 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
547 | struct qla_hw_data *ha = vha->hw; | ||
534 | uint32_t sn; | 548 | uint32_t sn; |
535 | 549 | ||
536 | if (IS_FWI2_CAPABLE(ha)) { | 550 | if (IS_FWI2_CAPABLE(ha)) { |
537 | qla2xxx_get_vpd_field(ha, "SN", buf, PAGE_SIZE); | 551 | qla2xxx_get_vpd_field(vha, "SN", buf, PAGE_SIZE); |
538 | return snprintf(buf, PAGE_SIZE, "%s\n", buf); | 552 | return snprintf(buf, PAGE_SIZE, "%s\n", buf); |
539 | } | 553 | } |
540 | 554 | ||
@@ -547,15 +561,16 @@ static ssize_t | |||
547 | qla2x00_isp_name_show(struct device *dev, struct device_attribute *attr, | 561 | qla2x00_isp_name_show(struct device *dev, struct device_attribute *attr, |
548 | char *buf) | 562 | char *buf) |
549 | { | 563 | { |
550 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 564 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
551 | return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device); | 565 | return snprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device); |
552 | } | 566 | } |
553 | 567 | ||
554 | static ssize_t | 568 | static ssize_t |
555 | qla2x00_isp_id_show(struct device *dev, struct device_attribute *attr, | 569 | qla2x00_isp_id_show(struct device *dev, struct device_attribute *attr, |
556 | char *buf) | 570 | char *buf) |
557 | { | 571 | { |
558 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 572 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
573 | struct qla_hw_data *ha = vha->hw; | ||
559 | return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", | 574 | return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", |
560 | ha->product_id[0], ha->product_id[1], ha->product_id[2], | 575 | ha->product_id[0], ha->product_id[1], ha->product_id[2], |
561 | ha->product_id[3]); | 576 | ha->product_id[3]); |
@@ -565,43 +580,44 @@ static ssize_t | |||
565 | qla2x00_model_name_show(struct device *dev, struct device_attribute *attr, | 580 | qla2x00_model_name_show(struct device *dev, struct device_attribute *attr, |
566 | char *buf) | 581 | char *buf) |
567 | { | 582 | { |
568 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 583 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
569 | return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number); | 584 | return snprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_number); |
570 | } | 585 | } |
571 | 586 | ||
572 | static ssize_t | 587 | static ssize_t |
573 | qla2x00_model_desc_show(struct device *dev, struct device_attribute *attr, | 588 | qla2x00_model_desc_show(struct device *dev, struct device_attribute *attr, |
574 | char *buf) | 589 | char *buf) |
575 | { | 590 | { |
576 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 591 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
577 | return snprintf(buf, PAGE_SIZE, "%s\n", | 592 | return snprintf(buf, PAGE_SIZE, "%s\n", |
578 | ha->model_desc ? ha->model_desc: ""); | 593 | vha->hw->model_desc ? vha->hw->model_desc : ""); |
579 | } | 594 | } |
580 | 595 | ||
581 | static ssize_t | 596 | static ssize_t |
582 | qla2x00_pci_info_show(struct device *dev, struct device_attribute *attr, | 597 | qla2x00_pci_info_show(struct device *dev, struct device_attribute *attr, |
583 | char *buf) | 598 | char *buf) |
584 | { | 599 | { |
585 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 600 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
586 | char pci_info[30]; | 601 | char pci_info[30]; |
587 | 602 | ||
588 | return snprintf(buf, PAGE_SIZE, "%s\n", | 603 | return snprintf(buf, PAGE_SIZE, "%s\n", |
589 | ha->isp_ops->pci_info_str(ha, pci_info)); | 604 | vha->hw->isp_ops->pci_info_str(vha, pci_info)); |
590 | } | 605 | } |
591 | 606 | ||
592 | static ssize_t | 607 | static ssize_t |
593 | qla2x00_link_state_show(struct device *dev, struct device_attribute *attr, | 608 | qla2x00_link_state_show(struct device *dev, struct device_attribute *attr, |
594 | char *buf) | 609 | char *buf) |
595 | { | 610 | { |
596 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 611 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
612 | struct qla_hw_data *ha = vha->hw; | ||
597 | int len = 0; | 613 | int len = 0; |
598 | 614 | ||
599 | if (atomic_read(&ha->loop_state) == LOOP_DOWN || | 615 | if (atomic_read(&vha->loop_state) == LOOP_DOWN || |
600 | atomic_read(&ha->loop_state) == LOOP_DEAD) | 616 | atomic_read(&vha->loop_state) == LOOP_DEAD) |
601 | len = snprintf(buf, PAGE_SIZE, "Link Down\n"); | 617 | len = snprintf(buf, PAGE_SIZE, "Link Down\n"); |
602 | else if (atomic_read(&ha->loop_state) != LOOP_READY || | 618 | else if (atomic_read(&vha->loop_state) != LOOP_READY || |
603 | test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || | 619 | test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || |
604 | test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) | 620 | test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) |
605 | len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n"); | 621 | len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n"); |
606 | else { | 622 | else { |
607 | len = snprintf(buf, PAGE_SIZE, "Link Up - "); | 623 | len = snprintf(buf, PAGE_SIZE, "Link Up - "); |
@@ -632,10 +648,10 @@ static ssize_t | |||
632 | qla2x00_zio_show(struct device *dev, struct device_attribute *attr, | 648 | qla2x00_zio_show(struct device *dev, struct device_attribute *attr, |
633 | char *buf) | 649 | char *buf) |
634 | { | 650 | { |
635 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 651 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
636 | int len = 0; | 652 | int len = 0; |
637 | 653 | ||
638 | switch (ha->zio_mode) { | 654 | switch (vha->hw->zio_mode) { |
639 | case QLA_ZIO_MODE_6: | 655 | case QLA_ZIO_MODE_6: |
640 | len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); | 656 | len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); |
641 | break; | 657 | break; |
@@ -650,7 +666,8 @@ static ssize_t | |||
650 | qla2x00_zio_store(struct device *dev, struct device_attribute *attr, | 666 | qla2x00_zio_store(struct device *dev, struct device_attribute *attr, |
651 | const char *buf, size_t count) | 667 | const char *buf, size_t count) |
652 | { | 668 | { |
653 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 669 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
670 | struct qla_hw_data *ha = vha->hw; | ||
654 | int val = 0; | 671 | int val = 0; |
655 | uint16_t zio_mode; | 672 | uint16_t zio_mode; |
656 | 673 | ||
@@ -668,7 +685,7 @@ qla2x00_zio_store(struct device *dev, struct device_attribute *attr, | |||
668 | /* Update per-hba values and queue a reset. */ | 685 | /* Update per-hba values and queue a reset. */ |
669 | if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { | 686 | if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { |
670 | ha->zio_mode = zio_mode; | 687 | ha->zio_mode = zio_mode; |
671 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 688 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
672 | } | 689 | } |
673 | return strlen(buf); | 690 | return strlen(buf); |
674 | } | 691 | } |
@@ -677,16 +694,16 @@ static ssize_t | |||
677 | qla2x00_zio_timer_show(struct device *dev, struct device_attribute *attr, | 694 | qla2x00_zio_timer_show(struct device *dev, struct device_attribute *attr, |
678 | char *buf) | 695 | char *buf) |
679 | { | 696 | { |
680 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 697 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
681 | 698 | ||
682 | return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100); | 699 | return snprintf(buf, PAGE_SIZE, "%d us\n", vha->hw->zio_timer * 100); |
683 | } | 700 | } |
684 | 701 | ||
685 | static ssize_t | 702 | static ssize_t |
686 | qla2x00_zio_timer_store(struct device *dev, struct device_attribute *attr, | 703 | qla2x00_zio_timer_store(struct device *dev, struct device_attribute *attr, |
687 | const char *buf, size_t count) | 704 | const char *buf, size_t count) |
688 | { | 705 | { |
689 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 706 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
690 | int val = 0; | 707 | int val = 0; |
691 | uint16_t zio_timer; | 708 | uint16_t zio_timer; |
692 | 709 | ||
@@ -696,7 +713,7 @@ qla2x00_zio_timer_store(struct device *dev, struct device_attribute *attr, | |||
696 | return -ERANGE; | 713 | return -ERANGE; |
697 | 714 | ||
698 | zio_timer = (uint16_t)(val / 100); | 715 | zio_timer = (uint16_t)(val / 100); |
699 | ha->zio_timer = zio_timer; | 716 | vha->hw->zio_timer = zio_timer; |
700 | 717 | ||
701 | return strlen(buf); | 718 | return strlen(buf); |
702 | } | 719 | } |
@@ -705,10 +722,10 @@ static ssize_t | |||
705 | qla2x00_beacon_show(struct device *dev, struct device_attribute *attr, | 722 | qla2x00_beacon_show(struct device *dev, struct device_attribute *attr, |
706 | char *buf) | 723 | char *buf) |
707 | { | 724 | { |
708 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 725 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
709 | int len = 0; | 726 | int len = 0; |
710 | 727 | ||
711 | if (ha->beacon_blink_led) | 728 | if (vha->hw->beacon_blink_led) |
712 | len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n"); | 729 | len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n"); |
713 | else | 730 | else |
714 | len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); | 731 | len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); |
@@ -719,14 +736,15 @@ static ssize_t | |||
719 | qla2x00_beacon_store(struct device *dev, struct device_attribute *attr, | 736 | qla2x00_beacon_store(struct device *dev, struct device_attribute *attr, |
720 | const char *buf, size_t count) | 737 | const char *buf, size_t count) |
721 | { | 738 | { |
722 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 739 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
740 | struct qla_hw_data *ha = vha->hw; | ||
723 | int val = 0; | 741 | int val = 0; |
724 | int rval; | 742 | int rval; |
725 | 743 | ||
726 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 744 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
727 | return -EPERM; | 745 | return -EPERM; |
728 | 746 | ||
729 | if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) { | 747 | if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) { |
730 | qla_printk(KERN_WARNING, ha, | 748 | qla_printk(KERN_WARNING, ha, |
731 | "Abort ISP active -- ignoring beacon request.\n"); | 749 | "Abort ISP active -- ignoring beacon request.\n"); |
732 | return -EBUSY; | 750 | return -EBUSY; |
@@ -736,9 +754,9 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr, | |||
736 | return -EINVAL; | 754 | return -EINVAL; |
737 | 755 | ||
738 | if (val) | 756 | if (val) |
739 | rval = ha->isp_ops->beacon_on(ha); | 757 | rval = ha->isp_ops->beacon_on(vha); |
740 | else | 758 | else |
741 | rval = ha->isp_ops->beacon_off(ha); | 759 | rval = ha->isp_ops->beacon_off(vha); |
742 | 760 | ||
743 | if (rval != QLA_SUCCESS) | 761 | if (rval != QLA_SUCCESS) |
744 | count = 0; | 762 | count = 0; |
@@ -750,8 +768,8 @@ static ssize_t | |||
750 | qla2x00_optrom_bios_version_show(struct device *dev, | 768 | qla2x00_optrom_bios_version_show(struct device *dev, |
751 | struct device_attribute *attr, char *buf) | 769 | struct device_attribute *attr, char *buf) |
752 | { | 770 | { |
753 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 771 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
754 | 772 | struct qla_hw_data *ha = vha->hw; | |
755 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], | 773 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], |
756 | ha->bios_revision[0]); | 774 | ha->bios_revision[0]); |
757 | } | 775 | } |
@@ -760,8 +778,8 @@ static ssize_t | |||
760 | qla2x00_optrom_efi_version_show(struct device *dev, | 778 | qla2x00_optrom_efi_version_show(struct device *dev, |
761 | struct device_attribute *attr, char *buf) | 779 | struct device_attribute *attr, char *buf) |
762 | { | 780 | { |
763 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 781 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
764 | 782 | struct qla_hw_data *ha = vha->hw; | |
765 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], | 783 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], |
766 | ha->efi_revision[0]); | 784 | ha->efi_revision[0]); |
767 | } | 785 | } |
@@ -770,8 +788,8 @@ static ssize_t | |||
770 | qla2x00_optrom_fcode_version_show(struct device *dev, | 788 | qla2x00_optrom_fcode_version_show(struct device *dev, |
771 | struct device_attribute *attr, char *buf) | 789 | struct device_attribute *attr, char *buf) |
772 | { | 790 | { |
773 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 791 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
774 | 792 | struct qla_hw_data *ha = vha->hw; | |
775 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], | 793 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], |
776 | ha->fcode_revision[0]); | 794 | ha->fcode_revision[0]); |
777 | } | 795 | } |
@@ -780,8 +798,8 @@ static ssize_t | |||
780 | qla2x00_optrom_fw_version_show(struct device *dev, | 798 | qla2x00_optrom_fw_version_show(struct device *dev, |
781 | struct device_attribute *attr, char *buf) | 799 | struct device_attribute *attr, char *buf) |
782 | { | 800 | { |
783 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 801 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
784 | 802 | struct qla_hw_data *ha = vha->hw; | |
785 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", | 803 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", |
786 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], | 804 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], |
787 | ha->fw_revision[3]); | 805 | ha->fw_revision[3]); |
@@ -791,8 +809,8 @@ static ssize_t | |||
791 | qla2x00_total_isp_aborts_show(struct device *dev, | 809 | qla2x00_total_isp_aborts_show(struct device *dev, |
792 | struct device_attribute *attr, char *buf) | 810 | struct device_attribute *attr, char *buf) |
793 | { | 811 | { |
794 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 812 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
795 | 813 | struct qla_hw_data *ha = vha->hw; | |
796 | return snprintf(buf, PAGE_SIZE, "%d\n", | 814 | return snprintf(buf, PAGE_SIZE, "%d\n", |
797 | ha->qla_stats.total_isp_aborts); | 815 | ha->qla_stats.total_isp_aborts); |
798 | } | 816 | } |
@@ -848,16 +866,17 @@ struct device_attribute *qla2x00_host_attrs[] = { | |||
848 | static void | 866 | static void |
849 | qla2x00_get_host_port_id(struct Scsi_Host *shost) | 867 | qla2x00_get_host_port_id(struct Scsi_Host *shost) |
850 | { | 868 | { |
851 | scsi_qla_host_t *ha = shost_priv(shost); | 869 | scsi_qla_host_t *vha = shost_priv(shost); |
852 | 870 | ||
853 | fc_host_port_id(shost) = ha->d_id.b.domain << 16 | | 871 | fc_host_port_id(shost) = vha->d_id.b.domain << 16 | |
854 | ha->d_id.b.area << 8 | ha->d_id.b.al_pa; | 872 | vha->d_id.b.area << 8 | vha->d_id.b.al_pa; |
855 | } | 873 | } |
856 | 874 | ||
857 | static void | 875 | static void |
858 | qla2x00_get_host_speed(struct Scsi_Host *shost) | 876 | qla2x00_get_host_speed(struct Scsi_Host *shost) |
859 | { | 877 | { |
860 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); | 878 | struct qla_hw_data *ha = ((struct scsi_qla_host *) |
879 | (shost_priv(shost)))->hw; | ||
861 | u32 speed = FC_PORTSPEED_UNKNOWN; | 880 | u32 speed = FC_PORTSPEED_UNKNOWN; |
862 | 881 | ||
863 | switch (ha->link_data_rate) { | 882 | switch (ha->link_data_rate) { |
@@ -880,14 +899,14 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
880 | static void | 899 | static void |
881 | qla2x00_get_host_port_type(struct Scsi_Host *shost) | 900 | qla2x00_get_host_port_type(struct Scsi_Host *shost) |
882 | { | 901 | { |
883 | scsi_qla_host_t *ha = shost_priv(shost); | 902 | scsi_qla_host_t *vha = shost_priv(shost); |
884 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; | 903 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; |
885 | 904 | ||
886 | if (ha->parent) { | 905 | if (vha->vp_idx) { |
887 | fc_host_port_type(shost) = FC_PORTTYPE_NPIV; | 906 | fc_host_port_type(shost) = FC_PORTTYPE_NPIV; |
888 | return; | 907 | return; |
889 | } | 908 | } |
890 | switch (ha->current_topology) { | 909 | switch (vha->hw->current_topology) { |
891 | case ISP_CFG_NL: | 910 | case ISP_CFG_NL: |
892 | port_type = FC_PORTTYPE_LPORT; | 911 | port_type = FC_PORTTYPE_LPORT; |
893 | break; | 912 | break; |
@@ -908,11 +927,11 @@ static void | |||
908 | qla2x00_get_starget_node_name(struct scsi_target *starget) | 927 | qla2x00_get_starget_node_name(struct scsi_target *starget) |
909 | { | 928 | { |
910 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); | 929 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); |
911 | scsi_qla_host_t *ha = shost_priv(host); | 930 | scsi_qla_host_t *vha = shost_priv(host); |
912 | fc_port_t *fcport; | 931 | fc_port_t *fcport; |
913 | u64 node_name = 0; | 932 | u64 node_name = 0; |
914 | 933 | ||
915 | list_for_each_entry(fcport, &ha->fcports, list) { | 934 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
916 | if (fcport->rport && | 935 | if (fcport->rport && |
917 | starget->id == fcport->rport->scsi_target_id) { | 936 | starget->id == fcport->rport->scsi_target_id) { |
918 | node_name = wwn_to_u64(fcport->node_name); | 937 | node_name = wwn_to_u64(fcport->node_name); |
@@ -927,11 +946,11 @@ static void | |||
927 | qla2x00_get_starget_port_name(struct scsi_target *starget) | 946 | qla2x00_get_starget_port_name(struct scsi_target *starget) |
928 | { | 947 | { |
929 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); | 948 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); |
930 | scsi_qla_host_t *ha = shost_priv(host); | 949 | scsi_qla_host_t *vha = shost_priv(host); |
931 | fc_port_t *fcport; | 950 | fc_port_t *fcport; |
932 | u64 port_name = 0; | 951 | u64 port_name = 0; |
933 | 952 | ||
934 | list_for_each_entry(fcport, &ha->fcports, list) { | 953 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
935 | if (fcport->rport && | 954 | if (fcport->rport && |
936 | starget->id == fcport->rport->scsi_target_id) { | 955 | starget->id == fcport->rport->scsi_target_id) { |
937 | port_name = wwn_to_u64(fcport->port_name); | 956 | port_name = wwn_to_u64(fcport->port_name); |
@@ -946,11 +965,11 @@ static void | |||
946 | qla2x00_get_starget_port_id(struct scsi_target *starget) | 965 | qla2x00_get_starget_port_id(struct scsi_target *starget) |
947 | { | 966 | { |
948 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); | 967 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); |
949 | scsi_qla_host_t *ha = shost_priv(host); | 968 | scsi_qla_host_t *vha = shost_priv(host); |
950 | fc_port_t *fcport; | 969 | fc_port_t *fcport; |
951 | uint32_t port_id = ~0U; | 970 | uint32_t port_id = ~0U; |
952 | 971 | ||
953 | list_for_each_entry(fcport, &ha->fcports, list) { | 972 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
954 | if (fcport->rport && | 973 | if (fcport->rport && |
955 | starget->id == fcport->rport->scsi_target_id) { | 974 | starget->id == fcport->rport->scsi_target_id) { |
956 | port_id = fcport->d_id.b.domain << 16 | | 975 | port_id = fcport->d_id.b.domain << 16 | |
@@ -999,9 +1018,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) | |||
999 | * final cleanup of firmware resources (PCBs and XCBs). | 1018 | * final cleanup of firmware resources (PCBs and XCBs). |
1000 | */ | 1019 | */ |
1001 | if (fcport->loop_id != FC_NO_LOOP_ID) { | 1020 | if (fcport->loop_id != FC_NO_LOOP_ID) { |
1002 | fcport->ha->isp_ops->fabric_logout(fcport->ha, fcport->loop_id, | 1021 | fcport->vha->hw->isp_ops->fabric_logout(fcport->vha, |
1003 | fcport->d_id.b.domain, fcport->d_id.b.area, | 1022 | fcport->loop_id, fcport->d_id.b.domain, |
1004 | fcport->d_id.b.al_pa); | 1023 | fcport->d_id.b.area, fcport->d_id.b.al_pa); |
1005 | fcport->loop_id = FC_NO_LOOP_ID; | 1024 | fcport->loop_id = FC_NO_LOOP_ID; |
1006 | } | 1025 | } |
1007 | 1026 | ||
@@ -1011,16 +1030,18 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) | |||
1011 | static int | 1030 | static int |
1012 | qla2x00_issue_lip(struct Scsi_Host *shost) | 1031 | qla2x00_issue_lip(struct Scsi_Host *shost) |
1013 | { | 1032 | { |
1014 | scsi_qla_host_t *ha = shost_priv(shost); | 1033 | scsi_qla_host_t *vha = shost_priv(shost); |
1015 | 1034 | ||
1016 | qla2x00_loop_reset(ha); | 1035 | qla2x00_loop_reset(vha); |
1017 | return 0; | 1036 | return 0; |
1018 | } | 1037 | } |
1019 | 1038 | ||
1020 | static struct fc_host_statistics * | 1039 | static struct fc_host_statistics * |
1021 | qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | 1040 | qla2x00_get_fc_host_stats(struct Scsi_Host *shost) |
1022 | { | 1041 | { |
1023 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); | 1042 | scsi_qla_host_t *vha = shost_priv(shost); |
1043 | struct qla_hw_data *ha = vha->hw; | ||
1044 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | ||
1024 | int rval; | 1045 | int rval; |
1025 | struct link_statistics *stats; | 1046 | struct link_statistics *stats; |
1026 | dma_addr_t stats_dma; | 1047 | dma_addr_t stats_dma; |
@@ -1032,21 +1053,21 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
1032 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); | 1053 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); |
1033 | if (stats == NULL) { | 1054 | if (stats == NULL) { |
1034 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | 1055 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", |
1035 | __func__, ha->host_no)); | 1056 | __func__, base_vha->host_no)); |
1036 | goto done; | 1057 | goto done; |
1037 | } | 1058 | } |
1038 | memset(stats, 0, DMA_POOL_SIZE); | 1059 | memset(stats, 0, DMA_POOL_SIZE); |
1039 | 1060 | ||
1040 | rval = QLA_FUNCTION_FAILED; | 1061 | rval = QLA_FUNCTION_FAILED; |
1041 | if (IS_FWI2_CAPABLE(ha)) { | 1062 | if (IS_FWI2_CAPABLE(ha)) { |
1042 | rval = qla24xx_get_isp_stats(ha, stats, stats_dma); | 1063 | rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma); |
1043 | } else if (atomic_read(&ha->loop_state) == LOOP_READY && | 1064 | } else if (atomic_read(&base_vha->loop_state) == LOOP_READY && |
1044 | !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) && | 1065 | !test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) && |
1045 | !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) && | 1066 | !test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) && |
1046 | !ha->dpc_active) { | 1067 | !ha->dpc_active) { |
1047 | /* Must be in a 'READY' state for statistics retrieval. */ | 1068 | /* Must be in a 'READY' state for statistics retrieval. */ |
1048 | rval = qla2x00_get_link_status(ha, ha->loop_id, stats, | 1069 | rval = qla2x00_get_link_status(base_vha, base_vha->loop_id, |
1049 | stats_dma); | 1070 | stats, stats_dma); |
1050 | } | 1071 | } |
1051 | 1072 | ||
1052 | if (rval != QLA_SUCCESS) | 1073 | if (rval != QLA_SUCCESS) |
@@ -1077,29 +1098,29 @@ done: | |||
1077 | static void | 1098 | static void |
1078 | qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) | 1099 | qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) |
1079 | { | 1100 | { |
1080 | scsi_qla_host_t *ha = shost_priv(shost); | 1101 | scsi_qla_host_t *vha = shost_priv(shost); |
1081 | 1102 | ||
1082 | qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost)); | 1103 | qla2x00_get_sym_node_name(vha, fc_host_symbolic_name(shost)); |
1083 | } | 1104 | } |
1084 | 1105 | ||
1085 | static void | 1106 | static void |
1086 | qla2x00_set_host_system_hostname(struct Scsi_Host *shost) | 1107 | qla2x00_set_host_system_hostname(struct Scsi_Host *shost) |
1087 | { | 1108 | { |
1088 | scsi_qla_host_t *ha = shost_priv(shost); | 1109 | scsi_qla_host_t *vha = shost_priv(shost); |
1089 | 1110 | ||
1090 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 1111 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); |
1091 | } | 1112 | } |
1092 | 1113 | ||
1093 | static void | 1114 | static void |
1094 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) | 1115 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) |
1095 | { | 1116 | { |
1096 | scsi_qla_host_t *ha = shost_priv(shost); | 1117 | scsi_qla_host_t *vha = shost_priv(shost); |
1097 | u64 node_name; | 1118 | u64 node_name; |
1098 | 1119 | ||
1099 | if (ha->device_flags & SWITCH_FOUND) | 1120 | if (vha->device_flags & SWITCH_FOUND) |
1100 | node_name = wwn_to_u64(ha->fabric_node_name); | 1121 | node_name = wwn_to_u64(vha->fabric_node_name); |
1101 | else | 1122 | else |
1102 | node_name = wwn_to_u64(ha->node_name); | 1123 | node_name = wwn_to_u64(vha->node_name); |
1103 | 1124 | ||
1104 | fc_host_fabric_name(shost) = node_name; | 1125 | fc_host_fabric_name(shost) = node_name; |
1105 | } | 1126 | } |
@@ -1107,11 +1128,12 @@ qla2x00_get_host_fabric_name(struct Scsi_Host *shost) | |||
1107 | static void | 1128 | static void |
1108 | qla2x00_get_host_port_state(struct Scsi_Host *shost) | 1129 | qla2x00_get_host_port_state(struct Scsi_Host *shost) |
1109 | { | 1130 | { |
1110 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); | 1131 | scsi_qla_host_t *vha = shost_priv(shost); |
1132 | struct scsi_qla_host *base_vha = pci_get_drvdata(vha->hw->pdev); | ||
1111 | 1133 | ||
1112 | if (!ha->flags.online) | 1134 | if (!base_vha->flags.online) |
1113 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | 1135 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; |
1114 | else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT) | 1136 | else if (atomic_read(&base_vha->loop_state) == LOOP_TIMEOUT) |
1115 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | 1137 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; |
1116 | else | 1138 | else |
1117 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | 1139 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; |
@@ -1121,8 +1143,8 @@ static int | |||
1121 | qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | 1143 | qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) |
1122 | { | 1144 | { |
1123 | int ret = 0; | 1145 | int ret = 0; |
1124 | scsi_qla_host_t *ha = shost_priv(fc_vport->shost); | 1146 | scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost); |
1125 | scsi_qla_host_t *vha; | 1147 | scsi_qla_host_t *vha = NULL; |
1126 | 1148 | ||
1127 | ret = qla24xx_vport_create_req_sanity_check(fc_vport); | 1149 | ret = qla24xx_vport_create_req_sanity_check(fc_vport); |
1128 | if (ret) { | 1150 | if (ret) { |
@@ -1144,18 +1166,19 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
1144 | atomic_set(&vha->vp_state, VP_FAILED); | 1166 | atomic_set(&vha->vp_state, VP_FAILED); |
1145 | 1167 | ||
1146 | /* ready to create vport */ | 1168 | /* ready to create vport */ |
1147 | qla_printk(KERN_INFO, vha, "VP entry id %d assigned.\n", vha->vp_idx); | 1169 | qla_printk(KERN_INFO, vha->hw, "VP entry id %d assigned.\n", |
1170 | vha->vp_idx); | ||
1148 | 1171 | ||
1149 | /* initialized vport states */ | 1172 | /* initialized vport states */ |
1150 | atomic_set(&vha->loop_state, LOOP_DOWN); | 1173 | atomic_set(&vha->loop_state, LOOP_DOWN); |
1151 | vha->vp_err_state= VP_ERR_PORTDWN; | 1174 | vha->vp_err_state= VP_ERR_PORTDWN; |
1152 | vha->vp_prev_err_state= VP_ERR_UNKWN; | 1175 | vha->vp_prev_err_state= VP_ERR_UNKWN; |
1153 | /* Check if physical ha port is Up */ | 1176 | /* Check if physical ha port is Up */ |
1154 | if (atomic_read(&ha->loop_state) == LOOP_DOWN || | 1177 | if (atomic_read(&base_vha->loop_state) == LOOP_DOWN || |
1155 | atomic_read(&ha->loop_state) == LOOP_DEAD) { | 1178 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
1156 | /* Don't retry or attempt login of this virtual port */ | 1179 | /* Don't retry or attempt login of this virtual port */ |
1157 | DEBUG15(printk ("scsi(%ld): pport loop_state is not UP.\n", | 1180 | DEBUG15(printk ("scsi(%ld): pport loop_state is not UP.\n", |
1158 | vha->host_no)); | 1181 | base_vha->host_no)); |
1159 | atomic_set(&vha->loop_state, LOOP_DEAD); | 1182 | atomic_set(&vha->loop_state, LOOP_DEAD); |
1160 | if (!disable) | 1183 | if (!disable) |
1161 | fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); | 1184 | fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); |
@@ -1171,9 +1194,9 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
1171 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); | 1194 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); |
1172 | fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); | 1195 | fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); |
1173 | fc_host_supported_classes(vha->host) = | 1196 | fc_host_supported_classes(vha->host) = |
1174 | fc_host_supported_classes(ha->host); | 1197 | fc_host_supported_classes(base_vha->host); |
1175 | fc_host_supported_speeds(vha->host) = | 1198 | fc_host_supported_speeds(vha->host) = |
1176 | fc_host_supported_speeds(ha->host); | 1199 | fc_host_supported_speeds(base_vha->host); |
1177 | 1200 | ||
1178 | qla24xx_vport_disable(fc_vport, disable); | 1201 | qla24xx_vport_disable(fc_vport, disable); |
1179 | 1202 | ||
@@ -1181,8 +1204,6 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
1181 | vport_create_failed_2: | 1204 | vport_create_failed_2: |
1182 | qla24xx_disable_vp(vha); | 1205 | qla24xx_disable_vp(vha); |
1183 | qla24xx_deallocate_vp_id(vha); | 1206 | qla24xx_deallocate_vp_id(vha); |
1184 | kfree(vha->port_name); | ||
1185 | kfree(vha->node_name); | ||
1186 | scsi_host_put(vha->host); | 1207 | scsi_host_put(vha->host); |
1187 | return FC_VPORT_FAILED; | 1208 | return FC_VPORT_FAILED; |
1188 | } | 1209 | } |
@@ -1191,17 +1212,25 @@ static int | |||
1191 | qla24xx_vport_delete(struct fc_vport *fc_vport) | 1212 | qla24xx_vport_delete(struct fc_vport *fc_vport) |
1192 | { | 1213 | { |
1193 | scsi_qla_host_t *vha = fc_vport->dd_data; | 1214 | scsi_qla_host_t *vha = fc_vport->dd_data; |
1194 | scsi_qla_host_t *pha = to_qla_parent(vha); | 1215 | fc_port_t *fcport, *tfcport; |
1195 | 1216 | ||
1196 | while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) || | 1217 | while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) || |
1197 | test_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags)) | 1218 | test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) |
1198 | msleep(1000); | 1219 | msleep(1000); |
1199 | 1220 | ||
1200 | qla24xx_disable_vp(vha); | 1221 | qla24xx_disable_vp(vha); |
1201 | qla24xx_deallocate_vp_id(vha); | ||
1202 | 1222 | ||
1203 | kfree(vha->node_name); | 1223 | fc_remove_host(vha->host); |
1204 | kfree(vha->port_name); | 1224 | |
1225 | scsi_remove_host(vha->host); | ||
1226 | |||
1227 | list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) { | ||
1228 | list_del(&fcport->list); | ||
1229 | kfree(fcport); | ||
1230 | fcport = NULL; | ||
1231 | } | ||
1232 | |||
1233 | qla24xx_deallocate_vp_id(vha); | ||
1205 | 1234 | ||
1206 | if (vha->timer_active) { | 1235 | if (vha->timer_active) { |
1207 | qla2x00_vp_stop_timer(vha); | 1236 | qla2x00_vp_stop_timer(vha); |
@@ -1210,10 +1239,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
1210 | vha->host_no, vha->vp_idx, vha)); | 1239 | vha->host_no, vha->vp_idx, vha)); |
1211 | } | 1240 | } |
1212 | 1241 | ||
1213 | fc_remove_host(vha->host); | ||
1214 | |||
1215 | scsi_remove_host(vha->host); | ||
1216 | |||
1217 | scsi_host_put(vha->host); | 1242 | scsi_host_put(vha->host); |
1218 | 1243 | ||
1219 | return 0; | 1244 | return 0; |
@@ -1318,15 +1343,16 @@ struct fc_function_template qla2xxx_transport_vport_functions = { | |||
1318 | }; | 1343 | }; |
1319 | 1344 | ||
1320 | void | 1345 | void |
1321 | qla2x00_init_host_attr(scsi_qla_host_t *ha) | 1346 | qla2x00_init_host_attr(scsi_qla_host_t *vha) |
1322 | { | 1347 | { |
1348 | struct qla_hw_data *ha = vha->hw; | ||
1323 | u32 speed = FC_PORTSPEED_UNKNOWN; | 1349 | u32 speed = FC_PORTSPEED_UNKNOWN; |
1324 | 1350 | ||
1325 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); | 1351 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); |
1326 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); | 1352 | fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); |
1327 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; | 1353 | fc_host_supported_classes(vha->host) = FC_COS_CLASS3; |
1328 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; | 1354 | fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; |
1329 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; | 1355 | fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; |
1330 | 1356 | ||
1331 | if (IS_QLA25XX(ha)) | 1357 | if (IS_QLA25XX(ha)) |
1332 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | 1358 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | |
@@ -1338,5 +1364,5 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha) | |||
1338 | speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | 1364 | speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; |
1339 | else | 1365 | else |
1340 | speed = FC_PORTSPEED_1GBIT; | 1366 | speed = FC_PORTSPEED_1GBIT; |
1341 | fc_host_supported_speeds(ha->host) = speed; | 1367 | fc_host_supported_speeds(vha->host) = speed; |
1342 | } | 1368 | } |