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