diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_vport.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 62 |
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 @@ | |||
32 | #include <scsi/scsi_device.h> | 32 | #include <scsi/scsi_device.h> |
33 | #include <scsi/scsi_host.h> | 33 | #include <scsi/scsi_host.h> |
34 | #include <scsi/scsi_transport_fc.h> | 34 | #include <scsi/scsi_transport_fc.h> |
35 | #include "lpfc_hw4.h" | ||
35 | #include "lpfc_hw.h" | 36 | #include "lpfc_hw.h" |
36 | #include "lpfc_sli.h" | 37 | #include "lpfc_sli.h" |
38 | #include "lpfc_sli4.h" | ||
37 | #include "lpfc_nl.h" | 39 | #include "lpfc_nl.h" |
38 | #include "lpfc_disc.h" | 40 | #include "lpfc_disc.h" |
39 | #include "lpfc_scsi.h" | 41 | #include "lpfc_scsi.h" |
@@ -89,6 +91,8 @@ lpfc_alloc_vpi(struct lpfc_hba *phba) | |||
89 | vpi = 0; | 91 | vpi = 0; |
90 | else | 92 | else |
91 | set_bit(vpi, phba->vpi_bmask); | 93 | set_bit(vpi, phba->vpi_bmask); |
94 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
95 | phba->sli4_hba.max_cfg_param.vpi_used++; | ||
92 | spin_unlock_irq(&phba->hbalock); | 96 | spin_unlock_irq(&phba->hbalock); |
93 | return vpi; | 97 | return vpi; |
94 | } | 98 | } |
@@ -96,8 +100,12 @@ lpfc_alloc_vpi(struct lpfc_hba *phba) | |||
96 | static void | 100 | static void |
97 | lpfc_free_vpi(struct lpfc_hba *phba, int vpi) | 101 | lpfc_free_vpi(struct lpfc_hba *phba, int vpi) |
98 | { | 102 | { |
103 | if (vpi == 0) | ||
104 | return; | ||
99 | spin_lock_irq(&phba->hbalock); | 105 | spin_lock_irq(&phba->hbalock); |
100 | clear_bit(vpi, phba->vpi_bmask); | 106 | clear_bit(vpi, phba->vpi_bmask); |
107 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
108 | phba->sli4_hba.max_cfg_param.vpi_used--; | ||
101 | spin_unlock_irq(&phba->hbalock); | 109 | spin_unlock_irq(&phba->hbalock); |
102 | } | 110 | } |
103 | 111 | ||
@@ -113,7 +121,7 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
113 | if (!pmb) { | 121 | if (!pmb) { |
114 | return -ENOMEM; | 122 | return -ENOMEM; |
115 | } | 123 | } |
116 | mb = &pmb->mb; | 124 | mb = &pmb->u.mb; |
117 | 125 | ||
118 | lpfc_read_sparam(phba, pmb, vport->vpi); | 126 | lpfc_read_sparam(phba, pmb, vport->vpi); |
119 | /* | 127 | /* |
@@ -243,23 +251,22 @@ static void lpfc_discovery_wait(struct lpfc_vport *vport) | |||
243 | (vport->fc_flag & wait_flags) || | 251 | (vport->fc_flag & wait_flags) || |
244 | ((vport->port_state > LPFC_VPORT_FAILED) && | 252 | ((vport->port_state > LPFC_VPORT_FAILED) && |
245 | (vport->port_state < LPFC_VPORT_READY))) { | 253 | (vport->port_state < LPFC_VPORT_READY))) { |
246 | lpfc_printf_log(phba, KERN_INFO, LOG_VPORT, | 254 | lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT, |
247 | "1833 Vport discovery quiesce Wait:" | 255 | "1833 Vport discovery quiesce Wait:" |
248 | " vpi x%x state x%x fc_flags x%x" | 256 | " state x%x fc_flags x%x" |
249 | " num_nodes x%x, waiting 1000 msecs" | 257 | " num_nodes x%x, waiting 1000 msecs" |
250 | " total wait msecs x%x\n", | 258 | " total wait msecs x%x\n", |
251 | vport->vpi, vport->port_state, | 259 | vport->port_state, vport->fc_flag, |
252 | vport->fc_flag, vport->num_disc_nodes, | 260 | vport->num_disc_nodes, |
253 | jiffies_to_msecs(jiffies - start_time)); | 261 | jiffies_to_msecs(jiffies - start_time)); |
254 | msleep(1000); | 262 | msleep(1000); |
255 | } else { | 263 | } else { |
256 | /* Base case. Wait variants satisfied. Break out */ | 264 | /* Base case. Wait variants satisfied. Break out */ |
257 | lpfc_printf_log(phba, KERN_INFO, LOG_VPORT, | 265 | lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT, |
258 | "1834 Vport discovery quiesced:" | 266 | "1834 Vport discovery quiesced:" |
259 | " vpi x%x state x%x fc_flags x%x" | 267 | " state x%x fc_flags x%x" |
260 | " wait msecs x%x\n", | 268 | " wait msecs x%x\n", |
261 | vport->vpi, vport->port_state, | 269 | vport->port_state, vport->fc_flag, |
262 | vport->fc_flag, | ||
263 | jiffies_to_msecs(jiffies | 270 | jiffies_to_msecs(jiffies |
264 | - start_time)); | 271 | - start_time)); |
265 | break; | 272 | break; |
@@ -267,12 +274,10 @@ static void lpfc_discovery_wait(struct lpfc_vport *vport) | |||
267 | } | 274 | } |
268 | 275 | ||
269 | if (time_after(jiffies, wait_time_max)) | 276 | if (time_after(jiffies, wait_time_max)) |
270 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, | 277 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, |
271 | "1835 Vport discovery quiesce failed:" | 278 | "1835 Vport discovery quiesce failed:" |
272 | " vpi x%x state x%x fc_flags x%x" | 279 | " state x%x fc_flags x%x wait msecs x%x\n", |
273 | " wait msecs x%x\n", | 280 | vport->port_state, vport->fc_flag, |
274 | vport->vpi, vport->port_state, | ||
275 | vport->fc_flag, | ||
276 | jiffies_to_msecs(jiffies - start_time)); | 281 | jiffies_to_msecs(jiffies - start_time)); |
277 | } | 282 | } |
278 | 283 | ||
@@ -308,6 +313,21 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
308 | goto error_out; | 313 | goto error_out; |
309 | } | 314 | } |
310 | 315 | ||
316 | /* | ||
317 | * In SLI4, the vpi must be activated before it can be used | ||
318 | * by the port. | ||
319 | */ | ||
320 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
321 | rc = lpfc_sli4_init_vpi(phba, vpi); | ||
322 | if (rc) { | ||
323 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, | ||
324 | "1838 Failed to INIT_VPI on vpi %d " | ||
325 | "status %d\n", vpi, rc); | ||
326 | rc = VPORT_NORESOURCES; | ||
327 | lpfc_free_vpi(phba, vpi); | ||
328 | goto error_out; | ||
329 | } | ||
330 | } | ||
311 | 331 | ||
312 | /* Assign an unused board number */ | 332 | /* Assign an unused board number */ |
313 | if ((instance = lpfc_get_instance()) < 0) { | 333 | if ((instance = lpfc_get_instance()) < 0) { |
@@ -535,6 +555,16 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
535 | "physical host\n"); | 555 | "physical host\n"); |
536 | return VPORT_ERROR; | 556 | return VPORT_ERROR; |
537 | } | 557 | } |
558 | |||
559 | /* If the vport is a static vport fail the deletion. */ | ||
560 | if ((vport->vport_flag & STATIC_VPORT) && | ||
561 | !(phba->pport->load_flag & FC_UNLOADING)) { | ||
562 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, | ||
563 | "1837 vport_delete failed: Cannot delete " | ||
564 | "static vport.\n"); | ||
565 | return VPORT_ERROR; | ||
566 | } | ||
567 | |||
538 | /* | 568 | /* |
539 | * If we are not unloading the driver then prevent the vport_delete | 569 | * If we are not unloading the driver then prevent the vport_delete |
540 | * from happening until after this vport's discovery is finished. | 570 | * from happening until after this vport's discovery is finished. |
@@ -710,7 +740,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) | |||
710 | struct lpfc_vport *port_iterator; | 740 | struct lpfc_vport *port_iterator; |
711 | struct lpfc_vport **vports; | 741 | struct lpfc_vport **vports; |
712 | int index = 0; | 742 | int index = 0; |
713 | vports = kzalloc((phba->max_vpi + 1) * sizeof(struct lpfc_vport *), | 743 | vports = kzalloc((phba->max_vports + 1) * sizeof(struct lpfc_vport *), |
714 | GFP_KERNEL); | 744 | GFP_KERNEL); |
715 | if (vports == NULL) | 745 | if (vports == NULL) |
716 | return NULL; | 746 | return NULL; |
@@ -734,7 +764,7 @@ lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports) | |||
734 | int i; | 764 | int i; |
735 | if (vports == NULL) | 765 | if (vports == NULL) |
736 | return; | 766 | return; |
737 | for (i=0; vports[i] != NULL && i <= phba->max_vpi; i++) | 767 | for (i = 0; vports[i] != NULL && i <= phba->max_vports; i++) |
738 | scsi_host_put(lpfc_shost_from_vport(vports[i])); | 768 | scsi_host_put(lpfc_shost_from_vport(vports[i])); |
739 | kfree(vports); | 769 | kfree(vports); |
740 | } | 770 | } |