1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright 2008 Cisco Systems, Inc. All rights reserved.
4 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
5 */
6#include <linux/module.h>
7#include <linux/mempool.h>
8#include <linux/string.h>
9#include <linux/slab.h>
10#include <linux/errno.h>
11#include <linux/init.h>
12#include <linux/pci.h>
13#include <linux/skbuff.h>
14#include <linux/interrupt.h>
15#include <linux/spinlock.h>
16#include <linux/workqueue.h>
17#include <linux/if_ether.h>
18#include <scsi/fc/fc_fip.h>
19#include <scsi/scsi_host.h>
20#include <scsi/scsi_transport.h>
21#include <scsi/scsi_transport_fc.h>
22#include <scsi/scsi_tcq.h>
23#include <scsi/libfc.h>
24#include <scsi/fc_frame.h>
25
26#include "vnic_dev.h"
27#include "vnic_intr.h"
28#include "vnic_stats.h"
29#include "fnic_io.h"
30#include "fnic_fip.h"
31#include "fnic.h"
32
33#define PCI_DEVICE_ID_CISCO_FNIC 0x0045
34
35/* Timer to poll notification area for events. Used for MSI interrupts */
36#define FNIC_NOTIFY_TIMER_PERIOD (2 * HZ)
37
38static struct kmem_cache *fnic_sgl_cache[FNIC_SGL_NUM_CACHES];
39static struct kmem_cache *fnic_io_req_cache;
40static LIST_HEAD(fnic_list);
41static DEFINE_SPINLOCK(fnic_list_lock);
42
43/* Supported devices by fnic module */
44static struct pci_device_id fnic_id_table[] = {
45 { PCI_DEVICE(PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_CISCO_FNIC) },
46 { 0, }
47};
48
49MODULE_DESCRIPTION(DRV_DESCRIPTION);
50MODULE_AUTHOR("Abhijeet Joglekar <abjoglek@cisco.com>, "
51 "Joseph R. Eykholt <jeykholt@cisco.com>");
52MODULE_LICENSE("GPL v2");
53MODULE_VERSION(DRV_VERSION);
54MODULE_DEVICE_TABLE(pci, fnic_id_table);
55
56unsigned int fnic_log_level;
57module_param(fnic_log_level, int, S_IRUGO|S_IWUSR);
58MODULE_PARM_DESC(fnic_log_level, "bit mask of fnic logging levels");
59
60
61unsigned int io_completions = FNIC_DFLT_IO_COMPLETIONS;
62module_param(io_completions, int, S_IRUGO|S_IWUSR);
63MODULE_PARM_DESC(io_completions, "Max CQ entries to process at a time");
64
65unsigned int fnic_trace_max_pages = 16;
66module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
67MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
68 "for fnic trace buffer");
69
70unsigned int fnic_fc_trace_max_pages = 64;
71module_param(fnic_fc_trace_max_pages, uint, S_IRUGO|S_IWUSR);
72MODULE_PARM_DESC(fnic_fc_trace_max_pages,
73 "Total allocated memory pages for fc trace buffer");
74
75static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
76module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
77MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
78
79static struct libfc_function_template fnic_transport_template = {
80 .frame_send = fnic_send,
81 .lport_set_port_id = fnic_set_port_id,
82 .fcp_abort_io = fnic_empty_scsi_cleanup,
83 .fcp_cleanup = fnic_empty_scsi_cleanup,
84 .exch_mgr_reset = fnic_exch_mgr_reset
85};
86
87static int fnic_slave_alloc(struct scsi_device *sdev)
88{
89 struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
90
91 if (!rport || fc_remote_port_chkready(rport))
92 return -ENXIO;
93
94 scsi_change_queue_depth(sdev, fnic_max_qdepth);
95 return 0;
96}
97
98static const struct scsi_host_template fnic_host_template = {
99 .module = THIS_MODULE,
100 .name = DRV_NAME,
101 .queuecommand = fnic_queuecommand,
102 .eh_timed_out = fc_eh_timed_out,
103 .eh_abort_handler = fnic_abort_cmd,
104 .eh_device_reset_handler = fnic_device_reset,
105 .eh_host_reset_handler = fnic_host_reset,
106 .slave_alloc = fnic_slave_alloc,
107 .change_queue_depth = scsi_change_queue_depth,
108 .this_id = -1,
109 .cmd_per_lun = 3,
110 .can_queue = FNIC_DFLT_IO_REQ,
111 .sg_tablesize = FNIC_MAX_SG_DESC_CNT,
112 .max_sectors = 0xffff,
113 .shost_groups = fnic_host_groups,
114 .track_queue_depth = 1,
115 .cmd_size = sizeof(struct fnic_cmd_priv),
116};
117
118static void
119fnic_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
120{
121 if (timeout)
122 rport->dev_loss_tmo = timeout;
123 else
124 rport->dev_loss_tmo = 1;
125}
126
127static void fnic_get_host_speed(struct Scsi_Host *shost);
128static struct scsi_transport_template *fnic_fc_transport;
129static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *);
130static void fnic_reset_host_stats(struct Scsi_Host *);
131
132static struct fc_function_template fnic_fc_functions = {
133
134 .show_host_node_name = 1,
135 .show_host_port_name = 1,
136 .show_host_supported_classes = 1,
137 .show_host_supported_fc4s = 1,
138 .show_host_active_fc4s = 1,
139 .show_host_maxframe_size = 1,
140 .show_host_port_id = 1,
141 .show_host_supported_speeds = 1,
142 .get_host_speed = fnic_get_host_speed,
143 .show_host_speed = 1,
144 .show_host_port_type = 1,
145 .get_host_port_state = fc_get_host_port_state,
146 .show_host_port_state = 1,
147 .show_host_symbolic_name = 1,
148 .show_rport_maxframe_size = 1,
149 .show_rport_supported_classes = 1,
150 .show_host_fabric_name = 1,
151 .show_starget_node_name = 1,
152 .show_starget_port_name = 1,
153 .show_starget_port_id = 1,
154 .show_rport_dev_loss_tmo = 1,
155 .set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo,
156 .issue_fc_host_lip = fnic_reset,
157 .get_fc_host_stats = fnic_get_stats,
158 .reset_fc_host_stats = fnic_reset_host_stats,
159 .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
160 .terminate_rport_io = fnic_terminate_rport_io,
161 .bsg_request = fc_lport_bsg_request,
162};
163
164static void fnic_get_host_speed(struct Scsi_Host *shost)
165{
166 struct fc_lport *lp = shost_priv(shost);
167 struct fnic *fnic = lport_priv(lport: lp);
168 u32 port_speed = vnic_dev_port_speed(vdev: fnic->vdev);
169
170 /* Add in other values as they get defined in fw */
171 switch (port_speed) {
172 case DCEM_PORTSPEED_10G:
173 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
174 break;
175 case DCEM_PORTSPEED_20G:
176 fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
177 break;
178 case DCEM_PORTSPEED_25G:
179 fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
180 break;
181 case DCEM_PORTSPEED_40G:
182 case DCEM_PORTSPEED_4x10G:
183 fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
184 break;
185 case DCEM_PORTSPEED_100G:
186 fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
187 break;
188 default:
189 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
190 break;
191 }
192}
193
194static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host)
195{
196 int ret;
197 struct fc_lport *lp = shost_priv(shost: host);
198 struct fnic *fnic = lport_priv(lport: lp);
199 struct fc_host_statistics *stats = &lp->host_stats;
200 struct vnic_stats *vs;
201 unsigned long flags;
202
203 if (time_before(jiffies, fnic->stats_time + HZ / FNIC_STATS_RATE_LIMIT))
204 return stats;
205 fnic->stats_time = jiffies;
206
207 spin_lock_irqsave(&fnic->fnic_lock, flags);
208 ret = vnic_dev_stats_dump(vdev: fnic->vdev, stats: &fnic->stats);
209 spin_unlock_irqrestore(lock: &fnic->fnic_lock, flags);
210
211 if (ret) {
212 FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host,
213 "fnic: Get vnic stats failed"
214 " 0x%x", ret);
215 return stats;
216 }
217 vs = fnic->stats;
218 stats->tx_frames = vs->tx.tx_unicast_frames_ok;
219 stats->tx_words = vs->tx.tx_unicast_bytes_ok / 4;
220 stats->rx_frames = vs->rx.rx_unicast_frames_ok;
221 stats->rx_words = vs->rx.rx_unicast_bytes_ok / 4;
222 stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors;
223 stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop;
224 stats->invalid_crc_count = vs->rx.rx_crc_errors;
225 stats->seconds_since_last_reset =
226 (jiffies - fnic->stats_reset_time) / HZ;
227 stats->fcp_input_megabytes = div_u64(dividend: fnic->fcp_input_bytes, divisor: 1000000);
228 stats->fcp_output_megabytes = div_u64(dividend: fnic->fcp_output_bytes, divisor: 1000000);
229
230 return stats;
231}
232
233/*
234 * fnic_dump_fchost_stats
235 * note : dumps fc_statistics into system logs
236 */
237void fnic_dump_fchost_stats(struct Scsi_Host *host,
238 struct fc_host_statistics *stats)
239{
240 FNIC_MAIN_NOTE(KERN_NOTICE, host,
241 "fnic: seconds since last reset = %llu\n",
242 stats->seconds_since_last_reset);
243 FNIC_MAIN_NOTE(KERN_NOTICE, host,
244 "fnic: tx frames = %llu\n",
245 stats->tx_frames);
246 FNIC_MAIN_NOTE(KERN_NOTICE, host,
247 "fnic: tx words = %llu\n",
248 stats->tx_words);
249 FNIC_MAIN_NOTE(KERN_NOTICE, host,
250 "fnic: rx frames = %llu\n",
251 stats->rx_frames);
252 FNIC_MAIN_NOTE(KERN_NOTICE, host,
253 "fnic: rx words = %llu\n",
254 stats->rx_words);
255 FNIC_MAIN_NOTE(KERN_NOTICE, host,
256 "fnic: lip count = %llu\n",
257 stats->lip_count);
258 FNIC_MAIN_NOTE(KERN_NOTICE, host,
259 "fnic: nos count = %llu\n",
260 stats->nos_count);
261 FNIC_MAIN_NOTE(KERN_NOTICE, host,
262 "fnic: error frames = %llu\n",
263 stats->error_frames);
264 FNIC_MAIN_NOTE(KERN_NOTICE, host,
265 "fnic: dumped frames = %llu\n",
266 stats->dumped_frames);
267 FNIC_MAIN_NOTE(KERN_NOTICE, host,
268 "fnic: link failure count = %llu\n",
269 stats->link_failure_count);
270 FNIC_MAIN_NOTE(KERN_NOTICE, host,
271 "fnic: loss of sync count = %llu\n",
272 stats->loss_of_sync_count);
273 FNIC_MAIN_NOTE(KERN_NOTICE, host,
274 "fnic: loss of signal count = %llu\n",
275 stats->loss_of_signal_count);
276 FNIC_MAIN_NOTE(KERN_NOTICE, host,
277 "fnic: prim seq protocol err count = %llu\n",
278 stats->prim_seq_protocol_err_count);
279 FNIC_MAIN_NOTE(KERN_NOTICE, host,
280 "fnic: invalid tx word count= %llu\n",
281 stats->invalid_tx_word_count);
282 FNIC_MAIN_NOTE(KERN_NOTICE, host,
283 "fnic: invalid crc count = %llu\n",
284 stats->invalid_crc_count);
285 FNIC_MAIN_NOTE(KERN_NOTICE, host,
286 "fnic: fcp input requests = %llu\n",
287 stats->fcp_input_requests);
288 FNIC_MAIN_NOTE(KERN_NOTICE, host,
289 "fnic: fcp output requests = %llu\n",
290 stats->fcp_output_requests);
291 FNIC_MAIN_NOTE(KERN_NOTICE, host,
292 "fnic: fcp control requests = %llu\n",
293 stats->fcp_control_requests);
294 FNIC_MAIN_NOTE(KERN_NOTICE, host,
295 "fnic: fcp input megabytes = %llu\n",
296 stats->fcp_input_megabytes);
297 FNIC_MAIN_NOTE(KERN_NOTICE, host,
298 "fnic: fcp output megabytes = %llu\n",
299 stats->fcp_output_megabytes);
300 return;
301}
302
303/*
304 * fnic_reset_host_stats : clears host stats
305 * note : called when reset_statistics set under sysfs dir
306 */
307static void fnic_reset_host_stats(struct Scsi_Host *host)
308{
309 int ret;
310 struct fc_lport *lp = shost_priv(shost: host);
311 struct fnic *fnic = lport_priv(lport: lp);
312 struct fc_host_statistics *stats;
313 unsigned long flags;
314
315 /* dump current stats, before clearing them */
316 stats = fnic_get_stats(host);
317 fnic_dump_fchost_stats(host, stats);
318
319 spin_lock_irqsave(&fnic->fnic_lock, flags);
320 ret = vnic_dev_stats_clear(vdev: fnic->vdev);
321 spin_unlock_irqrestore(lock: &fnic->fnic_lock, flags);
322
323 if (ret) {
324 FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host,
325 "fnic: Reset vnic stats failed"
326 " 0x%x", ret);
327 return;
328 }
329 fnic->stats_reset_time = jiffies;
330 memset(stats, 0, sizeof(*stats));
331
332 return;
333}
334
335void fnic_log_q_error(struct fnic *fnic)
336{
337 unsigned int i;
338 u32 error_status;
339
340 for (i = 0; i < fnic->raw_wq_count; i++) {
341 error_status = ioread32(&fnic->wq[i].ctrl->error_status);
342 if (error_status)
343 shost_printk(KERN_ERR, fnic->lport->host,
344 "WQ[%d] error_status"
345 " %d\n", i, error_status);
346 }
347
348 for (i = 0; i < fnic->rq_count; i++) {
349 error_status = ioread32(&fnic->rq[i].ctrl->error_status);
350 if (error_status)
351 shost_printk(KERN_ERR, fnic->lport->host,
352 "RQ[%d] error_status"
353 " %d\n", i, error_status);
354 }
355
356 for (i = 0; i < fnic->wq_copy_count; i++) {
357 error_status = ioread32(&fnic->wq_copy[i].ctrl->error_status);
358 if (error_status)
359 shost_printk(KERN_ERR, fnic->lport->host,
360 "CWQ[%d] error_status"
361 " %d\n", i, error_status);
362 }
363}
364
365void fnic_handle_link_event(struct fnic *fnic)
366{
367 unsigned long flags;
368
369 spin_lock_irqsave(&fnic->fnic_lock, flags);
370 if (fnic->stop_rx_link_events) {
371 spin_unlock_irqrestore(lock: &fnic->fnic_lock, flags);
372 return;
373 }
374 spin_unlock_irqrestore(lock: &fnic->fnic_lock, flags);
375
376 queue_work(wq: fnic_event_queue, work: &fnic->link_work);
377
378}
379
380static int fnic_notify_set(struct fnic *fnic)
381{
382 int err;
383
384 switch (vnic_dev_get_intr_mode(vdev: fnic->vdev)) {
385 case VNIC_DEV_INTR_MODE_INTX:
386 err = vnic_dev_notify_set(vdev: fnic->vdev, intr: FNIC_INTX_NOTIFY);
387 break;
388 case VNIC_DEV_INTR_MODE_MSI:
389 err = vnic_dev_notify_set(vdev: fnic->vdev, intr: -1);
390 break;
391 case VNIC_DEV_INTR_MODE_MSIX:
392 err = vnic_dev_notify_set(vdev: fnic->vdev, intr: FNIC_MSIX_ERR_NOTIFY);
393 break;
394 default:
395 shost_printk(KERN_ERR, fnic->lport->host,
396 "Interrupt mode should be set up"
397 " before devcmd notify set %d\n",
398 vnic_dev_get_intr_mode(fnic->vdev));
399 err = -1;
400 break;
401 }
402
403 return err;
404}
405
406static void fnic_notify_timer(struct timer_list *t)
407{
408 struct fnic *fnic = from_timer(fnic, t, notify_timer);
409
410 fnic_handle_link_event(fnic);
411 mod_timer(timer: &fnic->notify_timer,
412 expires: round_jiffies(j: jiffies + FNIC_NOTIFY_TIMER_PERIOD));
413}
414
415static void fnic_fip_notify_timer(struct timer_list *t)
416{
417 struct fnic *fnic = from_timer(fnic, t, fip_timer);
418
419 fnic_handle_fip_timer(fnic);
420}
421
422static void fnic_notify_timer_start(struct fnic *fnic)
423{
424 switch (vnic_dev_get_intr_mode(vdev: fnic->vdev)) {
425 case VNIC_DEV_INTR_MODE_MSI:
426 /*
427 * Schedule first timeout immediately. The driver is
428 * initiatialized and ready to look for link up notification
429 */
430 mod_timer(timer: &fnic->notify_timer, expires: jiffies);
431 break;
432 default:
433 /* Using intr for notification for INTx/MSI-X */
434 break;
435 }
436}
437
438static int fnic_dev_wait(struct vnic_dev *vdev,
439 int (*start)(struct vnic_dev *, int),
440 int (*finished)(struct vnic_dev *, int *),
441 int arg)
442{
443 unsigned long time;
444 int done;
445 int err;
446 int count;
447
448 count = 0;
449
450 err = start(vdev, arg);
451 if (err)
452 return err;
453
454 /* Wait for func to complete.
455 * Sometime schedule_timeout_uninterruptible take long time
456 * to wake up so we do not retry as we are only waiting for
457 * 2 seconds in while loop. By adding count, we make sure
458 * we try atleast three times before returning -ETIMEDOUT
459 */
460 time = jiffies + (HZ * 2);
461 do {
462 err = finished(vdev, &done);
463 count++;
464 if (err)
465 return err;
466 if (done)
467 return 0;
468 schedule_timeout_uninterruptible(HZ / 10);
469 } while (time_after(time, jiffies) || (count < 3));
470
471 return -ETIMEDOUT;
472}
473
474static int fnic_cleanup(struct fnic *fnic)
475{
476 unsigned int i;
477 int err;
478
479 vnic_dev_disable(vdev: fnic->vdev);
480 for (i = 0; i < fnic->intr_count; i++)
481 vnic_intr_mask(intr: &fnic->intr[i]);
482
483 for (i = 0; i < fnic->rq_count; i++) {
484 err = vnic_rq_disable(rq: &fnic->rq[i]);
485 if (err)
486 return err;
487 }
488 for (i = 0; i < fnic->raw_wq_count; i++) {
489 err = vnic_wq_disable(wq: &fnic->wq[i]);
490 if (err)
491 return err;
492 }
493 for (i = 0; i < fnic->wq_copy_count; i++) {
494 err = vnic_wq_copy_disable(wq: &fnic->wq_copy[i]);
495 if (err)
496 return err;
497 }
498
499 /* Clean up completed IOs and FCS frames */
500 fnic_wq_copy_cmpl_handler(fnic, io_completions);
501 fnic_wq_cmpl_handler(fnic, -1);
502 fnic_rq_cmpl_handler(fnic, -1);
503
504 /* Clean up the IOs and FCS frames that have not completed */
505 for (i = 0; i < fnic->raw_wq_count; i++)
506 vnic_wq_clean(wq: &fnic->wq[i], buf_clean: fnic_free_wq_buf);
507 for (i = 0; i < fnic->rq_count; i++)
508 vnic_rq_clean(rq: &fnic->rq[i], buf_clean: fnic_free_rq_buf);
509 for (i = 0; i < fnic->wq_copy_count; i++)
510 vnic_wq_copy_clean(wq: &fnic->wq_copy[i],
511 q_clean: fnic_wq_copy_cleanup_handler);
512
513 for (i = 0; i < fnic->cq_count; i++)
514 vnic_cq_clean(cq: &fnic->cq[i]);
515 for (i = 0; i < fnic->intr_count; i++)
516 vnic_intr_clean(intr: &fnic->intr[i]);
517
518 mempool_destroy(pool: fnic->io_req_pool);
519 for (i = 0; i < FNIC_SGL_NUM_CACHES; i++)
520 mempool_destroy(pool: fnic->io_sgl_pool[i]);
521
522 return 0;
523}
524
525static void fnic_iounmap(struct fnic *fnic)
526{
527 if (fnic->bar0.vaddr)
528 iounmap(addr: fnic->bar0.vaddr);
529}
530
531/**
532 * fnic_get_mac() - get assigned data MAC address for FIP code.
533 * @lport: local port.
534 */
535static u8 *fnic_get_mac(struct fc_lport *lport)
536{
537 struct fnic *fnic = lport_priv(lport);
538
539 return fnic->data_src_addr;
540}
541
542static void fnic_set_vlan(struct fnic *fnic, u16 vlan_id)
543{
544 vnic_dev_set_default_vlan(vdev: fnic->vdev, new_default_vlan: vlan_id);
545}
546
547static int fnic_scsi_drv_init(struct fnic *fnic)
548{
549 struct Scsi_Host *host = fnic->lport->host;
550
551 /* Configure maximum outstanding IO reqs*/
552 if (fnic->config.io_throttle_count != FNIC_UCSM_DFLT_THROTTLE_CNT_BLD)
553 host->can_queue = min_t(u32, FNIC_MAX_IO_REQ,
554 max_t(u32, FNIC_MIN_IO_REQ,
555 fnic->config.io_throttle_count));
556
557 fnic->fnic_max_tag_id = host->can_queue;
558 host->max_lun = fnic->config.luns_per_tgt;
559 host->max_id = FNIC_MAX_FCP_TARGET;
560 host->max_cmd_len = FCOE_MAX_CMD_LEN;
561
562 host->nr_hw_queues = fnic->wq_copy_count;
563 if (host->nr_hw_queues > 1)
564 shost_printk(KERN_ERR, host,
565 "fnic: blk-mq is not supported");
566
567 host->nr_hw_queues = fnic->wq_copy_count = 1;
568
569 shost_printk(KERN_INFO, host,
570 "fnic: can_queue: %d max_lun: %llu",
571 host->can_queue, host->max_lun);
572
573 shost_printk(KERN_INFO, host,
574 "fnic: max_id: %d max_cmd_len: %d nr_hw_queues: %d",
575 host->max_id, host->max_cmd_len, host->nr_hw_queues);
576
577 return 0;
578}
579
580static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
581{
582 struct Scsi_Host *host;
583 struct fc_lport *lp;
584 struct fnic *fnic;
585 mempool_t *pool;
586 int err;
587 int i;
588 unsigned long flags;
589
590 /*
591 * Allocate SCSI Host and set up association between host,
592 * local port, and fnic
593 */
594 lp = libfc_host_alloc(sht: &fnic_host_template, priv_size: sizeof(struct fnic));
595 if (!lp) {
596 printk(KERN_ERR PFX "Unable to alloc libfc local port\n");
597 err = -ENOMEM;
598 goto err_out;
599 }
600 host = lp->host;
601 fnic = lport_priv(lport: lp);
602 fnic->lport = lp;
603 fnic->ctlr.lp = lp;
604
605 fnic->link_events = 0;
606
607 snprintf(buf: fnic->name, size: sizeof(fnic->name) - 1, fmt: "%s%d", DRV_NAME,
608 host->host_no);
609
610 host->transportt = fnic_fc_transport;
611
612 fnic_stats_debugfs_init(fnic);
613
614 /* Setup PCI resources */
615 pci_set_drvdata(pdev, data: fnic);
616
617 fnic->pdev = pdev;
618
619 err = pci_enable_device(dev: pdev);
620 if (err) {
621 shost_printk(KERN_ERR, fnic->lport->host,
622 "Cannot enable PCI device, aborting.\n");
623 goto err_out_free_hba;
624 }
625
626 err = pci_request_regions(pdev, DRV_NAME);
627 if (err) {
628 shost_printk(KERN_ERR, fnic->lport->host,
629 "Cannot enable PCI resources, aborting\n");
630 goto err_out_disable_device;
631 }
632
633 pci_set_master(dev: pdev);
634
635 /* Query PCI controller on system for DMA addressing
636 * limitation for the device. Try 47-bit first, and
637 * fail to 32-bit. Cisco VIC supports 47 bits only.
638 */
639 err = dma_set_mask_and_coherent(dev: &pdev->dev, DMA_BIT_MASK(47));
640 if (err) {
641 err = dma_set_mask_and_coherent(dev: &pdev->dev, DMA_BIT_MASK(32));
642 if (err) {
643 shost_printk(KERN_ERR, fnic->lport->host,
644 "No usable DMA configuration "
645 "aborting\n");
646 goto err_out_release_regions;
647 }
648 }
649
650 /* Map vNIC resources from BAR0 */
651 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
652 shost_printk(KERN_ERR, fnic->lport->host,
653 "BAR0 not memory-map'able, aborting.\n");
654 err = -ENODEV;
655 goto err_out_release_regions;
656 }
657
658 fnic->bar0.vaddr = pci_iomap(dev: pdev, bar: 0, max: 0);
659 fnic->bar0.bus_addr = pci_resource_start(pdev, 0);
660 fnic->bar0.len = pci_resource_len(pdev, 0);
661
662 if (!fnic->bar0.vaddr) {
663 shost_printk(KERN_ERR, fnic->lport->host,
664 "Cannot memory-map BAR0 res hdr, "
665 "aborting.\n");
666 err = -ENODEV;
667 goto err_out_release_regions;
668 }
669
670 fnic->vdev = vnic_dev_register(NULL, priv: fnic, pdev, bar: &fnic->bar0);
671 if (!fnic->vdev) {
672 shost_printk(KERN_ERR, fnic->lport->host,
673 "vNIC registration failed, "
674 "aborting.\n");
675 err = -ENODEV;
676 goto err_out_iounmap;
677 }
678
679 err = vnic_dev_cmd_init(vdev: fnic->vdev);
680 if (err) {
681 shost_printk(KERN_ERR, fnic->lport->host,
682 "vnic_dev_cmd_init() returns %d, aborting\n",
683 err);
684 goto err_out_vnic_unregister;
685 }
686
687 err = fnic_dev_wait(vdev: fnic->vdev, vnic_dev_open,
688 vnic_dev_open_done, CMD_OPENF_RQ_ENABLE_THEN_POST);
689 if (err) {
690 shost_printk(KERN_ERR, fnic->lport->host,
691 "vNIC dev open failed, aborting.\n");
692 goto err_out_dev_cmd_deinit;
693 }
694
695 err = vnic_dev_init(vdev: fnic->vdev, arg: 0);
696 if (err) {
697 shost_printk(KERN_ERR, fnic->lport->host,
698 "vNIC dev init failed, aborting.\n");
699 goto err_out_dev_close;
700 }
701
702 err = vnic_dev_mac_addr(vdev: fnic->vdev, mac_addr: fnic->ctlr.ctl_src_addr);
703 if (err) {
704 shost_printk(KERN_ERR, fnic->lport->host,
705 "vNIC get MAC addr failed \n");
706 goto err_out_dev_close;
707 }
708 /* set data_src for point-to-point mode and to keep it non-zero */
709 memcpy(fnic->data_src_addr, fnic->ctlr.ctl_src_addr, ETH_ALEN);
710
711 /* Get vNIC configuration */
712 err = fnic_get_vnic_config(fnic);
713 if (err) {
714 shost_printk(KERN_ERR, fnic->lport->host,
715 "Get vNIC configuration failed, "
716 "aborting.\n");
717 goto err_out_dev_close;
718 }
719
720 fnic_scsi_drv_init(fnic);
721
722 fnic_get_res_counts(fnic);
723
724 err = fnic_set_intr_mode(fnic);
725 if (err) {
726 shost_printk(KERN_ERR, fnic->lport->host,
727 "Failed to set intr mode, "
728 "aborting.\n");
729 goto err_out_dev_close;
730 }
731
732 err = fnic_alloc_vnic_resources(fnic);
733 if (err) {
734 shost_printk(KERN_ERR, fnic->lport->host,
735 "Failed to alloc vNIC resources, "
736 "aborting.\n");
737 goto err_out_clear_intr;
738 }
739
740
741 /* initialize all fnic locks */
742 spin_lock_init(&fnic->fnic_lock);
743
744 for (i = 0; i < FNIC_WQ_MAX; i++)
745 spin_lock_init(&fnic->wq_lock[i]);
746
747 for (i = 0; i < FNIC_WQ_COPY_MAX; i++) {
748 spin_lock_init(&fnic->wq_copy_lock[i]);
749 fnic->wq_copy_desc_low[i] = DESC_CLEAN_LOW_WATERMARK;
750 fnic->fw_ack_recd[i] = 0;
751 fnic->fw_ack_index[i] = -1;
752 }
753
754 for (i = 0; i < FNIC_IO_LOCKS; i++)
755 spin_lock_init(&fnic->io_req_lock[i]);
756
757 spin_lock_init(&fnic->sgreset_lock);
758
759 err = -ENOMEM;
760 fnic->io_req_pool = mempool_create_slab_pool(min_nr: 2, kc: fnic_io_req_cache);
761 if (!fnic->io_req_pool)
762 goto err_out_free_resources;
763
764 pool = mempool_create_slab_pool(min_nr: 2, kc: fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
765 if (!pool)
766 goto err_out_free_ioreq_pool;
767 fnic->io_sgl_pool[FNIC_SGL_CACHE_DFLT] = pool;
768
769 pool = mempool_create_slab_pool(min_nr: 2, kc: fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
770 if (!pool)
771 goto err_out_free_dflt_pool;
772 fnic->io_sgl_pool[FNIC_SGL_CACHE_MAX] = pool;
773
774 /* setup vlan config, hw inserts vlan header */
775 fnic->vlan_hw_insert = 1;
776 fnic->vlan_id = 0;
777
778 /* Initialize the FIP fcoe_ctrl struct */
779 fnic->ctlr.send = fnic_eth_send;
780 fnic->ctlr.update_mac = fnic_update_mac;
781 fnic->ctlr.get_src_addr = fnic_get_mac;
782 if (fnic->config.flags & VFCF_FIP_CAPABLE) {
783 shost_printk(KERN_INFO, fnic->lport->host,
784 "firmware supports FIP\n");
785 /* enable directed and multicast */
786 vnic_dev_packet_filter(vdev: fnic->vdev, directed: 1, multicast: 1, broadcast: 0, promisc: 0, allmulti: 0);
787 vnic_dev_add_addr(vdev: fnic->vdev, FIP_ALL_ENODE_MACS);
788 vnic_dev_add_addr(vdev: fnic->vdev, addr: fnic->ctlr.ctl_src_addr);
789 fnic->set_vlan = fnic_set_vlan;
790 fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_AUTO);
791 timer_setup(&fnic->fip_timer, fnic_fip_notify_timer, 0);
792 spin_lock_init(&fnic->vlans_lock);
793 INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame);
794 INIT_WORK(&fnic->event_work, fnic_handle_event);
795 skb_queue_head_init(list: &fnic->fip_frame_queue);
796 INIT_LIST_HEAD(list: &fnic->evlist);
797 INIT_LIST_HEAD(list: &fnic->vlans);
798 } else {
799 shost_printk(KERN_INFO, fnic->lport->host,
800 "firmware uses non-FIP mode\n");
801 fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_NON_FIP);
802 fnic->ctlr.state = FIP_ST_NON_FIP;
803 }
804 fnic->state = FNIC_IN_FC_MODE;
805
806 atomic_set(v: &fnic->in_flight, i: 0);
807 fnic->state_flags = FNIC_FLAGS_NONE;
808
809 /* Enable hardware stripping of vlan header on ingress */
810 fnic_set_nic_config(fnic, rss_default_cpu: 0, rss_hash_type: 0, rss_hash_bits: 0, rss_base_cpu: 0, rss_enable: 0, tso_ipid_split_en: 0, ig_vlan_strip_en: 1);
811
812 /* Setup notification buffer area */
813 err = fnic_notify_set(fnic);
814 if (err) {
815 shost_printk(KERN_ERR, fnic->lport->host,
816 "Failed to alloc notify buffer, aborting.\n");
817 goto err_out_free_max_pool;
818 }
819
820 /* Setup notify timer when using MSI interrupts */
821 if (vnic_dev_get_intr_mode(vdev: fnic->vdev) == VNIC_DEV_INTR_MODE_MSI)
822 timer_setup(&fnic->notify_timer, fnic_notify_timer, 0);
823
824 /* allocate RQ buffers and post them to RQ*/
825 for (i = 0; i < fnic->rq_count; i++) {
826 vnic_rq_enable(rq: &fnic->rq[i]);
827 err = vnic_rq_fill(rq: &fnic->rq[i], buf_fill: fnic_alloc_rq_frame);
828 if (err) {
829 shost_printk(KERN_ERR, fnic->lport->host,
830 "fnic_alloc_rq_frame can't alloc "
831 "frame\n");
832 goto err_out_free_rq_buf;
833 }
834 }
835
836 /*
837 * Initialization done with PCI system, hardware, firmware.
838 * Add host to SCSI
839 */
840 err = scsi_add_host(host: lp->host, dev: &pdev->dev);
841 if (err) {
842 shost_printk(KERN_ERR, fnic->lport->host,
843 "fnic: scsi_add_host failed...exiting\n");
844 goto err_out_free_rq_buf;
845 }
846
847 /* Start local port initiatialization */
848
849 lp->link_up = 0;
850
851 lp->max_retry_count = fnic->config.flogi_retries;
852 lp->max_rport_retry_count = fnic->config.plogi_retries;
853 lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
854 FCP_SPPF_CONF_COMPL);
855 if (fnic->config.flags & VFCF_FCP_SEQ_LVL_ERR)
856 lp->service_params |= FCP_SPPF_RETRY;
857
858 lp->boot_time = jiffies;
859 lp->e_d_tov = fnic->config.ed_tov;
860 lp->r_a_tov = fnic->config.ra_tov;
861 lp->link_supported_speeds = FC_PORTSPEED_10GBIT;
862 fc_set_wwnn(lport: lp, wwnn: fnic->config.node_wwn);
863 fc_set_wwpn(lport: lp, wwpn: fnic->config.port_wwn);
864
865 fcoe_libfc_config(lp, &fnic->ctlr, &fnic_transport_template, init_fcp: 0);
866
867 if (!fc_exch_mgr_alloc(lp, class: FC_CLASS_3, FCPIO_HOST_EXCH_RANGE_START,
868 FCPIO_HOST_EXCH_RANGE_END, NULL)) {
869 err = -ENOMEM;
870 goto err_out_remove_scsi_host;
871 }
872
873 fc_lport_init_stats(lport: lp);
874 fnic->stats_reset_time = jiffies;
875
876 fc_lport_config(lp);
877
878 if (fc_set_mfs(lp, mfs: fnic->config.maxdatafieldsize +
879 sizeof(struct fc_frame_header))) {
880 err = -EINVAL;
881 goto err_out_free_exch_mgr;
882 }
883 fc_host_maxframe_size(lp->host) = lp->mfs;
884 fc_host_dev_loss_tmo(lp->host) = fnic->config.port_down_timeout / 1000;
885
886 sprintf(fc_host_symbolic_name(lp->host),
887 DRV_NAME " v" DRV_VERSION " over %s", fnic->name);
888
889 spin_lock_irqsave(&fnic_list_lock, flags);
890 list_add_tail(new: &fnic->list, head: &fnic_list);
891 spin_unlock_irqrestore(lock: &fnic_list_lock, flags);
892
893 INIT_WORK(&fnic->link_work, fnic_handle_link);
894 INIT_WORK(&fnic->frame_work, fnic_handle_frame);
895 skb_queue_head_init(list: &fnic->frame_queue);
896 skb_queue_head_init(list: &fnic->tx_queue);
897
898 /* Enable all queues */
899 for (i = 0; i < fnic->raw_wq_count; i++)
900 vnic_wq_enable(wq: &fnic->wq[i]);
901 for (i = 0; i < fnic->wq_copy_count; i++)
902 vnic_wq_copy_enable(wq: &fnic->wq_copy[i]);
903
904 fc_fabric_login(lp);
905
906 err = fnic_request_intr(fnic);
907 if (err) {
908 shost_printk(KERN_ERR, fnic->lport->host,
909 "Unable to request irq.\n");
910 goto err_out_free_exch_mgr;
911 }
912
913 vnic_dev_enable(vdev: fnic->vdev);
914
915 for (i = 0; i < fnic->intr_count; i++)
916 vnic_intr_unmask(intr: &fnic->intr[i]);
917
918 fnic_notify_timer_start(fnic);
919
920 return 0;
921
922err_out_free_exch_mgr:
923 fc_exch_mgr_free(lp);
924err_out_remove_scsi_host:
925 fc_remove_host(lp->host);
926 scsi_remove_host(lp->host);
927err_out_free_rq_buf:
928 for (i = 0; i < fnic->rq_count; i++)
929 vnic_rq_clean(rq: &fnic->rq[i], buf_clean: fnic_free_rq_buf);
930 vnic_dev_notify_unset(vdev: fnic->vdev);
931err_out_free_max_pool:
932 mempool_destroy(pool: fnic->io_sgl_pool[FNIC_SGL_CACHE_MAX]);
933err_out_free_dflt_pool:
934 mempool_destroy(pool: fnic->io_sgl_pool[FNIC_SGL_CACHE_DFLT]);
935err_out_free_ioreq_pool:
936 mempool_destroy(pool: fnic->io_req_pool);
937err_out_free_resources:
938 fnic_free_vnic_resources(fnic);
939err_out_clear_intr:
940 fnic_clear_intr_mode(fnic);
941err_out_dev_close:
942 vnic_dev_close(vdev: fnic->vdev);
943err_out_dev_cmd_deinit:
944err_out_vnic_unregister:
945 vnic_dev_unregister(vdev: fnic->vdev);
946err_out_iounmap:
947 fnic_iounmap(fnic);
948err_out_release_regions:
949 pci_release_regions(pdev);
950err_out_disable_device:
951 pci_disable_device(dev: pdev);
952err_out_free_hba:
953 fnic_stats_debugfs_remove(fnic);
954 scsi_host_put(t: lp->host);
955err_out:
956 return err;
957}
958
959static void fnic_remove(struct pci_dev *pdev)
960{
961 struct fnic *fnic = pci_get_drvdata(pdev);
962 struct fc_lport *lp = fnic->lport;
963 unsigned long flags;
964
965 /*
966 * Mark state so that the workqueue thread stops forwarding
967 * received frames and link events to the local port. ISR and
968 * other threads that can queue work items will also stop
969 * creating work items on the fnic workqueue
970 */
971 spin_lock_irqsave(&fnic->fnic_lock, flags);
972 fnic->stop_rx_link_events = 1;
973 spin_unlock_irqrestore(lock: &fnic->fnic_lock, flags);
974
975 if (vnic_dev_get_intr_mode(vdev: fnic->vdev) == VNIC_DEV_INTR_MODE_MSI)
976 del_timer_sync(timer: &fnic->notify_timer);
977
978 /*
979 * Flush the fnic event queue. After this call, there should
980 * be no event queued for this fnic device in the workqueue
981 */
982 flush_workqueue(fnic_event_queue);
983 skb_queue_purge(list: &fnic->frame_queue);
984 skb_queue_purge(list: &fnic->tx_queue);
985
986 if (fnic->config.flags & VFCF_FIP_CAPABLE) {
987 del_timer_sync(timer: &fnic->fip_timer);
988 skb_queue_purge(list: &fnic->fip_frame_queue);
989 fnic_fcoe_reset_vlans(fnic);
990 fnic_fcoe_evlist_free(fnic);
991 }
992
993 /*
994 * Log off the fabric. This stops all remote ports, dns port,
995 * logs off the fabric. This flushes all rport, disc, lport work
996 * before returning
997 */
998 fc_fabric_logoff(fnic->lport);
999
1000 spin_lock_irqsave(&fnic->fnic_lock, flags);
1001 fnic->in_remove = 1;
1002 spin_unlock_irqrestore(lock: &fnic->fnic_lock, flags);
1003
1004 fcoe_ctlr_destroy(&fnic->ctlr);
1005 fc_lport_destroy(lp);
1006 fnic_stats_debugfs_remove(fnic);
1007
1008 /*
1009 * This stops the fnic device, masks all interrupts. Completed
1010 * CQ entries are drained. Posted WQ/RQ/Copy-WQ entries are
1011 * cleaned up
1012 */
1013 fnic_cleanup(fnic);
1014
1015 BUG_ON(!skb_queue_empty(&fnic->frame_queue));
1016 BUG_ON(!skb_queue_empty(&fnic->tx_queue));
1017
1018 spin_lock_irqsave(&fnic_list_lock, flags);
1019 list_del(entry: &fnic->list);
1020 spin_unlock_irqrestore(lock: &fnic_list_lock, flags);
1021
1022 fc_remove_host(fnic->lport->host);
1023 scsi_remove_host(fnic->lport->host);
1024 fc_exch_mgr_free(fnic->lport);
1025 vnic_dev_notify_unset(vdev: fnic->vdev);
1026 fnic_free_intr(fnic);
1027 fnic_free_vnic_resources(fnic);
1028 fnic_clear_intr_mode(fnic);
1029 vnic_dev_close(vdev: fnic->vdev);
1030 vnic_dev_unregister(vdev: fnic->vdev);
1031 fnic_iounmap(fnic);
1032 pci_release_regions(pdev);
1033 pci_disable_device(dev: pdev);
1034 scsi_host_put(t: lp->host);
1035}
1036
1037static struct pci_driver fnic_driver = {
1038 .name = DRV_NAME,
1039 .id_table = fnic_id_table,
1040 .probe = fnic_probe,
1041 .remove = fnic_remove,
1042};
1043
1044static int __init fnic_init_module(void)
1045{
1046 size_t len;
1047 int err = 0;
1048
1049 printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION);
1050
1051 /* Create debugfs entries for fnic */
1052 err = fnic_debugfs_init();
1053 if (err < 0) {
1054 printk(KERN_ERR PFX "Failed to create fnic directory "
1055 "for tracing and stats logging\n");
1056 fnic_debugfs_terminate();
1057 }
1058
1059 /* Allocate memory for trace buffer */
1060 err = fnic_trace_buf_init();
1061 if (err < 0) {
1062 printk(KERN_ERR PFX
1063 "Trace buffer initialization Failed. "
1064 "Fnic Tracing utility is disabled\n");
1065 fnic_trace_free();
1066 }
1067
1068 /* Allocate memory for fc trace buffer */
1069 err = fnic_fc_trace_init();
1070 if (err < 0) {
1071 printk(KERN_ERR PFX "FC trace buffer initialization Failed "
1072 "FC frame tracing utility is disabled\n");
1073 fnic_fc_trace_free();
1074 }
1075
1076 /* Create a cache for allocation of default size sgls */
1077 len = sizeof(struct fnic_dflt_sgl_list);
1078 fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
1079 (name: "fnic_sgl_dflt", size: len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN,
1080 SLAB_HWCACHE_ALIGN,
1081 NULL);
1082 if (!fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]) {
1083 printk(KERN_ERR PFX "failed to create fnic dflt sgl slab\n");
1084 err = -ENOMEM;
1085 goto err_create_fnic_sgl_slab_dflt;
1086 }
1087
1088 /* Create a cache for allocation of max size sgls*/
1089 len = sizeof(struct fnic_sgl_list);
1090 fnic_sgl_cache[FNIC_SGL_CACHE_MAX] = kmem_cache_create
1091 (name: "fnic_sgl_max", size: len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN,
1092 SLAB_HWCACHE_ALIGN,
1093 NULL);
1094 if (!fnic_sgl_cache[FNIC_SGL_CACHE_MAX]) {
1095 printk(KERN_ERR PFX "failed to create fnic max sgl slab\n");
1096 err = -ENOMEM;
1097 goto err_create_fnic_sgl_slab_max;
1098 }
1099
1100 /* Create a cache of io_req structs for use via mempool */
1101 fnic_io_req_cache = kmem_cache_create(name: "fnic_io_req",
1102 size: sizeof(struct fnic_io_req),
1103 align: 0, SLAB_HWCACHE_ALIGN, NULL);
1104 if (!fnic_io_req_cache) {
1105 printk(KERN_ERR PFX "failed to create fnic io_req slab\n");
1106 err = -ENOMEM;
1107 goto err_create_fnic_ioreq_slab;
1108 }
1109
1110 fnic_event_queue = create_singlethread_workqueue("fnic_event_wq");
1111 if (!fnic_event_queue) {
1112 printk(KERN_ERR PFX "fnic work queue create failed\n");
1113 err = -ENOMEM;
1114 goto err_create_fnic_workq;
1115 }
1116
1117 fnic_fip_queue = create_singlethread_workqueue("fnic_fip_q");
1118 if (!fnic_fip_queue) {
1119 printk(KERN_ERR PFX "fnic FIP work queue create failed\n");
1120 err = -ENOMEM;
1121 goto err_create_fip_workq;
1122 }
1123
1124 fnic_fc_transport = fc_attach_transport(&fnic_fc_functions);
1125 if (!fnic_fc_transport) {
1126 printk(KERN_ERR PFX "fc_attach_transport error\n");
1127 err = -ENOMEM;
1128 goto err_fc_transport;
1129 }
1130
1131 /* register the driver with PCI system */
1132 err = pci_register_driver(&fnic_driver);
1133 if (err < 0) {
1134 printk(KERN_ERR PFX "pci register error\n");
1135 goto err_pci_register;
1136 }
1137 return err;
1138
1139err_pci_register:
1140 fc_release_transport(fnic_fc_transport);
1141err_fc_transport:
1142 destroy_workqueue(wq: fnic_fip_queue);
1143err_create_fip_workq:
1144 destroy_workqueue(wq: fnic_event_queue);
1145err_create_fnic_workq:
1146 kmem_cache_destroy(s: fnic_io_req_cache);
1147err_create_fnic_ioreq_slab:
1148 kmem_cache_destroy(s: fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
1149err_create_fnic_sgl_slab_max:
1150 kmem_cache_destroy(s: fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
1151err_create_fnic_sgl_slab_dflt:
1152 fnic_trace_free();
1153 fnic_fc_trace_free();
1154 fnic_debugfs_terminate();
1155 return err;
1156}
1157
1158static void __exit fnic_cleanup_module(void)
1159{
1160 pci_unregister_driver(dev: &fnic_driver);
1161 destroy_workqueue(wq: fnic_event_queue);
1162 if (fnic_fip_queue)
1163 destroy_workqueue(wq: fnic_fip_queue);
1164 kmem_cache_destroy(s: fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
1165 kmem_cache_destroy(s: fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
1166 kmem_cache_destroy(s: fnic_io_req_cache);
1167 fc_release_transport(fnic_fc_transport);
1168 fnic_trace_free();
1169 fnic_fc_trace_free();
1170 fnic_debugfs_terminate();
1171}
1172
1173module_init(fnic_init_module);
1174module_exit(fnic_cleanup_module);
1175

source code of linux/drivers/scsi/fnic/fnic_main.c