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