[SCSI] iscsi: add sysfs attrs for uspace sync up
[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/mempool.h>
25 #include <linux/mutex.h>
26 #include <net/tcp.h>
27 #include <scsi/scsi.h>
28 #include <scsi/scsi_host.h>
29 #include <scsi/scsi_device.h>
30 #include <scsi/scsi_transport.h>
31 #include <scsi/scsi_transport_iscsi.h>
32 #include <scsi/iscsi_if.h>
33
34 #define ISCSI_SESSION_ATTRS 10
35 #define ISCSI_CONN_ATTRS 10
36
37 struct iscsi_internal {
38         struct scsi_transport_template t;
39         struct iscsi_transport *iscsi_transport;
40         struct list_head list;
41         struct class_device cdev;
42         /*
43          * We do not have any private or other attrs.
44          */
45         struct transport_container conn_cont;
46         struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
47         struct transport_container session_cont;
48         struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
49 };
50
51 static int iscsi_session_nr;    /* sysfs session id for next new session */
52
53 /*
54  * list of registered transports and lock that must
55  * be held while accessing list. The iscsi_transport_lock must
56  * be acquired after the rx_queue_mutex.
57  */
58 static LIST_HEAD(iscsi_transports);
59 static DEFINE_SPINLOCK(iscsi_transport_lock);
60
61 #define to_iscsi_internal(tmpl) \
62         container_of(tmpl, struct iscsi_internal, t)
63
64 #define cdev_to_iscsi_internal(_cdev) \
65         container_of(_cdev, struct iscsi_internal, cdev)
66
67 static void iscsi_transport_release(struct class_device *cdev)
68 {
69         struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
70         kfree(priv);
71 }
72
73 /*
74  * iscsi_transport_class represents the iscsi_transports that are
75  * registered.
76  */
77 static struct class iscsi_transport_class = {
78         .name = "iscsi_transport",
79         .release = iscsi_transport_release,
80 };
81
82 static ssize_t
83 show_transport_handle(struct class_device *cdev, char *buf)
84 {
85         struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
86         return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
87 }
88 static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
89
90 #define show_transport_attr(name, format)                               \
91 static ssize_t                                                          \
92 show_transport_##name(struct class_device *cdev, char *buf)             \
93 {                                                                       \
94         struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);     \
95         return sprintf(buf, format"\n", priv->iscsi_transport->name);   \
96 }                                                                       \
97 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
98
99 show_transport_attr(caps, "0x%x");
100 show_transport_attr(max_lun, "%d");
101 show_transport_attr(max_conn, "%d");
102 show_transport_attr(max_cmd_len, "%d");
103
104 static struct attribute *iscsi_transport_attrs[] = {
105         &class_device_attr_handle.attr,
106         &class_device_attr_caps.attr,
107         &class_device_attr_max_lun.attr,
108         &class_device_attr_max_conn.attr,
109         &class_device_attr_max_cmd_len.attr,
110         NULL,
111 };
112
113 static struct attribute_group iscsi_transport_group = {
114         .attrs = iscsi_transport_attrs,
115 };
116
117 static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
118                                "iscsi_session",
119                                NULL,
120                                NULL,
121                                NULL);
122
123 static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
124                                "iscsi_connection",
125                                NULL,
126                                NULL,
127                                NULL);
128
129 static struct sock *nls;
130 static int daemon_pid;
131 static DEFINE_MUTEX(rx_queue_mutex);
132
133 struct mempool_zone {
134         mempool_t *pool;
135         atomic_t allocated;
136         int size;
137         int hiwat;
138         struct list_head freequeue;
139         spinlock_t freelock;
140 };
141
142 static struct mempool_zone *z_reply;
143
144 /*
145  * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
146  * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
147  *             so daemon will notice OOM on NETLINK tranposrt level and will
148  *             be able to predict or change operational behavior
149  */
150 #define Z_MAX_REPLY     8
151 #define Z_HIWAT_REPLY   6
152 #define Z_MAX_PDU       8
153 #define Z_HIWAT_PDU     6
154 #define Z_MAX_ERROR     16
155 #define Z_HIWAT_ERROR   12
156
157 static LIST_HEAD(sesslist);
158 static DEFINE_SPINLOCK(sesslock);
159 static LIST_HEAD(connlist);
160 static DEFINE_SPINLOCK(connlock);
161
162 static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn)
163 {
164         struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent);
165         return sess->sid;
166 }
167
168 /*
169  * Returns the matching session to a given sid
170  */
171 static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
172 {
173         unsigned long flags;
174         struct iscsi_cls_session *sess;
175
176         spin_lock_irqsave(&sesslock, flags);
177         list_for_each_entry(sess, &sesslist, sess_list) {
178                 if (sess->sid == sid) {
179                         spin_unlock_irqrestore(&sesslock, flags);
180                         return sess;
181                 }
182         }
183         spin_unlock_irqrestore(&sesslock, flags);
184         return NULL;
185 }
186
187 /*
188  * Returns the matching connection to a given sid / cid tuple
189  */
190 static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid)
191 {
192         unsigned long flags;
193         struct iscsi_cls_conn *conn;
194
195         spin_lock_irqsave(&connlock, flags);
196         list_for_each_entry(conn, &connlist, conn_list) {
197                 if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) {
198                         spin_unlock_irqrestore(&connlock, flags);
199                         return conn;
200                 }
201         }
202         spin_unlock_irqrestore(&connlock, flags);
203         return NULL;
204 }
205
206 /*
207  * The following functions can be used by LLDs that allocate
208  * their own scsi_hosts or by software iscsi LLDs
209  */
210 static void iscsi_session_release(struct device *dev)
211 {
212         struct iscsi_cls_session *session = iscsi_dev_to_session(dev);
213         struct iscsi_transport *transport = session->transport;
214         struct Scsi_Host *shost;
215
216         shost = iscsi_session_to_shost(session);
217         scsi_host_put(shost);
218         kfree(session->targetname);
219         kfree(session);
220         module_put(transport->owner);
221 }
222
223 static int iscsi_is_session_dev(const struct device *dev)
224 {
225         return dev->release == iscsi_session_release;
226 }
227
228 /**
229  * iscsi_create_session - create iscsi class session
230  * @shost: scsi host
231  * @transport: iscsi transport
232  *
233  * This can be called from a LLD or iscsi_transport.
234  **/
235 struct iscsi_cls_session *
236 iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport)
237 {
238         struct iscsi_cls_session *session;
239         int err;
240
241         if (!try_module_get(transport->owner))
242                 return NULL;
243
244         session = kzalloc(sizeof(*session) + transport->sessiondata_size,
245                           GFP_KERNEL);
246         if (!session)
247                 goto module_put;
248         session->transport = transport;
249
250         if (transport->sessiondata_size)
251                 session->dd_data = &session[1];
252
253         /* this is released in the dev's release function */
254         scsi_host_get(shost);
255         session->sid = iscsi_session_nr++;
256         snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
257                  session->sid);
258         session->dev.parent = &shost->shost_gendev;
259         session->dev.release = iscsi_session_release;
260         err = device_register(&session->dev);
261         if (err) {
262                 dev_printk(KERN_ERR, &session->dev, "iscsi: could not "
263                            "register session's dev\n");
264                 goto free_session;
265         }
266         transport_register_device(&session->dev);
267
268         return session;
269
270 free_session:
271         kfree(session);
272 module_put:
273         module_put(transport->owner);
274         return NULL;
275 }
276
277 EXPORT_SYMBOL_GPL(iscsi_create_session);
278
279 /**
280  * iscsi_destroy_session - destroy iscsi session
281  * @session: iscsi_session
282  *
283  * Can be called by a LLD or iscsi_transport. There must not be
284  * any running connections.
285  **/
286 int iscsi_destroy_session(struct iscsi_cls_session *session)
287 {
288         transport_unregister_device(&session->dev);
289         device_unregister(&session->dev);
290         return 0;
291 }
292
293 EXPORT_SYMBOL_GPL(iscsi_destroy_session);
294
295 static void iscsi_conn_release(struct device *dev)
296 {
297         struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
298         struct device *parent = conn->dev.parent;
299
300         kfree(conn->persistent_address);
301         kfree(conn);
302         put_device(parent);
303 }
304
305 static int iscsi_is_conn_dev(const struct device *dev)
306 {
307         return dev->release == iscsi_conn_release;
308 }
309
310 /**
311  * iscsi_create_conn - create iscsi class connection
312  * @session: iscsi cls session
313  * @cid: connection id
314  *
315  * This can be called from a LLD or iscsi_transport. The connection
316  * is child of the session so cid must be unique for all connections
317  * on the session.
318  *
319  * Since we do not support MCS, cid will normally be zero. In some cases
320  * for software iscsi we could be trying to preallocate a connection struct
321  * in which case there could be two connection structs and cid would be
322  * non-zero.
323  **/
324 struct iscsi_cls_conn *
325 iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
326 {
327         struct iscsi_transport *transport = session->transport;
328         struct iscsi_cls_conn *conn;
329         int err;
330
331         conn = kzalloc(sizeof(*conn) + transport->conndata_size, GFP_KERNEL);
332         if (!conn)
333                 return NULL;
334
335         if (transport->conndata_size)
336                 conn->dd_data = &conn[1];
337
338         INIT_LIST_HEAD(&conn->conn_list);
339         conn->transport = transport;
340         conn->cid = cid;
341
342         /* this is released in the dev's release function */
343         if (!get_device(&session->dev))
344                 goto free_conn;
345
346         snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
347                  session->sid, cid);
348         conn->dev.parent = &session->dev;
349         conn->dev.release = iscsi_conn_release;
350         err = device_register(&conn->dev);
351         if (err) {
352                 dev_printk(KERN_ERR, &conn->dev, "iscsi: could not register "
353                            "connection's dev\n");
354                 goto release_parent_ref;
355         }
356         transport_register_device(&conn->dev);
357         return conn;
358
359 release_parent_ref:
360         put_device(&session->dev);
361 free_conn:
362         kfree(conn);
363         return NULL;
364 }
365
366 EXPORT_SYMBOL_GPL(iscsi_create_conn);
367
368 /**
369  * iscsi_destroy_conn - destroy iscsi class connection
370  * @session: iscsi cls session
371  *
372  * This can be called from a LLD or iscsi_transport.
373  **/
374 int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
375 {
376         transport_unregister_device(&conn->dev);
377         device_unregister(&conn->dev);
378         return 0;
379 }
380
381 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
382
383 /*
384  * These functions are used only by software iscsi_transports
385  * which do not allocate and more their scsi_hosts since this
386  * is initiated from userspace.
387  */
388
389 /*
390  * iSCSI Session's hostdata organization:
391  *
392  *    *------------------* <== hostdata_session(host->hostdata)
393  *    | ptr to class sess|
394  *    |------------------| <== iscsi_hostdata(host->hostdata)
395  *    | transport's data |
396  *    *------------------*
397  */
398
399 #define hostdata_privsize(_t)   (sizeof(unsigned long) + _t->hostdata_size + \
400                                  _t->hostdata_size % sizeof(unsigned long))
401
402 #define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
403
404 /**
405  * iscsi_transport_create_session - create iscsi cls session and host
406  * scsit: scsi transport template
407  * transport: iscsi transport template
408  *
409  * This can be used by software iscsi_transports that allocate
410  * a session per scsi host.
411  **/
412 struct Scsi_Host *
413 iscsi_transport_create_session(struct scsi_transport_template *scsit,
414                                struct iscsi_transport *transport)
415 {
416         struct iscsi_cls_session *session;
417         struct Scsi_Host *shost;
418         unsigned long flags;
419
420         shost = scsi_host_alloc(transport->host_template,
421                                 hostdata_privsize(transport));
422         if (!shost) {
423                 printk(KERN_ERR "iscsi: can not allocate SCSI host for "
424                         "session\n");
425                 return NULL;
426         }
427
428         shost->max_id = 1;
429         shost->max_channel = 0;
430         shost->max_lun = transport->max_lun;
431         shost->max_cmd_len = transport->max_cmd_len;
432         shost->transportt = scsit;
433         shost->transportt->create_work_queue = 1;
434
435         if (scsi_add_host(shost, NULL))
436                 goto free_host;
437
438         session = iscsi_create_session(shost, transport);
439         if (!session)
440                 goto remove_host;
441
442         *(unsigned long*)shost->hostdata = (unsigned long)session;
443         spin_lock_irqsave(&sesslock, flags);
444         list_add(&session->sess_list, &sesslist);
445         spin_unlock_irqrestore(&sesslock, flags);
446         return shost;
447
448 remove_host:
449         scsi_remove_host(shost);
450 free_host:
451         scsi_host_put(shost);
452         return NULL;
453 }
454
455 EXPORT_SYMBOL_GPL(iscsi_transport_create_session);
456
457 /**
458  * iscsi_transport_destroy_session - destroy session and scsi host
459  * shost: scsi host
460  *
461  * This can be used by software iscsi_transports that allocate
462  * a session per scsi host.
463  **/
464 int iscsi_transport_destroy_session(struct Scsi_Host *shost)
465 {
466         struct iscsi_cls_session *session;
467         unsigned long flags;
468
469         scsi_remove_host(shost);
470         session = hostdata_session(shost->hostdata);
471         spin_lock_irqsave(&sesslock, flags);
472         list_del(&session->sess_list);
473         spin_unlock_irqrestore(&sesslock, flags);
474         iscsi_destroy_session(session);
475         /* ref from host alloc */
476         scsi_host_put(shost);
477         return 0;
478 }
479
480 EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session);
481
482 /*
483  * iscsi interface functions
484  */
485 static struct iscsi_internal *
486 iscsi_if_transport_lookup(struct iscsi_transport *tt)
487 {
488         struct iscsi_internal *priv;
489         unsigned long flags;
490
491         spin_lock_irqsave(&iscsi_transport_lock, flags);
492         list_for_each_entry(priv, &iscsi_transports, list) {
493                 if (tt == priv->iscsi_transport) {
494                         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
495                         return priv;
496                 }
497         }
498         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
499         return NULL;
500 }
501
502 static inline struct list_head *skb_to_lh(struct sk_buff *skb)
503 {
504         return (struct list_head *)&skb->cb;
505 }
506
507 static void*
508 mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
509 {
510         struct mempool_zone *zone = pool_data;
511
512         return alloc_skb(zone->size, gfp_mask);
513 }
514
515 static void
516 mempool_zone_free_skb(void *element, void *pool_data)
517 {
518         kfree_skb(element);
519 }
520
521 static void
522 mempool_zone_complete(struct mempool_zone *zone)
523 {
524         unsigned long flags;
525         struct list_head *lh, *n;
526
527         spin_lock_irqsave(&zone->freelock, flags);
528         list_for_each_safe(lh, n, &zone->freequeue) {
529                 struct sk_buff *skb = (struct sk_buff *)((char *)lh -
530                                 offsetof(struct sk_buff, cb));
531                 if (!skb_shared(skb)) {
532                         list_del(skb_to_lh(skb));
533                         mempool_free(skb, zone->pool);
534                         atomic_dec(&zone->allocated);
535                 }
536         }
537         spin_unlock_irqrestore(&zone->freelock, flags);
538 }
539
540 static struct mempool_zone *
541 mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)
542 {
543         struct mempool_zone *zp;
544
545         zp = kzalloc(sizeof(*zp), GFP_KERNEL);
546         if (!zp)
547                 return NULL;
548
549         zp->size = size;
550         zp->hiwat = hiwat;
551         INIT_LIST_HEAD(&zp->freequeue);
552         spin_lock_init(&zp->freelock);
553         atomic_set(&zp->allocated, 0);
554
555         zp->pool = mempool_create(max, mempool_zone_alloc_skb,
556                                   mempool_zone_free_skb, zp);
557         if (!zp->pool) {
558                 kfree(zp);
559                 return NULL;
560         }
561
562         return zp;
563 }
564
565 static void mempool_zone_destroy(struct mempool_zone *zp)
566 {
567         mempool_destroy(zp->pool);
568         kfree(zp);
569 }
570
571 static struct sk_buff*
572 mempool_zone_get_skb(struct mempool_zone *zone)
573 {
574         struct sk_buff *skb;
575
576         skb = mempool_alloc(zone->pool, GFP_ATOMIC);
577         if (skb)
578                 atomic_inc(&zone->allocated);
579         return skb;
580 }
581
582 static int
583 iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
584 {
585         unsigned long flags;
586         int rc;
587
588         skb_get(skb);
589         rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT);
590         if (rc < 0) {
591                 mempool_free(skb, zone->pool);
592                 printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
593                 return rc;
594         }
595
596         spin_lock_irqsave(&zone->freelock, flags);
597         list_add(skb_to_lh(skb), &zone->freequeue);
598         spin_unlock_irqrestore(&zone->freelock, flags);
599
600         return 0;
601 }
602
603 int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
604                    char *data, uint32_t data_size)
605 {
606         struct nlmsghdr *nlh;
607         struct sk_buff *skb;
608         struct iscsi_uevent *ev;
609         char *pdu;
610         int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
611                               data_size);
612
613         mempool_zone_complete(conn->z_pdu);
614
615         skb = mempool_zone_get_skb(conn->z_pdu);
616         if (!skb) {
617                 iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED);
618                 dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver "
619                            "control PDU: OOM\n");
620                 return -ENOMEM;
621         }
622
623         nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
624         ev = NLMSG_DATA(nlh);
625         memset(ev, 0, sizeof(*ev));
626         ev->transport_handle = iscsi_handle(conn->transport);
627         ev->type = ISCSI_KEVENT_RECV_PDU;
628         if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
629                 ev->iferror = -ENOMEM;
630         ev->r.recv_req.cid = conn->cid;
631         ev->r.recv_req.sid = iscsi_conn_get_sid(conn);
632         pdu = (char*)ev + sizeof(*ev);
633         memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
634         memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
635
636         return iscsi_unicast_skb(conn->z_pdu, skb);
637 }
638 EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
639
640 void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
641 {
642         struct nlmsghdr *nlh;
643         struct sk_buff  *skb;
644         struct iscsi_uevent *ev;
645         int len = NLMSG_SPACE(sizeof(*ev));
646
647         mempool_zone_complete(conn->z_error);
648
649         skb = mempool_zone_get_skb(conn->z_error);
650         if (!skb) {
651                 dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored "
652                           "conn error (%d)\n", error);
653                 return;
654         }
655
656         nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
657         ev = NLMSG_DATA(nlh);
658         ev->transport_handle = iscsi_handle(conn->transport);
659         ev->type = ISCSI_KEVENT_CONN_ERROR;
660         if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat)
661                 ev->iferror = -ENOMEM;
662         ev->r.connerror.error = error;
663         ev->r.connerror.cid = conn->cid;
664         ev->r.connerror.sid = iscsi_conn_get_sid(conn);
665
666         iscsi_unicast_skb(conn->z_error, skb);
667
668         dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
669                    error);
670 }
671 EXPORT_SYMBOL_GPL(iscsi_conn_error);
672
673 static int
674 iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
675                       void *payload, int size)
676 {
677         struct sk_buff  *skb;
678         struct nlmsghdr *nlh;
679         int len = NLMSG_SPACE(size);
680         int flags = multi ? NLM_F_MULTI : 0;
681         int t = done ? NLMSG_DONE : type;
682
683         mempool_zone_complete(z_reply);
684
685         skb = mempool_zone_get_skb(z_reply);
686         /*
687          * FIXME:
688          * user is supposed to react on iferror == -ENOMEM;
689          * see iscsi_if_rx().
690          */
691         BUG_ON(!skb);
692
693         nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
694         nlh->nlmsg_flags = flags;
695         memcpy(NLMSG_DATA(nlh), payload, size);
696         return iscsi_unicast_skb(z_reply, skb);
697 }
698
699 static int
700 iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
701 {
702         struct iscsi_uevent *ev = NLMSG_DATA(nlh);
703         struct iscsi_stats *stats;
704         struct sk_buff *skbstat;
705         struct iscsi_cls_conn *conn;
706         struct nlmsghdr *nlhstat;
707         struct iscsi_uevent *evstat;
708         int len = NLMSG_SPACE(sizeof(*ev) +
709                               sizeof(struct iscsi_stats) +
710                               sizeof(struct iscsi_stats_custom) *
711                               ISCSI_STATS_CUSTOM_MAX);
712         int err = 0;
713
714         conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
715         if (!conn)
716                 return -EEXIST;
717
718         do {
719                 int actual_size;
720
721                 mempool_zone_complete(conn->z_pdu);
722
723                 skbstat = mempool_zone_get_skb(conn->z_pdu);
724                 if (!skbstat) {
725                         dev_printk(KERN_ERR, &conn->dev, "iscsi: can not "
726                                    "deliver stats: OOM\n");
727                         return -ENOMEM;
728                 }
729
730                 nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0,
731                                       (len - sizeof(*nlhstat)), 0);
732                 evstat = NLMSG_DATA(nlhstat);
733                 memset(evstat, 0, sizeof(*evstat));
734                 evstat->transport_handle = iscsi_handle(conn->transport);
735                 evstat->type = nlh->nlmsg_type;
736                 if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
737                         evstat->iferror = -ENOMEM;
738                 evstat->u.get_stats.cid =
739                         ev->u.get_stats.cid;
740                 evstat->u.get_stats.sid =
741                         ev->u.get_stats.sid;
742                 stats = (struct iscsi_stats *)
743                         ((char*)evstat + sizeof(*evstat));
744                 memset(stats, 0, sizeof(*stats));
745
746                 transport->get_stats(conn, stats);
747                 actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) +
748                                           sizeof(struct iscsi_stats) +
749                                           sizeof(struct iscsi_stats_custom) *
750                                           stats->custom_length);
751                 actual_size -= sizeof(*nlhstat);
752                 actual_size = NLMSG_LENGTH(actual_size);
753                 skb_trim(skbstat, NLMSG_ALIGN(actual_size));
754                 nlhstat->nlmsg_len = actual_size;
755
756                 err = iscsi_unicast_skb(conn->z_pdu, skbstat);
757         } while (err < 0 && err != -ECONNREFUSED);
758
759         return err;
760 }
761
762 static int
763 iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
764 {
765         struct iscsi_transport *transport = priv->iscsi_transport;
766         struct iscsi_cls_session *session;
767         uint32_t hostno;
768
769         session = transport->create_session(&priv->t,
770                                             ev->u.c_session.initial_cmdsn,
771                                             &hostno);
772         if (!session)
773                 return -ENOMEM;
774
775         ev->r.c_session_ret.host_no = hostno;
776         ev->r.c_session_ret.sid = session->sid;
777         return 0;
778 }
779
780 static int
781 iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
782 {
783         struct iscsi_cls_conn *conn;
784         struct iscsi_cls_session *session;
785         unsigned long flags;
786
787         session = iscsi_session_lookup(ev->u.c_conn.sid);
788         if (!session) {
789                 printk(KERN_ERR "iscsi: invalid session %d\n",
790                        ev->u.c_conn.sid);
791                 return -EINVAL;
792         }
793
794         conn = transport->create_conn(session, ev->u.c_conn.cid);
795         if (!conn) {
796                 printk(KERN_ERR "iscsi: couldn't create a new "
797                            "connection for session %d\n",
798                            session->sid);
799                 return -ENOMEM;
800         }
801
802         conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
803                         NLMSG_SPACE(sizeof(struct iscsi_uevent) +
804                                     sizeof(struct iscsi_hdr) +
805                                     DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
806                         Z_HIWAT_PDU);
807         if (!conn->z_pdu) {
808                 dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
809                            "pdu zone for new conn\n");
810                 goto destroy_conn;
811         }
812
813         conn->z_error = mempool_zone_init(Z_MAX_ERROR,
814                         NLMSG_SPACE(sizeof(struct iscsi_uevent)),
815                         Z_HIWAT_ERROR);
816         if (!conn->z_error) {
817                 dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
818                            "error zone for new conn\n");
819                 goto free_pdu_pool;
820         }
821
822         ev->r.c_conn_ret.sid = session->sid;
823         ev->r.c_conn_ret.cid = conn->cid;
824
825         spin_lock_irqsave(&connlock, flags);
826         list_add(&conn->conn_list, &connlist);
827         conn->active = 1;
828         spin_unlock_irqrestore(&connlock, flags);
829
830         return 0;
831
832 free_pdu_pool:
833         mempool_zone_destroy(conn->z_pdu);
834 destroy_conn:
835         if (transport->destroy_conn)
836                 transport->destroy_conn(conn->dd_data);
837         return -ENOMEM;
838 }
839
840 static int
841 iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
842 {
843         unsigned long flags;
844         struct iscsi_cls_conn *conn;
845         struct mempool_zone *z_error, *z_pdu;
846
847         conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid);
848         if (!conn)
849                 return -EINVAL;
850         spin_lock_irqsave(&connlock, flags);
851         conn->active = 0;
852         list_del(&conn->conn_list);
853         spin_unlock_irqrestore(&connlock, flags);
854
855         z_pdu = conn->z_pdu;
856         z_error = conn->z_error;
857
858         if (transport->destroy_conn)
859                 transport->destroy_conn(conn);
860
861         mempool_zone_destroy(z_pdu);
862         mempool_zone_destroy(z_error);
863
864         return 0;
865 }
866
867 static void
868 iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data)
869 {
870         if (ev->u.set_param.len != sizeof(uint32_t))
871                 BUG();
872         memcpy(value, data, min_t(uint32_t, sizeof(uint32_t),
873                 ev->u.set_param.len));
874 }
875
876 static int
877 iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
878 {
879         char *data = (char*)ev + sizeof(*ev);
880         struct iscsi_cls_conn *conn;
881         struct iscsi_cls_session *session;
882         int err = 0;
883         uint32_t value = 0;
884
885         session = iscsi_session_lookup(ev->u.set_param.sid);
886         conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
887         if (!conn || !session)
888                 return -EINVAL;
889
890         switch (ev->u.set_param.param) {
891         case ISCSI_PARAM_TARGET_NAME:
892                 /* this should not change between logins */
893                 if (session->targetname)
894                         return 0;
895
896                 session->targetname = kstrdup(data, GFP_KERNEL);
897                 if (!session->targetname)
898                         return -ENOMEM;
899                 break;
900         case ISCSI_PARAM_TPGT:
901                 iscsi_copy_param(ev, &value, data);
902                 session->tpgt = value;
903                 break;
904         case ISCSI_PARAM_PERSISTENT_PORT:
905                 iscsi_copy_param(ev, &value, data);
906                 conn->persistent_port = value;
907                 break;
908         case ISCSI_PARAM_PERSISTENT_ADDRESS:
909                 /*
910                  * this is the address returned in discovery so it should
911                  * not change between logins.
912                  */
913                 if (conn->persistent_address)
914                         return 0;
915
916                 conn->persistent_address = kstrdup(data, GFP_KERNEL);
917                 if (!conn->persistent_address)
918                         return -ENOMEM;
919                 break;
920         default:
921                 iscsi_copy_param(ev, &value, data);
922                 err = transport->set_param(conn, ev->u.set_param.param, value);
923         }
924
925         return err;
926 }
927
928 static int
929 iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
930 {
931         int err = 0;
932         struct iscsi_uevent *ev = NLMSG_DATA(nlh);
933         struct iscsi_transport *transport = NULL;
934         struct iscsi_internal *priv;
935         struct iscsi_cls_session *session;
936         struct iscsi_cls_conn *conn;
937
938         priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
939         if (!priv)
940                 return -EINVAL;
941         transport = priv->iscsi_transport;
942
943         if (!try_module_get(transport->owner))
944                 return -EINVAL;
945
946         switch (nlh->nlmsg_type) {
947         case ISCSI_UEVENT_CREATE_SESSION:
948                 err = iscsi_if_create_session(priv, ev);
949                 break;
950         case ISCSI_UEVENT_DESTROY_SESSION:
951                 session = iscsi_session_lookup(ev->u.d_session.sid);
952                 if (session)
953                         transport->destroy_session(session);
954                 else
955                         err = -EINVAL;
956                 break;
957         case ISCSI_UEVENT_CREATE_CONN:
958                 err = iscsi_if_create_conn(transport, ev);
959                 break;
960         case ISCSI_UEVENT_DESTROY_CONN:
961                 err = iscsi_if_destroy_conn(transport, ev);
962                 break;
963         case ISCSI_UEVENT_BIND_CONN:
964                 session = iscsi_session_lookup(ev->u.b_conn.sid);
965                 conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
966
967                 if (session && conn)
968                         ev->r.retcode = transport->bind_conn(session, conn,
969                                         ev->u.b_conn.transport_fd,
970                                         ev->u.b_conn.is_leading);
971                 else
972                         err = -EINVAL;
973                 break;
974         case ISCSI_UEVENT_SET_PARAM:
975                 err = iscsi_set_param(transport, ev);
976                 break;
977         case ISCSI_UEVENT_START_CONN:
978                 conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid);
979                 if (conn)
980                         ev->r.retcode = transport->start_conn(conn);
981                 else
982                         err = -EINVAL;
983
984                 break;
985         case ISCSI_UEVENT_STOP_CONN:
986                 conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
987                 if (conn)
988                         transport->stop_conn(conn, ev->u.stop_conn.flag);
989                 else
990                         err = -EINVAL;
991                 break;
992         case ISCSI_UEVENT_SEND_PDU:
993                 conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
994                 if (conn)
995                         ev->r.retcode = transport->send_pdu(conn,
996                                 (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
997                                 (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
998                                 ev->u.send_pdu.data_size);
999                 else
1000                         err = -EINVAL;
1001                 break;
1002         case ISCSI_UEVENT_GET_STATS:
1003                 err = iscsi_if_get_stats(transport, nlh);
1004                 break;
1005         default:
1006                 err = -EINVAL;
1007                 break;
1008         }
1009
1010         module_put(transport->owner);
1011         return err;
1012 }
1013
1014 /*
1015  * Get message from skb (based on rtnetlink_rcv_skb).  Each message is
1016  * processed by iscsi_if_recv_msg.  Malformed skbs with wrong lengths or
1017  * invalid creds are discarded silently.
1018  */
1019 static void
1020 iscsi_if_rx(struct sock *sk, int len)
1021 {
1022         struct sk_buff *skb;
1023
1024         mutex_lock(&rx_queue_mutex);
1025         while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
1026                 if (NETLINK_CREDS(skb)->uid) {
1027                         skb_pull(skb, skb->len);
1028                         goto free_skb;
1029                 }
1030                 daemon_pid = NETLINK_CREDS(skb)->pid;
1031
1032                 while (skb->len >= NLMSG_SPACE(0)) {
1033                         int err;
1034                         uint32_t rlen;
1035                         struct nlmsghdr *nlh;
1036                         struct iscsi_uevent *ev;
1037
1038                         nlh = (struct nlmsghdr *)skb->data;
1039                         if (nlh->nlmsg_len < sizeof(*nlh) ||
1040                             skb->len < nlh->nlmsg_len) {
1041                                 break;
1042                         }
1043
1044                         ev = NLMSG_DATA(nlh);
1045                         rlen = NLMSG_ALIGN(nlh->nlmsg_len);
1046                         if (rlen > skb->len)
1047                                 rlen = skb->len;
1048
1049                         err = iscsi_if_recv_msg(skb, nlh);
1050                         if (err) {
1051                                 ev->type = ISCSI_KEVENT_IF_ERROR;
1052                                 ev->iferror = err;
1053                         }
1054                         do {
1055                                 /*
1056                                  * special case for GET_STATS:
1057                                  * on success - sending reply and stats from
1058                                  * inside of if_recv_msg(),
1059                                  * on error - fall through.
1060                                  */
1061                                 if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
1062                                         break;
1063                                 err = iscsi_if_send_reply(
1064                                         NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
1065                                         nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
1066                                 if (atomic_read(&z_reply->allocated) >=
1067                                                 z_reply->hiwat)
1068                                         ev->iferror = -ENOMEM;
1069                         } while (err < 0 && err != -ECONNREFUSED);
1070                         skb_pull(skb, rlen);
1071                 }
1072 free_skb:
1073                 kfree_skb(skb);
1074         }
1075         mutex_unlock(&rx_queue_mutex);
1076 }
1077
1078 #define iscsi_cdev_to_conn(_cdev) \
1079         iscsi_dev_to_conn(_cdev->dev)
1080
1081 #define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store)              \
1082 struct class_device_attribute class_device_attr_##_prefix##_##_name =   \
1083         __ATTR(_name,_mode,_show,_store)
1084
1085 /*
1086  * iSCSI connection attrs
1087  */
1088 #define iscsi_conn_int_attr_show(param, format)                         \
1089 static ssize_t                                                          \
1090 show_conn_int_param_##param(struct class_device *cdev, char *buf)       \
1091 {                                                                       \
1092         uint32_t value = 0;                                             \
1093         struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev);         \
1094         struct iscsi_transport *t = conn->transport;                    \
1095                                                                         \
1096         t->get_conn_param(conn, param, &value);                         \
1097         return snprintf(buf, 20, format"\n", value);                    \
1098 }
1099
1100 #define iscsi_conn_int_attr(field, param, format)                       \
1101         iscsi_conn_int_attr_show(param, format)                         \
1102 static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \
1103                         NULL);
1104
1105 iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u");
1106 iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u");
1107 iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d");
1108 iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d");
1109 iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
1110 iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
1111 iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d");
1112 iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d");
1113
1114 #define iscsi_conn_str_attr_show(param)                                 \
1115 static ssize_t                                                          \
1116 show_conn_str_param_##param(struct class_device *cdev, char *buf)       \
1117 {                                                                       \
1118         struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev);         \
1119         struct iscsi_transport *t = conn->transport;                    \
1120         return t->get_conn_str_param(conn, param, buf);                 \
1121 }
1122
1123 #define iscsi_conn_str_attr(field, param)                               \
1124         iscsi_conn_str_attr_show(param)                                 \
1125 static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \
1126                         NULL);
1127
1128 iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
1129 iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS);
1130
1131 #define iscsi_cdev_to_session(_cdev) \
1132         iscsi_dev_to_session(_cdev->dev)
1133
1134 /*
1135  * iSCSI session attrs
1136  */
1137 #define iscsi_session_int_attr_show(param, format)                      \
1138 static ssize_t                                                          \
1139 show_session_int_param_##param(struct class_device *cdev, char *buf)    \
1140 {                                                                       \
1141         uint32_t value = 0;                                             \
1142         struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);        \
1143         struct iscsi_transport *t = session->transport;                 \
1144                                                                         \
1145         t->get_session_param(session, param, &value);                   \
1146         return snprintf(buf, 20, format"\n", value);                    \
1147 }
1148
1149 #define iscsi_session_int_attr(field, param, format)                    \
1150         iscsi_session_int_attr_show(param, format)                      \
1151 static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \
1152                         NULL);
1153
1154 iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d");
1155 iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu");
1156 iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d");
1157 iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u");
1158 iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u");
1159 iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
1160 iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
1161 iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
1162 iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d");
1163
1164 #define iscsi_session_str_attr_show(param)                              \
1165 static ssize_t                                                          \
1166 show_session_str_param_##param(struct class_device *cdev, char *buf)    \
1167 {                                                                       \
1168         struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
1169         struct iscsi_transport *t = session->transport;                 \
1170         return t->get_session_str_param(session, param, buf);           \
1171 }
1172
1173 #define iscsi_session_str_attr(field, param)                            \
1174         iscsi_session_str_attr_show(param)                              \
1175 static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \
1176                         NULL);
1177
1178 iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME);
1179
1180 /*
1181  * Private session and conn attrs. userspace uses several iscsi values
1182  * to identify each session between reboots. Some of these values may not
1183  * be present in the iscsi_transport/LLD driver becuase userspace handles
1184  * login (and failback for login redirect) so for these type of drivers
1185  * the class manages the attrs and values for the iscsi_transport/LLD
1186  */
1187 #define iscsi_priv_session_attr_show(field, format)                     \
1188 static ssize_t                                                          \
1189 show_priv_session_##field(struct class_device *cdev, char *buf) \
1190 {                                                                       \
1191         struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
1192         return sprintf(buf, format"\n", session->field);                \
1193 }
1194
1195 #define iscsi_priv_session_attr(field, format)                          \
1196         iscsi_priv_session_attr_show(field, format)                     \
1197 static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \
1198                         NULL)
1199 iscsi_priv_session_attr(targetname, "%s");
1200 iscsi_priv_session_attr(tpgt, "%d");
1201
1202 #define iscsi_priv_conn_attr_show(field, format)                        \
1203 static ssize_t                                                          \
1204 show_priv_conn_##field(struct class_device *cdev, char *buf)            \
1205 {                                                                       \
1206         struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev);         \
1207         return sprintf(buf, format"\n", conn->field);                   \
1208 }
1209
1210 #define iscsi_priv_conn_attr(field, format)                             \
1211         iscsi_priv_conn_attr_show(field, format)                        \
1212 static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \
1213                         NULL)
1214 iscsi_priv_conn_attr(persistent_address, "%s");
1215 iscsi_priv_conn_attr(persistent_port, "%d");
1216
1217 #define SETUP_PRIV_SESSION_RD_ATTR(field)                               \
1218 do {                                                                    \
1219         priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
1220         count++;                                                        \
1221 } while (0)
1222
1223 #define SETUP_SESSION_RD_ATTR(field, param_flag)                        \
1224 do {                                                                    \
1225         if (tt->param_mask & param_flag) {                              \
1226                 priv->session_attrs[count] = &class_device_attr_sess_##field; \
1227                 count++;                                                \
1228         }                                                               \
1229 } while (0)
1230
1231 #define SETUP_PRIV_CONN_RD_ATTR(field)                                  \
1232 do {                                                                    \
1233         priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \
1234         count++;                                                        \
1235 } while (0)
1236
1237 #define SETUP_CONN_RD_ATTR(field, param_flag)                           \
1238 do {                                                                    \
1239         if (tt->param_mask & param_flag) {                              \
1240                 priv->conn_attrs[count] = &class_device_attr_conn_##field; \
1241                 count++;                                                \
1242         }                                                               \
1243 } while (0)
1244
1245 static int iscsi_session_match(struct attribute_container *cont,
1246                            struct device *dev)
1247 {
1248         struct iscsi_cls_session *session;
1249         struct Scsi_Host *shost;
1250         struct iscsi_internal *priv;
1251
1252         if (!iscsi_is_session_dev(dev))
1253                 return 0;
1254
1255         session = iscsi_dev_to_session(dev);
1256         shost = iscsi_session_to_shost(session);
1257         if (!shost->transportt)
1258                 return 0;
1259
1260         priv = to_iscsi_internal(shost->transportt);
1261         if (priv->session_cont.ac.class != &iscsi_session_class.class)
1262                 return 0;
1263
1264         return &priv->session_cont.ac == cont;
1265 }
1266
1267 static int iscsi_conn_match(struct attribute_container *cont,
1268                            struct device *dev)
1269 {
1270         struct iscsi_cls_session *session;
1271         struct iscsi_cls_conn *conn;
1272         struct Scsi_Host *shost;
1273         struct iscsi_internal *priv;
1274
1275         if (!iscsi_is_conn_dev(dev))
1276                 return 0;
1277
1278         conn = iscsi_dev_to_conn(dev);
1279         session = iscsi_dev_to_session(conn->dev.parent);
1280         shost = iscsi_session_to_shost(session);
1281
1282         if (!shost->transportt)
1283                 return 0;
1284
1285         priv = to_iscsi_internal(shost->transportt);
1286         if (priv->conn_cont.ac.class != &iscsi_connection_class.class)
1287                 return 0;
1288
1289         return &priv->conn_cont.ac == cont;
1290 }
1291
1292 struct scsi_transport_template *
1293 iscsi_register_transport(struct iscsi_transport *tt)
1294 {
1295         struct iscsi_internal *priv;
1296         unsigned long flags;
1297         int count = 0, err;
1298
1299         BUG_ON(!tt);
1300
1301         priv = iscsi_if_transport_lookup(tt);
1302         if (priv)
1303                 return NULL;
1304
1305         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1306         if (!priv)
1307                 return NULL;
1308         INIT_LIST_HEAD(&priv->list);
1309         priv->iscsi_transport = tt;
1310
1311         priv->cdev.class = &iscsi_transport_class;
1312         snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
1313         err = class_device_register(&priv->cdev);
1314         if (err)
1315                 goto free_priv;
1316
1317         err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
1318         if (err)
1319                 goto unregister_cdev;
1320
1321         /* connection parameters */
1322         priv->conn_cont.ac.attrs = &priv->conn_attrs[0];
1323         priv->conn_cont.ac.class = &iscsi_connection_class.class;
1324         priv->conn_cont.ac.match = iscsi_conn_match;
1325         transport_container_register(&priv->conn_cont);
1326
1327         SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_MAX_RECV_DLENGTH);
1328         SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_MAX_XMIT_DLENGTH);
1329         SETUP_CONN_RD_ATTR(header_digest, ISCSI_HDRDGST_EN);
1330         SETUP_CONN_RD_ATTR(data_digest, ISCSI_DATADGST_EN);
1331         SETUP_CONN_RD_ATTR(ifmarker, ISCSI_IFMARKER_EN);
1332         SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN);
1333         SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS);
1334         SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT);
1335
1336         if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS)
1337                 SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);
1338         else
1339                 SETUP_PRIV_CONN_RD_ATTR(persistent_address);
1340
1341         if (tt->param_mask & ISCSI_PERSISTENT_PORT)
1342                 SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT);
1343         else
1344                 SETUP_PRIV_CONN_RD_ATTR(persistent_port);
1345
1346         BUG_ON(count > ISCSI_CONN_ATTRS);
1347         priv->conn_attrs[count] = NULL;
1348         count = 0;
1349
1350         /* session parameters */
1351         priv->session_cont.ac.attrs = &priv->session_attrs[0];
1352         priv->session_cont.ac.class = &iscsi_session_class.class;
1353         priv->session_cont.ac.match = iscsi_session_match;
1354         transport_container_register(&priv->session_cont);
1355
1356         SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_INITIAL_R2T_EN);
1357         SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_MAX_R2T);
1358         SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_IMM_DATA_EN);
1359         SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_FIRST_BURST);
1360         SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_MAX_BURST);
1361         SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN);
1362         SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN);
1363         SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL);
1364
1365         if (tt->param_mask & ISCSI_TARGET_NAME)
1366                 SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME);
1367         else
1368                 SETUP_PRIV_SESSION_RD_ATTR(targetname);
1369
1370         if (tt->param_mask & ISCSI_TPGT)
1371                 SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT);
1372         else
1373                 SETUP_PRIV_SESSION_RD_ATTR(tpgt);
1374
1375         BUG_ON(count > ISCSI_SESSION_ATTRS);
1376         priv->session_attrs[count] = NULL;
1377
1378         spin_lock_irqsave(&iscsi_transport_lock, flags);
1379         list_add(&priv->list, &iscsi_transports);
1380         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
1381
1382         printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
1383         return &priv->t;
1384
1385 unregister_cdev:
1386         class_device_unregister(&priv->cdev);
1387 free_priv:
1388         kfree(priv);
1389         return NULL;
1390 }
1391 EXPORT_SYMBOL_GPL(iscsi_register_transport);
1392
1393 int iscsi_unregister_transport(struct iscsi_transport *tt)
1394 {
1395         struct iscsi_internal *priv;
1396         unsigned long flags;
1397
1398         BUG_ON(!tt);
1399
1400         mutex_lock(&rx_queue_mutex);
1401
1402         priv = iscsi_if_transport_lookup(tt);
1403         BUG_ON (!priv);
1404
1405         spin_lock_irqsave(&iscsi_transport_lock, flags);
1406         list_del(&priv->list);
1407         spin_unlock_irqrestore(&iscsi_transport_lock, flags);
1408
1409         transport_container_unregister(&priv->conn_cont);
1410         transport_container_unregister(&priv->session_cont);
1411
1412         sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
1413         class_device_unregister(&priv->cdev);
1414         mutex_unlock(&rx_queue_mutex);
1415
1416         return 0;
1417 }
1418 EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
1419
1420 static int
1421 iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
1422 {
1423         struct netlink_notify *n = ptr;
1424
1425         if (event == NETLINK_URELEASE &&
1426             n->protocol == NETLINK_ISCSI && n->pid) {
1427                 struct iscsi_cls_conn *conn;
1428                 unsigned long flags;
1429
1430                 mempool_zone_complete(z_reply);
1431                 spin_lock_irqsave(&connlock, flags);
1432                 list_for_each_entry(conn, &connlist, conn_list) {
1433                         mempool_zone_complete(conn->z_error);
1434                         mempool_zone_complete(conn->z_pdu);
1435                 }
1436                 spin_unlock_irqrestore(&connlock, flags);
1437         }
1438
1439         return NOTIFY_DONE;
1440 }
1441
1442 static struct notifier_block iscsi_nl_notifier = {
1443         .notifier_call  = iscsi_rcv_nl_event,
1444 };
1445
1446 static __init int iscsi_transport_init(void)
1447 {
1448         int err;
1449
1450         err = class_register(&iscsi_transport_class);
1451         if (err)
1452                 return err;
1453
1454         err = transport_class_register(&iscsi_connection_class);
1455         if (err)
1456                 goto unregister_transport_class;
1457
1458         err = transport_class_register(&iscsi_session_class);
1459         if (err)
1460                 goto unregister_conn_class;
1461
1462         err = netlink_register_notifier(&iscsi_nl_notifier);
1463         if (err)
1464                 goto unregister_session_class;
1465
1466         nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
1467                         THIS_MODULE);
1468         if (!nls) {
1469                 err = -ENOBUFS;
1470                 goto unregister_notifier;
1471         }
1472
1473         z_reply = mempool_zone_init(Z_MAX_REPLY,
1474                 NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
1475         if (z_reply)
1476                 return 0;
1477
1478         sock_release(nls->sk_socket);
1479 unregister_notifier:
1480         netlink_unregister_notifier(&iscsi_nl_notifier);
1481 unregister_session_class:
1482         transport_class_unregister(&iscsi_session_class);
1483 unregister_conn_class:
1484         transport_class_unregister(&iscsi_connection_class);
1485 unregister_transport_class:
1486         class_unregister(&iscsi_transport_class);
1487         return err;
1488 }
1489
1490 static void __exit iscsi_transport_exit(void)
1491 {
1492         mempool_zone_destroy(z_reply);
1493         sock_release(nls->sk_socket);
1494         netlink_unregister_notifier(&iscsi_nl_notifier);
1495         transport_class_unregister(&iscsi_connection_class);
1496         transport_class_unregister(&iscsi_session_class);
1497         class_unregister(&iscsi_transport_class);
1498 }
1499
1500 module_init(iscsi_transport_init);
1501 module_exit(iscsi_transport_exit);
1502
1503 MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
1504               "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
1505               "Alex Aizman <itn780@yahoo.com>");
1506 MODULE_DESCRIPTION("iSCSI Transport Interface");
1507 MODULE_LICENSE("GPL");