diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-08-02 11:10:31 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-08-01 13:24:10 -0400 |
commit | 51ef4c26891a734bc8416b639ad460a8162926bc (patch) | |
tree | 8279e11bf1a0a3200e8aa9bb3d956345ef73533c /drivers/scsi/lpfc/lpfc_vport.c | |
parent | 78b2d852a88cd2a55e3ab632109de045d58b83e3 (diff) |
[SCSI] lpfc 8.2.2 : Miscellaneous Bug Fixes
- Fix vport ndlp ref counting errors
- Fix use after free of ndlp structure
- Use the correct flag to check for LOADING setting.
- Fix driver unload bugs (related to shost references) after link down or rscn
- Fix up HBQ initialization
- Fix port_list locking around driver unload.
- Fix references to hostdata as a phba
- Fix GFFID type offset to work correctly with big endian structure.
- Only call pci_disable_msi if the pci_enable_msi succeeded
- Fix vport_delete wait/fail if in discovery
- Put a reference on the nameservers ndlp when performing CT traffic.
- Remove unbalanced hba unlock.
- Fix up HBQ processing
- Fix lpfc debugfs discovery trace output for ELS rsp cmpl
- Send ADISC when rpi is 0
- Stop FDISC retrying forever
- Unable to retrieve correct config parameter for vport
- Fix sli_validate_fcp_iocb, sli_sum_iocb, sli_abort_iocb to be vport-aware.
- Fix index-out-of-range error in iocb. Spotted by Coverity.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_vport.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 77067d17c39d..7f0c263d1bd3 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -432,8 +432,29 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
432 | struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; | 432 | struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; |
433 | struct lpfc_hba *phba = vport->phba; | 433 | struct lpfc_hba *phba = vport->phba; |
434 | long timeout; | 434 | long timeout; |
435 | int rc = VPORT_ERROR; | ||
436 | 435 | ||
436 | if (vport->port_type == LPFC_PHYSICAL_PORT) { | ||
437 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, | ||
438 | "1812 vport_delete failed: Cannot delete " | ||
439 | "physical host\n"); | ||
440 | return VPORT_ERROR; | ||
441 | } | ||
442 | /* | ||
443 | * If we are not unloading the driver then prevent the vport_delete | ||
444 | * from happening until after this vport's discovery is finished. | ||
445 | */ | ||
446 | if (!(phba->pport->load_flag & FC_UNLOADING)) { | ||
447 | int check_count = 0; | ||
448 | while (check_count < ((phba->fc_ratov * 3) + 3) && | ||
449 | vport->port_state > LPFC_VPORT_FAILED && | ||
450 | vport->port_state < LPFC_VPORT_READY) { | ||
451 | check_count++; | ||
452 | msleep(1000); | ||
453 | } | ||
454 | if (vport->port_state > LPFC_VPORT_FAILED && | ||
455 | vport->port_state < LPFC_VPORT_READY) | ||
456 | return -EAGAIN; | ||
457 | } | ||
437 | /* | 458 | /* |
438 | * This is a bit of a mess. We want to ensure the shost doesn't get | 459 | * This is a bit of a mess. We want to ensure the shost doesn't get |
439 | * torn down until we're done with the embedded lpfc_vport structure. | 460 | * torn down until we're done with the embedded lpfc_vport structure. |
@@ -451,16 +472,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
451 | */ | 472 | */ |
452 | if (!scsi_host_get(shost) || !scsi_host_get(shost)) | 473 | if (!scsi_host_get(shost) || !scsi_host_get(shost)) |
453 | return VPORT_INVAL; | 474 | return VPORT_INVAL; |
454 | 475 | spin_lock_irq(&phba->hbalock); | |
455 | if (vport->port_type == LPFC_PHYSICAL_PORT) { | ||
456 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, | ||
457 | "1812 vport_delete failed: Cannot delete " | ||
458 | "physical host\n"); | ||
459 | goto out; | ||
460 | } | ||
461 | |||
462 | vport->load_flag |= FC_UNLOADING; | 476 | vport->load_flag |= FC_UNLOADING; |
463 | 477 | spin_unlock_irq(&phba->hbalock); | |
464 | kfree(vport->vname); | 478 | kfree(vport->vname); |
465 | lpfc_debugfs_terminate(vport); | 479 | lpfc_debugfs_terminate(vport); |
466 | fc_remove_host(lpfc_shost_from_vport(vport)); | 480 | fc_remove_host(lpfc_shost_from_vport(vport)); |
@@ -514,10 +528,8 @@ skip_logo: | |||
514 | spin_unlock_irq(&phba->hbalock); | 528 | spin_unlock_irq(&phba->hbalock); |
515 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, | 529 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, |
516 | "1828 Vport Deleted.\n"); | 530 | "1828 Vport Deleted.\n"); |
517 | rc = VPORT_OK; | ||
518 | out: | ||
519 | scsi_host_put(shost); | 531 | scsi_host_put(shost); |
520 | return rc; | 532 | return VPORT_OK; |
521 | } | 533 | } |
522 | 534 | ||
523 | EXPORT_SYMBOL(lpfc_vport_create); | 535 | EXPORT_SYMBOL(lpfc_vport_create); |
@@ -536,7 +548,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) | |||
536 | spin_lock_irq(&phba->hbalock); | 548 | spin_lock_irq(&phba->hbalock); |
537 | list_for_each_entry(port_iterator, &phba->port_list, listentry) { | 549 | list_for_each_entry(port_iterator, &phba->port_list, listentry) { |
538 | if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) { | 550 | if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) { |
539 | lpfc_printf_vlog(port_iterator, KERN_ERR, LOG_VPORT, | 551 | lpfc_printf_vlog(port_iterator, KERN_WARNING, LOG_VPORT, |
540 | "1801 Create vport work array FAILED: " | 552 | "1801 Create vport work array FAILED: " |
541 | "cannot do scsi_host_get\n"); | 553 | "cannot do scsi_host_get\n"); |
542 | continue; | 554 | continue; |