Merge branch 'drm-forlinus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[linux-2.6] / drivers / scsi / scsi_transport_iscsi.c
1 /*
2  * iSCSI transport class definitions
3  *
4  * Copyright (C) IBM Corporation, 2004
5  * Copyright (C) Mike Christie, 2004 - 2005
6  * Copyright (C) Dmitry Yusupov, 2004 - 2005
7  * Copyright (C) Alex Aizman, 2004 - 2005
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23 #include <linux/module.h>
24 #include <linux/string.h>
25 #include <linux/slab.h>
26 #include <linux/mempool.h>
27 #include <net/tcp.h>
28
29 #include <scsi/scsi.h>
30 #include <scsi/scsi_host.h>
31 #include <scsi/scsi_device.h>
32 #include <scsi/scsi_transport.h>
33 #include <scsi/scsi_transport_iscsi.h>
34 #include <scsi/iscsi_if.h>
35
36 #define ISCSI_SESSION_ATTRS 8
37 #define ISCSI_CONN_ATTRS 6
38
39 struct iscsi_internal {
40         struct scsi_transport_template t;
41         struct iscsi_transport *iscsi_transport;
42         struct list_head list;
43         /*
44          * List of sessions for this transport
45          */
46         struct list_head sessions;
47         /*
48          * lock to serialize access to the sessions list which must
49          * be taken after the rx_queue_sema
50          */
51         spinlock_t session_lock;
52         /*
53          * based on transport capabilities, at register time we set these
54          * bits to tell the transport class it wants attributes displayed
55          * in sysfs or that it can support different iSCSI Data-Path
56          * capabilities
57          */
58         uint32_t param_mask;
59
60         struct class_device cdev;
61         /*
62          * We do not have any private or other attrs.
63          */
64         struct transport_container conn_cont;
65         struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
66         struct transport_container session_cont;
67         struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
68 };
69
70 /*
71  * list of registered transports and lock that must
72  * be held while accessing list. The iscsi_transport_lock must
73  * be acquired after the rx_queue_sema.
74  */
75 static LIST_HEAD(iscsi_transports);
76 static DEFINE_SPINLOCK(iscsi_transport_lock);
77
78 #define to_iscsi_internal(tmpl) \
79         container_of(tmpl, struct iscsi_internal, t)
80
81 #define cdev_to_iscsi_internal(_cdev) \
82         container_of(_cdev, struct iscsi_internal, cdev)
83
84 static void iscsi_transport_release(struct class_device *cdev)
85 {
86         struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
87         kfree(priv);
88 }
89
90 /*
91  * iscsi_transport_class represents the iscsi_transports that are
92  * registered.
93  */
94 static struct class iscsi_transport_class = {
95         .name = "iscsi_transport",
96         .release = iscsi_transport_release,
97 };
98
99 static ssize_t
100 show_transport_handle(struct class_device *cdev, char *buf)
101 {
102         struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
103         return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
104 }
105 static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
106
107 #define show_transport_attr(name, format)                               \
108 static ssize_t                                                          \
109 show_transport_##name(struct class_device *cdev, char *buf)             \
110 {                                                                       \
111         struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);     \
112         return sprintf(buf, format"\n", priv->iscsi_transport->name);   \
113 }                                                                       \
114 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
115
116 show_transport_attr(caps, "0x%x");
117 show_transport_attr(max_lun, "%d");
118 show_transport_attr(max_conn, "%d");
119 show_transport_attr(max_cmd_len, "%d");
120
121 static struct attribute *iscsi_transport_attrs[] = {
122         &class_device_attr_handle.attr,
123         &class_device_attr_caps.attr,
124         &class_device_attr_max_lun.attr,
125         &class_device_attr_max_conn.attr,
126         &class_device_attr_max_cmd_len.attr,
127         NULL,
128 };
129
130 static struct attribute_group iscsi_transport_group = {
131         .attrs = iscsi_transport_attrs,
132 };
133
134 static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
135                                "iscsi_session",
136                                NULL,
137                                NULL,
138                                NULL);
139
140 static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
141                                "iscsi_connection",
142                                NULL,
143                                NULL,
144                                NULL);
145
146 static struct sock *nls;
147 static int daemon_pid;
148 static DECLARE_MUTEX(rx_queue_sema);
149
150 struct mempool_zone {
151         mempool_t *pool;
152         atomic_t allocated;
153         int size;
154         int hiwat;
155         struct list_head freequeue;
156         spinlock_t freelock;
157 };
158
159 static struct mempool_zone z_reply;
160
161 /*
162  * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
163  * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
164  *             so daemon will notice OOM on NETLINK tranposrt level and will
165  *             be able to predict or change operational behavior
166  */
167 #define Z_MAX_REPLY     8
168 #define Z_HIWAT_REPLY   6
169 #define Z_MAX_PDU       8
170 #define Z_HIWAT_PDU     6
171 #define Z_MAX_ERROR     16
172 #define Z_HIWAT_ERROR   12
173
174 struct iscsi_if_conn {
175         struct list_head conn_list;     /* item in connlist */
176         struct list_head session_list;  /* item in session->connections */
177         iscsi_connh_t connh;
178         int active;                     /* must be accessed with the connlock */
179         struct Scsi_Host *host;         /* originated shost */
180         struct device dev;              /* sysfs transport/container device */
181         struct iscsi_transport *transport;
182         struct mempool_zone z_error;
183         struct mempool_zone z_pdu;
184         struct list_head freequeue;
185 };
186
187 #define iscsi_dev_to_if_conn(_dev) \
188         container_of(_dev, struct iscsi_if_conn, dev)
189
190 #define iscsi_cdev_to_if_conn(_cdev) \
191         iscsi_dev_to_if_conn(_cdev->dev)
192
193 static LIST_HEAD(connlist);
194 static DEFINE_SPINLOCK(connlock);
195
196 struct iscsi_if_session {
197         struct list_head list;  /* item in session_list */
198         struct list_head connections;
199         iscsi_sessionh_t sessionh;
200         struct iscsi_transport *transport;
201         struct device dev;      /* sysfs transport/container device */
202 };
203
204 #define iscsi_dev_to_if_session(_dev) \
205         container_of(_dev, struct iscsi_if_session, dev)
206
207 #define iscsi_cdev_to_if_session(_cdev) \
208         iscsi_dev_to_if_session(_cdev->dev)
209
210 #define iscsi_if_session_to_shost(_session) \
211         dev_to_shost(_session->dev.parent)
212
213 static struct iscsi_if_conn*
214 iscsi_if_find_conn(uint64_t key)
215 {
216         unsigned long flags;
217         struct iscsi_if_conn *conn;
218
219         spin_lock_irqsave(&connlock, flags);
220         list_for_each_entry(conn, &connlist, conn_list)
221                 if (conn->connh == key) {
222                         spin_unlock_irqrestore(&connlock, flags);
223                         return conn;
224                 }
225         spin_unlock_irqrestore(&connlock, flags);
226         return NULL;
227 }
228
229 static struct iscsi_internal *
230 iscsi_if_transport_lookup(struct iscsi_transport *tt)
231 {
232         struct iscsi_internal *priv;
233         unsigned long flags;
234
235         spin_lock_irqsave(&iscsi_transport_lock, flags);
236         list_for_each_entry(priv, &iscsi_transports, list) {
237                 if (tt == priv->iscsi_transport) {
238                         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
239                         return priv;
240                 }
241         }
242         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
243         return NULL;
244 }
245
246 static inline struct list_head *skb_to_lh(struct sk_buff *skb)
247 {
248         return (struct list_head *)&skb->cb;
249 }
250
251 static void*
252 mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
253 {
254         struct mempool_zone *zone = pool_data;
255
256         return alloc_skb(zone->size, gfp_mask);
257 }
258
259 static void
260 mempool_zone_free_skb(void *element, void *pool_data)
261 {
262         kfree_skb(element);
263 }
264
265 static void
266 mempool_zone_complete(struct mempool_zone *zone)
267 {
268         unsigned long flags;
269         struct list_head *lh, *n;
270
271         spin_lock_irqsave(&zone->freelock, flags);
272         list_for_each_safe(lh, n, &zone->freequeue) {
273                 struct sk_buff *skb = (struct sk_buff *)((char *)lh -
274                                 offsetof(struct sk_buff, cb));
275                 if (!skb_shared(skb)) {
276                         list_del(skb_to_lh(skb));
277                         mempool_free(skb, zone->pool);
278                         atomic_dec(&zone->allocated);
279                 }
280         }
281         spin_unlock_irqrestore(&zone->freelock, flags);
282 }
283
284 static int
285 mempool_zone_init(struct mempool_zone *zp, unsigned max, unsigned size,
286                 unsigned hiwat)
287 {
288         zp->pool = mempool_create(max, mempool_zone_alloc_skb,
289                                   mempool_zone_free_skb, zp);
290         if (!zp->pool)
291                 return -ENOMEM;
292
293         zp->size = size;
294         zp->hiwat = hiwat;
295
296         INIT_LIST_HEAD(&zp->freequeue);
297         spin_lock_init(&zp->freelock);
298         atomic_set(&zp->allocated, 0);
299
300         return 0;
301 }
302
303
304 static struct sk_buff*
305 mempool_zone_get_skb(struct mempool_zone *zone)
306 {
307         struct sk_buff *skb;
308
309         skb = mempool_alloc(zone->pool, GFP_ATOMIC);
310         if (skb)
311                 atomic_inc(&zone->allocated);
312         return skb;
313 }
314
315 static int
316 iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
317 {
318         unsigned long flags;
319         int rc;
320
321         skb_get(skb);
322         rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT);
323         if (rc < 0) {
324                 mempool_free(skb, zone->pool);
325                 printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
326                 return rc;
327         }
328
329         spin_lock_irqsave(&zone->freelock, flags);
330         list_add(skb_to_lh(skb), &zone->freequeue);
331         spin_unlock_irqrestore(&zone->freelock, flags);
332
333         return 0;
334 }
335
336 int iscsi_recv_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr,
337                    char *data, uint32_t data_size)
338 {
339         struct nlmsghdr *nlh;
340         struct sk_buff *skb;
341         struct iscsi_uevent *ev;
342         struct iscsi_if_conn *conn;
343         char *pdu;
344         int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
345                               data_size);
346
347         conn = iscsi_if_find_conn(connh);
348         BUG_ON(!conn);
349
350         mempool_zone_complete(&conn->z_pdu);
351
352         skb = mempool_zone_get_skb(&conn->z_pdu);
353         if (!skb) {
354                 iscsi_conn_error(connh, ISCSI_ERR_CONN_FAILED);
355                 printk(KERN_ERR "iscsi%d: can not deliver control PDU: OOM\n",
356                        conn->host->host_no);
357                 return -ENOMEM;
358         }
359
360         nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
361         ev = NLMSG_DATA(nlh);
362         memset(ev, 0, sizeof(*ev));
363         ev->transport_handle = iscsi_handle(conn->transport);
364         ev->type = ISCSI_KEVENT_RECV_PDU;
365         if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)
366                 ev->iferror = -ENOMEM;
367         ev->r.recv_req.conn_handle = connh;
368         pdu = (char*)ev + sizeof(*ev);
369         memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
370         memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
371
372         return iscsi_unicast_skb(&conn->z_pdu, skb);
373 }
374 EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
375
376 void iscsi_conn_error(iscsi_connh_t connh, enum iscsi_err error)
377 {
378         struct nlmsghdr *nlh;
379         struct sk_buff  *skb;
380         struct iscsi_uevent *ev;
381         struct iscsi_if_conn *conn;
382         int len = NLMSG_SPACE(sizeof(*ev));
383
384         conn = iscsi_if_find_conn(connh);
385         BUG_ON(!conn);
386
387         mempool_zone_complete(&conn->z_error);
388
389         skb = mempool_zone_get_skb(&conn->z_error);
390         if (!skb) {
391                 printk(KERN_ERR "iscsi%d: gracefully ignored conn error (%d)\n",
392                        conn->host->host_no, error);
393                 return;
394         }
395
396         nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
397         ev = NLMSG_DATA(nlh);
398         ev->transport_handle = iscsi_handle(conn->transport);
399         ev->type = ISCSI_KEVENT_CONN_ERROR;
400         if (atomic_read(&conn->z_error.allocated) >= conn->z_error.hiwat)
401                 ev->iferror = -ENOMEM;
402         ev->r.connerror.error = error;
403         ev->r.connerror.conn_handle = connh;
404
405         iscsi_unicast_skb(&conn->z_error, skb);
406
407         printk(KERN_INFO "iscsi%d: detected conn error (%d)\n",
408                conn->host->host_no, error);
409 }
410 EXPORT_SYMBOL_GPL(iscsi_conn_error);
411
412 static int
413 iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
414                       void *payload, int size)
415 {
416         struct sk_buff  *skb;
417         struct nlmsghdr *nlh;
418         int len = NLMSG_SPACE(size);
419         int flags = multi ? NLM_F_MULTI : 0;
420         int t = done ? NLMSG_DONE : type;
421
422         mempool_zone_complete(&z_reply);
423
424         skb = mempool_zone_get_skb(&z_reply);
425         /*
426          * FIXME:
427          * user is supposed to react on iferror == -ENOMEM;
428          * see iscsi_if_rx().
429          */
430         BUG_ON(!skb);
431
432         nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
433         nlh->nlmsg_flags = flags;
434         memcpy(NLMSG_DATA(nlh), payload, size);
435         return iscsi_unicast_skb(&z_reply, skb);
436 }
437
438 /*
439  * iSCSI Session's hostdata organization:
440  *
441  *    *------------------* <== host->hostdata
442  *    | transport        |
443  *    |------------------| <== iscsi_hostdata(host->hostdata)
444  *    | transport's data |
445  *    |------------------| <== hostdata_session(host->hostdata)
446  *    | interface's data |
447  *    *------------------*
448  */
449
450 #define hostdata_privsize(_t)   (sizeof(unsigned long) + _t->hostdata_size + \
451                                  _t->hostdata_size % sizeof(unsigned long) + \
452                                  sizeof(struct iscsi_if_session))
453
454 #define hostdata_session(_hostdata) ((void*)_hostdata + sizeof(unsigned long) + \
455                         ((struct iscsi_transport *) \
456                          iscsi_ptr(*(uint64_t *)_hostdata))->hostdata_size)
457
458 static void iscsi_if_session_dev_release(struct device *dev)
459 {
460         struct iscsi_if_session *session = iscsi_dev_to_if_session(dev);
461         struct iscsi_transport *transport = session->transport;
462         struct Scsi_Host *shost = iscsi_if_session_to_shost(session);
463         struct iscsi_if_conn *conn, *tmp;
464         unsigned long flags;
465
466         /* now free connections */
467         spin_lock_irqsave(&connlock, flags);
468         list_for_each_entry_safe(conn, tmp, &session->connections,
469                                  session_list) {
470                 list_del(&conn->session_list);
471                 mempool_destroy(conn->z_pdu.pool);
472                 mempool_destroy(conn->z_error.pool);
473                 kfree(conn);
474         }
475         spin_unlock_irqrestore(&connlock, flags);
476         scsi_host_put(shost);
477         module_put(transport->owner);
478 }
479
480 static int
481 iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
482 {
483         struct iscsi_transport *transport = priv->iscsi_transport;
484         struct iscsi_if_session *session;
485         struct Scsi_Host *shost;
486         unsigned long flags;
487         int error;
488
489         if (!try_module_get(transport->owner))
490                 return -EPERM;
491
492         shost = scsi_host_alloc(transport->host_template,
493                                 hostdata_privsize(transport));
494         if (!shost) {
495                 ev->r.c_session_ret.session_handle = iscsi_handle(NULL);
496                 printk(KERN_ERR "iscsi: can not allocate SCSI host for "
497                        "session\n");
498                 error = -ENOMEM;
499                 goto out_module_put;
500         }
501         shost->max_id = 1;
502         shost->max_channel = 0;
503         shost->max_lun = transport->max_lun;
504         shost->max_cmd_len = transport->max_cmd_len;
505         shost->transportt = &priv->t;
506
507         /* store struct iscsi_transport in hostdata */
508         *(uint64_t*)shost->hostdata = ev->transport_handle;
509
510         ev->r.c_session_ret.session_handle = transport->create_session(
511                                         ev->u.c_session.initial_cmdsn, shost);
512         if (ev->r.c_session_ret.session_handle == iscsi_handle(NULL)) {
513                 error = 0;
514                 goto out_host_put;
515         }
516
517         /* host_no becomes assigned SID */
518         ev->r.c_session_ret.sid = shost->host_no;
519         /* initialize session */
520         session = hostdata_session(shost->hostdata);
521         INIT_LIST_HEAD(&session->connections);
522         INIT_LIST_HEAD(&session->list);
523         session->sessionh = ev->r.c_session_ret.session_handle;
524         session->transport = transport;
525
526         error = scsi_add_host(shost, NULL);
527         if (error)
528                 goto out_destroy_session;
529
530         /*
531          * this is released in the dev's release function)
532          */
533         scsi_host_get(shost);
534         snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no);
535         session->dev.parent = &shost->shost_gendev;
536         session->dev.release = iscsi_if_session_dev_release;
537         error = device_register(&session->dev);
538         if (error) {
539                 printk(KERN_ERR "iscsi: could not register session%d's dev\n",
540                        shost->host_no);
541                 goto out_remove_host;
542         }
543         transport_register_device(&session->dev);
544
545         /* add this session to the list of active sessions */
546         spin_lock_irqsave(&priv->session_lock, flags);
547         list_add(&session->list, &priv->sessions);
548         spin_unlock_irqrestore(&priv->session_lock, flags);
549
550         return 0;
551
552 out_remove_host:
553         scsi_remove_host(shost);
554 out_destroy_session:
555         transport->destroy_session(ev->r.c_session_ret.session_handle);
556         ev->r.c_session_ret.session_handle = iscsi_handle(NULL);
557 out_host_put:
558         scsi_host_put(shost);
559 out_module_put:
560         module_put(transport->owner);
561         return error;
562 }
563
564 static int
565 iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
566 {
567         struct iscsi_transport *transport = priv->iscsi_transport;
568         struct Scsi_Host *shost;
569         struct iscsi_if_session *session;
570         unsigned long flags;
571         struct iscsi_if_conn *conn;
572         int error = 0;
573
574         shost = scsi_host_lookup(ev->u.d_session.sid);
575         if (shost == ERR_PTR(-ENXIO))
576                 return -EEXIST;
577         session = hostdata_session(shost->hostdata);
578
579         /* check if we have active connections */
580         spin_lock_irqsave(&connlock, flags);
581         list_for_each_entry(conn, &session->connections, session_list) {
582                 if (conn->active) {
583                         printk(KERN_ERR "iscsi%d: can not destroy session: "
584                                "has active connection (%p)\n",
585                                shost->host_no, iscsi_ptr(conn->connh));
586                         spin_unlock_irqrestore(&connlock, flags);
587                         error = EIO;
588                         goto out_release_ref;
589                 }
590         }
591         spin_unlock_irqrestore(&connlock, flags);
592
593         scsi_remove_host(shost);
594         transport->destroy_session(ev->u.d_session.session_handle);
595         transport_unregister_device(&session->dev);
596         device_unregister(&session->dev);
597
598         /* remove this session from the list of active sessions */
599         spin_lock_irqsave(&priv->session_lock, flags);
600         list_del(&session->list);
601         spin_unlock_irqrestore(&priv->session_lock, flags);
602
603         /* ref from host alloc */
604         scsi_host_put(shost);
605 out_release_ref:
606         /* ref from host lookup */
607         scsi_host_put(shost);
608         return error;
609 }
610
611 static void iscsi_if_conn_dev_release(struct device *dev)
612 {
613         struct iscsi_if_conn *conn = iscsi_dev_to_if_conn(dev);
614         struct Scsi_Host *shost = conn->host;
615
616         scsi_host_put(shost);
617 }
618
619 static int
620 iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
621 {
622         struct iscsi_if_session *session;
623         struct Scsi_Host *shost;
624         struct iscsi_if_conn *conn;
625         unsigned long flags;
626         int error;
627
628         shost = scsi_host_lookup(ev->u.c_conn.sid);
629         if (shost == ERR_PTR(-ENXIO))
630                 return -EEXIST;
631         session = hostdata_session(shost->hostdata);
632
633         conn = kmalloc(sizeof(struct iscsi_if_conn), GFP_KERNEL);
634         if (!conn) {
635                 error = -ENOMEM;
636                 goto out_release_ref;
637         }
638         memset(conn, 0, sizeof(struct iscsi_if_conn));
639         INIT_LIST_HEAD(&conn->session_list);
640         INIT_LIST_HEAD(&conn->conn_list);
641         conn->host = shost;
642         conn->transport = transport;
643
644         error = mempool_zone_init(&conn->z_pdu, Z_MAX_PDU,
645                         NLMSG_SPACE(sizeof(struct iscsi_uevent) +
646                                     sizeof(struct iscsi_hdr) +
647                                     DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
648                         Z_HIWAT_PDU);
649         if (error) {
650                 printk(KERN_ERR "iscsi%d: can not allocate pdu zone for new "
651                        "conn\n", shost->host_no);
652                 goto out_free_conn;
653         }
654         error = mempool_zone_init(&conn->z_error, Z_MAX_ERROR,
655                         NLMSG_SPACE(sizeof(struct iscsi_uevent)),
656                         Z_HIWAT_ERROR);
657         if (error) {
658                 printk(KERN_ERR "iscsi%d: can not allocate error zone for "
659                        "new conn\n", shost->host_no);
660                 goto out_free_pdu_pool;
661         }
662
663         ev->r.handle = transport->create_conn(ev->u.c_conn.session_handle,
664                                         ev->u.c_conn.cid);
665         if (!ev->r.handle) {
666                 error = -ENODEV;
667                 goto out_free_error_pool;
668         }
669
670         conn->connh = ev->r.handle;
671
672         /*
673          * this is released in the dev's release function
674          */
675         if (!scsi_host_get(shost))
676                 goto out_destroy_conn;
677         snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
678                  shost->host_no, ev->u.c_conn.cid);
679         conn->dev.parent = &session->dev;
680         conn->dev.release = iscsi_if_conn_dev_release;
681         error = device_register(&conn->dev);
682         if (error) {
683                 printk(KERN_ERR "iscsi%d: could not register connections%u "
684                        "dev\n", shost->host_no, ev->u.c_conn.cid);
685                 goto out_release_parent_ref;
686         }
687         transport_register_device(&conn->dev);
688
689         spin_lock_irqsave(&connlock, flags);
690         list_add(&conn->conn_list, &connlist);
691         list_add(&conn->session_list, &session->connections);
692         conn->active = 1;
693         spin_unlock_irqrestore(&connlock, flags);
694
695         scsi_host_put(shost);
696         return 0;
697
698 out_release_parent_ref:
699         scsi_host_put(shost);
700 out_destroy_conn:
701         transport->destroy_conn(ev->r.handle);
702 out_free_error_pool:
703         mempool_destroy(conn->z_error.pool);
704 out_free_pdu_pool:
705         mempool_destroy(conn->z_pdu.pool);
706 out_free_conn:
707         kfree(conn);
708 out_release_ref:
709         scsi_host_put(shost);
710         return error;
711 }
712
713 static int
714 iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
715 {
716         unsigned long flags;
717         struct iscsi_if_conn *conn;
718
719         conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle);
720         if (!conn)
721                 return -EEXIST;
722
723         transport->destroy_conn(ev->u.d_conn.conn_handle);
724
725         spin_lock_irqsave(&connlock, flags);
726         conn->active = 0;
727         list_del(&conn->conn_list);
728         spin_unlock_irqrestore(&connlock, flags);
729
730         transport_unregister_device(&conn->dev);
731         device_unregister(&conn->dev);
732         return 0;
733 }
734
735 static int
736 iscsi_if_get_stats(struct iscsi_transport *transport, struct sk_buff *skb,
737                    struct nlmsghdr *nlh)
738 {
739         struct iscsi_uevent *ev = NLMSG_DATA(nlh);
740         struct iscsi_stats *stats;
741         struct sk_buff *skbstat;
742         struct iscsi_if_conn *conn;
743         struct nlmsghdr *nlhstat;
744         struct iscsi_uevent *evstat;
745         int len = NLMSG_SPACE(sizeof(*ev) +
746                               sizeof(struct iscsi_stats) +
747                               sizeof(struct iscsi_stats_custom) *
748                               ISCSI_STATS_CUSTOM_MAX);
749         int err = 0;
750
751         conn = iscsi_if_find_conn(ev->u.get_stats.conn_handle);
752         if (!conn)
753                 return -EEXIST;
754
755         do {
756                 int actual_size;
757
758                 mempool_zone_complete(&conn->z_pdu);
759
760                 skbstat = mempool_zone_get_skb(&conn->z_pdu);
761                 if (!skbstat) {
762                         printk(KERN_ERR "iscsi%d: can not deliver stats: OOM\n",
763                                conn->host->host_no);
764                         return -ENOMEM;
765                 }
766
767                 nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0,
768                                       (len - sizeof(*nlhstat)), 0);
769                 evstat = NLMSG_DATA(nlhstat);
770                 memset(evstat, 0, sizeof(*evstat));
771                 evstat->transport_handle = iscsi_handle(conn->transport);
772                 evstat->type = nlh->nlmsg_type;
773                 if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)
774                         evstat->iferror = -ENOMEM;
775                 evstat->u.get_stats.conn_handle =
776                         ev->u.get_stats.conn_handle;
777                 stats = (struct iscsi_stats *)
778                         ((char*)evstat + sizeof(*evstat));
779                 memset(stats, 0, sizeof(*stats));
780
781                 transport->get_stats(ev->u.get_stats.conn_handle, stats);
782                 actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) +
783                                           sizeof(struct iscsi_stats) +
784                                           sizeof(struct iscsi_stats_custom) *
785                                           stats->custom_length);
786                 actual_size -= sizeof(*nlhstat);
787                 actual_size = NLMSG_LENGTH(actual_size);
788                 skb_trim(skb, NLMSG_ALIGN(actual_size));
789                 nlhstat->nlmsg_len = actual_size;
790
791                 err = iscsi_unicast_skb(&conn->z_pdu, skbstat);
792         } while (err < 0 && err != -ECONNREFUSED);
793
794         return err;
795 }
796
797 static int
798 iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
799 {
800         int err = 0;
801         struct iscsi_uevent *ev = NLMSG_DATA(nlh);
802         struct iscsi_transport *transport = NULL;
803         struct iscsi_internal *priv;
804
805         if (NETLINK_CREDS(skb)->uid)
806                 return -EPERM;
807
808         priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
809         if (!priv)
810                 return -EINVAL;
811         transport = priv->iscsi_transport;
812
813         daemon_pid = NETLINK_CREDS(skb)->pid;
814
815         switch (nlh->nlmsg_type) {
816         case ISCSI_UEVENT_CREATE_SESSION:
817                 err = iscsi_if_create_session(priv, ev);
818                 break;
819         case ISCSI_UEVENT_DESTROY_SESSION:
820                 err = iscsi_if_destroy_session(priv, ev);
821                 break;
822         case ISCSI_UEVENT_CREATE_CONN:
823                 err = iscsi_if_create_conn(transport, ev);
824                 break;
825         case ISCSI_UEVENT_DESTROY_CONN:
826                 err = iscsi_if_destroy_conn(transport, ev);
827                 break;
828         case ISCSI_UEVENT_BIND_CONN:
829                 if (!iscsi_if_find_conn(ev->u.b_conn.conn_handle))
830                         return -EEXIST;
831                 ev->r.retcode = transport->bind_conn(
832                         ev->u.b_conn.session_handle,
833                         ev->u.b_conn.conn_handle,
834                         ev->u.b_conn.transport_fd,
835                         ev->u.b_conn.is_leading);
836                 break;
837         case ISCSI_UEVENT_SET_PARAM:
838                 if (!iscsi_if_find_conn(ev->u.set_param.conn_handle))
839                         return -EEXIST;
840                 ev->r.retcode = transport->set_param(
841                         ev->u.set_param.conn_handle,
842                         ev->u.set_param.param, ev->u.set_param.value);
843                 break;
844         case ISCSI_UEVENT_START_CONN:
845                 if (!iscsi_if_find_conn(ev->u.start_conn.conn_handle))
846                         return -EEXIST;
847                 ev->r.retcode = transport->start_conn(
848                         ev->u.start_conn.conn_handle);
849                 break;
850         case ISCSI_UEVENT_STOP_CONN:
851                 if (!iscsi_if_find_conn(ev->u.stop_conn.conn_handle))
852                         return -EEXIST;
853                 transport->stop_conn(ev->u.stop_conn.conn_handle,
854                         ev->u.stop_conn.flag);
855                 break;
856         case ISCSI_UEVENT_SEND_PDU:
857                 if (!iscsi_if_find_conn(ev->u.send_pdu.conn_handle))
858                         return -EEXIST;
859                 ev->r.retcode = transport->send_pdu(
860                        ev->u.send_pdu.conn_handle,
861                        (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
862                        (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
863                         ev->u.send_pdu.data_size);
864                 break;
865         case ISCSI_UEVENT_GET_STATS:
866                 err = iscsi_if_get_stats(transport, skb, nlh);
867                 break;
868         default:
869                 err = -EINVAL;
870                 break;
871         }
872
873         return err;
874 }
875
876 /* Get message from skb (based on rtnetlink_rcv_skb).  Each message is
877  * processed by iscsi_if_recv_msg.  Malformed skbs with wrong length are
878  * discarded silently.  */
879 static void
880 iscsi_if_rx(struct sock *sk, int len)
881 {
882         struct sk_buff *skb;
883
884         down(&rx_queue_sema);
885         while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
886                 while (skb->len >= NLMSG_SPACE(0)) {
887                         int err;
888                         uint32_t rlen;
889                         struct nlmsghdr *nlh;
890                         struct iscsi_uevent *ev;
891
892                         nlh = (struct nlmsghdr *)skb->data;
893                         if (nlh->nlmsg_len < sizeof(*nlh) ||
894                             skb->len < nlh->nlmsg_len) {
895                                 break;
896                         }
897                         ev = NLMSG_DATA(nlh);
898                         rlen = NLMSG_ALIGN(nlh->nlmsg_len);
899                         if (rlen > skb->len)
900                                 rlen = skb->len;
901                         err = iscsi_if_recv_msg(skb, nlh);
902                         if (err) {
903                                 ev->type = ISCSI_KEVENT_IF_ERROR;
904                                 ev->iferror = err;
905                         }
906                         do {
907                                 /*
908                                  * special case for GET_STATS:
909                                  * on success - sending reply and stats from
910                                  * inside of if_recv_msg(),
911                                  * on error - fall through.
912                                  */
913                                 if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
914                                         break;
915                                 err = iscsi_if_send_reply(
916                                         NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
917                                         nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
918                                 if (atomic_read(&z_reply.allocated) >=
919                                                 z_reply.hiwat)
920                                         ev->iferror = -ENOMEM;
921                         } while (err < 0 && err != -ECONNREFUSED);
922                         skb_pull(skb, rlen);
923                 }
924                 kfree_skb(skb);
925         }
926         up(&rx_queue_sema);
927 }
928
929 /*
930  * iSCSI connection attrs
931  */
932 #define iscsi_conn_int_attr_show(param, format)                         \
933 static ssize_t                                                          \
934 show_conn_int_param_##param(struct class_device *cdev, char *buf)       \
935 {                                                                       \
936         uint32_t value = 0;                                             \
937         struct iscsi_if_conn *conn = iscsi_cdev_to_if_conn(cdev);       \
938         struct iscsi_internal *priv;                                    \
939                                                                         \
940         priv = to_iscsi_internal(conn->host->transportt);               \
941         if (priv->param_mask & (1 << param))                            \
942                 priv->iscsi_transport->get_param(conn->connh, param, &value); \
943         return snprintf(buf, 20, format"\n", value);                    \
944 }
945
946 #define iscsi_conn_int_attr(field, param, format)                       \
947         iscsi_conn_int_attr_show(param, format)                         \
948 static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL);
949
950 iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u");
951 iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u");
952 iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d");
953 iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d");
954 iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
955 iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
956
957 /*
958  * iSCSI session attrs
959  */
960 #define iscsi_session_int_attr_show(param, format)                      \
961 static ssize_t                                                          \
962 show_session_int_param_##param(struct class_device *cdev, char *buf)    \
963 {                                                                       \
964         uint32_t value = 0;                                             \
965         struct iscsi_if_session *session = iscsi_cdev_to_if_session(cdev); \
966         struct Scsi_Host *shost = iscsi_if_session_to_shost(session);   \
967         struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
968         struct iscsi_if_conn *conn = NULL;                              \
969         unsigned long  flags;                                           \
970                                                                         \
971         spin_lock_irqsave(&connlock, flags);                            \
972         if (!list_empty(&session->connections))                         \
973                 conn = list_entry(session->connections.next,            \
974                                   struct iscsi_if_conn, session_list);  \
975         spin_unlock_irqrestore(&connlock, flags);                       \
976                                                                         \
977         if (conn && (priv->param_mask & (1 << param)))                  \
978                 priv->iscsi_transport->get_param(conn->connh, param, &value);\
979         return snprintf(buf, 20, format"\n", value);                    \
980 }
981
982 #define iscsi_session_int_attr(field, param, format)                    \
983         iscsi_session_int_attr_show(param, format)                      \
984 static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL);
985
986 iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d");
987 iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu");
988 iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d");
989 iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u");
990 iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u");
991 iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
992 iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
993 iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
994
995 #define SETUP_SESSION_RD_ATTR(field, param)                             \
996         if (priv->param_mask & (1 << param)) {                          \
997                 priv->session_attrs[count] = &class_device_attr_##field;\
998                 count++;                                                \
999         }
1000
1001 #define SETUP_CONN_RD_ATTR(field, param)                                \
1002         if (priv->param_mask & (1 << param)) {                          \
1003                 priv->conn_attrs[count] = &class_device_attr_##field;   \
1004                 count++;                                                \
1005         }
1006
1007 static int iscsi_is_session_dev(const struct device *dev)
1008 {
1009         return dev->release == iscsi_if_session_dev_release;
1010 }
1011
1012 static int iscsi_session_match(struct attribute_container *cont,
1013                            struct device *dev)
1014 {
1015         struct iscsi_if_session *session;
1016         struct Scsi_Host *shost;
1017         struct iscsi_internal *priv;
1018
1019         if (!iscsi_is_session_dev(dev))
1020                 return 0;
1021
1022         session = iscsi_dev_to_if_session(dev);
1023         shost = iscsi_if_session_to_shost(session);
1024         if (!shost->transportt)
1025                 return 0;
1026
1027         priv = to_iscsi_internal(shost->transportt);
1028         if (priv->session_cont.ac.class != &iscsi_session_class.class)
1029                 return 0;
1030
1031         return &priv->session_cont.ac == cont;
1032 }
1033
1034 static int iscsi_is_conn_dev(const struct device *dev)
1035 {
1036         return dev->release == iscsi_if_conn_dev_release;
1037 }
1038
1039 static int iscsi_conn_match(struct attribute_container *cont,
1040                            struct device *dev)
1041 {
1042         struct iscsi_if_conn *conn;
1043         struct Scsi_Host *shost;
1044         struct iscsi_internal *priv;
1045
1046         if (!iscsi_is_conn_dev(dev))
1047                 return 0;
1048
1049         conn = iscsi_dev_to_if_conn(dev);
1050         shost = conn->host;
1051         if (!shost->transportt)
1052                 return 0;
1053
1054         priv = to_iscsi_internal(shost->transportt);
1055         if (priv->conn_cont.ac.class != &iscsi_connection_class.class)
1056                 return 0;
1057
1058         return &priv->conn_cont.ac == cont;
1059 }
1060
1061 int iscsi_register_transport(struct iscsi_transport *tt)
1062 {
1063         struct iscsi_internal *priv;
1064         unsigned long flags;
1065         int count = 0, err;
1066
1067         BUG_ON(!tt);
1068
1069         priv = iscsi_if_transport_lookup(tt);
1070         if (priv)
1071                 return -EEXIST;
1072
1073         priv = kmalloc(sizeof(*priv), GFP_KERNEL);
1074         if (!priv)
1075                 return -ENOMEM;
1076         memset(priv, 0, sizeof(*priv));
1077         INIT_LIST_HEAD(&priv->list);
1078         INIT_LIST_HEAD(&priv->sessions);
1079         spin_lock_init(&priv->session_lock);
1080         priv->iscsi_transport = tt;
1081
1082         priv->cdev.class = &iscsi_transport_class;
1083         snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
1084         err = class_device_register(&priv->cdev);
1085         if (err)
1086                 goto free_priv;
1087
1088         err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
1089         if (err)
1090                 goto unregister_cdev;
1091
1092         /* setup parameters mask */
1093         priv->param_mask = 0xFFFFFFFF;
1094         if (!(tt->caps & CAP_MULTI_R2T))
1095                 priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T);
1096         if (!(tt->caps & CAP_HDRDGST))
1097                 priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN);
1098         if (!(tt->caps & CAP_DATADGST))
1099                 priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN);
1100         if (!(tt->caps & CAP_MARKERS)) {
1101                 priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN);
1102                 priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN);
1103         }
1104
1105         /* connection parameters */
1106         priv->conn_cont.ac.attrs = &priv->conn_attrs[0];
1107         priv->conn_cont.ac.class = &iscsi_connection_class.class;
1108         priv->conn_cont.ac.match = iscsi_conn_match;
1109         transport_container_register(&priv->conn_cont);
1110
1111         SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
1112         SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
1113         SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN);
1114         SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN);
1115         SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN);
1116         SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN);
1117
1118         BUG_ON(count > ISCSI_CONN_ATTRS);
1119         priv->conn_attrs[count] = NULL;
1120         count = 0;
1121
1122         /* session parameters */
1123         priv->session_cont.ac.attrs = &priv->session_attrs[0];
1124         priv->session_cont.ac.class = &iscsi_session_class.class;
1125         priv->session_cont.ac.match = iscsi_session_match;
1126         transport_container_register(&priv->session_cont);
1127
1128         SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN);
1129         SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T);
1130         SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN);
1131         SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST);
1132         SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST);
1133         SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN);
1134         SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN)
1135         SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL);
1136
1137         BUG_ON(count > ISCSI_SESSION_ATTRS);
1138         priv->session_attrs[count] = NULL;
1139
1140         spin_lock_irqsave(&iscsi_transport_lock, flags);
1141         list_add(&priv->list, &iscsi_transports);
1142         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
1143
1144         printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
1145         return 0;
1146
1147 unregister_cdev:
1148         class_device_unregister(&priv->cdev);
1149 free_priv:
1150         kfree(priv);
1151         return err;
1152 }
1153 EXPORT_SYMBOL_GPL(iscsi_register_transport);
1154
1155 int iscsi_unregister_transport(struct iscsi_transport *tt)
1156 {
1157         struct iscsi_internal *priv;
1158         unsigned long flags;
1159
1160         BUG_ON(!tt);
1161
1162         down(&rx_queue_sema);
1163
1164         priv = iscsi_if_transport_lookup(tt);
1165         BUG_ON (!priv);
1166
1167         spin_lock_irqsave(&priv->session_lock, flags);
1168         if (!list_empty(&priv->sessions)) {
1169                 spin_unlock_irqrestore(&priv->session_lock, flags);
1170                 up(&rx_queue_sema);
1171                 return -EPERM;
1172         }
1173         spin_unlock_irqrestore(&priv->session_lock, flags);
1174
1175         spin_lock_irqsave(&iscsi_transport_lock, flags);
1176         list_del(&priv->list);
1177         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
1178
1179         transport_container_unregister(&priv->conn_cont);
1180         transport_container_unregister(&priv->session_cont);
1181
1182         sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
1183         class_device_unregister(&priv->cdev);
1184         up(&rx_queue_sema);
1185
1186         return 0;
1187 }
1188 EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
1189
1190 static int
1191 iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
1192 {
1193         struct netlink_notify *n = ptr;
1194
1195         if (event == NETLINK_URELEASE &&
1196             n->protocol == NETLINK_ISCSI && n->pid) {
1197                 struct iscsi_if_conn *conn;
1198                 unsigned long flags;
1199
1200                 mempool_zone_complete(&z_reply);
1201                 spin_lock_irqsave(&connlock, flags);
1202                 list_for_each_entry(conn, &connlist, conn_list) {
1203                         mempool_zone_complete(&conn->z_error);
1204                         mempool_zone_complete(&conn->z_pdu);
1205                 }
1206                 spin_unlock_irqrestore(&connlock, flags);
1207         }
1208
1209         return NOTIFY_DONE;
1210 }
1211
1212 static struct notifier_block iscsi_nl_notifier = {
1213         .notifier_call  = iscsi_rcv_nl_event,
1214 };
1215
1216 static __init int iscsi_transport_init(void)
1217 {
1218         int err;
1219
1220         err = class_register(&iscsi_transport_class);
1221         if (err)
1222                 return err;
1223
1224         err = transport_class_register(&iscsi_connection_class);
1225         if (err)
1226                 goto unregister_transport_class;
1227
1228         err = transport_class_register(&iscsi_session_class);
1229         if (err)
1230                 goto unregister_conn_class;
1231
1232         err = netlink_register_notifier(&iscsi_nl_notifier);
1233         if (err)
1234                 goto unregister_session_class;
1235
1236         nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
1237                                     THIS_MODULE);
1238         if (!nls) {
1239                 err = -ENOBUFS;
1240                 goto unregister_notifier;
1241         }
1242
1243         err = mempool_zone_init(&z_reply, Z_MAX_REPLY,
1244                 NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
1245         if (!err)
1246                 return 0;
1247
1248         sock_release(nls->sk_socket);
1249 unregister_notifier:
1250         netlink_unregister_notifier(&iscsi_nl_notifier);
1251 unregister_session_class:
1252         transport_class_unregister(&iscsi_session_class);
1253 unregister_conn_class:
1254         transport_class_unregister(&iscsi_connection_class);
1255 unregister_transport_class:
1256         class_unregister(&iscsi_transport_class);
1257         return err;
1258 }
1259
1260 static void __exit iscsi_transport_exit(void)
1261 {
1262         mempool_destroy(z_reply.pool);
1263         sock_release(nls->sk_socket);
1264         netlink_unregister_notifier(&iscsi_nl_notifier);
1265         transport_class_unregister(&iscsi_connection_class);
1266         transport_class_unregister(&iscsi_session_class);
1267         class_unregister(&iscsi_transport_class);
1268 }
1269
1270 module_init(iscsi_transport_init);
1271 module_exit(iscsi_transport_exit);
1272
1273 MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
1274               "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
1275               "Alex Aizman <itn780@yahoo.com>");
1276 MODULE_DESCRIPTION("iSCSI Transport Interface");
1277 MODULE_LICENSE("GPL");