aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/cxgb3i/cxgb3i_init.c
blob: 042d9bce9914550ad37ba68937195b6fdf4e1dd9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* cxgb3i_init.c: Chelsio S3xx iSCSI driver.
 *
 * Copyright (c) 2008 Chelsio Communications, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Written by: Karen Xie (kxie@chelsio.com)
 */

#include "cxgb3i.h"

#define DRV_MODULE_NAME         "cxgb3i"
#define DRV_MODULE_VERSION	"1.0.2"
#define DRV_MODULE_RELDATE	"Mar. 2009"

static char version[] =
	"Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
	" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";

MODULE_AUTHOR("Karen Xie <kxie@chelsio.com>");
MODULE_DESCRIPTION("Chelsio S3xx iSCSI Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);

static void open_s3_dev(struct t3cdev *);
static void close_s3_dev(struct t3cdev *);
static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error);

static cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS];
static struct cxgb3_client t3c_client = {
	.name = "iscsi_cxgb3",
	.handlers = cxgb3i_cpl_handlers,
	.add = open_s3_dev,
	.remove = close_s3_dev,
	.err_handler = s3_err_handler,
};

/**
 * open_s3_dev - register with cxgb3 LLD
 * @t3dev:	cxgb3 adapter instance
 */
static void open_s3_dev(struct t3cdev *t3dev)
{
	static int vers_printed;

	if (!vers_printed) {
		printk(KERN_INFO "%s", version);
		vers_printed = 1;
	}

	cxgb3i_ddp_init(t3dev);
	cxgb3i_sdev_add(t3dev, &t3c_client);
	cxgb3i_adapter_open(t3dev);
}

/**
 * close_s3_dev - de-register with cxgb3 LLD
 * @t3dev:	cxgb3 adapter instance
 */
static void close_s3_dev(struct t3cdev *t3dev)
{
	cxgb3i_adapter_close(t3dev);
	cxgb3i_sdev_remove(t3dev);
	cxgb3i_ddp_cleanup(t3dev);
}

static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error)
{
	struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(tdev);

	cxgb3i_log_info("snic 0x%p, tdev 0x%p, status 0x%x, err 0x%x.\n",
			snic, tdev, status, error);
	if (!snic)
		return;

	switch (status) {
	case OFFLOAD_STATUS_DOWN:
		snic->flags |= CXGB3I_ADAPTER_FLAG_RESET;
		break;
	case OFFLOAD_STATUS_UP:
		snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
		break;
	}
}

/**
 * cxgb3i_init_module - module init entry point
 *
 * initialize any driver wide global data structures and register itself
 *	with the cxgb3 module
 */
static int __init cxgb3i_init_module(void)
{
	int err;

	err = cxgb3i_sdev_init(cxgb3i_cpl_handlers);
	if (err < 0)
		return err;

	err = cxgb3i_iscsi_init();
	if (err < 0)
		return err;

	err = cxgb3i_pdu_init();
	if (err < 0)
		return err;

	cxgb3_register_client(&t3c_client);

	return 0;
}

/**
 * cxgb3i_exit_module - module cleanup/exit entry point
 *
 * go through the driver hba list and for each hba, release any resource held.
 *	and unregisters iscsi transport and the cxgb3 module
 */
static void __exit cxgb3i_exit_module(void)
{
	cxgb3_unregister_client(&t3c_client);
	cxgb3i_pdu_cleanup();
	cxgb3i_iscsi_cleanup();
	cxgb3i_sdev_cleanup();
}

module_init(cxgb3i_init_module);
module_exit(cxgb3i_exit_module);