summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_vport.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 09:50:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 09:50:42 -0700
commitc9b8af00ff71f86ff3d092cc60ca673e1d0eae5b (patch)
tree25cc016481cc693552bebb4040041817280c2ccf /drivers/scsi/lpfc/lpfc_vport.c
parentc59a264c9e932c828d533497e286b89e43c8d1be (diff)
parent82681a318f9f028ea64e61f24bbd9ac535531921 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (154 commits) [SCSI] osd: Remove out-of-tree left overs [SCSI] libosd: Use REQ_QUIET requests. [SCSI] osduld: use filp_open() when looking up an osd-device [SCSI] libosd: Define an osd_dev wrapper to retrieve the request_queue [SCSI] libosd: osd_req_{read,write} takes a length parameter [SCSI] libosd: Let _osd_req_finalize_data_integrity receive number of out_bytes [SCSI] libosd: osd_req_{read,write}_kern new API [SCSI] libosd: Better printout of OSD target system information [SCSI] libosd: OSD2r05: Attribute definitions [SCSI] libosd: OSD2r05: Additional command enums [SCSI] mpt fusion: fix up doc book comments [SCSI] mpt fusion: Added support for Broadcast primitives Event handling [SCSI] mpt fusion: Queue full event handling [SCSI] mpt fusion: RAID device handling and Dual port Raid support is added [SCSI] mpt fusion: Put IOC into ready state if it not already in ready state [SCSI] mpt fusion: Code Cleanup patch [SCSI] mpt fusion: Rescan SAS topology added [SCSI] mpt fusion: SAS topology scan changes, expander events [SCSI] mpt fusion: Firmware event implementation using seperate WorkQueue [SCSI] mpt fusion: rewrite of ioctl_cmds internal generated function ...
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_vport.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 917ad56b0af..a6313ee84ac 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -32,8 +32,10 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_fc.h>
+#include "lpfc_hw4.h"
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_sli4.h"
#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
@@ -89,6 +91,8 @@ lpfc_alloc_vpi(struct lpfc_hba *phba)
vpi = 0;
else
set_bit(vpi, phba->vpi_bmask);
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ phba->sli4_hba.max_cfg_param.vpi_used++;
spin_unlock_irq(&phba->hbalock);
return vpi;
}
@@ -96,8 +100,12 @@ lpfc_alloc_vpi(struct lpfc_hba *phba)
static void
lpfc_free_vpi(struct lpfc_hba *phba, int vpi)
{
+ if (vpi == 0)
+ return;
spin_lock_irq(&phba->hbalock);
clear_bit(vpi, phba->vpi_bmask);
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ phba->sli4_hba.max_cfg_param.vpi_used--;
spin_unlock_irq(&phba->hbalock);
}
@@ -113,7 +121,7 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport)
if (!pmb) {
return -ENOMEM;
}
- mb = &pmb->mb;
+ mb = &pmb->u.mb;
lpfc_read_sparam(phba, pmb, vport->vpi);
/*
@@ -243,23 +251,22 @@ static void lpfc_discovery_wait(struct lpfc_vport *vport)
(vport->fc_flag & wait_flags) ||
((vport->port_state > LPFC_VPORT_FAILED) &&
(vport->port_state < LPFC_VPORT_READY))) {
- lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT,
"1833 Vport discovery quiesce Wait:"
- " vpi x%x state x%x fc_flags x%x"
+ " state x%x fc_flags x%x"
" num_nodes x%x, waiting 1000 msecs"
" total wait msecs x%x\n",
- vport->vpi, vport->port_state,
- vport->fc_flag, vport->num_disc_nodes,
+ vport->port_state, vport->fc_flag,
+ vport->num_disc_nodes,
jiffies_to_msecs(jiffies - start_time));
msleep(1000);
} else {
/* Base case. Wait variants satisfied. Break out */
- lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT,
"1834 Vport discovery quiesced:"
- " vpi x%x state x%x fc_flags x%x"
+ " state x%x fc_flags x%x"
" wait msecs x%x\n",
- vport->vpi, vport->port_state,
- vport->fc_flag,
+ vport->port_state, vport->fc_flag,
jiffies_to_msecs(jiffies
- start_time));
break;
@@ -267,12 +274,10 @@ static void lpfc_discovery_wait(struct lpfc_vport *vport)
}
if (time_after(jiffies, wait_time_max))
- lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
"1835 Vport discovery quiesce failed:"
- " vpi x%x state x%x fc_flags x%x"
- " wait msecs x%x\n",
- vport->vpi, vport->port_state,
- vport->fc_flag,
+ " state x%x fc_flags x%x wait msecs x%x\n",
+ vport->port_state, vport->fc_flag,
jiffies_to_msecs(jiffies - start_time));
}
@@ -308,6 +313,21 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
goto error_out;
}
+ /*
+ * In SLI4, the vpi must be activated before it can be used
+ * by the port.
+ */
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ rc = lpfc_sli4_init_vpi(phba, vpi);
+ if (rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
+ "1838 Failed to INIT_VPI on vpi %d "
+ "status %d\n", vpi, rc);
+ rc = VPORT_NORESOURCES;
+ lpfc_free_vpi(phba, vpi);
+ goto error_out;
+ }
+ }
/* Assign an unused board number */
if ((instance = lpfc_get_instance()) < 0) {
@@ -535,6 +555,16 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
"physical host\n");
return VPORT_ERROR;
}
+
+ /* If the vport is a static vport fail the deletion. */
+ if ((vport->vport_flag & STATIC_VPORT) &&
+ !(phba->pport->load_flag & FC_UNLOADING)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1837 vport_delete failed: Cannot delete "
+ "static vport.\n");
+ return VPORT_ERROR;
+ }
+
/*
* If we are not unloading the driver then prevent the vport_delete
* from happening until after this vport's discovery is finished.
@@ -710,7 +740,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba)
struct lpfc_vport *port_iterator;
struct lpfc_vport **vports;
int index = 0;
- vports = kzalloc((phba->max_vpi + 1) * sizeof(struct lpfc_vport *),
+ vports = kzalloc((phba->max_vports + 1) * sizeof(struct lpfc_vport *),
GFP_KERNEL);
if (vports == NULL)
return NULL;
@@ -734,7 +764,7 @@ lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports)
int i;
if (vports == NULL)
return;
- for (i=0; vports[i] != NULL && i <= phba->max_vpi; i++)
+ for (i = 0; vports[i] != NULL && i <= phba->max_vports; i++)
scsi_host_put(lpfc_shost_from_vport(vports[i]));
kfree(vports);
}