static int bfad_im_vport_delete(struct fc_vport *fc_vport) { struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data; struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) vport->drv_port.im_port; struct bfad_s *bfad = im_port->bfad; struct bfad_port_s *port; struct bfa_fcs_vport_s *fcs_vport; struct Scsi_Host *vshost; wwn_t pwwn; int rc; unsigned long flags; struct completion fcomp; if (im_port->flags & BFAD_PORT_DELETE) goto free_scsi_host; port = im_port->port; vshost = vport->drv_port.im_port->shost; pwwn = wwn_to_u64((u8 *) &fc_host_port_name(vshost)); spin_lock_irqsave(&bfad->bfad_lock, flags); fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn); spin_unlock_irqrestore(&bfad->bfad_lock, flags); if (fcs_vport == NULL) return VPCERR_BAD_WWN; vport->drv_port.flags |= BFAD_PORT_DELETE; vport->comp_del = &fcomp; init_completion(vport->comp_del); spin_lock_irqsave(&bfad->bfad_lock, flags); rc = bfa_fcs_vport_delete(&vport->fcs_vport); spin_unlock_irqrestore(&bfad->bfad_lock, flags); wait_for_completion(vport->comp_del); free_scsi_host: bfad_os_scsi_host_free(bfad, im_port); kfree(vport); return 0; }
/** * Create a vport under a vf. */ bfa_status_t bfad_vport_create(struct bfad_s *bfad, u16 vf_id, struct bfa_port_cfg_s *port_cfg) { struct bfad_vport_s *vport; int rc = BFA_STATUS_OK; unsigned long flags; struct completion fcomp; vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL); if (!vport) { rc = BFA_STATUS_ENOMEM; goto ext; } 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); spin_unlock_irqrestore(&bfad->bfad_lock, flags); if (rc != BFA_STATUS_OK) goto ext_free_vport; if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) { rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port); if (rc != BFA_STATUS_OK) goto ext_free_fcs_vport; } spin_lock_irqsave(&bfad->bfad_lock, flags); bfa_fcs_vport_start(&vport->fcs_vport); spin_unlock_irqrestore(&bfad->bfad_lock, flags); return BFA_STATUS_OK; ext_free_fcs_vport: spin_lock_irqsave(&bfad->bfad_lock, flags); vport->comp_del = &fcomp; init_completion(vport->comp_del); bfa_fcs_vport_delete(&vport->fcs_vport); spin_unlock_irqrestore(&bfad->bfad_lock, flags); wait_for_completion(vport->comp_del); ext_free_vport: kfree(vport); ext: return rc; }
static ssize_t bfad_im_vport_delete(struct class_device *cdev, const char *buf, size_t count) { struct Scsi_Host *shost = class_to_shost(cdev); struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; u8 wwn[8]; int status; unsigned long flags; struct bfa_fcs_vport_s *fcs_vport; struct bfad_vport_s *bfad_vport; struct completion fcomp; status = bfad_im_parse_wwn(&buf[0], wwn); if (status) return status; spin_lock_irqsave(&bfad->bfad_lock, flags); fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, *(wwn_t *)wwn); if (fcs_vport == NULL) { spin_unlock_irqrestore(&bfad->bfad_lock, flags); return -EINVAL; } bfad_vport = fcs_vport->vport_drv; bfad_vport->drv_port.flags |= BFAD_PORT_DELETE; bfad_vport->comp_del = &fcomp; init_completion(bfad_vport->comp_del); status = bfa_fcs_vport_delete(fcs_vport); spin_unlock_irqrestore(&bfad->bfad_lock, flags); wait_for_completion(bfad_vport->comp_del); if (status != BFA_STATUS_OK) return -EIO; bfad_os_scsi_host_free(bfad, bfad_vport->drv_port.im_port); kfree(bfad_vport); return count; }