bfad_bsg.c revision 1a4d8e1bd81c018f7b8c7622066d5cfead59b38a
1b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati/*
2b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
3b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * All rights reserved
4b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * www.brocade.com
5b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati *
6b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati *
8b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * This program is free software; you can redistribute it and/or modify it
9b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * under the terms of the GNU General Public License (GPL) Version 2 as
10b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * published by the Free Software Foundation
11b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati *
12b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * This program is distributed in the hope that it will be useful, but
13b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * WITHOUT ANY WARRANTY; without even the implied warranty of
14b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati * General Public License for more details.
16b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati */
17b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
18b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati#include <linux/uaccess.h>
19b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati#include "bfad_drv.h"
20b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati#include "bfad_im.h"
21b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati#include "bfad_bsg.h"
22b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
23b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna GudipatiBFA_TRC_FILE(LDRV, BSG);
24b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
25b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati/* bfad_im_bsg_get_kobject - increment the bfa refcnt */
26b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic void
27b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_im_bsg_get_kobject(struct fc_bsg_job *job)
28b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
29b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct Scsi_Host *shost = job->shost;
30b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long flags;
31b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
32b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(shost->host_lock, flags);
33b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	__module_get(shost->dma_dev->driver->owner);
34b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(shost->host_lock, flags);
35b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
36b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
37b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati/* bfad_im_bsg_put_kobject - decrement the bfa refcnt */
38b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic void
39b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_im_bsg_put_kobject(struct fc_bsg_job *job)
40b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
41b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct Scsi_Host *shost = job->shost;
42b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long flags;
43b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
44b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(shost->host_lock, flags);
45b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	module_put(shost->dma_dev->driver->owner);
46b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(shost->host_lock, flags);
47b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
48b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
49b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
50b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd)
51b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
52b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	int	i;
53b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_ioc_info_s *iocmd = (struct bfa_bsg_ioc_info_s *)cmd;
54b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_im_port_s	*im_port;
55b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_port_attr_s	pattr;
56b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
57b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
58b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
59b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_fcport_get_attr(&bfad->bfa, &pattr);
60b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->nwwn = pattr.nwwn;
61b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->pwwn = pattr.pwwn;
62b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->ioc_type = bfa_get_type(&bfad->bfa);
63b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->mac = bfa_get_mac(&bfad->bfa);
64b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->factory_mac = bfa_get_mfg_mac(&bfad->bfa);
65b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum);
66b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->factorynwwn = pattr.factorynwwn;
67b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->factorypwwn = pattr.factorypwwn;
68b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	im_port = bfad->pport.im_port;
69b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->host = im_port->shost->host_no;
70b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
71b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
72b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strcpy(iocmd->name, bfad->adapter_name);
73b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strcpy(iocmd->port_name, bfad->port_name);
74b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strcpy(iocmd->hwpath, bfad->pci_name);
75b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
76b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* set adapter hw path */
77b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strcpy(iocmd->adapter_hwpath, bfad->pci_name);
78b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	i = strlen(iocmd->adapter_hwpath) - 1;
79b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	while (iocmd->adapter_hwpath[i] != '.')
80b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		i--;
81b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->adapter_hwpath[i] = '\0';
82b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->status = BFA_STATUS_OK;
83b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return 0;
84b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
85b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
86b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
87b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd)
88b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
89b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_ioc_attr_s *iocmd = (struct bfa_bsg_ioc_attr_s *)cmd;
90b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
91b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
92b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
93b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_ioc_get_attr(&bfad->bfa.ioc, &iocmd->ioc_attr);
94b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
95b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
96b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* fill in driver attr info */
97b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME);
98b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strncpy(iocmd->ioc_attr.driver_attr.driver_ver,
99b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		BFAD_DRIVER_VERSION, BFA_VERSION_LEN);
100b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strcpy(iocmd->ioc_attr.driver_attr.fw_ver,
101b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->ioc_attr.adapter_attr.fw_ver);
102b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strcpy(iocmd->ioc_attr.driver_attr.bios_ver,
103b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->ioc_attr.adapter_attr.optrom_ver);
104b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
105b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* copy chip rev info first otherwise it will be overwritten */
106b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	memcpy(bfad->pci_attr.chip_rev, iocmd->ioc_attr.pci_attr.chip_rev,
107b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		sizeof(bfad->pci_attr.chip_rev));
108b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	memcpy(&iocmd->ioc_attr.pci_attr, &bfad->pci_attr,
109b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		sizeof(struct bfa_ioc_pci_attr_s));
110b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
111b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->status = BFA_STATUS_OK;
112b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return 0;
113b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
114b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
115b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
116b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd)
117b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
118b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_port_attr_s *iocmd = (struct bfa_bsg_port_attr_s *)cmd;
119b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_lport_attr_s	port_attr;
120b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
121b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
122b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
123b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_fcport_get_attr(&bfad->bfa, &iocmd->attr);
124b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
125b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
126b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
127b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (iocmd->attr.topology != BFA_PORT_TOPOLOGY_NONE)
128b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->attr.pid = port_attr.pid;
129b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	else
130b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->attr.pid = 0;
131b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
132b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->attr.port_type = port_attr.port_type;
133b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->attr.loopback = port_attr.loopback;
134b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->attr.authfail = port_attr.authfail;
135b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	strncpy(iocmd->attr.port_symname.symname,
136b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		port_attr.port_cfg.sym_name.symname,
137b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		sizeof(port_attr.port_cfg.sym_name.symname));
138b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
139b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->status = BFA_STATUS_OK;
140b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return 0;
141b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
142b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
143b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
144b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd)
145b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
146b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_fcs_lport_s	*fcs_port;
147b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_lport_attr_s *iocmd = (struct bfa_bsg_lport_attr_s *)cmd;
148b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
149b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
150b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
151b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
152b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				iocmd->vf_id, iocmd->pwwn);
153b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (fcs_port == NULL) {
154b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
155b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
156b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
157b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
158b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
159b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_fcs_lport_get_attr(fcs_port, &iocmd->port_attr);
160b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
161b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->status = BFA_STATUS_OK;
162b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiout:
163b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return 0;
164b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
165b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
166b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
167b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_rport_get_addr(struct bfad_s *bfad, void *cmd)
168b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
169b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_rport_scsi_addr_s *iocmd =
170b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			(struct bfa_bsg_rport_scsi_addr_s *)cmd;
171b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_fcs_lport_s	*fcs_port;
172b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_fcs_itnim_s	*fcs_itnim;
173b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_itnim_s	*drv_itnim;
174b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
175b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
176b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
177b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
178b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				iocmd->vf_id, iocmd->pwwn);
179b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (fcs_port == NULL) {
180b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bfa_trc(bfad, 0);
181b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
182b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
183b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
184b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
185b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
186b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	fcs_itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
187b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (fcs_itnim == NULL) {
188b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bfa_trc(bfad, 0);
189b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
190b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
191b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
192b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
193b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
194b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_itnim = fcs_itnim->itnim_drv;
195b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
196b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (drv_itnim && drv_itnim->im_port)
197b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->host = drv_itnim->im_port->shost->host_no;
198b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	else {
199b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bfa_trc(bfad, 0);
200b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
201b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
202b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
203b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
204b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
205b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->target = drv_itnim->scsi_tgt_id;
206b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
207b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
208b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->bus = 0;
209b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->lun = 0;
210b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->status = BFA_STATUS_OK;
211b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiout:
212b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return 0;
213b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
214b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
215b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
216b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd,
217b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			unsigned int payload_len)
218b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
219b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_fabric_get_lports_s *iocmd =
220b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			(struct bfa_bsg_fabric_get_lports_s *)cmd;
221b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_fcs_vf_t	*fcs_vf;
222b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	uint32_t	nports = iocmd->nports;
223b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
224b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	void	*iocmd_bufptr;
225b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
226b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (nports == 0) {
227b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_EINVAL;
228b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
229b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
230b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
231b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (bfad_chk_iocmd_sz(payload_len,
232b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		sizeof(struct bfa_bsg_fabric_get_lports_s),
233b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		sizeof(wwn_t[iocmd->nports])) != BFA_STATUS_OK) {
234b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_VERSION_FAIL;
235b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
236b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
237b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
238b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd_bufptr = (char *)iocmd +
239b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			sizeof(struct bfa_bsg_fabric_get_lports_s);
240b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
241b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
242b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id);
243b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (fcs_vf == NULL) {
244b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
245b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_UNKNOWN_VFID;
246b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
247b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
248b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_fcs_vf_get_ports(fcs_vf, (wwn_t *)iocmd_bufptr, &nports);
249b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
250b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
251b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->nports = nports;
252b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	iocmd->status = BFA_STATUS_OK;
253b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiout:
254b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return 0;
255b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
256b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
257b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
258b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_itnim_get_attr(struct bfad_s *bfad, void *cmd)
259b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
260b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_itnim_attr_s *iocmd = (struct bfa_bsg_itnim_attr_s *)cmd;
261b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_fcs_lport_s	*fcs_port;
262b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
263b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
264b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
265b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
266b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				iocmd->vf_id, iocmd->lpwwn);
267b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!fcs_port)
268b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
269b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	else
270b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		iocmd->status = bfa_fcs_itnim_attr_get(fcs_port,
271b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					iocmd->rpwwn, &iocmd->attr);
272b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
273b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return 0;
274b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
275b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
2761a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiint
2771a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatibfad_iocmd_ioc_get_pcifn_cfg(struct bfad_s *bfad, void *cmd)
2781a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati{
2791a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfa_bsg_pcifn_cfg_s *iocmd = (struct bfa_bsg_pcifn_cfg_s *)cmd;
2801a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfad_hal_comp fcomp;
2811a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	unsigned long flags;
2821a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
2831a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	init_completion(&fcomp.comp);
2841a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
2851a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = bfa_ablk_query(&bfad->bfa.modules.ablk,
2861a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				&iocmd->pcifn_cfg,
2871a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				bfad_hcb_comp, &fcomp);
2881a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2891a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (iocmd->status != BFA_STATUS_OK)
2901a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		goto out;
2911a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
2921a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	wait_for_completion(&fcomp.comp);
2931a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = fcomp.status;
2941a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiout:
2951a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	return 0;
2961a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati}
2971a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
2981a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiint
2991a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatibfad_iocmd_pcifn_create(struct bfad_s *bfad, void *cmd)
3001a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati{
3011a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
3021a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfad_hal_comp fcomp;
3031a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	unsigned long flags;
3041a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3051a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	init_completion(&fcomp.comp);
3061a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
3071a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk,
3081a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				&iocmd->pcifn_id, iocmd->port,
3091a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				iocmd->pcifn_class, iocmd->bandwidth,
3101a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				bfad_hcb_comp, &fcomp);
3111a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
3121a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (iocmd->status != BFA_STATUS_OK)
3131a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		goto out;
3141a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3151a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	wait_for_completion(&fcomp.comp);
3161a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = fcomp.status;
3171a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiout:
3181a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	return 0;
3191a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati}
3201a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3211a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiint
3221a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatibfad_iocmd_pcifn_delete(struct bfad_s *bfad, void *cmd)
3231a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati{
3241a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
3251a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfad_hal_comp fcomp;
3261a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	unsigned long flags;
3271a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3281a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	init_completion(&fcomp.comp);
3291a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
3301a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = bfa_ablk_pf_delete(&bfad->bfa.modules.ablk,
3311a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				iocmd->pcifn_id,
3321a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				bfad_hcb_comp, &fcomp);
3331a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
3341a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (iocmd->status != BFA_STATUS_OK)
3351a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		goto out;
3361a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3371a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	wait_for_completion(&fcomp.comp);
3381a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = fcomp.status;
3391a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiout:
3401a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	return 0;
3411a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati}
3421a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3431a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiint
3441a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatibfad_iocmd_pcifn_bw(struct bfad_s *bfad, void *cmd)
3451a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati{
3461a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
3471a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfad_hal_comp fcomp;
3481a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	unsigned long flags;
3491a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3501a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	init_completion(&fcomp.comp);
3511a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
3521a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk,
3531a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				iocmd->pcifn_id, iocmd->bandwidth,
3541a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				bfad_hcb_comp, &fcomp);
3551a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
3561a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	bfa_trc(bfad, iocmd->status);
3571a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (iocmd->status != BFA_STATUS_OK)
3581a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		goto out;
3591a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3601a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	wait_for_completion(&fcomp.comp);
3611a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = fcomp.status;
3621a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	bfa_trc(bfad, iocmd->status);
3631a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiout:
3641a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	return 0;
3651a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati}
3661a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3671a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiint
3681a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatibfad_iocmd_adapter_cfg_mode(struct bfad_s *bfad, void *cmd)
3691a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati{
3701a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfa_bsg_adapter_cfg_mode_s *iocmd =
3711a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati			(struct bfa_bsg_adapter_cfg_mode_s *)cmd;
3721a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfad_hal_comp fcomp;
3731a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	unsigned long flags = 0;
3741a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3751a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	init_completion(&fcomp.comp);
3761a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
3771a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = bfa_ablk_adapter_config(&bfad->bfa.modules.ablk,
3781a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				iocmd->cfg.mode, iocmd->cfg.max_pf,
3791a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				iocmd->cfg.max_vf, bfad_hcb_comp, &fcomp);
3801a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
3811a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (iocmd->status != BFA_STATUS_OK)
3821a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		goto out;
3831a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3841a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	wait_for_completion(&fcomp.comp);
3851a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = fcomp.status;
3861a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiout:
3871a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	return 0;
3881a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati}
3891a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3901a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiint
3911a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatibfad_iocmd_port_cfg_mode(struct bfad_s *bfad, void *cmd)
3921a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati{
3931a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfa_bsg_port_cfg_mode_s *iocmd =
3941a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati			(struct bfa_bsg_port_cfg_mode_s *)cmd;
3951a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfad_hal_comp fcomp;
3961a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	unsigned long flags = 0;
3971a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
3981a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	init_completion(&fcomp.comp);
3991a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
4001a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = bfa_ablk_port_config(&bfad->bfa.modules.ablk,
4011a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				iocmd->instance, iocmd->cfg.mode,
4021a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				iocmd->cfg.max_pf, iocmd->cfg.max_vf,
4031a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati				bfad_hcb_comp, &fcomp);
4041a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
4051a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (iocmd->status != BFA_STATUS_OK)
4061a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		goto out;
4071a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
4081a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	wait_for_completion(&fcomp.comp);
4091a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = fcomp.status;
4101a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiout:
4111a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	return 0;
4121a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati}
4131a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
4141a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiint
4151a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatibfad_iocmd_ablk_optrom(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
4161a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati{
4171a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
4181a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	struct bfad_hal_comp fcomp;
4191a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	unsigned long   flags;
4201a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
4211a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	init_completion(&fcomp.comp);
4221a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
4231a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (cmd == IOCMD_FLASH_ENABLE_OPTROM)
4241a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		iocmd->status = bfa_ablk_optrom_en(&bfad->bfa.modules.ablk,
4251a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati					bfad_hcb_comp, &fcomp);
4261a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	else
4271a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		iocmd->status = bfa_ablk_optrom_dis(&bfad->bfa.modules.ablk,
4281a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati					bfad_hcb_comp, &fcomp);
4291a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
4301a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
4311a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	if (iocmd->status != BFA_STATUS_OK)
4321a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		goto out;
4331a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
4341a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	wait_for_completion(&fcomp.comp);
4351a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	iocmd->status = fcomp.status;
4361a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipatiout:
4371a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	return 0;
4381a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati}
4391a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati
440b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
441b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
442b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		unsigned int payload_len)
443b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
444b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	int rc = EINVAL;
445b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
446b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	switch (cmd) {
447b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case IOCMD_IOC_GET_INFO:
448b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_iocmd_ioc_get_info(bfad, iocmd);
449b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
450b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case IOCMD_IOC_GET_ATTR:
451b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_iocmd_ioc_get_attr(bfad, iocmd);
452b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
453b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case IOCMD_PORT_GET_ATTR:
454b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_iocmd_port_get_attr(bfad, iocmd);
455b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
456b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case IOCMD_LPORT_GET_ATTR:
457b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_iocmd_lport_get_attr(bfad, iocmd);
458b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
459b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case IOCMD_RPORT_GET_ADDR:
460b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_iocmd_rport_get_addr(bfad, iocmd);
461b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
462b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case IOCMD_FABRIC_GET_LPORTS:
463b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len);
464b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
465b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case IOCMD_ITNIM_GET_ATTR:
466b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_iocmd_itnim_get_attr(bfad, iocmd);
467b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
4681a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_IOC_PCIFN_CFG:
4691a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd);
4701a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		break;
4711a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_PCIFN_CREATE:
4721a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		rc = bfad_iocmd_pcifn_create(bfad, iocmd);
4731a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		break;
4741a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_PCIFN_DELETE:
4751a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		rc = bfad_iocmd_pcifn_delete(bfad, iocmd);
4761a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		break;
4771a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_PCIFN_BW:
4781a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		rc = bfad_iocmd_pcifn_bw(bfad, iocmd);
4791a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		break;
4801a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_ADAPTER_CFG_MODE:
4811a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		rc = bfad_iocmd_adapter_cfg_mode(bfad, iocmd);
4821a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		break;
4831a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_PORT_CFG_MODE:
4841a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		rc = bfad_iocmd_port_cfg_mode(bfad, iocmd);
4851a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		break;
4861a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_FLASH_ENABLE_OPTROM:
4871a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	case IOCMD_FLASH_DISABLE_OPTROM:
4881a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd);
4891a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati		break;
490b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	default:
491b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = EINVAL;
492b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
493b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
494b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return -rc;
495b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
496b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
497b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistatic int
498b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_im_bsg_vendor_request(struct fc_bsg_job *job)
499b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
500b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	uint32_t vendor_cmd = job->request->rqst_data.h_vendor.vendor_cmd[0];
501b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_im_port_s *im_port =
502b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			(struct bfad_im_port_s *) job->shost->hostdata[0];
503b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_s *bfad = im_port->bfad;
504b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	void *payload_kbuf;
505b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	int rc = -EINVAL;
506b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
507b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Allocate a temp buffer to hold the passed in user space command */
508b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	payload_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL);
509b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!payload_kbuf) {
510b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = -ENOMEM;
511b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
512b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
513b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
514b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Copy the sg_list passed in to a linear buffer: holds the cmnd data */
515b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sg_copy_to_buffer(job->request_payload.sg_list,
516b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			  job->request_payload.sg_cnt, payload_kbuf,
517b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			  job->request_payload.payload_len);
518b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
519b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Invoke IOCMD handler - to handle all the vendor command requests */
520b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	rc = bfad_iocmd_handler(bfad, vendor_cmd, payload_kbuf,
521b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				job->request_payload.payload_len);
522b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (rc != BFA_STATUS_OK)
523b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto error;
524b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
525b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Copy the response data to the job->reply_payload sg_list */
526b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sg_copy_from_buffer(job->reply_payload.sg_list,
527b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    job->reply_payload.sg_cnt,
528b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    payload_kbuf,
529b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    job->reply_payload.payload_len);
530b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
531b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* free the command buffer */
532b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	kfree(payload_kbuf);
533b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
534b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Fill the BSG job reply data */
535b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply_len = job->reply_payload.payload_len;
536b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
537b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply->result = rc;
538b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
539b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->job_done(job);
540b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return rc;
541b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatierror:
542b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* free the command buffer */
543b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	kfree(payload_kbuf);
544b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiout:
545b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply->result = rc;
546b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply_len = sizeof(uint32_t);
547b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply->reply_payload_rcv_len = 0;
548b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return rc;
549b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
550b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
551b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati/* FC passthru call backs */
552b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiu64
553b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_fcxp_get_req_sgaddr_cb(void *bfad_fcxp, int sgeid)
554b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
555b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_fcxp	*drv_fcxp = bfad_fcxp;
556b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_sge_s  *sge;
557b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	u64	addr;
558b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
559b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sge = drv_fcxp->req_sge + sgeid;
560b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	addr = (u64)(size_t) sge->sg_addr;
561b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return addr;
562b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
563b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
564b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiu32
565b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_fcxp_get_req_sglen_cb(void *bfad_fcxp, int sgeid)
566b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
567b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_fcxp	*drv_fcxp = bfad_fcxp;
568b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_sge_s	*sge;
569b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
570b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sge = drv_fcxp->req_sge + sgeid;
571b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return sge->sg_len;
572b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
573b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
574b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiu64
575b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_fcxp_get_rsp_sgaddr_cb(void *bfad_fcxp, int sgeid)
576b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
577b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_fcxp	*drv_fcxp = bfad_fcxp;
578b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_sge_s	*sge;
579b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	u64	addr;
580b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
581b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sge = drv_fcxp->rsp_sge + sgeid;
582b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	addr = (u64)(size_t) sge->sg_addr;
583b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return addr;
584b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
585b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
586b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiu32
587b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_fcxp_get_rsp_sglen_cb(void *bfad_fcxp, int sgeid)
588b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
589b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_fcxp	*drv_fcxp = bfad_fcxp;
590b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_sge_s	*sge;
591b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
592b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sge = drv_fcxp->rsp_sge + sgeid;
593b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return sge->sg_len;
594b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
595b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
596b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipativoid
597b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_send_fcpt_cb(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
598b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bfa_status_t req_status, u32 rsp_len, u32 resid_len,
599b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		struct fchs_s *rsp_fchs)
600b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
601b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_fcxp *drv_fcxp = bfad_fcxp;
602b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
603b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->req_status = req_status;
604b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->rsp_len = rsp_len;
605b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
606b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* bfa_fcxp will be automatically freed by BFA */
607b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->bfa_fcxp = NULL;
608b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	complete(&drv_fcxp->comp);
609b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
610b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
611b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatistruct bfad_buf_info *
612b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf,
613b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		 uint32_t payload_len, uint32_t *num_sgles)
614b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
615b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_buf_info	*buf_base, *buf_info;
616b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_sge_s	*sg_table;
617b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	int sge_num = 1;
618b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
619b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	buf_base = kzalloc((sizeof(struct bfad_buf_info) +
620b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			   sizeof(struct bfa_sge_s)) * sge_num, GFP_KERNEL);
621b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!buf_base)
622b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		return NULL;
623b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
624b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sg_table = (struct bfa_sge_s *) (((uint8_t *)buf_base) +
625b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			(sizeof(struct bfad_buf_info) * sge_num));
626b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
627b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Allocate dma coherent memory */
628b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	buf_info = buf_base;
629b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	buf_info->size = payload_len;
630b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	buf_info->virt = dma_alloc_coherent(&bfad->pcidev->dev, buf_info->size,
631b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					&buf_info->phys, GFP_KERNEL);
632b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!buf_info->virt)
633b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
634b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
635b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* copy the linear bsg buffer to buf_info */
636b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	memset(buf_info->virt, 0, buf_info->size);
637b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	memcpy(buf_info->virt, payload_kbuf, buf_info->size);
638b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
639b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/*
640b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 * Setup SG table
641b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 */
642b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sg_table->sg_len = buf_info->size;
643b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sg_table->sg_addr = (void *)(size_t) buf_info->phys;
644b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
645b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	*num_sgles = sge_num;
646b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
647b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return buf_base;
648b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
649b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiout_free_mem:
650b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	kfree(buf_base);
651b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return NULL;
652b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
653b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
654b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipativoid
655b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base,
656b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		   uint32_t num_sgles)
657b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
658b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	int i;
659b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_buf_info *buf_info = buf_base;
660b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
661b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (buf_base) {
662b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		for (i = 0; i < num_sgles; buf_info++, i++) {
663b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			if (buf_info->virt != NULL)
664b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				dma_free_coherent(&bfad->pcidev->dev,
665b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					buf_info->size, buf_info->virt,
666b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					buf_info->phys);
667b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		}
668b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		kfree(buf_base);
669b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
670b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
671b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
672b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiint
673b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_fcxp_bsg_send(struct fc_bsg_job *job, struct bfad_fcxp *drv_fcxp,
674b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		   bfa_bsg_fcpt_t *bsg_fcpt)
675b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
676b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_fcxp_s *hal_fcxp;
677b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_s	*bfad = drv_fcxp->port->bfad;
678b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long	flags;
679b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	uint8_t	lp_tag;
680b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
681b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
682b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
683b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Allocate bfa_fcxp structure */
684b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	hal_fcxp = bfa_fcxp_alloc(drv_fcxp, &bfad->bfa,
685b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				  drv_fcxp->num_req_sgles,
686b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				  drv_fcxp->num_rsp_sgles,
687b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				  bfad_fcxp_get_req_sgaddr_cb,
688b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				  bfad_fcxp_get_req_sglen_cb,
689b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				  bfad_fcxp_get_rsp_sgaddr_cb,
690b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				  bfad_fcxp_get_rsp_sglen_cb);
691b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!hal_fcxp) {
692b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bfa_trc(bfad, 0);
693b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
694b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		return BFA_STATUS_ENOMEM;
695b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
696b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
697b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->bfa_fcxp = hal_fcxp;
698b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
699b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	lp_tag = bfa_lps_get_tag_from_pid(&bfad->bfa, bsg_fcpt->fchs.s_id);
700b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
701b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_fcxp_send(hal_fcxp, drv_fcxp->bfa_rport, bsg_fcpt->vf_id, lp_tag,
702b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		      bsg_fcpt->cts, bsg_fcpt->cos,
703b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		      job->request_payload.payload_len,
704b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		      &bsg_fcpt->fchs, bfad_send_fcpt_cb, bfad,
705b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		      job->reply_payload.payload_len, bsg_fcpt->tsecs);
706b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
707b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
708b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
709b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return BFA_STATUS_OK;
710b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
711b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
712b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiint
713b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
714b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
715b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_bsg_data *bsg_data;
716b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_im_port_s *im_port =
717b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			(struct bfad_im_port_s *) job->shost->hostdata[0];
718b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_s *bfad = im_port->bfad;
719b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfa_bsg_fcpt_t *bsg_fcpt;
720b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_fcxp    *drv_fcxp;
721b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_fcs_lport_s *fcs_port;
722b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfa_fcs_rport_s *fcs_rport;
723b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	uint32_t command_type = job->request->msgcode;
724b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	unsigned long flags;
725b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	struct bfad_buf_info *rsp_buf_info;
726b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	void *req_kbuf = NULL, *rsp_kbuf = NULL;
727b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	int rc = -EINVAL;
728b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
729b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply_len  = sizeof(uint32_t);	/* Atleast uint32_t reply_len */
730b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply->reply_payload_rcv_len = 0;
731b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
732b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Get the payload passed in from userspace */
733b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bsg_data = (struct bfa_bsg_data *) (((char *)job->request) +
734b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					sizeof(struct fc_bsg_request));
735b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (bsg_data == NULL)
736b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
737b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
738b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/*
739b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload
740b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 * buffer of size bsg_data->payload_len
741b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 */
742b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bsg_fcpt = (struct bfa_bsg_fcpt_s *)
743b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		   kzalloc(bsg_data->payload_len, GFP_KERNEL);
744b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!bsg_fcpt)
745b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
746b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
747b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (copy_from_user((uint8_t *)bsg_fcpt, bsg_data->payload,
748b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				bsg_data->payload_len)) {
749b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		kfree(bsg_fcpt);
750b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
751b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
752b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
753b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL);
754b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (drv_fcxp == NULL) {
755b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = -ENOMEM;
756b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out;
757b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
758b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
759b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
760b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, bsg_fcpt->vf_id,
761b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					bsg_fcpt->lpwwn);
762b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (fcs_port == NULL) {
763b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bsg_fcpt->status = BFA_STATUS_UNKNOWN_LWWN;
764b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
765b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
766b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
767b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
768b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Check if the port is online before sending FC Passthru cmd */
769b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!bfa_fcs_lport_is_online(fcs_port)) {
770b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bsg_fcpt->status = BFA_STATUS_PORT_OFFLINE;
771b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
772b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
773b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
774b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
775b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->port = fcs_port->bfad_port;
776b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
777b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (drv_fcxp->port->bfad == 0)
778b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		drv_fcxp->port->bfad = bfad;
779b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
780b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Fetch the bfa_rport - if nexus needed */
781b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (command_type == FC_BSG_HST_ELS_NOLOGIN ||
782b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	    command_type == FC_BSG_HST_CT) {
783b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		/* BSG HST commands: no nexus needed */
784b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		drv_fcxp->bfa_rport = NULL;
785b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
786b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	} else if (command_type == FC_BSG_RPT_ELS ||
787b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		   command_type == FC_BSG_RPT_CT) {
788b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		/* BSG RPT commands: nexus needed */
789b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		fcs_rport = bfa_fcs_lport_get_rport_by_pwwn(fcs_port,
790b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati							    bsg_fcpt->dpwwn);
791b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		if (fcs_rport == NULL) {
792b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			bsg_fcpt->status = BFA_STATUS_UNKNOWN_RWWN;
793b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
794b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			goto out_free_mem;
795b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		}
796b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
797b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		drv_fcxp->bfa_rport = fcs_rport->bfa_rport;
798b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
799b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	} else { /* Unknown BSG msgcode; return -EINVAL */
800b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
801b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
802b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
803b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
804b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
805b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
806b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* allocate memory for req / rsp buffers */
807b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	req_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL);
808b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!req_kbuf) {
809b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		printk(KERN_INFO "bfa %s: fcpt request buffer alloc failed\n",
810b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				bfad->pci_name);
811b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = -ENOMEM;
812b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
813b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
814b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
815b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	rsp_kbuf = kzalloc(job->reply_payload.payload_len, GFP_KERNEL);
816b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!rsp_kbuf) {
817b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		printk(KERN_INFO "bfa %s: fcpt response buffer alloc failed\n",
818b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				bfad->pci_name);
819b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = -ENOMEM;
820b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
821b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
822b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
823b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* map req sg - copy the sg_list passed in to the linear buffer */
824b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sg_copy_to_buffer(job->request_payload.sg_list,
825b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			  job->request_payload.sg_cnt, req_kbuf,
826b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			  job->request_payload.payload_len);
827b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
828b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->reqbuf_info = bfad_fcxp_map_sg(bfad, req_kbuf,
829b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					job->request_payload.payload_len,
830b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					&drv_fcxp->num_req_sgles);
831b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!drv_fcxp->reqbuf_info) {
832b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		printk(KERN_INFO "bfa %s: fcpt request fcxp_map_sg failed\n",
833b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				bfad->pci_name);
834b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = -ENOMEM;
835b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
836b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
837b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
838b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->req_sge = (struct bfa_sge_s *)
839b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    (((uint8_t *)drv_fcxp->reqbuf_info) +
840b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    (sizeof(struct bfad_buf_info) *
841b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					drv_fcxp->num_req_sgles));
842b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
843b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* map rsp sg */
844b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->rspbuf_info = bfad_fcxp_map_sg(bfad, rsp_kbuf,
845b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					job->reply_payload.payload_len,
846b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					&drv_fcxp->num_rsp_sgles);
847b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (!drv_fcxp->rspbuf_info) {
848b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		printk(KERN_INFO "bfa %s: fcpt response fcxp_map_sg failed\n",
849b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati				bfad->pci_name);
850b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = -ENOMEM;
851b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
852b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
853b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
854b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	rsp_buf_info = (struct bfad_buf_info *)drv_fcxp->rspbuf_info;
855b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	drv_fcxp->rsp_sge = (struct bfa_sge_s  *)
856b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    (((uint8_t *)drv_fcxp->rspbuf_info) +
857b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    (sizeof(struct bfad_buf_info) *
858b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					drv_fcxp->num_rsp_sgles));
859b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
860b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* fcxp send */
861b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	init_completion(&drv_fcxp->comp);
862b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	rc = bfad_fcxp_bsg_send(job, drv_fcxp, bsg_fcpt);
863b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (rc == BFA_STATUS_OK) {
864b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		wait_for_completion(&drv_fcxp->comp);
865b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bsg_fcpt->status = drv_fcxp->req_status;
866b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	} else {
867b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		bsg_fcpt->status = rc;
868b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		goto out_free_mem;
869b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
870b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
871b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* fill the job->reply data */
872b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (drv_fcxp->req_status == BFA_STATUS_OK) {
873b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply_len = drv_fcxp->rsp_len;
874b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
875b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
876b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	} else {
877b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply->reply_payload_rcv_len =
878b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati					sizeof(struct fc_bsg_ctels_reply);
879b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply_len = sizeof(uint32_t);
880b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply->reply_data.ctels_reply.status =
881b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati						FC_CTELS_STATUS_REJECT;
882b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
883b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
884b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Copy the response data to the reply_payload sg list */
885b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	sg_copy_from_buffer(job->reply_payload.sg_list,
886b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    job->reply_payload.sg_cnt,
887b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    (uint8_t *)rsp_buf_info->virt,
888b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			    job->reply_payload.payload_len);
889b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
890b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiout_free_mem:
891b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfad_fcxp_free_mem(bfad, drv_fcxp->rspbuf_info,
892b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			   drv_fcxp->num_rsp_sgles);
893b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfad_fcxp_free_mem(bfad, drv_fcxp->reqbuf_info,
894b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			   drv_fcxp->num_req_sgles);
895b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	kfree(req_kbuf);
896b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	kfree(rsp_kbuf);
897b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
898b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Need a copy to user op */
899b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (copy_to_user(bsg_data->payload, (void *) bsg_fcpt,
900b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati			 bsg_data->payload_len))
901b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = -EIO;
902b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
903b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	kfree(bsg_fcpt);
904b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	kfree(drv_fcxp);
905b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiout:
906b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	job->reply->result = rc;
907b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
908b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	if (rc == BFA_STATUS_OK)
909b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->job_done(job);
910b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
911b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return rc;
912b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
913b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
914b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiint
915b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_im_bsg_request(struct fc_bsg_job *job)
916b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
917b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	uint32_t rc = BFA_STATUS_OK;
918b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
919b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Increment the bfa module refcnt - if bsg request is in service */
920b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfad_im_bsg_get_kobject(job);
921b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
922b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	switch (job->request->msgcode) {
923b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case FC_BSG_HST_VENDOR:
924b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		/* Process BSG HST Vendor requests */
925b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_im_bsg_vendor_request(job);
926b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
927b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case FC_BSG_HST_ELS_NOLOGIN:
928b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case FC_BSG_RPT_ELS:
929b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case FC_BSG_HST_CT:
930b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	case FC_BSG_RPT_CT:
931b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		/* Process BSG ELS/CT commands */
932b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		rc = bfad_im_bsg_els_ct_request(job);
933b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
934b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	default:
935b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply->result = rc = -EINVAL;
936b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		job->reply->reply_payload_rcv_len = 0;
937b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati		break;
938b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	}
939b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
940b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Decrement the bfa module refcnt - on completion of bsg request */
941b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	bfad_im_bsg_put_kobject(job);
942b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
943b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return rc;
944b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
945b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati
946b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatiint
947b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipatibfad_im_bsg_timeout(struct fc_bsg_job *job)
948b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati{
949b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	/* Don't complete the BSG job request - return -EAGAIN
950b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 * to reset bsg job timeout : for ELS/CT pass thru we
951b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 * already have timer to track the request.
952b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	 */
953b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati	return -EAGAIN;
954b85daafe46eeb0a9ad32c4b2c3a4e09ffcae9599Krishna Gudipati}
955