• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/scsi/bfa/
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 *  bfad.c Linux driver PCI interface module.
20 */
21
22#include <linux/slab.h>
23#include <linux/module.h>
24#include <linux/kthread.h>
25#include "bfad_drv.h"
26#include "bfad_im.h"
27#include "bfad_tm.h"
28#include "bfad_ipfc.h"
29#include "bfad_trcmod.h"
30#include <fcb/bfa_fcb_vf.h>
31#include <fcb/bfa_fcb_rport.h>
32#include <fcb/bfa_fcb_port.h>
33#include <fcb/bfa_fcb.h>
34
35BFA_TRC_FILE(LDRV, BFAD);
36DEFINE_MUTEX(bfad_mutex);
37LIST_HEAD(bfad_list);
38static int      bfad_inst;
39int bfad_supported_fc4s;
40
41static char     *host_name;
42static char     *os_name;
43static char     *os_patch;
44static int      num_rports;
45static int      num_ios;
46static int      num_tms;
47static int      num_fcxps;
48static int      num_ufbufs;
49static int      reqq_size;
50static int      rspq_size;
51static int      num_sgpgs;
52static int      rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
53static int      bfa_io_max_sge = BFAD_IO_MAX_SGE;
54static int      log_level = BFA_LOG_WARNING;
55static int      ioc_auto_recover = BFA_TRUE;
56static int      ipfc_enable = BFA_FALSE;
57static int	fdmi_enable = BFA_TRUE;
58int 		bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
59int      	bfa_linkup_delay = -1;
60int		bfa_debugfs_enable = 1;
61
62module_param(os_name, charp, S_IRUGO | S_IWUSR);
63MODULE_PARM_DESC(os_name, "OS name of the hba host machine");
64module_param(os_patch, charp, S_IRUGO | S_IWUSR);
65MODULE_PARM_DESC(os_patch, "OS patch level of the hba host machine");
66module_param(host_name, charp, S_IRUGO | S_IWUSR);
67MODULE_PARM_DESC(host_name, "Hostname of the hba host machine");
68module_param(num_rports, int, S_IRUGO | S_IWUSR);
69MODULE_PARM_DESC(num_rports, "Max number of rports supported per port"
70		" (physical/logical), default=1024");
71module_param(num_ios, int, S_IRUGO | S_IWUSR);
72MODULE_PARM_DESC(num_ios, "Max number of ioim requests, default=2000");
73module_param(num_tms, int, S_IRUGO | S_IWUSR);
74MODULE_PARM_DESC(num_tms, "Max number of task im requests, default=128");
75module_param(num_fcxps, int, S_IRUGO | S_IWUSR);
76MODULE_PARM_DESC(num_fcxps, "Max number of fcxp requests, default=64");
77module_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
78MODULE_PARM_DESC(num_ufbufs, "Max number of unsolicited frame buffers,"
79		" default=64");
80module_param(reqq_size, int, S_IRUGO | S_IWUSR);
81MODULE_PARM_DESC(reqq_size, "Max number of request queue elements,"
82		" default=256");
83module_param(rspq_size, int, S_IRUGO | S_IWUSR);
84MODULE_PARM_DESC(rspq_size, "Max number of response queue elements,"
85		" default=64");
86module_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
87MODULE_PARM_DESC(num_sgpgs, "Number of scatter/gather pages, default=2048");
88module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
89MODULE_PARM_DESC(rport_del_timeout, "Rport delete timeout, default=90 secs,"
90		" Range[>0]");
91module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
92MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32,"
93		" Range[>0]");
94module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
95MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255");
96module_param(log_level, int, S_IRUGO | S_IWUSR);
97MODULE_PARM_DESC(log_level, "Driver log level, default=3,"
98		" Range[Critical:1|Error:2|Warning:3|Info:4]");
99module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
100MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1,"
101		" Range[off:0|on:1]");
102module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
103MODULE_PARM_DESC(ipfc_enable, "Enable IPoFC, default=0, Range[off:0|on:1]");
104module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
105MODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for boot"
106		" port. Otherwise Range[>0]");
107module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
108MODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1,"
109		" Range[false:0|true:1]");
110module_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR);
111MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1,"
112		" Range[false:0|true:1]");
113
114/*
115 * Stores the module parm num_sgpgs value;
116 * used to reset for bfad next instance.
117 */
118static int num_sgpgs_parm;
119
120static bfa_status_t
121bfad_fc4_probe(struct bfad_s *bfad)
122{
123	int             rc;
124
125	rc = bfad_im_probe(bfad);
126	if (rc != BFA_STATUS_OK)
127		goto ext;
128
129	bfad_tm_probe(bfad);
130
131	if (ipfc_enable)
132		bfad_ipfc_probe(bfad);
133
134	bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
135ext:
136	return rc;
137}
138
139static void
140bfad_fc4_probe_undo(struct bfad_s *bfad)
141{
142	bfad_im_probe_undo(bfad);
143	bfad_tm_probe_undo(bfad);
144	if (ipfc_enable)
145		bfad_ipfc_probe_undo(bfad);
146	bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
147}
148
149static void
150bfad_fc4_probe_post(struct bfad_s *bfad)
151{
152	if (bfad->im)
153		bfad_im_probe_post(bfad->im);
154
155	bfad_tm_probe_post(bfad);
156	if (ipfc_enable)
157		bfad_ipfc_probe_post(bfad);
158}
159
160static bfa_status_t
161bfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
162{
163	int             rc = BFA_STATUS_FAILED;
164
165	if (roles & BFA_PORT_ROLE_FCP_IM)
166		rc = bfad_im_port_new(bfad, port);
167	if (rc != BFA_STATUS_OK)
168		goto ext;
169
170	if (roles & BFA_PORT_ROLE_FCP_TM)
171		rc = bfad_tm_port_new(bfad, port);
172	if (rc != BFA_STATUS_OK)
173		goto ext;
174
175	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
176		rc = bfad_ipfc_port_new(bfad, port, port->pvb_type);
177ext:
178	return rc;
179}
180
181static void
182bfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
183{
184	if (roles & BFA_PORT_ROLE_FCP_IM)
185		bfad_im_port_delete(bfad, port);
186
187	if (roles & BFA_PORT_ROLE_FCP_TM)
188		bfad_tm_port_delete(bfad, port);
189
190	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
191		bfad_ipfc_port_delete(bfad, port);
192}
193
194/**
195 *  BFA callbacks
196 */
197void
198bfad_hcb_comp(void *arg, bfa_status_t status)
199{
200	struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
201
202	fcomp->status = status;
203	complete(&fcomp->comp);
204}
205
206/**
207 * bfa_init callback
208 */
209void
210bfa_cb_init(void *drv, bfa_status_t init_status)
211{
212	struct bfad_s  *bfad = drv;
213
214	if (init_status == BFA_STATUS_OK) {
215		bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
216
217		/* If BFAD_HAL_INIT_FAIL flag is set:
218		 * Wake up the kernel thread to start
219		 * the bfad operations after HAL init done
220		 */
221		if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
222			bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
223			wake_up_process(bfad->bfad_tsk);
224		}
225	}
226
227	complete(&bfad->comp);
228}
229
230
231
232/**
233 *  BFA_FCS callbacks
234 */
235static struct bfad_port_s *
236bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
237		  struct bfad_vport_s *vp_drv)
238{
239	return (vp_drv) ? (&(vp_drv)->drv_port)
240		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport));
241}
242
243struct bfad_port_s *
244bfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port,
245		 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
246		 struct bfad_vport_s *vp_drv)
247{
248	bfa_status_t    rc;
249	struct bfad_port_s *port_drv;
250
251	if (!vp_drv && !vf_drv) {
252		port_drv = &bfad->pport;
253		port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
254	} else if (!vp_drv && vf_drv) {
255		port_drv = &vf_drv->base_port;
256		port_drv->pvb_type = BFAD_PORT_VF_BASE;
257	} else if (vp_drv && !vf_drv) {
258		port_drv = &vp_drv->drv_port;
259		port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
260	} else {
261		port_drv = &vp_drv->drv_port;
262		port_drv->pvb_type = BFAD_PORT_VF_VPORT;
263	}
264
265	port_drv->fcs_port = port;
266	port_drv->roles = roles;
267	rc = bfad_fc4_port_new(bfad, port_drv, roles);
268	if (rc != BFA_STATUS_OK) {
269		bfad_fc4_port_delete(bfad, port_drv, roles);
270		port_drv = NULL;
271	}
272
273	return port_drv;
274}
275
276void
277bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
278		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
279{
280	struct bfad_port_s *port_drv;
281
282	/*
283	 * this will be only called from rmmod context
284	 */
285	if (vp_drv && !vp_drv->comp_del) {
286		port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
287		bfa_trc(bfad, roles);
288		bfad_fc4_port_delete(bfad, port_drv, roles);
289	}
290}
291
292void
293bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
294		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
295{
296	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
297
298	if (roles & BFA_PORT_ROLE_FCP_IM)
299		bfad_im_port_online(bfad, port_drv);
300
301	if (roles & BFA_PORT_ROLE_FCP_TM)
302		bfad_tm_port_online(bfad, port_drv);
303
304	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
305		bfad_ipfc_port_online(bfad, port_drv);
306
307	bfad->bfad_flags |= BFAD_PORT_ONLINE;
308}
309
310void
311bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
312		     struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
313{
314	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
315
316	if (roles & BFA_PORT_ROLE_FCP_IM)
317		bfad_im_port_offline(bfad, port_drv);
318
319	if (roles & BFA_PORT_ROLE_FCP_TM)
320		bfad_tm_port_offline(bfad, port_drv);
321
322	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
323		bfad_ipfc_port_offline(bfad, port_drv);
324}
325
326void
327bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv)
328{
329	if (vport_drv->comp_del) {
330		complete(vport_drv->comp_del);
331		return;
332	}
333}
334
335/**
336 * FCS RPORT alloc callback, after successful PLOGI by FCS
337 */
338bfa_status_t
339bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
340		    struct bfad_rport_s **rport_drv)
341{
342	bfa_status_t    rc = BFA_STATUS_OK;
343
344	*rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
345	if (*rport_drv == NULL) {
346		rc = BFA_STATUS_ENOMEM;
347		goto ext;
348	}
349
350	*rport = &(*rport_drv)->fcs_rport;
351
352ext:
353	return rc;
354}
355
356/**
357 * @brief
358 * FCS PBC VPORT Create
359 */
360void
361bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport)
362{
363
364	struct bfad_pcfg_s *pcfg;
365
366	pcfg = kzalloc(sizeof(struct bfad_pcfg_s), GFP_ATOMIC);
367	if (!pcfg) {
368		bfa_trc(bfad, 0);
369		return;
370	}
371
372	pcfg->port_cfg.roles = BFA_PORT_ROLE_FCP_IM;
373	pcfg->port_cfg.pwwn = pbc_vport.vp_pwwn;
374	pcfg->port_cfg.nwwn = pbc_vport.vp_nwwn;
375	pcfg->port_cfg.preboot_vp  = BFA_TRUE;
376
377	list_add_tail(&pcfg->list_entry, &bfad->pbc_pcfg_list);
378
379	return;
380}
381
382void
383bfad_hal_mem_release(struct bfad_s *bfad)
384{
385	int             i;
386	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
387	struct bfa_mem_elem_s *meminfo_elem;
388
389	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
390		meminfo_elem = &hal_meminfo->meminfo[i];
391		if (meminfo_elem->kva != NULL) {
392			switch (meminfo_elem->mem_type) {
393			case BFA_MEM_TYPE_KVA:
394				vfree(meminfo_elem->kva);
395				break;
396			case BFA_MEM_TYPE_DMA:
397				dma_free_coherent(&bfad->pcidev->dev,
398						meminfo_elem->mem_len,
399						meminfo_elem->kva,
400						(dma_addr_t) meminfo_elem->dma);
401				break;
402			default:
403				bfa_assert(0);
404				break;
405			}
406		}
407	}
408
409	memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
410}
411
412void
413bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
414{
415	if (num_rports > 0)
416		bfa_cfg->fwcfg.num_rports = num_rports;
417	if (num_ios > 0)
418		bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
419	if (num_tms > 0)
420		bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
421	if (num_fcxps > 0)
422		bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
423	if (num_ufbufs > 0)
424		bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
425	if (reqq_size > 0)
426		bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
427	if (rspq_size > 0)
428		bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
429	if (num_sgpgs > 0)
430		bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
431
432	/*
433	 * populate the hal values back to the driver for sysfs use.
434	 * otherwise, the default values will be shown as 0 in sysfs
435	 */
436	num_rports = bfa_cfg->fwcfg.num_rports;
437	num_ios    = bfa_cfg->fwcfg.num_ioim_reqs;
438	num_tms	   = bfa_cfg->fwcfg.num_tskim_reqs;
439	num_fcxps  = bfa_cfg->fwcfg.num_fcxp_reqs;
440	num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
441	reqq_size  = bfa_cfg->drvcfg.num_reqq_elems;
442	rspq_size  = bfa_cfg->drvcfg.num_rspq_elems;
443	num_sgpgs  = bfa_cfg->drvcfg.num_sgpgs;
444}
445
446bfa_status_t
447bfad_hal_mem_alloc(struct bfad_s *bfad)
448{
449	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
450	struct bfa_mem_elem_s *meminfo_elem;
451	bfa_status_t    rc = BFA_STATUS_OK;
452	dma_addr_t      phys_addr;
453	int             retry_count = 0;
454	int             reset_value = 1;
455	int             min_num_sgpgs = 512;
456	void           *kva;
457	int             i;
458
459	bfa_cfg_get_default(&bfad->ioc_cfg);
460
461retry:
462	bfad_update_hal_cfg(&bfad->ioc_cfg);
463	bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
464	bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
465
466	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
467		meminfo_elem = &hal_meminfo->meminfo[i];
468		switch (meminfo_elem->mem_type) {
469		case BFA_MEM_TYPE_KVA:
470			kva = vmalloc(meminfo_elem->mem_len);
471			if (kva == NULL) {
472				bfad_hal_mem_release(bfad);
473				rc = BFA_STATUS_ENOMEM;
474				goto ext;
475			}
476			memset(kva, 0, meminfo_elem->mem_len);
477			meminfo_elem->kva = kva;
478			break;
479		case BFA_MEM_TYPE_DMA:
480			kva = dma_alloc_coherent(&bfad->pcidev->dev,
481					meminfo_elem->mem_len,
482					&phys_addr, GFP_KERNEL);
483			if (kva == NULL) {
484				bfad_hal_mem_release(bfad);
485				/*
486				 * If we cannot allocate with default
487				 * num_sgpages try with half the value.
488				 */
489				if (num_sgpgs > min_num_sgpgs) {
490					printk(KERN_INFO "bfad[%d]: memory"
491						" allocation failed with"
492						" num_sgpgs: %d\n",
493						bfad->inst_no, num_sgpgs);
494					nextLowerInt(&num_sgpgs);
495					printk(KERN_INFO "bfad[%d]: trying to"
496						" allocate memory with"
497						" num_sgpgs: %d\n",
498						bfad->inst_no, num_sgpgs);
499					retry_count++;
500					goto retry;
501				} else {
502					if (num_sgpgs_parm > 0)
503						num_sgpgs = num_sgpgs_parm;
504					else {
505						reset_value =
506							(1 << retry_count);
507						num_sgpgs *= reset_value;
508					}
509					rc = BFA_STATUS_ENOMEM;
510					goto ext;
511				}
512			}
513
514			if (num_sgpgs_parm > 0)
515				num_sgpgs = num_sgpgs_parm;
516			else {
517				reset_value = (1 << retry_count);
518				num_sgpgs *= reset_value;
519			}
520
521			memset(kva, 0, meminfo_elem->mem_len);
522			meminfo_elem->kva = kva;
523			meminfo_elem->dma = phys_addr;
524			break;
525		default:
526			break;
527
528		}
529	}
530ext:
531	return rc;
532}
533
534/**
535 * Create a vport under a vf.
536 */
537bfa_status_t
538bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
539			struct bfa_port_cfg_s *port_cfg, struct device *dev)
540{
541	struct bfad_vport_s *vport;
542	int rc = BFA_STATUS_OK;
543	unsigned long   flags;
544	struct completion fcomp;
545
546	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
547	if (!vport) {
548		rc = BFA_STATUS_ENOMEM;
549		goto ext;
550	}
551
552	vport->drv_port.bfad = bfad;
553	spin_lock_irqsave(&bfad->bfad_lock, flags);
554	if (port_cfg->preboot_vp == BFA_TRUE)
555		rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport,
556				&bfad->bfa_fcs, vf_id, port_cfg, vport);
557	else
558		rc = bfa_fcs_vport_create(&vport->fcs_vport,
559				&bfad->bfa_fcs, vf_id, port_cfg, vport);
560	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
561
562	if (rc != BFA_STATUS_OK)
563		goto ext_free_vport;
564
565	if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) {
566		rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port,
567							dev);
568		if (rc != BFA_STATUS_OK)
569			goto ext_free_fcs_vport;
570	}
571
572	spin_lock_irqsave(&bfad->bfad_lock, flags);
573	bfa_fcs_vport_start(&vport->fcs_vport);
574	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
575
576	return BFA_STATUS_OK;
577
578ext_free_fcs_vport:
579	spin_lock_irqsave(&bfad->bfad_lock, flags);
580	vport->comp_del = &fcomp;
581	init_completion(vport->comp_del);
582	bfa_fcs_vport_delete(&vport->fcs_vport);
583	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
584	wait_for_completion(vport->comp_del);
585ext_free_vport:
586	kfree(vport);
587ext:
588	return rc;
589}
590
591/**
592 * Create a vf and its base vport implicitely.
593 */
594bfa_status_t
595bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
596	       struct bfa_port_cfg_s *port_cfg)
597{
598	struct bfad_vf_s *vf;
599	int             rc = BFA_STATUS_OK;
600
601	vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL);
602	if (!vf) {
603		rc = BFA_STATUS_FAILED;
604		goto ext;
605	}
606
607	rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg,
608			       vf);
609	if (rc != BFA_STATUS_OK)
610		kfree(vf);
611ext:
612	return rc;
613}
614
615void
616bfad_bfa_tmo(unsigned long data)
617{
618	struct bfad_s  *bfad = (struct bfad_s *)data;
619	unsigned long   flags;
620	struct list_head  doneq;
621
622	spin_lock_irqsave(&bfad->bfad_lock, flags);
623
624	bfa_timer_tick(&bfad->bfa);
625
626	bfa_comp_deq(&bfad->bfa, &doneq);
627	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
628
629	if (!list_empty(&doneq)) {
630		bfa_comp_process(&bfad->bfa, &doneq);
631		spin_lock_irqsave(&bfad->bfad_lock, flags);
632		bfa_comp_free(&bfad->bfa, &doneq);
633		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
634	}
635
636	mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
637}
638
639void
640bfad_init_timer(struct bfad_s *bfad)
641{
642	init_timer(&bfad->hal_tmo);
643	bfad->hal_tmo.function = bfad_bfa_tmo;
644	bfad->hal_tmo.data = (unsigned long)bfad;
645
646	mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
647}
648
649int
650bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
651{
652	int             rc = -ENODEV;
653
654	if (pci_enable_device(pdev)) {
655		BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev);
656		goto out;
657	}
658
659	if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
660		goto out_disable_device;
661
662	pci_set_master(pdev);
663
664
665	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
666		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
667			BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev);
668			goto out_release_region;
669		}
670
671	bfad->pci_bar0_kva = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
672
673	if (bfad->pci_bar0_kva == NULL) {
674		BFA_PRINTF(BFA_ERR, "Fail to map bar0\n");
675		goto out_release_region;
676	}
677
678	bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
679	bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
680	bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
681	bfad->hal_pcidev.device_id = pdev->device;
682	bfad->pci_name = pci_name(pdev);
683
684	bfad->pci_attr.vendor_id = pdev->vendor;
685	bfad->pci_attr.device_id = pdev->device;
686	bfad->pci_attr.ssid = pdev->subsystem_device;
687	bfad->pci_attr.ssvid = pdev->subsystem_vendor;
688	bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
689
690	bfad->pcidev = pdev;
691	return 0;
692
693out_release_region:
694	pci_release_regions(pdev);
695out_disable_device:
696	pci_disable_device(pdev);
697out:
698	return rc;
699}
700
701void
702bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
703{
704	pci_iounmap(pdev, bfad->pci_bar0_kva);
705	pci_release_regions(pdev);
706	pci_disable_device(pdev);
707	pci_set_drvdata(pdev, NULL);
708}
709
710void
711bfad_fcs_port_cfg(struct bfad_s *bfad)
712{
713	struct bfa_port_cfg_s port_cfg;
714	struct bfa_pport_attr_s attr;
715	char            symname[BFA_SYMNAME_MAXLEN];
716
717	sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
718	memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
719	bfa_fcport_get_attr(&bfad->bfa, &attr);
720	port_cfg.nwwn = attr.nwwn;
721	port_cfg.pwwn = attr.pwwn;
722
723	bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg);
724}
725
726bfa_status_t
727bfad_drv_init(struct bfad_s *bfad)
728{
729	bfa_status_t    rc;
730	unsigned long   flags;
731	struct bfa_fcs_driver_info_s driver_info;
732
733	bfad->cfg_data.rport_del_timeout = rport_del_timeout;
734	bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
735	bfad->cfg_data.io_max_sge = bfa_io_max_sge;
736	bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
737
738	rc = bfad_hal_mem_alloc(bfad);
739	if (rc != BFA_STATUS_OK) {
740		printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
741		       bfad->inst_no);
742		printk(KERN_WARNING
743			"Not enough memory to attach all Brocade HBA ports,"
744			" System may need more memory.\n");
745		goto out_hal_mem_alloc_failure;
746	}
747
748	bfa_init_log(&bfad->bfa, bfad->logmod);
749	bfa_init_trc(&bfad->bfa, bfad->trcmod);
750	bfa_init_aen(&bfad->bfa, bfad->aen);
751	memset(bfad->file_map, 0, sizeof(bfad->file_map));
752	bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
753	bfa_plog_init(&bfad->plog_buf);
754	bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
755		     0, "Driver Attach");
756
757	bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
758		   &bfad->hal_pcidev);
759
760	init_completion(&bfad->comp);
761
762	/*
763	 * Enable Interrupt and wait bfa_init completion
764	 */
765	if (bfad_setup_intr(bfad)) {
766		printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
767		       bfad->inst_no);
768		goto out_setup_intr_failure;
769	}
770
771	spin_lock_irqsave(&bfad->bfad_lock, flags);
772	bfa_init(&bfad->bfa);
773	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
774
775	/*
776	 * Set up interrupt handler for each vectors
777	 */
778	if ((bfad->bfad_flags & BFAD_MSIX_ON)
779	    && bfad_install_msix_handler(bfad)) {
780		printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
781		       __func__, bfad->inst_no);
782	}
783
784	bfad_init_timer(bfad);
785
786	wait_for_completion(&bfad->comp);
787
788	memset(&driver_info, 0, sizeof(driver_info));
789	strncpy(driver_info.version, BFAD_DRIVER_VERSION,
790		sizeof(driver_info.version) - 1);
791	__kernel_param_lock();
792	if (host_name)
793		strncpy(driver_info.host_machine_name, host_name,
794			sizeof(driver_info.host_machine_name) - 1);
795	if (os_name)
796		strncpy(driver_info.host_os_name, os_name,
797			sizeof(driver_info.host_os_name) - 1);
798	if (os_patch)
799		strncpy(driver_info.host_os_patch, os_patch,
800			sizeof(driver_info.host_os_patch) - 1);
801	__kernel_param_unlock();
802
803	strncpy(driver_info.os_device_name, bfad->pci_name,
804		sizeof(driver_info.os_device_name - 1));
805
806	/*
807	 * FCS INIT
808	 */
809	spin_lock_irqsave(&bfad->bfad_lock, flags);
810	bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
811	bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
812	bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
813	bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
814
815	/* Do FCS init only when HAL init is done */
816	if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
817		bfa_fcs_init(&bfad->bfa_fcs);
818		bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
819	}
820
821	bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
822	bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
823	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
824
825	bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
826	return BFA_STATUS_OK;
827
828out_setup_intr_failure:
829	bfa_detach(&bfad->bfa);
830	bfad_hal_mem_release(bfad);
831out_hal_mem_alloc_failure:
832	return BFA_STATUS_FAILED;
833}
834
835void
836bfad_drv_uninit(struct bfad_s *bfad)
837{
838	unsigned long   flags;
839
840	spin_lock_irqsave(&bfad->bfad_lock, flags);
841	init_completion(&bfad->comp);
842	bfa_stop(&bfad->bfa);
843	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
844	wait_for_completion(&bfad->comp);
845
846	del_timer_sync(&bfad->hal_tmo);
847	bfa_isr_disable(&bfad->bfa);
848	bfa_detach(&bfad->bfa);
849	bfad_remove_intr(bfad);
850	bfad_hal_mem_release(bfad);
851
852	bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
853}
854
855void
856bfad_drv_start(struct bfad_s *bfad)
857{
858	unsigned long   flags;
859
860	spin_lock_irqsave(&bfad->bfad_lock, flags);
861	bfa_start(&bfad->bfa);
862	bfa_fcs_start(&bfad->bfa_fcs);
863	bfad->bfad_flags |= BFAD_HAL_START_DONE;
864	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
865
866	bfad_fc4_probe_post(bfad);
867}
868
869void
870bfad_drv_stop(struct bfad_s *bfad)
871{
872	unsigned long   flags;
873
874	spin_lock_irqsave(&bfad->bfad_lock, flags);
875	init_completion(&bfad->comp);
876	bfad->pport.flags |= BFAD_PORT_DELETE;
877	bfa_fcs_exit(&bfad->bfa_fcs);
878	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
879	wait_for_completion(&bfad->comp);
880
881	spin_lock_irqsave(&bfad->bfad_lock, flags);
882	init_completion(&bfad->comp);
883	bfa_stop(&bfad->bfa);
884	bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
885	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
886	wait_for_completion(&bfad->comp);
887}
888
889bfa_status_t
890bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
891{
892	int             rc = BFA_STATUS_OK;
893
894	/*
895	 * Allocate scsi_host for the physical port
896	 */
897	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
898	    && (role & BFA_PORT_ROLE_FCP_IM)) {
899		if (bfad->pport.im_port == NULL) {
900			rc = BFA_STATUS_FAILED;
901			goto out;
902		}
903
904		rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port,
905						&bfad->pcidev->dev);
906		if (rc != BFA_STATUS_OK)
907			goto out;
908
909		bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
910	}
911
912	/* Setup the debugfs node for this scsi_host */
913	if (bfa_debugfs_enable)
914		bfad_debugfs_init(&bfad->pport);
915
916	bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
917
918out:
919	return rc;
920}
921
922void
923bfad_uncfg_pport(struct bfad_s *bfad)
924{
925	 /* Remove the debugfs node for this scsi_host */
926	kfree(bfad->regdata);
927	bfad_debugfs_exit(&bfad->pport);
928
929	if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
930		bfad_ipfc_port_delete(bfad, &bfad->pport);
931		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
932	}
933
934	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
935	    && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) {
936		bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
937		bfad_im_port_clean(bfad->pport.im_port);
938		kfree(bfad->pport.im_port);
939		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM;
940	}
941
942	bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
943}
944
945void
946bfad_drv_log_level_set(struct bfad_s *bfad)
947{
948	if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX)
949		bfa_log_set_level_all(&bfad->log_data, log_level);
950}
951
952bfa_status_t
953bfad_start_ops(struct bfad_s *bfad)
954{
955	int retval;
956	struct bfad_pcfg_s *pcfg, *pcfg_new;
957
958	/* PPORT FCS config */
959	bfad_fcs_port_cfg(bfad);
960
961	retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
962	if (retval != BFA_STATUS_OK)
963		goto out_cfg_pport_failure;
964
965	/* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
966	retval = bfad_fc4_probe(bfad);
967	if (retval != BFA_STATUS_OK) {
968		printk(KERN_WARNING "bfad_fc4_probe failed\n");
969		goto out_fc4_probe_failure;
970	}
971
972	bfad_drv_start(bfad);
973
974	/* pbc vport creation */
975	list_for_each_entry_safe(pcfg, pcfg_new,  &bfad->pbc_pcfg_list,
976					list_entry) {
977		struct fc_vport_identifiers vid;
978		struct fc_vport *fc_vport;
979
980		memset(&vid, 0, sizeof(vid));
981		vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
982		vid.vport_type = FC_PORTTYPE_NPIV;
983		vid.disable = false;
984		vid.node_name = wwn_to_u64((u8 *)&pcfg->port_cfg.nwwn);
985		vid.port_name = wwn_to_u64((u8 *)&pcfg->port_cfg.pwwn);
986		fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid);
987		if (!fc_vport)
988			printk(KERN_WARNING "bfad%d: failed to create pbc vport"
989				" %llx\n", bfad->inst_no, vid.port_name);
990		list_del(&pcfg->list_entry);
991		kfree(pcfg);
992
993	}
994
995	/*
996	 * If bfa_linkup_delay is set to -1 default; try to retrive the
997	 * value using the bfad_os_get_linkup_delay(); else use the
998	 * passed in module param value as the bfa_linkup_delay.
999	 */
1000	if (bfa_linkup_delay < 0) {
1001
1002		bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
1003		bfad_os_rport_online_wait(bfad);
1004		bfa_linkup_delay = -1;
1005
1006	} else {
1007		bfad_os_rport_online_wait(bfad);
1008	}
1009
1010	bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
1011
1012	return BFA_STATUS_OK;
1013
1014out_fc4_probe_failure:
1015	bfad_fc4_probe_undo(bfad);
1016	bfad_uncfg_pport(bfad);
1017out_cfg_pport_failure:
1018	return BFA_STATUS_FAILED;
1019}
1020
1021int
1022bfad_worker(void *ptr)
1023{
1024	struct bfad_s *bfad;
1025	unsigned long   flags;
1026
1027	bfad = (struct bfad_s *)ptr;
1028
1029	while (!kthread_should_stop()) {
1030
1031		/* Check if the FCS init is done from bfad_drv_init;
1032		 * if not done do FCS init and set the flag.
1033		 */
1034		if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
1035			spin_lock_irqsave(&bfad->bfad_lock, flags);
1036			bfa_fcs_init(&bfad->bfa_fcs);
1037			bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
1038			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1039		}
1040
1041		/* Start the bfad operations after HAL init done */
1042		bfad_start_ops(bfad);
1043
1044		spin_lock_irqsave(&bfad->bfad_lock, flags);
1045		bfad->bfad_tsk = NULL;
1046		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1047
1048		break;
1049	}
1050
1051	return 0;
1052}
1053
1054 /*
1055  *  PCI_entry PCI driver entries * {
1056  */
1057
1058/**
1059 * PCI probe entry.
1060 */
1061int
1062bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
1063{
1064	struct bfad_s  *bfad;
1065	int             error = -ENODEV, retval;
1066
1067	/*
1068	 * For single port cards - only claim function 0
1069	 */
1070	if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P)
1071	    && (PCI_FUNC(pdev->devfn) != 0))
1072		return -ENODEV;
1073
1074	BFA_TRACE(BFA_INFO, "bfad_pci_probe entry");
1075
1076	bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
1077	if (!bfad) {
1078		error = -ENOMEM;
1079		goto out;
1080	}
1081
1082	bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
1083	if (!bfad->trcmod) {
1084		printk(KERN_WARNING "Error alloc trace buffer!\n");
1085		error = -ENOMEM;
1086		goto out_alloc_trace_failure;
1087	}
1088
1089	/*
1090	 * LOG/TRACE INIT
1091	 */
1092	bfa_trc_init(bfad->trcmod);
1093	bfa_trc(bfad, bfad_inst);
1094
1095	bfad->logmod = &bfad->log_data;
1096	bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
1097
1098	bfad_drv_log_level_set(bfad);
1099
1100	bfad->aen = &bfad->aen_buf;
1101
1102	if (!(bfad_load_fwimg(pdev))) {
1103		printk(KERN_WARNING "bfad_load_fwimg failure!\n");
1104		kfree(bfad->trcmod);
1105		goto out_alloc_trace_failure;
1106	}
1107
1108	retval = bfad_pci_init(pdev, bfad);
1109	if (retval) {
1110		printk(KERN_WARNING "bfad_pci_init failure!\n");
1111		error = retval;
1112		goto out_pci_init_failure;
1113	}
1114
1115	mutex_lock(&bfad_mutex);
1116	bfad->inst_no = bfad_inst++;
1117	list_add_tail(&bfad->list_entry, &bfad_list);
1118	mutex_unlock(&bfad_mutex);
1119
1120	spin_lock_init(&bfad->bfad_lock);
1121	pci_set_drvdata(pdev, bfad);
1122
1123	bfad->ref_count = 0;
1124	bfad->pport.bfad = bfad;
1125	INIT_LIST_HEAD(&bfad->pbc_pcfg_list);
1126
1127	bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
1128					"bfad_worker");
1129	if (IS_ERR(bfad->bfad_tsk)) {
1130		printk(KERN_INFO "bfad[%d]: Kernel thread"
1131			" creation failed!\n",
1132			bfad->inst_no);
1133		goto out_kthread_create_failure;
1134	}
1135
1136	retval = bfad_drv_init(bfad);
1137	if (retval != BFA_STATUS_OK)
1138		goto out_drv_init_failure;
1139	if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1140		bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
1141		printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
1142		goto ok;
1143	}
1144
1145	retval = bfad_start_ops(bfad);
1146	if (retval != BFA_STATUS_OK)
1147		goto out_start_ops_failure;
1148
1149	kthread_stop(bfad->bfad_tsk);
1150	bfad->bfad_tsk = NULL;
1151
1152ok:
1153	return 0;
1154
1155out_start_ops_failure:
1156	bfad_drv_uninit(bfad);
1157out_drv_init_failure:
1158	kthread_stop(bfad->bfad_tsk);
1159out_kthread_create_failure:
1160	mutex_lock(&bfad_mutex);
1161	bfad_inst--;
1162	list_del(&bfad->list_entry);
1163	mutex_unlock(&bfad_mutex);
1164	bfad_pci_uninit(pdev, bfad);
1165out_pci_init_failure:
1166	kfree(bfad->trcmod);
1167out_alloc_trace_failure:
1168	kfree(bfad);
1169out:
1170	return error;
1171}
1172
1173/**
1174 * PCI remove entry.
1175 */
1176void
1177bfad_pci_remove(struct pci_dev *pdev)
1178{
1179	struct bfad_s  *bfad = pci_get_drvdata(pdev);
1180	unsigned long   flags;
1181
1182	bfa_trc(bfad, bfad->inst_no);
1183
1184	spin_lock_irqsave(&bfad->bfad_lock, flags);
1185	if (bfad->bfad_tsk != NULL)
1186		kthread_stop(bfad->bfad_tsk);
1187	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1188
1189	if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
1190	    && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1191
1192		spin_lock_irqsave(&bfad->bfad_lock, flags);
1193		init_completion(&bfad->comp);
1194		bfa_stop(&bfad->bfa);
1195		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1196		wait_for_completion(&bfad->comp);
1197
1198		bfad_remove_intr(bfad);
1199		del_timer_sync(&bfad->hal_tmo);
1200		goto hal_detach;
1201	} else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) {
1202		goto remove_sysfs;
1203	}
1204
1205	if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
1206		bfad_drv_stop(bfad);
1207	} else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
1208		/* Invoking bfa_stop() before bfa_detach
1209		 * when HAL and DRV init are success
1210		 * but HAL start did not occur.
1211		 */
1212		spin_lock_irqsave(&bfad->bfad_lock, flags);
1213		init_completion(&bfad->comp);
1214		bfa_stop(&bfad->bfa);
1215		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1216		wait_for_completion(&bfad->comp);
1217	}
1218
1219	bfad_remove_intr(bfad);
1220	del_timer_sync(&bfad->hal_tmo);
1221
1222	if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
1223		bfad_fc4_probe_undo(bfad);
1224
1225	if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
1226		bfad_uncfg_pport(bfad);
1227
1228hal_detach:
1229	spin_lock_irqsave(&bfad->bfad_lock, flags);
1230	bfa_detach(&bfad->bfa);
1231	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1232	bfad_hal_mem_release(bfad);
1233remove_sysfs:
1234
1235	mutex_lock(&bfad_mutex);
1236	bfad_inst--;
1237	list_del(&bfad->list_entry);
1238	mutex_unlock(&bfad_mutex);
1239	bfad_pci_uninit(pdev, bfad);
1240
1241	kfree(bfad->trcmod);
1242	kfree(bfad);
1243}
1244
1245
1246static struct pci_device_id bfad_id_table[] = {
1247	{
1248	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1249	 .device = BFA_PCI_DEVICE_ID_FC_8G2P,
1250	 .subvendor = PCI_ANY_ID,
1251	 .subdevice = PCI_ANY_ID,
1252	 },
1253	{
1254	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1255	 .device = BFA_PCI_DEVICE_ID_FC_8G1P,
1256	 .subvendor = PCI_ANY_ID,
1257	 .subdevice = PCI_ANY_ID,
1258	 },
1259	{
1260	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1261	 .device = BFA_PCI_DEVICE_ID_CT,
1262	 .subvendor = PCI_ANY_ID,
1263	 .subdevice = PCI_ANY_ID,
1264	 .class = (PCI_CLASS_SERIAL_FIBER << 8),
1265	 .class_mask = ~0,
1266	 },
1267	{
1268	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1269	 .device = BFA_PCI_DEVICE_ID_CT_FC,
1270	 .subvendor = PCI_ANY_ID,
1271	 .subdevice = PCI_ANY_ID,
1272	 .class = (PCI_CLASS_SERIAL_FIBER << 8),
1273	 .class_mask = ~0,
1274	},
1275
1276	{0, 0},
1277};
1278
1279MODULE_DEVICE_TABLE(pci, bfad_id_table);
1280
1281static struct pci_driver bfad_pci_driver = {
1282	.name = BFAD_DRIVER_NAME,
1283	.id_table = bfad_id_table,
1284	.probe = bfad_pci_probe,
1285	.remove = __devexit_p(bfad_pci_remove),
1286};
1287
1288/**
1289 *  Linux driver module functions
1290 */
1291bfa_status_t
1292bfad_fc4_module_init(void)
1293{
1294	int             rc;
1295
1296	rc = bfad_im_module_init();
1297	if (rc != BFA_STATUS_OK)
1298		goto ext;
1299
1300	bfad_tm_module_init();
1301	if (ipfc_enable)
1302		bfad_ipfc_module_init();
1303ext:
1304	return rc;
1305}
1306
1307void
1308bfad_fc4_module_exit(void)
1309{
1310	if (ipfc_enable)
1311		bfad_ipfc_module_exit();
1312	bfad_tm_module_exit();
1313	bfad_im_module_exit();
1314}
1315
1316/**
1317 * Driver module init.
1318 */
1319static int      __init
1320bfad_init(void)
1321{
1322	int             error = 0;
1323
1324	printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
1325	       BFAD_DRIVER_VERSION);
1326
1327	if (num_sgpgs > 0)
1328		num_sgpgs_parm = num_sgpgs;
1329
1330	error = bfad_fc4_module_init();
1331	if (error) {
1332		error = -ENOMEM;
1333		printk(KERN_WARNING "bfad_fc4_module_init failure\n");
1334		goto ext;
1335	}
1336
1337	if (!strcmp(FCPI_NAME, " fcpim"))
1338		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM;
1339	if (!strcmp(FCPT_NAME, " fcptm"))
1340		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM;
1341	if (!strcmp(IPFC_NAME, " ipfc"))
1342		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC;
1343
1344	bfa_ioc_auto_recover(ioc_auto_recover);
1345	bfa_fcs_rport_set_del_timeout(rport_del_timeout);
1346	error = pci_register_driver(&bfad_pci_driver);
1347
1348	if (error) {
1349		printk(KERN_WARNING "bfad pci_register_driver failure\n");
1350		goto ext;
1351	}
1352
1353	return 0;
1354
1355ext:
1356	bfad_fc4_module_exit();
1357	return error;
1358}
1359
1360/**
1361 * Driver module exit.
1362 */
1363static void     __exit
1364bfad_exit(void)
1365{
1366	pci_unregister_driver(&bfad_pci_driver);
1367	bfad_fc4_module_exit();
1368	bfad_free_fwimg();
1369}
1370
1371#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME
1372
1373module_init(bfad_init);
1374module_exit(bfad_exit);
1375MODULE_LICENSE("GPL");
1376MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
1377MODULE_AUTHOR("Brocade Communications Systems, Inc.");
1378MODULE_VERSION(BFAD_DRIVER_VERSION);
1379