~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to ubuntu/iscsitarget/session.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
3
 
 *
4
 
 * Released under the terms of the GNU GPL v2.0.
5
 
 */
6
 
 
7
 
#include "iscsi.h"
8
 
#include "iscsi_dbg.h"
9
 
 
10
 
struct iscsi_session *session_lookup(struct iscsi_target *target, u64 sid)
11
 
{
12
 
        struct iscsi_session *session;
13
 
 
14
 
        list_for_each_entry(session, &target->session_list, list) {
15
 
                if (session->sid == sid)
16
 
                        return session;
17
 
        }
18
 
        return NULL;
19
 
}
20
 
 
21
 
static struct iscsi_session *
22
 
iet_session_alloc(struct iscsi_target *target, struct session_info *info)
23
 
{
24
 
        int i;
25
 
        struct iscsi_session *session;
26
 
        struct iet_volume *vol;
27
 
 
28
 
        dprintk(D_SETUP, "%p %u %#Lx\n", target, target->tid,
29
 
                (unsigned long long) info->sid);
30
 
 
31
 
        session = kzalloc(sizeof(*session), GFP_KERNEL);
32
 
        if (!session)
33
 
                return NULL;
34
 
 
35
 
        session->target = target;
36
 
        session->sid = info->sid;
37
 
        memcpy(&session->param, &target->sess_param, sizeof(session->param));
38
 
        session->max_queued_cmnds = target->trgt_param.queued_cmnds;
39
 
 
40
 
        session->exp_cmd_sn = info->exp_cmd_sn;
41
 
        session->max_cmd_sn = info->max_cmd_sn;
42
 
 
43
 
        session->initiator = kstrdup(info->initiator_name, GFP_KERNEL);
44
 
        if (!session->initiator) {
45
 
                kfree(session);
46
 
                return NULL;
47
 
        }
48
 
 
49
 
        INIT_LIST_HEAD(&session->conn_list);
50
 
        INIT_LIST_HEAD(&session->pending_list);
51
 
 
52
 
        spin_lock_init(&session->cmnd_hash_lock);
53
 
        for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++)
54
 
                INIT_LIST_HEAD(&session->cmnd_hash[i]);
55
 
 
56
 
        spin_lock_init(&session->ua_hash_lock);
57
 
        for (i = 0; i < ARRAY_SIZE(session->ua_hash); i++)
58
 
                INIT_LIST_HEAD(&session->ua_hash[i]);
59
 
 
60
 
        list_for_each_entry(vol, &target->volumes, list)
61
 
                /* power-on, reset, or bus device reset occurred */
62
 
                ua_establish_for_session(session, vol->lun, 0x29, 0x0);
63
 
 
64
 
        session->next_ttt = 1;
65
 
 
66
 
        spin_lock(&target->session_list_lock);
67
 
        list_add(&session->list, &target->session_list);
68
 
        spin_unlock(&target->session_list_lock);
69
 
 
70
 
        return session;
71
 
}
72
 
 
73
 
static int session_free(struct iscsi_session *session)
74
 
{
75
 
        int i;
76
 
        struct ua_entry *ua, *tmp;
77
 
        struct list_head *l;
78
 
        struct iscsi_target *target = session->target;
79
 
 
80
 
        dprintk(D_SETUP, "%#Lx\n", (unsigned long long) session->sid);
81
 
 
82
 
        spin_lock(&target->session_list_lock);
83
 
 
84
 
        assert(list_empty(&session->conn_list));
85
 
 
86
 
        for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) {
87
 
                if (!list_empty(&session->cmnd_hash[i]))
88
 
                        BUG();
89
 
        }
90
 
 
91
 
        for (i = 0; i < ARRAY_SIZE(session->ua_hash); i++) {
92
 
                l = &session->ua_hash[i];
93
 
                list_for_each_entry_safe(ua, tmp, l, entry) {
94
 
                        list_del_init(&ua->entry);
95
 
                        ua_free(ua);
96
 
                }
97
 
        }
98
 
 
99
 
        list_del(&session->list);
100
 
 
101
 
        kfree(session->initiator);
102
 
        kfree(session);
103
 
 
104
 
        spin_unlock(&target->session_list_lock);
105
 
 
106
 
        return 0;
107
 
}
108
 
 
109
 
int session_add(struct iscsi_target *target, struct session_info *info)
110
 
{
111
 
        struct iscsi_session *session;
112
 
 
113
 
        session = session_lookup(target, info->sid);
114
 
        if (session)
115
 
                return -EEXIST;
116
 
 
117
 
        session = iet_session_alloc(target, info);
118
 
        if (!session)
119
 
                return -ENOMEM;
120
 
 
121
 
        return 0;
122
 
}
123
 
 
124
 
int session_del(struct iscsi_target *target, u64 sid)
125
 
{
126
 
        struct iscsi_session *session;
127
 
        struct iet_volume *volume;
128
 
 
129
 
        session = session_lookup(target, sid);
130
 
        if (!session)
131
 
                return -ENOENT;
132
 
 
133
 
        if (!list_empty(&session->conn_list)) {
134
 
                DECLARE_COMPLETION_ONSTACK(done);
135
 
                struct iscsi_conn *conn;
136
 
 
137
 
                session->done = &done;
138
 
                list_for_each_entry(conn, &session->conn_list, list)
139
 
                        conn_close(conn);
140
 
 
141
 
                target_unlock(target);
142
 
                wait_for_completion(&done);
143
 
                target_lock(target, 0);
144
 
        }
145
 
 
146
 
        list_for_each_entry(volume, &target->volumes, list){
147
 
                volume_release(volume, sid, 0);
148
 
        }
149
 
 
150
 
        return session_free(session);
151
 
}
152
 
 
153
 
static void iet_session_info_show(struct seq_file *seq, struct iscsi_target *target)
154
 
{
155
 
        struct iscsi_session *session;
156
 
 
157
 
        list_for_each_entry(session, &target->session_list, list) {
158
 
                seq_printf(seq, "\tsid:%llu initiator:%s\n",
159
 
                           (unsigned long long) session->sid, session->initiator);
160
 
                conn_info_show(seq, session);
161
 
        }
162
 
}
163
 
 
164
 
static int iet_session_seq_open(struct inode *inode, struct file *file)
165
 
{
166
 
        int res;
167
 
        res = seq_open(file, &iet_seq_op);
168
 
        if (!res)
169
 
                ((struct seq_file *)file->private_data)->private =
170
 
                        iet_session_info_show;
171
 
        return res;
172
 
}
173
 
 
174
 
struct file_operations session_seq_fops = {
175
 
        .owner          = THIS_MODULE,
176
 
        .open           = iet_session_seq_open,
177
 
        .read           = seq_read,
178
 
        .llseek         = seq_lseek,
179
 
        .release        = seq_release,
180
 
};