Skip to content

Commit

Permalink
[SCSI] bfa: PBC vport create
Browse files Browse the repository at this point in the history
This patch enables creating PBC vport.
During fcs init, fcs will read PBC vport using bfa iocfc API and invoke fcb
callback to add the pbc vport entries into a list. The pbc vport list will be
traversed in the subsequent pci probe process and vport will be created using
fc transport provided vport create function.

Signed-off-by: Jing Huang <huangj@brocade.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Jing Huang authored and James Bottomley committed Jul 27, 2010
1 parent ed96932 commit d988354
Show file tree
Hide file tree
Showing 15 changed files with 179 additions and 34 deletions.
10 changes: 9 additions & 1 deletion drivers/scsi/bfa/bfa_fcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,22 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
void
bfa_fcs_init(struct bfa_fcs_s *fcs)
{
int i;
int i, npbc_vports;
struct bfa_fcs_mod_s *mod;
struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];

for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
mod = &fcs_modules[i];
if (mod->modinit)
mod->modinit(fcs);
}
/* Initialize pbc vports */
if (!fcs->min_cfg) {
npbc_vports =
bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
for (i = 0; i < npbc_vports; i++)
bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
}
}

/**
Expand Down
11 changes: 11 additions & 0 deletions drivers/scsi/bfa/bfa_iocfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,17 @@ bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, struct bfa_boot_pbc_s *pbcfg)
memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun));
}

int
bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
{
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;

memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport));
return cfgrsp->pbc_cfg.nvports;
}


#endif


3 changes: 3 additions & 0 deletions drivers/scsi/bfa/bfa_iocfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <bfa_ioc.h>
#include <bfa.h>
#include <bfi/bfi_iocfc.h>
#include <bfi/bfi_pbc.h>
#include <bfa_callback_priv.h>

#define BFA_REQQ_NELEMS_MIN (4)
Expand Down Expand Up @@ -169,6 +170,8 @@ void bfa_com_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi,
void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns);
void bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa,
struct bfa_boot_pbc_s *pbcfg);
int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
struct bfi_pbc_vport_s *pbc_vport);

#endif /* __BFA_IOCFC_H__ */

61 changes: 56 additions & 5 deletions drivers/scsi/bfa/bfad.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,31 @@ bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
return rc;
}

/**
* @brief
* FCS PBC VPORT Create
*/
void
bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport)
{

struct bfad_pcfg_s *pcfg;

pcfg = kzalloc(sizeof(struct bfad_pcfg_s), GFP_ATOMIC);
if (!pcfg) {
bfa_trc(bfad, 0);
return;
}

pcfg->port_cfg.roles = BFA_PORT_ROLE_FCP_IM;
pcfg->port_cfg.pwwn = pbc_vport.vp_pwwn;
pcfg->port_cfg.nwwn = pbc_vport.vp_nwwn;
pcfg->port_cfg.preboot_vp = BFA_TRUE;

list_add_tail(&pcfg->list_entry, &bfad->pbc_pcfg_list);

return;
}

void
bfad_hal_mem_release(struct bfad_s *bfad)
Expand Down Expand Up @@ -481,10 +505,10 @@ bfad_hal_mem_alloc(struct bfad_s *bfad)
*/
bfa_status_t
bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
struct bfa_port_cfg_s *port_cfg, struct device *dev)
struct bfa_port_cfg_s *port_cfg, struct device *dev)
{
struct bfad_vport_s *vport;
int rc = BFA_STATUS_OK;
int rc = BFA_STATUS_OK;
unsigned long flags;
struct completion fcomp;

Expand All @@ -496,8 +520,12 @@ bfad_vport_create(struct bfad_s *bfad, u16 vf_id,

vport->drv_port.bfad = bfad;
spin_lock_irqsave(&bfad->bfad_lock, flags);
rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
port_cfg, vport);
if (port_cfg->preboot_vp == BFA_TRUE)
rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport,
&bfad->bfa_fcs, vf_id, port_cfg, vport);
else
rc = bfa_fcs_vport_create(&vport->fcs_vport,
&bfad->bfa_fcs, vf_id, port_cfg, vport);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);

if (rc != BFA_STATUS_OK)
Expand Down Expand Up @@ -884,6 +912,7 @@ bfa_status_t
bfad_start_ops(struct bfad_s *bfad)
{
int retval;
struct bfad_pcfg_s *pcfg, *pcfg_new;

/* PPORT FCS config */
bfad_fcs_port_cfg(bfad);
Expand All @@ -901,6 +930,27 @@ bfad_start_ops(struct bfad_s *bfad)

bfad_drv_start(bfad);

/* pbc vport creation */
list_for_each_entry_safe(pcfg, pcfg_new, &bfad->pbc_pcfg_list,
list_entry) {
struct fc_vport_identifiers vid;
struct fc_vport *fc_vport;

memset(&vid, 0, sizeof(vid));
vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
vid.vport_type = FC_PORTTYPE_NPIV;
vid.disable = false;
vid.node_name = wwn_to_u64((u8 *)&pcfg->port_cfg.nwwn);
vid.port_name = wwn_to_u64((u8 *)&pcfg->port_cfg.pwwn);
fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid);
if (!fc_vport)
printk(KERN_WARNING "bfad%d: failed to create pbc vport"
" %llx\n", bfad->inst_no, vid.port_name);
list_del(&pcfg->list_entry);
kfree(pcfg);

}

/*
* If bfa_linkup_delay is set to -1 default; try to retrive the
* value using the bfad_os_get_linkup_delay(); else use the
Expand Down Expand Up @@ -928,7 +978,7 @@ bfad_start_ops(struct bfad_s *bfad)
}

int
bfad_worker (void *ptr)
bfad_worker(void *ptr)
{
struct bfad_s *bfad;
unsigned long flags;
Expand Down Expand Up @@ -1031,6 +1081,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)

bfad->ref_count = 0;
bfad->pport.bfad = bfad;
INIT_LIST_HEAD(&bfad->pbc_pcfg_list);

bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
"bfad_worker");
Expand Down
43 changes: 26 additions & 17 deletions drivers/scsi/bfa/bfad_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,47 +373,53 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
(struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad;
struct bfa_port_cfg_s port_cfg;
struct bfad_pcfg_s *pcfg;
int status = 0, rc;
unsigned long flags;

memset(&port_cfg, 0, sizeof(port_cfg));

port_cfg.pwwn = wwn_to_u64((u8 *) &fc_vport->port_name);
port_cfg.nwwn = wwn_to_u64((u8 *) &fc_vport->node_name);

u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn);
u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn);
if (strlen(vname) > 0)
strcpy((char *)&port_cfg.sym_name, vname);

port_cfg.roles = BFA_PORT_ROLE_FCP_IM;
rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);

spin_lock_irqsave(&bfad->bfad_lock, flags);
list_for_each_entry(pcfg, &bfad->pbc_pcfg_list, list_entry) {
if (port_cfg.pwwn == pcfg->port_cfg.pwwn) {
port_cfg.preboot_vp = pcfg->port_cfg.preboot_vp;
break;
}
}
spin_unlock_irqrestore(&bfad->bfad_lock, flags);

rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);
if (rc == BFA_STATUS_OK) {
struct bfad_vport_s *vport;
struct bfad_vport_s *vport;
struct bfa_fcs_vport_s *fcs_vport;
struct Scsi_Host *vshost;

spin_lock_irqsave(&bfad->bfad_lock, flags);
fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0,
port_cfg.pwwn);
if (fcs_vport == NULL) {
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
if (fcs_vport == NULL)
return VPCERR_BAD_WWN;
}

fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
if (disable) {
spin_lock_irqsave(&bfad->bfad_lock, flags);
bfa_fcs_vport_stop(fcs_vport);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
}
spin_unlock_irqrestore(&bfad->bfad_lock, flags);

vport = fcs_vport->vport_drv;
vshost = vport->drv_port.im_port->shost;
fc_host_node_name(vshost) = wwn_to_u64((u8 *) &port_cfg.nwwn);
fc_host_port_name(vshost) = wwn_to_u64((u8 *) &port_cfg.pwwn);
fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn);
fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn);
fc_vport->dd_data = vport;
vport->drv_port.im_port->fc_vport = fc_vport;

} else if (rc == BFA_STATUS_INVALID_WWN)
return VPCERR_BAD_WWN;
else if (rc == BFA_STATUS_VPORT_EXISTS)
Expand All @@ -422,7 +428,7 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
return VPCERR_NO_FABRIC_SUPP;
else if (rc == BFA_STATUS_VPORT_WWN_BP)
return VPCERR_BAD_WWN;
else
else
return FC_VPORT_FAILED;

return status;
Expand All @@ -449,7 +455,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
port = im_port->port;

vshost = vport->drv_port.im_port->shost;
pwwn = wwn_to_u64((u8 *) &fc_host_port_name(vshost));
u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);

spin_lock_irqsave(&bfad->bfad_lock, flags);
fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
Expand All @@ -467,6 +473,9 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
rc = bfa_fcs_vport_delete(&vport->fcs_vport);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);

if (rc == BFA_STATUS_PBC)
return -1;

wait_for_completion(vport->comp_del);

free_scsi_host:
Expand All @@ -490,7 +499,7 @@ bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
vport = (struct bfad_vport_s *)fc_vport->dd_data;
bfad = vport->drv_port.bfad;
vshost = vport->drv_port.im_port->shost;
pwwn = wwn_to_u64((u8 *) &fc_vport->port_name);
u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);

spin_lock_irqsave(&bfad->bfad_lock, flags);
fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
Expand Down
8 changes: 8 additions & 0 deletions drivers/scsi/bfa/bfad_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ struct bfad_vport_s {
struct bfad_port_s drv_port;
struct bfa_fcs_vport_s fcs_vport;
struct completion *comp_del;
struct list_head list_entry;
struct bfa_port_cfg_s port_cfg;
};

/*
Expand Down Expand Up @@ -195,6 +197,12 @@ struct bfad_s {
bfa_boolean_t ipfc_enabled;
union bfad_tmp_buf tmp_buf;
struct fc_host_statistics link_stats;
struct list_head pbc_pcfg_list;
};

struct bfad_pcfg_s {
struct list_head list_entry;
struct bfa_port_cfg_s port_cfg;
};

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/bfa/bfad_im.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,

out_fc_rel:
scsi_host_put(im_port->shost);
im_port->shost = NULL;
out_free_idr:
mutex_lock(&bfad_mutex);
idr_remove(&bfad_im_port_index, im_port->idr_id);
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/bfa/fabric.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)

list_for_each_safe(qe, qen, &fabric->vport_q) {
vport = (struct bfa_fcs_vport_s *)qe;
bfa_fcs_vport_delete(vport);
bfa_fcs_vport_fcs_delete(vport);
}

bfa_fcs_port_delete(&fabric->bport);
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/bfa/fcs_vport.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
void bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport);

#endif /* __FCS_VPORT_H__ */

12 changes: 6 additions & 6 deletions drivers/scsi/bfa/include/defs/bfa_defs_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ enum bfa_port_role {
* FCS port configuration.
*/
struct bfa_port_cfg_s {
wwn_t pwwn; /* port wwn */
wwn_t nwwn; /* node wwn */
struct bfa_port_symname_s sym_name; /* vm port symbolic name */
enum bfa_port_role roles; /* FCS port roles */
u32 rsvd;
u8 tag[16]; /* opaque tag from application */
wwn_t pwwn; /* port wwn */
wwn_t nwwn; /* node wwn */
struct bfa_port_symname_s sym_name; /* vm port symbolic name */
bfa_boolean_t preboot_vp; /* vport created from PBC */
enum bfa_port_role roles; /* FCS port roles */
u8 tag[16]; /* opaque tag from application */
};

/**
Expand Down
5 changes: 4 additions & 1 deletion drivers/scsi/bfa/include/defs/bfa_defs_status.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ enum bfa_status {
* loaded */
BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */
BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */
BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed or loaded */
BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed
* or loaded */
BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */
BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */
BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */
Expand Down Expand Up @@ -249,6 +250,8 @@ enum bfa_status {
BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not
* allowed for the current
* Teaming mode */
BFA_STATUS_PBC = 154, /* Operation not allowed for pre-boot
* configuration */
BFA_STATUS_MAX_VAL /* Unknown error code */
};
#define bfa_status_t enum bfa_status
Expand Down
3 changes: 2 additions & 1 deletion drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ struct bfad_vport_s;
*
* @return None
*/
void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv);
void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv);
void bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s);



Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/bfa/include/fcs/bfa_fcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ struct bfa_fcs_s {
/*
* bfa fcs API functions
*/
void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa_boolean_t min_cfg);
void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa,
struct bfad_s *bfad, bfa_boolean_t min_cfg);
void bfa_fcs_init(struct bfa_fcs_s *fcs);
void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
struct bfa_fcs_driver_info_s *driver_info);
Expand Down
4 changes: 4 additions & 0 deletions drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ bfa_status_t bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport,
struct bfa_fcs_s *fcs, u16 vf_id,
struct bfa_port_cfg_s *port_cfg,
struct bfad_vport_s *vport_drv);
bfa_status_t bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport,
struct bfa_fcs_s *fcs, uint16_t vf_id,
struct bfa_port_cfg_s *port_cfg,
struct bfad_vport_s *vport_drv);
bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport);
bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport);
bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport);
Expand Down
Loading

0 comments on commit d988354

Please sign in to comment.