1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/module.h>
24#include <linux/mutex.h>
25#include <linux/slab.h>
26#include <linux/bsg-lib.h>
27#include <linux/idr.h>
28#include <net/tcp.h>
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#include <scsi/scsi_cmnd.h>
36#include <scsi/scsi_bsg_iscsi.h>
37
38#define ISCSI_TRANSPORT_VERSION "2.0-870"
39
40static int dbg_session;
41module_param_named(debug_session, dbg_session, int,
42 S_IRUGO | S_IWUSR);
43MODULE_PARM_DESC(debug_session,
44 "Turn on debugging for sessions in scsi_transport_iscsi "
45 "module. Set to 1 to turn on, and zero to turn off. Default "
46 "is off.");
47
48static int dbg_conn;
49module_param_named(debug_conn, dbg_conn, int,
50 S_IRUGO | S_IWUSR);
51MODULE_PARM_DESC(debug_conn,
52 "Turn on debugging for connections in scsi_transport_iscsi "
53 "module. Set to 1 to turn on, and zero to turn off. Default "
54 "is off.");
55
56#define ISCSI_DBG_TRANS_SESSION(_session, dbg_fmt, arg...) \
57 do { \
58 if (dbg_session) \
59 iscsi_cls_session_printk(KERN_INFO, _session, \
60 "%s: " dbg_fmt, \
61 __func__, ##arg); \
62 } while (0);
63
64#define ISCSI_DBG_TRANS_CONN(_conn, dbg_fmt, arg...) \
65 do { \
66 if (dbg_conn) \
67 iscsi_cls_conn_printk(KERN_INFO, _conn, \
68 "%s: " dbg_fmt, \
69 __func__, ##arg); \
70 } while (0);
71
72struct iscsi_internal {
73 struct scsi_transport_template t;
74 struct iscsi_transport *iscsi_transport;
75 struct list_head list;
76 struct device dev;
77
78 struct transport_container conn_cont;
79 struct transport_container session_cont;
80};
81
82static atomic_t iscsi_session_nr;
83static struct workqueue_struct *iscsi_eh_timer_workq;
84
85static DEFINE_IDA(iscsi_sess_ida);
86
87
88
89
90
91static LIST_HEAD(iscsi_transports);
92static DEFINE_SPINLOCK(iscsi_transport_lock);
93
94#define to_iscsi_internal(tmpl) \
95 container_of(tmpl, struct iscsi_internal, t)
96
97#define dev_to_iscsi_internal(_dev) \
98 container_of(_dev, struct iscsi_internal, dev)
99
100static void iscsi_transport_release(struct device *dev)
101{
102 struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
103 kfree(priv);
104}
105
106
107
108
109
110static struct class iscsi_transport_class = {
111 .name = "iscsi_transport",
112 .dev_release = iscsi_transport_release,
113};
114
115static ssize_t
116show_transport_handle(struct device *dev, struct device_attribute *attr,
117 char *buf)
118{
119 struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
120 return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
121}
122static DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
123
124#define show_transport_attr(name, format) \
125static ssize_t \
126show_transport_##name(struct device *dev, \
127 struct device_attribute *attr,char *buf) \
128{ \
129 struct iscsi_internal *priv = dev_to_iscsi_internal(dev); \
130 return sprintf(buf, format"\n", priv->iscsi_transport->name); \
131} \
132static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
133
134show_transport_attr(caps, "0x%x");
135
136static struct attribute *iscsi_transport_attrs[] = {
137 &dev_attr_handle.attr,
138 &dev_attr_caps.attr,
139 NULL,
140};
141
142static struct attribute_group iscsi_transport_group = {
143 .attrs = iscsi_transport_attrs,
144};
145
146
147
148
149#define iscsi_dev_to_endpoint(_dev) \
150 container_of(_dev, struct iscsi_endpoint, dev)
151
152#define ISCSI_ATTR(_prefix,_name,_mode,_show,_store) \
153struct device_attribute dev_attr_##_prefix##_##_name = \
154 __ATTR(_name,_mode,_show,_store)
155
156static void iscsi_endpoint_release(struct device *dev)
157{
158 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
159 kfree(ep);
160}
161
162static struct class iscsi_endpoint_class = {
163 .name = "iscsi_endpoint",
164 .dev_release = iscsi_endpoint_release,
165};
166
167static ssize_t
168show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf)
169{
170 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
171 return sprintf(buf, "%llu\n", (unsigned long long) ep->id);
172}
173static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL);
174
175static struct attribute *iscsi_endpoint_attrs[] = {
176 &dev_attr_ep_handle.attr,
177 NULL,
178};
179
180static struct attribute_group iscsi_endpoint_group = {
181 .attrs = iscsi_endpoint_attrs,
182};
183
184#define ISCSI_MAX_EPID -1
185
186static int iscsi_match_epid(struct device *dev, const void *data)
187{
188 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
189 const uint64_t *epid = data;
190
191 return *epid == ep->id;
192}
193
194struct iscsi_endpoint *
195iscsi_create_endpoint(int dd_size)
196{
197 struct device *dev;
198 struct iscsi_endpoint *ep;
199 uint64_t id;
200 int err;
201
202 for (id = 1; id < ISCSI_MAX_EPID; id++) {
203 dev = class_find_device(&iscsi_endpoint_class, NULL, &id,
204 iscsi_match_epid);
205 if (!dev)
206 break;
207 }
208 if (id == ISCSI_MAX_EPID) {
209 printk(KERN_ERR "Too many connections. Max supported %u\n",
210 ISCSI_MAX_EPID - 1);
211 return NULL;
212 }
213
214 ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL);
215 if (!ep)
216 return NULL;
217
218 ep->id = id;
219 ep->dev.class = &iscsi_endpoint_class;
220 dev_set_name(&ep->dev, "ep-%llu", (unsigned long long) id);
221 err = device_register(&ep->dev);
222 if (err)
223 goto free_ep;
224
225 err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
226 if (err)
227 goto unregister_dev;
228
229 if (dd_size)
230 ep->dd_data = &ep[1];
231 return ep;
232
233unregister_dev:
234 device_unregister(&ep->dev);
235 return NULL;
236
237free_ep:
238 kfree(ep);
239 return NULL;
240}
241EXPORT_SYMBOL_GPL(iscsi_create_endpoint);
242
243void iscsi_destroy_endpoint(struct iscsi_endpoint *ep)
244{
245 sysfs_remove_group(&ep->dev.kobj, &iscsi_endpoint_group);
246 device_unregister(&ep->dev);
247}
248EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint);
249
250struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
251{
252 struct iscsi_endpoint *ep;
253 struct device *dev;
254
255 dev = class_find_device(&iscsi_endpoint_class, NULL, &handle,
256 iscsi_match_epid);
257 if (!dev)
258 return NULL;
259
260 ep = iscsi_dev_to_endpoint(dev);
261
262
263
264
265 put_device(dev);
266 return ep;
267}
268EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
269
270
271
272
273
274static void iscsi_iface_release(struct device *dev)
275{
276 struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
277 struct device *parent = iface->dev.parent;
278
279 kfree(iface);
280 put_device(parent);
281}
282
283
284static struct class iscsi_iface_class = {
285 .name = "iscsi_iface",
286 .dev_release = iscsi_iface_release,
287};
288
289#define ISCSI_IFACE_ATTR(_prefix, _name, _mode, _show, _store) \
290struct device_attribute dev_attr_##_prefix##_##_name = \
291 __ATTR(_name, _mode, _show, _store)
292
293
294#define iscsi_iface_attr_show(type, name, param_type, param) \
295static ssize_t \
296show_##type##_##name(struct device *dev, struct device_attribute *attr, \
297 char *buf) \
298{ \
299 struct iscsi_iface *iface = iscsi_dev_to_iface(dev); \
300 struct iscsi_transport *t = iface->transport; \
301 return t->get_iface_param(iface, param_type, param, buf); \
302} \
303
304#define iscsi_iface_net_attr(type, name, param) \
305 iscsi_iface_attr_show(type, name, ISCSI_NET_PARAM, param) \
306static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);
307
308
309iscsi_iface_net_attr(ipv4_iface, ipaddress, ISCSI_NET_PARAM_IPV4_ADDR);
310iscsi_iface_net_attr(ipv4_iface, gateway, ISCSI_NET_PARAM_IPV4_GW);
311iscsi_iface_net_attr(ipv4_iface, subnet, ISCSI_NET_PARAM_IPV4_SUBNET);
312iscsi_iface_net_attr(ipv4_iface, bootproto, ISCSI_NET_PARAM_IPV4_BOOTPROTO);
313
314
315iscsi_iface_net_attr(ipv6_iface, ipaddress, ISCSI_NET_PARAM_IPV6_ADDR);
316iscsi_iface_net_attr(ipv6_iface, link_local_addr, ISCSI_NET_PARAM_IPV6_LINKLOCAL);
317iscsi_iface_net_attr(ipv6_iface, router_addr, ISCSI_NET_PARAM_IPV6_ROUTER);
318iscsi_iface_net_attr(ipv6_iface, ipaddr_autocfg,
319 ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG);
320iscsi_iface_net_attr(ipv6_iface, link_local_autocfg,
321 ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG);
322
323
324iscsi_iface_net_attr(iface, enabled, ISCSI_NET_PARAM_IFACE_ENABLE);
325iscsi_iface_net_attr(iface, vlan_id, ISCSI_NET_PARAM_VLAN_ID);
326iscsi_iface_net_attr(iface, vlan_priority, ISCSI_NET_PARAM_VLAN_PRIORITY);
327iscsi_iface_net_attr(iface, vlan_enabled, ISCSI_NET_PARAM_VLAN_ENABLED);
328iscsi_iface_net_attr(iface, mtu, ISCSI_NET_PARAM_MTU);
329iscsi_iface_net_attr(iface, port, ISCSI_NET_PARAM_PORT);
330
331static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
332 struct attribute *attr, int i)
333{
334 struct device *dev = container_of(kobj, struct device, kobj);
335 struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
336 struct iscsi_transport *t = iface->transport;
337 int param;
338
339 if (attr == &dev_attr_iface_enabled.attr)
340 param = ISCSI_NET_PARAM_IFACE_ENABLE;
341 else if (attr == &dev_attr_iface_vlan_id.attr)
342 param = ISCSI_NET_PARAM_VLAN_ID;
343 else if (attr == &dev_attr_iface_vlan_priority.attr)
344 param = ISCSI_NET_PARAM_VLAN_PRIORITY;
345 else if (attr == &dev_attr_iface_vlan_enabled.attr)
346 param = ISCSI_NET_PARAM_VLAN_ENABLED;
347 else if (attr == &dev_attr_iface_mtu.attr)
348 param = ISCSI_NET_PARAM_MTU;
349 else if (attr == &dev_attr_iface_port.attr)
350 param = ISCSI_NET_PARAM_PORT;
351 else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
352 if (attr == &dev_attr_ipv4_iface_ipaddress.attr)
353 param = ISCSI_NET_PARAM_IPV4_ADDR;
354 else if (attr == &dev_attr_ipv4_iface_gateway.attr)
355 param = ISCSI_NET_PARAM_IPV4_GW;
356 else if (attr == &dev_attr_ipv4_iface_subnet.attr)
357 param = ISCSI_NET_PARAM_IPV4_SUBNET;
358 else if (attr == &dev_attr_ipv4_iface_bootproto.attr)
359 param = ISCSI_NET_PARAM_IPV4_BOOTPROTO;
360 else
361 return 0;
362 } else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) {
363 if (attr == &dev_attr_ipv6_iface_ipaddress.attr)
364 param = ISCSI_NET_PARAM_IPV6_ADDR;
365 else if (attr == &dev_attr_ipv6_iface_link_local_addr.attr)
366 param = ISCSI_NET_PARAM_IPV6_LINKLOCAL;
367 else if (attr == &dev_attr_ipv6_iface_router_addr.attr)
368 param = ISCSI_NET_PARAM_IPV6_ROUTER;
369 else if (attr == &dev_attr_ipv6_iface_ipaddr_autocfg.attr)
370 param = ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG;
371 else if (attr == &dev_attr_ipv6_iface_link_local_autocfg.attr)
372 param = ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG;
373 else
374 return 0;
375 } else {
376 WARN_ONCE(1, "Invalid iface attr");
377 return 0;
378 }
379
380 return t->attr_is_visible(ISCSI_NET_PARAM, param);
381}
382
383static struct attribute *iscsi_iface_attrs[] = {
384 &dev_attr_iface_enabled.attr,
385 &dev_attr_iface_vlan_id.attr,
386 &dev_attr_iface_vlan_priority.attr,
387 &dev_attr_iface_vlan_enabled.attr,
388 &dev_attr_ipv4_iface_ipaddress.attr,
389 &dev_attr_ipv4_iface_gateway.attr,
390 &dev_attr_ipv4_iface_subnet.attr,
391 &dev_attr_ipv4_iface_bootproto.attr,
392 &dev_attr_ipv6_iface_ipaddress.attr,
393 &dev_attr_ipv6_iface_link_local_addr.attr,
394 &dev_attr_ipv6_iface_router_addr.attr,
395 &dev_attr_ipv6_iface_ipaddr_autocfg.attr,
396 &dev_attr_ipv6_iface_link_local_autocfg.attr,
397 &dev_attr_iface_mtu.attr,
398 &dev_attr_iface_port.attr,
399 NULL,
400};
401
402static struct attribute_group iscsi_iface_group = {
403 .attrs = iscsi_iface_attrs,
404 .is_visible = iscsi_iface_attr_is_visible,
405};
406
407struct iscsi_iface *
408iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
409 uint32_t iface_type, uint32_t iface_num, int dd_size)
410{
411 struct iscsi_iface *iface;
412 int err;
413
414 iface = kzalloc(sizeof(*iface) + dd_size, GFP_KERNEL);
415 if (!iface)
416 return NULL;
417
418 iface->transport = transport;
419 iface->iface_type = iface_type;
420 iface->iface_num = iface_num;
421 iface->dev.release = iscsi_iface_release;
422 iface->dev.class = &iscsi_iface_class;
423
424 iface->dev.parent = get_device(&shost->shost_gendev);
425 if (iface_type == ISCSI_IFACE_TYPE_IPV4)
426 dev_set_name(&iface->dev, "ipv4-iface-%u-%u", shost->host_no,
427 iface_num);
428 else
429 dev_set_name(&iface->dev, "ipv6-iface-%u-%u", shost->host_no,
430 iface_num);
431
432 err = device_register(&iface->dev);
433 if (err)
434 goto free_iface;
435
436 err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
437 if (err)
438 goto unreg_iface;
439
440 if (dd_size)
441 iface->dd_data = &iface[1];
442 return iface;
443
444unreg_iface:
445 device_unregister(&iface->dev);
446 return NULL;
447
448free_iface:
449 put_device(iface->dev.parent);
450 kfree(iface);
451 return NULL;
452}
453EXPORT_SYMBOL_GPL(iscsi_create_iface);
454
455void iscsi_destroy_iface(struct iscsi_iface *iface)
456{
457 sysfs_remove_group(&iface->dev.kobj, &iscsi_iface_group);
458 device_unregister(&iface->dev);
459}
460EXPORT_SYMBOL_GPL(iscsi_destroy_iface);
461
462
463
464
465
466#define ISCSI_FLASHNODE_ATTR(_prefix, _name, _mode, _show, _store) \
467struct device_attribute dev_attr_##_prefix##_##_name = \
468 __ATTR(_name, _mode, _show, _store)
469
470
471#define iscsi_flashnode_sess_attr_show(type, name, param) \
472static ssize_t \
473show_##type##_##name(struct device *dev, struct device_attribute *attr, \
474 char *buf) \
475{ \
476 struct iscsi_bus_flash_session *fnode_sess = \
477 iscsi_dev_to_flash_session(dev);\
478 struct iscsi_transport *t = fnode_sess->transport; \
479 return t->get_flashnode_param(fnode_sess, param, buf); \
480} \
481
482
483#define iscsi_flashnode_sess_attr(type, name, param) \
484 iscsi_flashnode_sess_attr_show(type, name, param) \
485static ISCSI_FLASHNODE_ATTR(type, name, S_IRUGO, \
486 show_##type##_##name, NULL);
487
488
489
490iscsi_flashnode_sess_attr(fnode, auto_snd_tgt_disable,
491 ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE);
492iscsi_flashnode_sess_attr(fnode, discovery_session,
493 ISCSI_FLASHNODE_DISCOVERY_SESS);
494iscsi_flashnode_sess_attr(fnode, portal_type, ISCSI_FLASHNODE_PORTAL_TYPE);
495iscsi_flashnode_sess_attr(fnode, entry_enable, ISCSI_FLASHNODE_ENTRY_EN);
496iscsi_flashnode_sess_attr(fnode, immediate_data, ISCSI_FLASHNODE_IMM_DATA_EN);
497iscsi_flashnode_sess_attr(fnode, initial_r2t, ISCSI_FLASHNODE_INITIAL_R2T_EN);
498iscsi_flashnode_sess_attr(fnode, data_seq_in_order,
499 ISCSI_FLASHNODE_DATASEQ_INORDER);
500iscsi_flashnode_sess_attr(fnode, data_pdu_in_order,
501 ISCSI_FLASHNODE_PDU_INORDER);
502iscsi_flashnode_sess_attr(fnode, chap_auth, ISCSI_FLASHNODE_CHAP_AUTH_EN);
503iscsi_flashnode_sess_attr(fnode, discovery_logout,
504 ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN);
505iscsi_flashnode_sess_attr(fnode, bidi_chap, ISCSI_FLASHNODE_BIDI_CHAP_EN);
506iscsi_flashnode_sess_attr(fnode, discovery_auth_optional,
507 ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL);
508iscsi_flashnode_sess_attr(fnode, erl, ISCSI_FLASHNODE_ERL);
509iscsi_flashnode_sess_attr(fnode, first_burst_len, ISCSI_FLASHNODE_FIRST_BURST);
510iscsi_flashnode_sess_attr(fnode, def_time2wait, ISCSI_FLASHNODE_DEF_TIME2WAIT);
511iscsi_flashnode_sess_attr(fnode, def_time2retain,
512 ISCSI_FLASHNODE_DEF_TIME2RETAIN);
513iscsi_flashnode_sess_attr(fnode, max_outstanding_r2t, ISCSI_FLASHNODE_MAX_R2T);
514iscsi_flashnode_sess_attr(fnode, isid, ISCSI_FLASHNODE_ISID);
515iscsi_flashnode_sess_attr(fnode, tsid, ISCSI_FLASHNODE_TSID);
516iscsi_flashnode_sess_attr(fnode, max_burst_len, ISCSI_FLASHNODE_MAX_BURST);
517iscsi_flashnode_sess_attr(fnode, def_taskmgmt_tmo,
518 ISCSI_FLASHNODE_DEF_TASKMGMT_TMO);
519iscsi_flashnode_sess_attr(fnode, targetalias, ISCSI_FLASHNODE_ALIAS);
520iscsi_flashnode_sess_attr(fnode, targetname, ISCSI_FLASHNODE_NAME);
521iscsi_flashnode_sess_attr(fnode, tpgt, ISCSI_FLASHNODE_TPGT);
522iscsi_flashnode_sess_attr(fnode, discovery_parent_idx,
523 ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX);
524iscsi_flashnode_sess_attr(fnode, discovery_parent_type,
525 ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE);
526iscsi_flashnode_sess_attr(fnode, chap_in_idx, ISCSI_FLASHNODE_CHAP_IN_IDX);
527iscsi_flashnode_sess_attr(fnode, chap_out_idx, ISCSI_FLASHNODE_CHAP_OUT_IDX);
528iscsi_flashnode_sess_attr(fnode, username, ISCSI_FLASHNODE_USERNAME);
529iscsi_flashnode_sess_attr(fnode, username_in, ISCSI_FLASHNODE_USERNAME_IN);
530iscsi_flashnode_sess_attr(fnode, password, ISCSI_FLASHNODE_PASSWORD);
531iscsi_flashnode_sess_attr(fnode, password_in, ISCSI_FLASHNODE_PASSWORD_IN);
532iscsi_flashnode_sess_attr(fnode, is_boot_target, ISCSI_FLASHNODE_IS_BOOT_TGT);
533
534static struct attribute *iscsi_flashnode_sess_attrs[] = {
535 &dev_attr_fnode_auto_snd_tgt_disable.attr,
536 &dev_attr_fnode_discovery_session.attr,
537 &dev_attr_fnode_portal_type.attr,
538 &dev_attr_fnode_entry_enable.attr,
539 &dev_attr_fnode_immediate_data.attr,
540 &dev_attr_fnode_initial_r2t.attr,
541 &dev_attr_fnode_data_seq_in_order.attr,
542 &dev_attr_fnode_data_pdu_in_order.attr,
543 &dev_attr_fnode_chap_auth.attr,
544 &dev_attr_fnode_discovery_logout.attr,
545 &dev_attr_fnode_bidi_chap.attr,
546 &dev_attr_fnode_discovery_auth_optional.attr,
547 &dev_attr_fnode_erl.attr,
548 &dev_attr_fnode_first_burst_len.attr,
549 &dev_attr_fnode_def_time2wait.attr,
550 &dev_attr_fnode_def_time2retain.attr,
551 &dev_attr_fnode_max_outstanding_r2t.attr,
552 &dev_attr_fnode_isid.attr,
553 &dev_attr_fnode_tsid.attr,
554 &dev_attr_fnode_max_burst_len.attr,
555 &dev_attr_fnode_def_taskmgmt_tmo.attr,
556 &dev_attr_fnode_targetalias.attr,
557 &dev_attr_fnode_targetname.attr,
558 &dev_attr_fnode_tpgt.attr,
559 &dev_attr_fnode_discovery_parent_idx.attr,
560 &dev_attr_fnode_discovery_parent_type.attr,
561 &dev_attr_fnode_chap_in_idx.attr,
562 &dev_attr_fnode_chap_out_idx.attr,
563 &dev_attr_fnode_username.attr,
564 &dev_attr_fnode_username_in.attr,
565 &dev_attr_fnode_password.attr,
566 &dev_attr_fnode_password_in.attr,
567 &dev_attr_fnode_is_boot_target.attr,
568 NULL,
569};
570
571static umode_t iscsi_flashnode_sess_attr_is_visible(struct kobject *kobj,
572 struct attribute *attr,
573 int i)
574{
575 struct device *dev = container_of(kobj, struct device, kobj);
576 struct iscsi_bus_flash_session *fnode_sess =
577 iscsi_dev_to_flash_session(dev);
578 struct iscsi_transport *t = fnode_sess->transport;
579 int param;
580
581 if (attr == &dev_attr_fnode_auto_snd_tgt_disable.attr) {
582 param = ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE;
583 } else if (attr == &dev_attr_fnode_discovery_session.attr) {
584 param = ISCSI_FLASHNODE_DISCOVERY_SESS;
585 } else if (attr == &dev_attr_fnode_portal_type.attr) {
586 param = ISCSI_FLASHNODE_PORTAL_TYPE;
587 } else if (attr == &dev_attr_fnode_entry_enable.attr) {
588 param = ISCSI_FLASHNODE_ENTRY_EN;
589 } else if (attr == &dev_attr_fnode_immediate_data.attr) {
590 param = ISCSI_FLASHNODE_IMM_DATA_EN;
591 } else if (attr == &dev_attr_fnode_initial_r2t.attr) {
592 param = ISCSI_FLASHNODE_INITIAL_R2T_EN;
593 } else if (attr == &dev_attr_fnode_data_seq_in_order.attr) {
594 param = ISCSI_FLASHNODE_DATASEQ_INORDER;
595 } else if (attr == &dev_attr_fnode_data_pdu_in_order.attr) {
596 param = ISCSI_FLASHNODE_PDU_INORDER;
597 } else if (attr == &dev_attr_fnode_chap_auth.attr) {
598 param = ISCSI_FLASHNODE_CHAP_AUTH_EN;
599 } else if (attr == &dev_attr_fnode_discovery_logout.attr) {
600 param = ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN;
601 } else if (attr == &dev_attr_fnode_bidi_chap.attr) {
602 param = ISCSI_FLASHNODE_BIDI_CHAP_EN;
603 } else if (attr == &dev_attr_fnode_discovery_auth_optional.attr) {
604 param = ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL;
605 } else if (attr == &dev_attr_fnode_erl.attr) {
606 param = ISCSI_FLASHNODE_ERL;
607 } else if (attr == &dev_attr_fnode_first_burst_len.attr) {
608 param = ISCSI_FLASHNODE_FIRST_BURST;
609 } else if (attr == &dev_attr_fnode_def_time2wait.attr) {
610 param = ISCSI_FLASHNODE_DEF_TIME2WAIT;
611 } else if (attr == &dev_attr_fnode_def_time2retain.attr) {
612 param = ISCSI_FLASHNODE_DEF_TIME2RETAIN;
613 } else if (attr == &dev_attr_fnode_max_outstanding_r2t.attr) {
614 param = ISCSI_FLASHNODE_MAX_R2T;
615 } else if (attr == &dev_attr_fnode_isid.attr) {
616 param = ISCSI_FLASHNODE_ISID;
617 } else if (attr == &dev_attr_fnode_tsid.attr) {
618 param = ISCSI_FLASHNODE_TSID;
619 } else if (attr == &dev_attr_fnode_max_burst_len.attr) {
620 param = ISCSI_FLASHNODE_MAX_BURST;
621 } else if (attr == &dev_attr_fnode_def_taskmgmt_tmo.attr) {
622 param = ISCSI_FLASHNODE_DEF_TASKMGMT_TMO;
623 } else if (attr == &dev_attr_fnode_targetalias.attr) {
624 param = ISCSI_FLASHNODE_ALIAS;
625 } else if (attr == &dev_attr_fnode_targetname.attr) {
626 param = ISCSI_FLASHNODE_NAME;
627 } else if (attr == &dev_attr_fnode_tpgt.attr) {
628 param = ISCSI_FLASHNODE_TPGT;
629 } else if (attr == &dev_attr_fnode_discovery_parent_idx.attr) {
630 param = ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX;
631 } else if (attr == &dev_attr_fnode_discovery_parent_type.attr) {
632 param = ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE;
633 } else if (attr == &dev_attr_fnode_chap_in_idx.attr) {
634 param = ISCSI_FLASHNODE_CHAP_IN_IDX;
635 } else if (attr == &dev_attr_fnode_chap_out_idx.attr) {
636 param = ISCSI_FLASHNODE_CHAP_OUT_IDX;
637 } else if (attr == &dev_attr_fnode_username.attr) {
638 param = ISCSI_FLASHNODE_USERNAME;
639 } else if (attr == &dev_attr_fnode_username_in.attr) {
640 param = ISCSI_FLASHNODE_USERNAME_IN;
641 } else if (attr == &dev_attr_fnode_password.attr) {
642 param = ISCSI_FLASHNODE_PASSWORD;
643 } else if (attr == &dev_attr_fnode_password_in.attr) {
644 param = ISCSI_FLASHNODE_PASSWORD_IN;
645 } else if (attr == &dev_attr_fnode_is_boot_target.attr) {
646 param = ISCSI_FLASHNODE_IS_BOOT_TGT;
647 } else {
648 WARN_ONCE(1, "Invalid flashnode session attr");
649 return 0;
650 }
651
652 return t->attr_is_visible(ISCSI_FLASHNODE_PARAM, param);
653}
654
655static struct attribute_group iscsi_flashnode_sess_attr_group = {
656 .attrs = iscsi_flashnode_sess_attrs,
657 .is_visible = iscsi_flashnode_sess_attr_is_visible,
658};
659
660static const struct attribute_group *iscsi_flashnode_sess_attr_groups[] = {
661 &iscsi_flashnode_sess_attr_group,
662 NULL,
663};
664
665static void iscsi_flashnode_sess_release(struct device *dev)
666{
667 struct iscsi_bus_flash_session *fnode_sess =
668 iscsi_dev_to_flash_session(dev);
669
670 kfree(fnode_sess->targetname);
671 kfree(fnode_sess->targetalias);
672 kfree(fnode_sess->portal_type);
673 kfree(fnode_sess);
674}
675
676struct device_type iscsi_flashnode_sess_dev_type = {
677 .name = "iscsi_flashnode_sess_dev_type",
678 .groups = iscsi_flashnode_sess_attr_groups,
679 .release = iscsi_flashnode_sess_release,
680};
681
682
683#define iscsi_flashnode_conn_attr_show(type, name, param) \
684static ssize_t \
685show_##type##_##name(struct device *dev, struct device_attribute *attr, \
686 char *buf) \
687{ \
688 struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);\
689 struct iscsi_bus_flash_session *fnode_sess = \
690 iscsi_flash_conn_to_flash_session(fnode_conn);\
691 struct iscsi_transport *t = fnode_conn->transport; \
692 return t->get_flashnode_param(fnode_sess, param, buf); \
693} \
694
695
696#define iscsi_flashnode_conn_attr(type, name, param) \
697 iscsi_flashnode_conn_attr_show(type, name, param) \
698static ISCSI_FLASHNODE_ATTR(type, name, S_IRUGO, \
699 show_##type##_##name, NULL);
700
701
702
703iscsi_flashnode_conn_attr(fnode, is_fw_assigned_ipv6,
704 ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6);
705iscsi_flashnode_conn_attr(fnode, header_digest, ISCSI_FLASHNODE_HDR_DGST_EN);
706iscsi_flashnode_conn_attr(fnode, data_digest, ISCSI_FLASHNODE_DATA_DGST_EN);
707iscsi_flashnode_conn_attr(fnode, snack_req, ISCSI_FLASHNODE_SNACK_REQ_EN);
708iscsi_flashnode_conn_attr(fnode, tcp_timestamp_stat,
709 ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT);
710iscsi_flashnode_conn_attr(fnode, tcp_nagle_disable,
711 ISCSI_FLASHNODE_TCP_NAGLE_DISABLE);
712iscsi_flashnode_conn_attr(fnode, tcp_wsf_disable,
713 ISCSI_FLASHNODE_TCP_WSF_DISABLE);
714iscsi_flashnode_conn_attr(fnode, tcp_timer_scale,
715 ISCSI_FLASHNODE_TCP_TIMER_SCALE);
716iscsi_flashnode_conn_attr(fnode, tcp_timestamp_enable,
717 ISCSI_FLASHNODE_TCP_TIMESTAMP_EN);
718iscsi_flashnode_conn_attr(fnode, fragment_disable,
719 ISCSI_FLASHNODE_IP_FRAG_DISABLE);
720iscsi_flashnode_conn_attr(fnode, keepalive_tmo, ISCSI_FLASHNODE_KEEPALIVE_TMO);
721iscsi_flashnode_conn_attr(fnode, port, ISCSI_FLASHNODE_PORT);
722iscsi_flashnode_conn_attr(fnode, ipaddress, ISCSI_FLASHNODE_IPADDR);
723iscsi_flashnode_conn_attr(fnode, max_recv_dlength,
724 ISCSI_FLASHNODE_MAX_RECV_DLENGTH);
725iscsi_flashnode_conn_attr(fnode, max_xmit_dlength,
726 ISCSI_FLASHNODE_MAX_XMIT_DLENGTH);
727iscsi_flashnode_conn_attr(fnode, local_port, ISCSI_FLASHNODE_LOCAL_PORT);
728iscsi_flashnode_conn_attr(fnode, ipv4_tos, ISCSI_FLASHNODE_IPV4_TOS);
729iscsi_flashnode_conn_attr(fnode, ipv6_traffic_class, ISCSI_FLASHNODE_IPV6_TC);
730iscsi_flashnode_conn_attr(fnode, ipv6_flow_label,
731 ISCSI_FLASHNODE_IPV6_FLOW_LABEL);
732iscsi_flashnode_conn_attr(fnode, redirect_ipaddr,
733 ISCSI_FLASHNODE_REDIRECT_IPADDR);
734iscsi_flashnode_conn_attr(fnode, max_segment_size,
735 ISCSI_FLASHNODE_MAX_SEGMENT_SIZE);
736iscsi_flashnode_conn_attr(fnode, link_local_ipv6,
737 ISCSI_FLASHNODE_LINK_LOCAL_IPV6);
738iscsi_flashnode_conn_attr(fnode, tcp_xmit_wsf, ISCSI_FLASHNODE_TCP_XMIT_WSF);
739iscsi_flashnode_conn_attr(fnode, tcp_recv_wsf, ISCSI_FLASHNODE_TCP_RECV_WSF);
740iscsi_flashnode_conn_attr(fnode, statsn, ISCSI_FLASHNODE_STATSN);
741iscsi_flashnode_conn_attr(fnode, exp_statsn, ISCSI_FLASHNODE_EXP_STATSN);
742
743static struct attribute *iscsi_flashnode_conn_attrs[] = {
744 &dev_attr_fnode_is_fw_assigned_ipv6.attr,
745 &dev_attr_fnode_header_digest.attr,
746 &dev_attr_fnode_data_digest.attr,
747 &dev_attr_fnode_snack_req.attr,
748 &dev_attr_fnode_tcp_timestamp_stat.attr,
749 &dev_attr_fnode_tcp_nagle_disable.attr,
750 &dev_attr_fnode_tcp_wsf_disable.attr,
751 &dev_attr_fnode_tcp_timer_scale.attr,
752 &dev_attr_fnode_tcp_timestamp_enable.attr,
753 &dev_attr_fnode_fragment_disable.attr,
754 &dev_attr_fnode_max_recv_dlength.attr,
755 &dev_attr_fnode_max_xmit_dlength.attr,
756 &dev_attr_fnode_keepalive_tmo.attr,
757 &dev_attr_fnode_port.attr,
758 &dev_attr_fnode_ipaddress.attr,
759 &dev_attr_fnode_redirect_ipaddr.attr,
760 &dev_attr_fnode_max_segment_size.attr,
761 &dev_attr_fnode_local_port.attr,
762 &dev_attr_fnode_ipv4_tos.attr,
763 &dev_attr_fnode_ipv6_traffic_class.attr,
764 &dev_attr_fnode_ipv6_flow_label.attr,
765 &dev_attr_fnode_link_local_ipv6.attr,
766 &dev_attr_fnode_tcp_xmit_wsf.attr,
767 &dev_attr_fnode_tcp_recv_wsf.attr,
768 &dev_attr_fnode_statsn.attr,
769 &dev_attr_fnode_exp_statsn.attr,
770 NULL,
771};
772
773static umode_t iscsi_flashnode_conn_attr_is_visible(struct kobject *kobj,
774 struct attribute *attr,
775 int i)
776{
777 struct device *dev = container_of(kobj, struct device, kobj);
778 struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);
779 struct iscsi_transport *t = fnode_conn->transport;
780 int param;
781
782 if (attr == &dev_attr_fnode_is_fw_assigned_ipv6.attr) {
783 param = ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6;
784 } else if (attr == &dev_attr_fnode_header_digest.attr) {
785 param = ISCSI_FLASHNODE_HDR_DGST_EN;
786 } else if (attr == &dev_attr_fnode_data_digest.attr) {
787 param = ISCSI_FLASHNODE_DATA_DGST_EN;
788 } else if (attr == &dev_attr_fnode_snack_req.attr) {
789 param = ISCSI_FLASHNODE_SNACK_REQ_EN;
790 } else if (attr == &dev_attr_fnode_tcp_timestamp_stat.attr) {
791 param = ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT;
792 } else if (attr == &dev_attr_fnode_tcp_nagle_disable.attr) {
793 param = ISCSI_FLASHNODE_TCP_NAGLE_DISABLE;
794 } else if (attr == &dev_attr_fnode_tcp_wsf_disable.attr) {
795 param = ISCSI_FLASHNODE_TCP_WSF_DISABLE;
796 } else if (attr == &dev_attr_fnode_tcp_timer_scale.attr) {
797 param = ISCSI_FLASHNODE_TCP_TIMER_SCALE;
798 } else if (attr == &dev_attr_fnode_tcp_timestamp_enable.attr) {
799 param = ISCSI_FLASHNODE_TCP_TIMESTAMP_EN;
800 } else if (attr == &dev_attr_fnode_fragment_disable.attr) {
801 param = ISCSI_FLASHNODE_IP_FRAG_DISABLE;
802 } else if (attr == &dev_attr_fnode_max_recv_dlength.attr) {
803 param = ISCSI_FLASHNODE_MAX_RECV_DLENGTH;
804 } else if (attr == &dev_attr_fnode_max_xmit_dlength.attr) {
805 param = ISCSI_FLASHNODE_MAX_XMIT_DLENGTH;
806 } else if (attr == &dev_attr_fnode_keepalive_tmo.attr) {
807 param = ISCSI_FLASHNODE_KEEPALIVE_TMO;
808 } else if (attr == &dev_attr_fnode_port.attr) {
809 param = ISCSI_FLASHNODE_PORT;
810 } else if (attr == &dev_attr_fnode_ipaddress.attr) {
811 param = ISCSI_FLASHNODE_IPADDR;
812 } else if (attr == &dev_attr_fnode_redirect_ipaddr.attr) {
813 param = ISCSI_FLASHNODE_REDIRECT_IPADDR;
814 } else if (attr == &dev_attr_fnode_max_segment_size.attr) {
815 param = ISCSI_FLASHNODE_MAX_SEGMENT_SIZE;
816 } else if (attr == &dev_attr_fnode_local_port.attr) {
817 param = ISCSI_FLASHNODE_LOCAL_PORT;
818 } else if (attr == &dev_attr_fnode_ipv4_tos.attr) {
819 param = ISCSI_FLASHNODE_IPV4_TOS;
820 } else if (attr == &dev_attr_fnode_ipv6_traffic_class.attr) {
821 param = ISCSI_FLASHNODE_IPV6_TC;
822 } else if (attr == &dev_attr_fnode_ipv6_flow_label.attr) {
823 param = ISCSI_FLASHNODE_IPV6_FLOW_LABEL;
824 } else if (attr == &dev_attr_fnode_link_local_ipv6.attr) {
825 param = ISCSI_FLASHNODE_LINK_LOCAL_IPV6;
826 } else if (attr == &dev_attr_fnode_tcp_xmit_wsf.attr) {
827 param = ISCSI_FLASHNODE_TCP_XMIT_WSF;
828 } else if (attr == &dev_attr_fnode_tcp_recv_wsf.attr) {
829 param = ISCSI_FLASHNODE_TCP_RECV_WSF;
830 } else if (attr == &dev_attr_fnode_statsn.attr) {
831 param = ISCSI_FLASHNODE_STATSN;
832 } else if (attr == &dev_attr_fnode_exp_statsn.attr) {
833 param = ISCSI_FLASHNODE_EXP_STATSN;
834 } else {
835 WARN_ONCE(1, "Invalid flashnode connection attr");
836 return 0;
837 }
838
839 return t->attr_is_visible(ISCSI_FLASHNODE_PARAM, param);
840}
841
842static struct attribute_group iscsi_flashnode_conn_attr_group = {
843 .attrs = iscsi_flashnode_conn_attrs,
844 .is_visible = iscsi_flashnode_conn_attr_is_visible,
845};
846
847static const struct attribute_group *iscsi_flashnode_conn_attr_groups[] = {
848 &iscsi_flashnode_conn_attr_group,
849 NULL,
850};
851
852static void iscsi_flashnode_conn_release(struct device *dev)
853{
854 struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);
855
856 kfree(fnode_conn->ipaddress);
857 kfree(fnode_conn->redirect_ipaddr);
858 kfree(fnode_conn->link_local_ipv6_addr);
859 kfree(fnode_conn);
860}
861
862struct device_type iscsi_flashnode_conn_dev_type = {
863 .name = "iscsi_flashnode_conn_dev_type",
864 .groups = iscsi_flashnode_conn_attr_groups,
865 .release = iscsi_flashnode_conn_release,
866};
867
868struct bus_type iscsi_flashnode_bus;
869
870int iscsi_flashnode_bus_match(struct device *dev,
871 struct device_driver *drv)
872{
873 if (dev->bus == &iscsi_flashnode_bus)
874 return 1;
875 return 0;
876}
877EXPORT_SYMBOL_GPL(iscsi_flashnode_bus_match);
878
879struct bus_type iscsi_flashnode_bus = {
880 .name = "iscsi_flashnode",
881 .match = &iscsi_flashnode_bus_match,
882};
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897struct iscsi_bus_flash_session *
898iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
899 struct iscsi_transport *transport,
900 int dd_size)
901{
902 struct iscsi_bus_flash_session *fnode_sess;
903 int err;
904
905 fnode_sess = kzalloc(sizeof(*fnode_sess) + dd_size, GFP_KERNEL);
906 if (!fnode_sess)
907 return NULL;
908
909 fnode_sess->transport = transport;
910 fnode_sess->target_id = index;
911 fnode_sess->dev.type = &iscsi_flashnode_sess_dev_type;
912 fnode_sess->dev.bus = &iscsi_flashnode_bus;
913 fnode_sess->dev.parent = &shost->shost_gendev;
914 dev_set_name(&fnode_sess->dev, "flashnode_sess-%u:%u",
915 shost->host_no, index);
916
917 err = device_register(&fnode_sess->dev);
918 if (err)
919 goto free_fnode_sess;
920
921 if (dd_size)
922 fnode_sess->dd_data = &fnode_sess[1];
923
924 return fnode_sess;
925
926free_fnode_sess:
927 kfree(fnode_sess);
928 return NULL;
929}
930EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945struct iscsi_bus_flash_conn *
946iscsi_create_flashnode_conn(struct Scsi_Host *shost,
947 struct iscsi_bus_flash_session *fnode_sess,
948 struct iscsi_transport *transport,
949 int dd_size)
950{
951 struct iscsi_bus_flash_conn *fnode_conn;
952 int err;
953
954 fnode_conn = kzalloc(sizeof(*fnode_conn) + dd_size, GFP_KERNEL);
955 if (!fnode_conn)
956 return NULL;
957
958 fnode_conn->transport = transport;
959 fnode_conn->dev.type = &iscsi_flashnode_conn_dev_type;
960 fnode_conn->dev.bus = &iscsi_flashnode_bus;
961 fnode_conn->dev.parent = &fnode_sess->dev;
962 dev_set_name(&fnode_conn->dev, "flashnode_conn-%u:%u:0",
963 shost->host_no, fnode_sess->target_id);
964
965 err = device_register(&fnode_conn->dev);
966 if (err)
967 goto free_fnode_conn;
968
969 if (dd_size)
970 fnode_conn->dd_data = &fnode_conn[1];
971
972 return fnode_conn;
973
974free_fnode_conn:
975 kfree(fnode_conn);
976 return NULL;
977}
978EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
979
980
981
982
983
984
985
986
987
988
989
990
991int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
992{
993 return dev->bus == &iscsi_flashnode_bus;
994}
995EXPORT_SYMBOL_GPL(iscsi_is_flashnode_conn_dev);
996
997static int iscsi_destroy_flashnode_conn(struct iscsi_bus_flash_conn *fnode_conn)
998{
999 device_unregister(&fnode_conn->dev);
1000 return 0;
1001}
1002
1003static int flashnode_match_index(struct device *dev, void *data)
1004{
1005 struct iscsi_bus_flash_session *fnode_sess = NULL;
1006 int ret = 0;
1007
1008 if (!iscsi_flashnode_bus_match(dev, NULL))
1009 goto exit_match_index;
1010
1011 fnode_sess = iscsi_dev_to_flash_session(dev);
1012 ret = (fnode_sess->target_id == *((int *)data)) ? 1 : 0;
1013
1014exit_match_index:
1015 return ret;
1016}
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029static struct iscsi_bus_flash_session *
1030iscsi_get_flashnode_by_index(struct Scsi_Host *shost, uint32_t idx)
1031{
1032 struct iscsi_bus_flash_session *fnode_sess = NULL;
1033 struct device *dev;
1034
1035 dev = device_find_child(&shost->shost_gendev, &idx,
1036 flashnode_match_index);
1037 if (dev)
1038 fnode_sess = iscsi_dev_to_flash_session(dev);
1039
1040 return fnode_sess;
1041}
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056struct device *
1057iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,
1058 int (*fn)(struct device *dev, void *data))
1059{
1060 return device_find_child(&shost->shost_gendev, data, fn);
1061}
1062EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess);
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075struct device *
1076iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess)
1077{
1078 return device_find_child(&fnode_sess->dev, NULL,
1079 iscsi_is_flashnode_conn_dev);
1080}
1081EXPORT_SYMBOL_GPL(iscsi_find_flashnode_conn);
1082
1083static int iscsi_iter_destroy_flashnode_conn_fn(struct device *dev, void *data)
1084{
1085 if (!iscsi_is_flashnode_conn_dev(dev, NULL))
1086 return 0;
1087
1088 return iscsi_destroy_flashnode_conn(iscsi_dev_to_flash_conn(dev));
1089}
1090
1091
1092
1093
1094
1095
1096
1097
1098void iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess)
1099{
1100 int err;
1101
1102 err = device_for_each_child(&fnode_sess->dev, NULL,
1103 iscsi_iter_destroy_flashnode_conn_fn);
1104 if (err)
1105 pr_err("Could not delete all connections for %s. Error %d.\n",
1106 fnode_sess->dev.kobj.name, err);
1107
1108 device_unregister(&fnode_sess->dev);
1109}
1110EXPORT_SYMBOL_GPL(iscsi_destroy_flashnode_sess);
1111
1112static int iscsi_iter_destroy_flashnode_fn(struct device *dev, void *data)
1113{
1114 if (!iscsi_flashnode_bus_match(dev, NULL))
1115 return 0;
1116
1117 iscsi_destroy_flashnode_sess(iscsi_dev_to_flash_session(dev));
1118 return 0;
1119}
1120
1121
1122
1123
1124
1125
1126
1127
1128void iscsi_destroy_all_flashnode(struct Scsi_Host *shost)
1129{
1130 device_for_each_child(&shost->shost_gendev, NULL,
1131 iscsi_iter_destroy_flashnode_fn);
1132}
1133EXPORT_SYMBOL_GPL(iscsi_destroy_all_flashnode);
1134
1135
1136
1137
1138
1139
1140
1141
1142static int iscsi_bsg_host_dispatch(struct bsg_job *job)
1143{
1144 struct Scsi_Host *shost = iscsi_job_to_shost(job);
1145 struct iscsi_bsg_request *req = job->request;
1146 struct iscsi_bsg_reply *reply = job->reply;
1147 struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
1148 int cmdlen = sizeof(uint32_t);
1149 int ret;
1150
1151
1152 if (job->request_len < sizeof(uint32_t)) {
1153 ret = -ENOMSG;
1154 goto fail_host_msg;
1155 }
1156
1157
1158 switch (req->msgcode) {
1159 case ISCSI_BSG_HST_VENDOR:
1160 cmdlen += sizeof(struct iscsi_bsg_host_vendor);
1161 if ((shost->hostt->vendor_id == 0L) ||
1162 (req->rqst_data.h_vendor.vendor_id !=
1163 shost->hostt->vendor_id)) {
1164 ret = -ESRCH;
1165 goto fail_host_msg;
1166 }
1167 break;
1168 default:
1169 ret = -EBADR;
1170 goto fail_host_msg;
1171 }
1172
1173
1174 if (job->request_len < cmdlen) {
1175 ret = -ENOMSG;
1176 goto fail_host_msg;
1177 }
1178
1179 ret = i->iscsi_transport->bsg_request(job);
1180 if (!ret)
1181 return 0;
1182
1183fail_host_msg:
1184
1185 BUG_ON(job->reply_len < sizeof(uint32_t));
1186 reply->reply_payload_rcv_len = 0;
1187 reply->result = ret;
1188 job->reply_len = sizeof(uint32_t);
1189 bsg_job_done(job, ret, 0);
1190 return 0;
1191}
1192
1193
1194
1195
1196
1197
1198static int
1199iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost)
1200{
1201 struct device *dev = &shost->shost_gendev;
1202 struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
1203 struct request_queue *q;
1204 char bsg_name[20];
1205 int ret;
1206
1207 if (!i->iscsi_transport->bsg_request)
1208 return -ENOTSUPP;
1209
1210 snprintf(bsg_name, sizeof(bsg_name), "iscsi_host%d", shost->host_no);
1211
1212 q = __scsi_alloc_queue(shost, bsg_request_fn);
1213 if (!q)
1214 return -ENOMEM;
1215
1216 ret = bsg_setup_queue(dev, q, bsg_name, iscsi_bsg_host_dispatch, 0);
1217 if (ret) {
1218 shost_printk(KERN_ERR, shost, "bsg interface failed to "
1219 "initialize - no request queue\n");
1220 blk_cleanup_queue(q);
1221 return ret;
1222 }
1223
1224 ihost->bsg_q = q;
1225 return 0;
1226}
1227
1228static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
1229 struct device *cdev)
1230{
1231 struct Scsi_Host *shost = dev_to_shost(dev);
1232 struct iscsi_cls_host *ihost = shost->shost_data;
1233
1234 memset(ihost, 0, sizeof(*ihost));
1235 atomic_set(&ihost->nr_scans, 0);
1236 mutex_init(&ihost->mutex);
1237
1238 iscsi_bsg_host_add(shost, ihost);
1239
1240
1241 return 0;
1242}
1243
1244static int iscsi_remove_host(struct transport_container *tc,
1245 struct device *dev, struct device *cdev)
1246{
1247 struct Scsi_Host *shost = dev_to_shost(dev);
1248 struct iscsi_cls_host *ihost = shost->shost_data;
1249
1250 if (ihost->bsg_q) {
1251 bsg_unregister_queue(ihost->bsg_q);
1252 blk_cleanup_queue(ihost->bsg_q);
1253 }
1254 return 0;
1255}
1256
1257static DECLARE_TRANSPORT_CLASS(iscsi_host_class,
1258 "iscsi_host",
1259 iscsi_setup_host,
1260 iscsi_remove_host,
1261 NULL);
1262
1263static DECLARE_TRANSPORT_CLASS(iscsi_session_class,
1264 "iscsi_session",
1265 NULL,
1266 NULL,
1267 NULL);
1268
1269static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
1270 "iscsi_connection",
1271 NULL,
1272 NULL,
1273 NULL);
1274
1275static struct sock *nls;
1276static DEFINE_MUTEX(rx_queue_mutex);
1277
1278static LIST_HEAD(sesslist);
1279static DEFINE_SPINLOCK(sesslock);
1280static LIST_HEAD(connlist);
1281static DEFINE_SPINLOCK(connlock);
1282
1283static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn)
1284{
1285 struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent);
1286 return sess->sid;
1287}
1288
1289
1290
1291
1292static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
1293{
1294 unsigned long flags;
1295 struct iscsi_cls_session *sess;
1296
1297 spin_lock_irqsave(&sesslock, flags);
1298 list_for_each_entry(sess, &sesslist, sess_list) {
1299 if (sess->sid == sid) {
1300 spin_unlock_irqrestore(&sesslock, flags);
1301 return sess;
1302 }
1303 }
1304 spin_unlock_irqrestore(&sesslock, flags);
1305 return NULL;
1306}
1307
1308
1309
1310
1311static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid)
1312{
1313 unsigned long flags;
1314 struct iscsi_cls_conn *conn;
1315
1316 spin_lock_irqsave(&connlock, flags);
1317 list_for_each_entry(conn, &connlist, conn_list) {
1318 if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) {
1319 spin_unlock_irqrestore(&connlock, flags);
1320 return conn;
1321 }
1322 }
1323 spin_unlock_irqrestore(&connlock, flags);
1324 return NULL;
1325}
1326
1327
1328
1329
1330
1331static struct {
1332 int value;
1333 char *name;
1334} iscsi_session_state_names[] = {
1335 { ISCSI_SESSION_LOGGED_IN, "LOGGED_IN" },
1336 { ISCSI_SESSION_FAILED, "FAILED" },
1337 { ISCSI_SESSION_FREE, "FREE" },
1338};
1339
1340static const char *iscsi_session_state_name(int state)
1341{
1342 int i;
1343 char *name = NULL;
1344
1345 for (i = 0; i < ARRAY_SIZE(iscsi_session_state_names); i++) {
1346 if (iscsi_session_state_names[i].value == state) {
1347 name = iscsi_session_state_names[i].name;
1348 break;
1349 }
1350 }
1351 return name;
1352}
1353
1354int iscsi_session_chkready(struct iscsi_cls_session *session)
1355{
1356 unsigned long flags;
1357 int err;
1358
1359 spin_lock_irqsave(&session->lock, flags);
1360 switch (session->state) {
1361 case ISCSI_SESSION_LOGGED_IN:
1362 err = 0;
1363 break;
1364 case ISCSI_SESSION_FAILED:
1365 err = DID_IMM_RETRY << 16;
1366 break;
1367 case ISCSI_SESSION_FREE:
1368 err = DID_TRANSPORT_FAILFAST << 16;
1369 break;
1370 default:
1371 err = DID_NO_CONNECT << 16;
1372 break;
1373 }
1374 spin_unlock_irqrestore(&session->lock, flags);
1375 return err;
1376}
1377EXPORT_SYMBOL_GPL(iscsi_session_chkready);
1378
1379int iscsi_is_session_online(struct iscsi_cls_session *session)
1380{
1381 unsigned long flags;
1382 int ret = 0;
1383
1384 spin_lock_irqsave(&session->lock, flags);
1385 if (session->state == ISCSI_SESSION_LOGGED_IN)
1386 ret = 1;
1387 spin_unlock_irqrestore(&session->lock, flags);
1388 return ret;
1389}
1390EXPORT_SYMBOL_GPL(iscsi_is_session_online);
1391
1392static void iscsi_session_release(struct device *dev)
1393{
1394 struct iscsi_cls_session *session = iscsi_dev_to_session(dev);
1395 struct Scsi_Host *shost;
1396
1397 shost = iscsi_session_to_shost(session);
1398 scsi_host_put(shost);
1399 ISCSI_DBG_TRANS_SESSION(session, "Completing session release\n");
1400 kfree(session);
1401}
1402
1403int iscsi_is_session_dev(const struct device *dev)
1404{
1405 return dev->release == iscsi_session_release;
1406}
1407EXPORT_SYMBOL_GPL(iscsi_is_session_dev);
1408
1409static int iscsi_iter_session_fn(struct device *dev, void *data)
1410{
1411 void (* fn) (struct iscsi_cls_session *) = data;
1412
1413 if (!iscsi_is_session_dev(dev))
1414 return 0;
1415 fn(iscsi_dev_to_session(dev));
1416 return 0;
1417}
1418
1419void iscsi_host_for_each_session(struct Scsi_Host *shost,
1420 void (*fn)(struct iscsi_cls_session *))
1421{
1422 device_for_each_child(&shost->shost_gendev, fn,
1423 iscsi_iter_session_fn);
1424}
1425EXPORT_SYMBOL_GPL(iscsi_host_for_each_session);
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time)
1436{
1437 struct iscsi_cls_host *ihost = shost->shost_data;
1438
1439
1440
1441
1442 return !atomic_read(&ihost->nr_scans);
1443}
1444EXPORT_SYMBOL_GPL(iscsi_scan_finished);
1445
1446struct iscsi_scan_data {
1447 unsigned int channel;
1448 unsigned int id;
1449 unsigned int lun;
1450};
1451
1452static int iscsi_user_scan_session(struct device *dev, void *data)
1453{
1454 struct iscsi_scan_data *scan_data = data;
1455 struct iscsi_cls_session *session;
1456 struct Scsi_Host *shost;
1457 struct iscsi_cls_host *ihost;
1458 unsigned long flags;
1459 unsigned int id;
1460
1461 if (!iscsi_is_session_dev(dev))
1462 return 0;
1463
1464 session = iscsi_dev_to_session(dev);
1465
1466 ISCSI_DBG_TRANS_SESSION(session, "Scanning session\n");
1467
1468 shost = iscsi_session_to_shost(session);
1469 ihost = shost->shost_data;
1470
1471 mutex_lock(&ihost->mutex);
1472 spin_lock_irqsave(&session->lock, flags);
1473 if (session->state != ISCSI_SESSION_LOGGED_IN) {
1474 spin_unlock_irqrestore(&session->lock, flags);
1475 goto user_scan_exit;
1476 }
1477 id = session->target_id;
1478 spin_unlock_irqrestore(&session->lock, flags);
1479
1480 if (id != ISCSI_MAX_TARGET) {
1481 if ((scan_data->channel == SCAN_WILD_CARD ||
1482 scan_data->channel == 0) &&
1483 (scan_data->id == SCAN_WILD_CARD ||
1484 scan_data->id == id))
1485 scsi_scan_target(&session->dev, 0, id,
1486 scan_data->lun, 1);
1487 }
1488
1489user_scan_exit:
1490 mutex_unlock(&ihost->mutex);
1491 ISCSI_DBG_TRANS_SESSION(session, "Completed session scan\n");
1492 return 0;
1493}
1494
1495static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
1496 uint id, uint lun)
1497{
1498 struct iscsi_scan_data scan_data;
1499
1500 scan_data.channel = channel;
1501 scan_data.id = id;
1502 scan_data.lun = lun;
1503
1504 return device_for_each_child(&shost->shost_gendev, &scan_data,
1505 iscsi_user_scan_session);
1506}
1507
1508static void iscsi_scan_session(struct work_struct *work)
1509{
1510 struct iscsi_cls_session *session =
1511 container_of(work, struct iscsi_cls_session, scan_work);
1512 struct Scsi_Host *shost = iscsi_session_to_shost(session);
1513 struct iscsi_cls_host *ihost = shost->shost_data;
1514 struct iscsi_scan_data scan_data;
1515
1516 scan_data.channel = 0;
1517 scan_data.id = SCAN_WILD_CARD;
1518 scan_data.lun = SCAN_WILD_CARD;
1519
1520 iscsi_user_scan_session(&session->dev, &scan_data);
1521 atomic_dec(&ihost->nr_scans);
1522}
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533int iscsi_block_scsi_eh(struct scsi_cmnd *cmd)
1534{
1535 struct iscsi_cls_session *session =
1536 starget_to_session(scsi_target(cmd->device));
1537 unsigned long flags;
1538 int ret = 0;
1539
1540 spin_lock_irqsave(&session->lock, flags);
1541 while (session->state != ISCSI_SESSION_LOGGED_IN) {
1542 if (session->state == ISCSI_SESSION_FREE) {
1543 ret = FAST_IO_FAIL;
1544 break;
1545 }
1546 spin_unlock_irqrestore(&session->lock, flags);
1547 msleep(1000);
1548 spin_lock_irqsave(&session->lock, flags);
1549 }
1550 spin_unlock_irqrestore(&session->lock, flags);
1551 return ret;
1552}
1553EXPORT_SYMBOL_GPL(iscsi_block_scsi_eh);
1554
1555static void session_recovery_timedout(struct work_struct *work)
1556{
1557 struct iscsi_cls_session *session =
1558 container_of(work, struct iscsi_cls_session,
1559 recovery_work.work);
1560 unsigned long flags;
1561
1562 iscsi_cls_session_printk(KERN_INFO, session,
1563 "session recovery timed out after %d secs\n",
1564 session->recovery_tmo);
1565
1566 spin_lock_irqsave(&session->lock, flags);
1567 switch (session->state) {
1568 case ISCSI_SESSION_FAILED:
1569 session->state = ISCSI_SESSION_FREE;
1570 break;
1571 case ISCSI_SESSION_LOGGED_IN:
1572 case ISCSI_SESSION_FREE:
1573
1574 spin_unlock_irqrestore(&session->lock, flags);
1575 return;
1576 }
1577 spin_unlock_irqrestore(&session->lock, flags);
1578
1579 if (session->transport->session_recovery_timedout)
1580 session->transport->session_recovery_timedout(session);
1581
1582 ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
1583 scsi_target_unblock(&session->dev, SDEV_TRANSPORT_OFFLINE);
1584 ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
1585}
1586
1587static void __iscsi_unblock_session(struct work_struct *work)
1588{
1589 struct iscsi_cls_session *session =
1590 container_of(work, struct iscsi_cls_session,
1591 unblock_work);
1592 struct Scsi_Host *shost = iscsi_session_to_shost(session);
1593 struct iscsi_cls_host *ihost = shost->shost_data;
1594 unsigned long flags;
1595
1596 ISCSI_DBG_TRANS_SESSION(session, "Unblocking session\n");
1597
1598
1599
1600
1601 cancel_delayed_work(&session->recovery_work);
1602 spin_lock_irqsave(&session->lock, flags);
1603 session->state = ISCSI_SESSION_LOGGED_IN;
1604 spin_unlock_irqrestore(&session->lock, flags);
1605
1606 scsi_target_unblock(&session->dev, SDEV_RUNNING);
1607
1608
1609
1610
1611
1612 if (shost->hostt->scan_finished) {
1613 if (scsi_queue_work(shost, &session->scan_work))
1614 atomic_inc(&ihost->nr_scans);
1615 }
1616 ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking session\n");
1617}
1618
1619
1620
1621
1622
1623
1624
1625void iscsi_unblock_session(struct iscsi_cls_session *session)
1626{
1627 queue_work(iscsi_eh_timer_workq, &session->unblock_work);
1628
1629
1630
1631
1632 flush_workqueue(iscsi_eh_timer_workq);
1633}
1634EXPORT_SYMBOL_GPL(iscsi_unblock_session);
1635
1636static void __iscsi_block_session(struct work_struct *work)
1637{
1638 struct iscsi_cls_session *session =
1639 container_of(work, struct iscsi_cls_session,
1640 block_work);
1641 unsigned long flags;
1642
1643 ISCSI_DBG_TRANS_SESSION(session, "Blocking session\n");
1644 spin_lock_irqsave(&session->lock, flags);
1645 session->state = ISCSI_SESSION_FAILED;
1646 spin_unlock_irqrestore(&session->lock, flags);
1647 scsi_target_block(&session->dev);
1648 ISCSI_DBG_TRANS_SESSION(session, "Completed SCSI target blocking\n");
1649 if (session->recovery_tmo >= 0)
1650 queue_delayed_work(iscsi_eh_timer_workq,
1651 &session->recovery_work,
1652 session->recovery_tmo * HZ);
1653}
1654
1655void iscsi_block_session(struct iscsi_cls_session *session)
1656{
1657 queue_work(iscsi_eh_timer_workq, &session->block_work);
1658}
1659EXPORT_SYMBOL_GPL(iscsi_block_session);
1660
1661static void __iscsi_unbind_session(struct work_struct *work)
1662{
1663 struct iscsi_cls_session *session =
1664 container_of(work, struct iscsi_cls_session,
1665 unbind_work);
1666 struct Scsi_Host *shost = iscsi_session_to_shost(session);
1667 struct iscsi_cls_host *ihost = shost->shost_data;
1668 unsigned long flags;
1669 unsigned int target_id;
1670
1671 ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
1672
1673
1674 mutex_lock(&ihost->mutex);
1675 spin_lock_irqsave(&session->lock, flags);
1676 if (session->target_id == ISCSI_MAX_TARGET) {
1677 spin_unlock_irqrestore(&session->lock, flags);
1678 mutex_unlock(&ihost->mutex);
1679 return;
1680 }
1681
1682 target_id = session->target_id;
1683 session->target_id = ISCSI_MAX_TARGET;
1684 spin_unlock_irqrestore(&session->lock, flags);
1685 mutex_unlock(&ihost->mutex);
1686
1687 if (session->ida_used)
1688 ida_simple_remove(&iscsi_sess_ida, target_id);
1689
1690 scsi_remove_target(&session->dev);
1691 iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
1692 ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
1693}
1694
1695struct iscsi_cls_session *
1696iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
1697 int dd_size)
1698{
1699 struct iscsi_cls_session *session;
1700
1701 session = kzalloc(sizeof(*session) + dd_size,
1702 GFP_KERNEL);
1703 if (!session)
1704 return NULL;
1705
1706 session->transport = transport;
1707 session->creator = -1;
1708 session->recovery_tmo = 120;
1709 session->state = ISCSI_SESSION_FREE;
1710 INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
1711 INIT_LIST_HEAD(&session->sess_list);
1712 INIT_WORK(&session->unblock_work, __iscsi_unblock_session);
1713 INIT_WORK(&session->block_work, __iscsi_block_session);
1714 INIT_WORK(&session->unbind_work, __iscsi_unbind_session);
1715 INIT_WORK(&session->scan_work, iscsi_scan_session);
1716 spin_lock_init(&session->lock);
1717
1718
1719 scsi_host_get(shost);
1720 session->dev.parent = &shost->shost_gendev;
1721 session->dev.release = iscsi_session_release;
1722 device_initialize(&session->dev);
1723 if (dd_size)
1724 session->dd_data = &session[1];
1725
1726 ISCSI_DBG_TRANS_SESSION(session, "Completed session allocation\n");
1727 return session;
1728}
1729EXPORT_SYMBOL_GPL(iscsi_alloc_session);
1730
1731int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
1732{
1733 struct Scsi_Host *shost = iscsi_session_to_shost(session);
1734 struct iscsi_cls_host *ihost;
1735 unsigned long flags;
1736 int id = 0;
1737 int err;
1738
1739 ihost = shost->shost_data;
1740 session->sid = atomic_add_return(1, &iscsi_session_nr);
1741
1742 if (target_id == ISCSI_MAX_TARGET) {
1743 id = ida_simple_get(&iscsi_sess_ida, 0, 0, GFP_KERNEL);
1744
1745 if (id < 0) {
1746 iscsi_cls_session_printk(KERN_ERR, session,
1747 "Failure in Target ID Allocation\n");
1748 return id;
1749 }
1750 session->target_id = (unsigned int)id;
1751 session->ida_used = true;
1752 } else
1753 session->target_id = target_id;
1754
1755 dev_set_name(&session->dev, "session%u", session->sid);
1756 err = device_add(&session->dev);
1757 if (err) {
1758 iscsi_cls_session_printk(KERN_ERR, session,
1759 "could not register session's dev\n");
1760 goto release_ida;
1761 }
1762 transport_register_device(&session->dev);
1763
1764 spin_lock_irqsave(&sesslock, flags);
1765 list_add(&session->sess_list, &sesslist);
1766 spin_unlock_irqrestore(&sesslock, flags);
1767
1768 iscsi_session_event(session, ISCSI_KEVENT_CREATE_SESSION);
1769 ISCSI_DBG_TRANS_SESSION(session, "Completed session adding\n");
1770 return 0;
1771
1772release_ida:
1773 if (session->ida_used)
1774 ida_simple_remove(&iscsi_sess_ida, session->target_id);
1775
1776 return err;
1777}
1778EXPORT_SYMBOL_GPL(iscsi_add_session);
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789struct iscsi_cls_session *
1790iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
1791 int dd_size, unsigned int target_id)
1792{
1793 struct iscsi_cls_session *session;
1794
1795 session = iscsi_alloc_session(shost, transport, dd_size);
1796 if (!session)
1797 return NULL;
1798
1799 if (iscsi_add_session(session, target_id)) {
1800 iscsi_free_session(session);
1801 return NULL;
1802 }
1803 return session;
1804}
1805EXPORT_SYMBOL_GPL(iscsi_create_session);
1806
1807static void iscsi_conn_release(struct device *dev)
1808{
1809 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
1810 struct device *parent = conn->dev.parent;
1811
1812 ISCSI_DBG_TRANS_CONN(conn, "Releasing conn\n");
1813 kfree(conn);
1814 put_device(parent);
1815}
1816
1817static int iscsi_is_conn_dev(const struct device *dev)
1818{
1819 return dev->release == iscsi_conn_release;
1820}
1821
1822static int iscsi_iter_destroy_conn_fn(struct device *dev, void *data)
1823{
1824 if (!iscsi_is_conn_dev(dev))
1825 return 0;
1826 return iscsi_destroy_conn(iscsi_dev_to_conn(dev));
1827}
1828
1829void iscsi_remove_session(struct iscsi_cls_session *session)
1830{
1831 struct Scsi_Host *shost = iscsi_session_to_shost(session);
1832 unsigned long flags;
1833 int err;
1834
1835 ISCSI_DBG_TRANS_SESSION(session, "Removing session\n");
1836
1837 spin_lock_irqsave(&sesslock, flags);
1838 list_del(&session->sess_list);
1839 spin_unlock_irqrestore(&sesslock, flags);
1840
1841
1842 flush_workqueue(iscsi_eh_timer_workq);
1843
1844 if (!cancel_delayed_work(&session->recovery_work))
1845 flush_workqueue(iscsi_eh_timer_workq);
1846
1847
1848
1849
1850
1851
1852 spin_lock_irqsave(&session->lock, flags);
1853 session->state = ISCSI_SESSION_FREE;
1854 spin_unlock_irqrestore(&session->lock, flags);
1855
1856 scsi_target_unblock(&session->dev, SDEV_TRANSPORT_OFFLINE);
1857
1858 scsi_flush_work(shost);
1859 __iscsi_unbind_session(&session->unbind_work);
1860
1861
1862 err = device_for_each_child(&session->dev, NULL,
1863 iscsi_iter_destroy_conn_fn);
1864 if (err)
1865 iscsi_cls_session_printk(KERN_ERR, session,
1866 "Could not delete all connections "
1867 "for session. Error %d.\n", err);
1868
1869 transport_unregister_device(&session->dev);
1870
1871 ISCSI_DBG_TRANS_SESSION(session, "Completing session removal\n");
1872 device_del(&session->dev);
1873}
1874EXPORT_SYMBOL_GPL(iscsi_remove_session);
1875
1876void iscsi_free_session(struct iscsi_cls_session *session)
1877{
1878 ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n");
1879 iscsi_session_event(session, ISCSI_KEVENT_DESTROY_SESSION);
1880 put_device(&session->dev);
1881}
1882EXPORT_SYMBOL_GPL(iscsi_free_session);
1883
1884
1885
1886
1887
1888
1889
1890
1891int iscsi_destroy_session(struct iscsi_cls_session *session)
1892{
1893 iscsi_remove_session(session);
1894 ISCSI_DBG_TRANS_SESSION(session, "Completing session destruction\n");
1895 iscsi_free_session(session);
1896 return 0;
1897}
1898EXPORT_SYMBOL_GPL(iscsi_destroy_session);
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915struct iscsi_cls_conn *
1916iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
1917{
1918 struct iscsi_transport *transport = session->transport;
1919 struct iscsi_cls_conn *conn;
1920 unsigned long flags;
1921 int err;
1922
1923 conn = kzalloc(sizeof(*conn) + dd_size, GFP_KERNEL);
1924 if (!conn)
1925 return NULL;
1926 if (dd_size)
1927 conn->dd_data = &conn[1];
1928
1929 mutex_init(&conn->ep_mutex);
1930 INIT_LIST_HEAD(&conn->conn_list);
1931 conn->transport = transport;
1932 conn->cid = cid;
1933
1934
1935 if (!get_device(&session->dev))
1936 goto free_conn;
1937
1938 dev_set_name(&conn->dev, "connection%d:%u", session->sid, cid);
1939 conn->dev.parent = &session->dev;
1940 conn->dev.release = iscsi_conn_release;
1941 err = device_register(&conn->dev);
1942 if (err) {
1943 iscsi_cls_session_printk(KERN_ERR, session, "could not "
1944 "register connection's dev\n");
1945 goto release_parent_ref;
1946 }
1947 transport_register_device(&conn->dev);
1948
1949 spin_lock_irqsave(&connlock, flags);
1950 list_add(&conn->conn_list, &connlist);
1951 spin_unlock_irqrestore(&connlock, flags);
1952
1953 ISCSI_DBG_TRANS_CONN(conn, "Completed conn creation\n");
1954 return conn;
1955
1956release_parent_ref:
1957 put_device(&session->dev);
1958free_conn:
1959 kfree(conn);
1960 return NULL;
1961}
1962
1963EXPORT_SYMBOL_GPL(iscsi_create_conn);
1964
1965
1966
1967
1968
1969
1970
1971int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
1972{
1973 unsigned long flags;
1974
1975 spin_lock_irqsave(&connlock, flags);
1976 list_del(&conn->conn_list);
1977 spin_unlock_irqrestore(&connlock, flags);
1978
1979 transport_unregister_device(&conn->dev);
1980 ISCSI_DBG_TRANS_CONN(conn, "Completing conn destruction\n");
1981 device_unregister(&conn->dev);
1982 return 0;
1983}
1984EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
1985
1986
1987
1988
1989static struct iscsi_internal *
1990iscsi_if_transport_lookup(struct iscsi_transport *tt)
1991{
1992 struct iscsi_internal *priv;
1993 unsigned long flags;
1994
1995 spin_lock_irqsave(&iscsi_transport_lock, flags);
1996 list_for_each_entry(priv, &iscsi_transports, list) {
1997 if (tt == priv->iscsi_transport) {
1998 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
1999 return priv;
2000 }
2001 }
2002 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
2003 return NULL;
2004}
2005
2006static int
2007iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp)
2008{
2009 return nlmsg_multicast(nls, skb, 0, group, gfp);
2010}
2011
2012int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
2013 char *data, uint32_t data_size)
2014{
2015 struct nlmsghdr *nlh;
2016 struct sk_buff *skb;
2017 struct iscsi_uevent *ev;
2018 char *pdu;
2019 struct iscsi_internal *priv;
2020 int len = nlmsg_total_size(sizeof(*ev) + sizeof(struct iscsi_hdr) +
2021 data_size);
2022
2023 priv = iscsi_if_transport_lookup(conn->transport);
2024 if (!priv)
2025 return -EINVAL;
2026
2027 skb = alloc_skb(len, GFP_ATOMIC);
2028 if (!skb) {
2029 iscsi_conn_error_event(conn, ISCSI_ERR_CONN_FAILED);
2030 iscsi_cls_conn_printk(KERN_ERR, conn, "can not deliver "
2031 "control PDU: OOM\n");
2032 return -ENOMEM;
2033 }
2034
2035 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
2036 ev = nlmsg_data(nlh);
2037 memset(ev, 0, sizeof(*ev));
2038 ev->transport_handle = iscsi_handle(conn->transport);
2039 ev->type = ISCSI_KEVENT_RECV_PDU;
2040 ev->r.recv_req.cid = conn->cid;
2041 ev->r.recv_req.sid = iscsi_conn_get_sid(conn);
2042 pdu = (char*)ev + sizeof(*ev);
2043 memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
2044 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
2045
2046 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
2047}
2048EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
2049
2050int iscsi_offload_mesg(struct Scsi_Host *shost,
2051 struct iscsi_transport *transport, uint32_t type,
2052 char *data, uint16_t data_size)
2053{
2054 struct nlmsghdr *nlh;
2055 struct sk_buff *skb;
2056 struct iscsi_uevent *ev;
2057 int len = nlmsg_total_size(sizeof(*ev) + data_size);
2058
2059 skb = alloc_skb(len, GFP_ATOMIC);
2060 if (!skb) {
2061 printk(KERN_ERR "can not deliver iscsi offload message:OOM\n");
2062 return -ENOMEM;
2063 }
2064
2065 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
2066 ev = nlmsg_data(nlh);
2067 memset(ev, 0, sizeof(*ev));
2068 ev->type = type;
2069 ev->transport_handle = iscsi_handle(transport);
2070 switch (type) {
2071 case ISCSI_KEVENT_PATH_REQ:
2072 ev->r.req_path.host_no = shost->host_no;
2073 break;
2074 case ISCSI_KEVENT_IF_DOWN:
2075 ev->r.notify_if_down.host_no = shost->host_no;
2076 break;
2077 }
2078
2079 memcpy((char *)ev + sizeof(*ev), data, data_size);
2080
2081 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_ATOMIC);
2082}
2083EXPORT_SYMBOL_GPL(iscsi_offload_mesg);
2084
2085void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
2086{
2087 struct nlmsghdr *nlh;
2088 struct sk_buff *skb;
2089 struct iscsi_uevent *ev;
2090 struct iscsi_internal *priv;
2091 int len = nlmsg_total_size(sizeof(*ev));
2092
2093 priv = iscsi_if_transport_lookup(conn->transport);
2094 if (!priv)
2095 return;
2096
2097 skb = alloc_skb(len, GFP_ATOMIC);
2098 if (!skb) {
2099 iscsi_cls_conn_printk(KERN_ERR, conn, "gracefully ignored "
2100 "conn error (%d)\n", error);
2101 return;
2102 }
2103
2104 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
2105 ev = nlmsg_data(nlh);
2106 ev->transport_handle = iscsi_handle(conn->transport);
2107 ev->type = ISCSI_KEVENT_CONN_ERROR;
2108 ev->r.connerror.error = error;
2109 ev->r.connerror.cid = conn->cid;
2110 ev->r.connerror.sid = iscsi_conn_get_sid(conn);
2111
2112 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
2113
2114 iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n",
2115 error);
2116}
2117EXPORT_SYMBOL_GPL(iscsi_conn_error_event);
2118
2119void iscsi_conn_login_event(struct iscsi_cls_conn *conn,
2120 enum iscsi_conn_state state)
2121{
2122 struct nlmsghdr *nlh;
2123 struct sk_buff *skb;
2124 struct iscsi_uevent *ev;
2125 struct iscsi_internal *priv;
2126 int len = nlmsg_total_size(sizeof(*ev));
2127
2128 priv = iscsi_if_transport_lookup(conn->transport);
2129 if (!priv)
2130 return;
2131
2132 skb = alloc_skb(len, GFP_ATOMIC);
2133 if (!skb) {
2134 iscsi_cls_conn_printk(KERN_ERR, conn, "gracefully ignored "
2135 "conn login (%d)\n", state);
2136 return;
2137 }
2138
2139 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
2140 ev = nlmsg_data(nlh);
2141 ev->transport_handle = iscsi_handle(conn->transport);
2142 ev->type = ISCSI_KEVENT_CONN_LOGIN_STATE;
2143 ev->r.conn_login.state = state;
2144 ev->r.conn_login.cid = conn->cid;
2145 ev->r.conn_login.sid = iscsi_conn_get_sid(conn);
2146 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC);
2147
2148 iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn login (%d)\n",
2149 state);
2150}
2151EXPORT_SYMBOL_GPL(iscsi_conn_login_event);
2152
2153void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
2154 enum iscsi_host_event_code code, uint32_t data_size,
2155 uint8_t *data)
2156{
2157 struct nlmsghdr *nlh;
2158 struct sk_buff *skb;
2159 struct iscsi_uevent *ev;
2160 int len = nlmsg_total_size(sizeof(*ev) + data_size);
2161
2162 skb = alloc_skb(len, GFP_NOIO);
2163 if (!skb) {
2164 printk(KERN_ERR "gracefully ignored host event (%d):%d OOM\n",
2165 host_no, code);
2166 return;
2167 }
2168
2169 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
2170 ev = nlmsg_data(nlh);
2171 ev->transport_handle = iscsi_handle(transport);
2172 ev->type = ISCSI_KEVENT_HOST_EVENT;
2173 ev->r.host_event.host_no = host_no;
2174 ev->r.host_event.code = code;
2175 ev->r.host_event.data_size = data_size;
2176
2177 if (data_size)
2178 memcpy((char *)ev + sizeof(*ev), data, data_size);
2179
2180 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO);
2181}
2182EXPORT_SYMBOL_GPL(iscsi_post_host_event);
2183
2184void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
2185 uint32_t status, uint32_t pid, uint32_t data_size,
2186 uint8_t *data)
2187{
2188 struct nlmsghdr *nlh;
2189 struct sk_buff *skb;
2190 struct iscsi_uevent *ev;
2191 int len = nlmsg_total_size(sizeof(*ev) + data_size);
2192
2193 skb = alloc_skb(len, GFP_NOIO);
2194 if (!skb) {
2195 printk(KERN_ERR "gracefully ignored ping comp: OOM\n");
2196 return;
2197 }
2198
2199 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
2200 ev = nlmsg_data(nlh);
2201 ev->transport_handle = iscsi_handle(transport);
2202 ev->type = ISCSI_KEVENT_PING_COMP;
2203 ev->r.ping_comp.host_no = host_no;
2204 ev->r.ping_comp.status = status;
2205 ev->r.ping_comp.pid = pid;
2206 ev->r.ping_comp.data_size = data_size;
2207 memcpy((char *)ev + sizeof(*ev), data, data_size);
2208
2209 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO);
2210}
2211EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);
2212
2213static int
2214iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
2215 void *payload, int size)
2216{
2217 struct sk_buff *skb;
2218 struct nlmsghdr *nlh;
2219 int len = nlmsg_total_size(size);
2220 int flags = multi ? NLM_F_MULTI : 0;
2221 int t = done ? NLMSG_DONE : type;
2222
2223 skb = alloc_skb(len, GFP_ATOMIC);
2224 if (!skb) {
2225 printk(KERN_ERR "Could not allocate skb to send reply.\n");
2226 return -ENOMEM;
2227 }
2228
2229 nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0);
2230 nlh->nlmsg_flags = flags;
2231 memcpy(nlmsg_data(nlh), payload, size);
2232 return iscsi_multicast_skb(skb, group, GFP_ATOMIC);
2233}
2234
2235static int
2236iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
2237{
2238 struct iscsi_uevent *ev = nlmsg_data(nlh);
2239 struct iscsi_stats *stats;
2240 struct sk_buff *skbstat;
2241 struct iscsi_cls_conn *conn;
2242 struct nlmsghdr *nlhstat;
2243 struct iscsi_uevent *evstat;
2244 struct iscsi_internal *priv;
2245 int len = nlmsg_total_size(sizeof(*ev) +
2246 sizeof(struct iscsi_stats) +
2247 sizeof(struct iscsi_stats_custom) *
2248 ISCSI_STATS_CUSTOM_MAX);
2249 int err = 0;
2250
2251 priv = iscsi_if_transport_lookup(transport);
2252 if (!priv)
2253 return -EINVAL;
2254
2255 conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
2256 if (!conn)
2257 return -EEXIST;
2258
2259 do {
2260 int actual_size;
2261
2262 skbstat = alloc_skb(len, GFP_ATOMIC);
2263 if (!skbstat) {
2264 iscsi_cls_conn_printk(KERN_ERR, conn, "can not "
2265 "deliver stats: OOM\n");
2266 return -ENOMEM;
2267 }
2268
2269 nlhstat = __nlmsg_put(skbstat, 0, 0, 0,
2270 (len - sizeof(*nlhstat)), 0);
2271 evstat = nlmsg_data(nlhstat);
2272 memset(evstat, 0, sizeof(*evstat));
2273 evstat->transport_handle = iscsi_handle(conn->transport);
2274 evstat->type = nlh->nlmsg_type;
2275 evstat->u.get_stats.cid =
2276 ev->u.get_stats.cid;
2277 evstat->u.get_stats.sid =
2278 ev->u.get_stats.sid;
2279 stats = (struct iscsi_stats *)
2280 ((char*)evstat + sizeof(*evstat));
2281 memset(stats, 0, sizeof(*stats));
2282
2283 transport->get_stats(conn, stats);
2284 actual_size = nlmsg_total_size(sizeof(struct iscsi_uevent) +
2285 sizeof(struct iscsi_stats) +
2286 sizeof(struct iscsi_stats_custom) *
2287 stats->custom_length);
2288 actual_size -= sizeof(*nlhstat);
2289 actual_size = nlmsg_msg_size(actual_size);
2290 skb_trim(skbstat, NLMSG_ALIGN(actual_size));
2291 nlhstat->nlmsg_len = actual_size;
2292
2293 err = iscsi_multicast_skb(skbstat, ISCSI_NL_GRP_ISCSID,
2294 GFP_ATOMIC);
2295 } while (err < 0 && err != -ECONNREFUSED);
2296
2297 return err;
2298}
2299
2300
2301
2302
2303
2304
2305int iscsi_session_event(struct iscsi_cls_session *session,
2306 enum iscsi_uevent_e event)
2307{
2308 struct iscsi_internal *priv;
2309 struct Scsi_Host *shost;
2310 struct iscsi_uevent *ev;
2311 struct sk_buff *skb;
2312 struct nlmsghdr *nlh;
2313 int rc, len = nlmsg_total_size(sizeof(*ev));
2314
2315 priv = iscsi_if_transport_lookup(session->transport);
2316 if (!priv)
2317 return -EINVAL;
2318 shost = iscsi_session_to_shost(session);
2319
2320 skb = alloc_skb(len, GFP_KERNEL);
2321 if (!skb) {
2322 iscsi_cls_session_printk(KERN_ERR, session,
2323 "Cannot notify userspace of session "
2324 "event %u\n", event);
2325 return -ENOMEM;
2326 }
2327
2328 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
2329 ev = nlmsg_data(nlh);
2330 ev->transport_handle = iscsi_handle(session->transport);
2331
2332 ev->type = event;
2333 switch (event) {
2334 case ISCSI_KEVENT_DESTROY_SESSION:
2335 ev->r.d_session.host_no = shost->host_no;
2336 ev->r.d_session.sid = session->sid;
2337 break;
2338 case ISCSI_KEVENT_CREATE_SESSION:
2339 ev->r.c_session_ret.host_no = shost->host_no;
2340 ev->r.c_session_ret.sid = session->sid;
2341 break;
2342 case ISCSI_KEVENT_UNBIND_SESSION:
2343 ev->r.unbind_session.host_no = shost->host_no;
2344 ev->r.unbind_session.sid = session->sid;
2345 break;
2346 default:
2347 iscsi_cls_session_printk(KERN_ERR, session, "Invalid event "
2348 "%u.\n", event);
2349 kfree_skb(skb);
2350 return -EINVAL;
2351 }
2352
2353
2354
2355
2356
2357 rc = iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
2358 if (rc == -ESRCH)
2359 iscsi_cls_session_printk(KERN_ERR, session,
2360 "Cannot notify userspace of session "
2361 "event %u. Check iscsi daemon\n",
2362 event);
2363
2364 ISCSI_DBG_TRANS_SESSION(session, "Completed handling event %d rc %d\n",
2365 event, rc);
2366 return rc;
2367}
2368EXPORT_SYMBOL_GPL(iscsi_session_event);
2369
2370static int
2371iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
2372 struct iscsi_uevent *ev, pid_t pid,
2373 uint32_t initial_cmdsn, uint16_t cmds_max,
2374 uint16_t queue_depth)
2375{
2376 struct iscsi_transport *transport = priv->iscsi_transport;
2377 struct iscsi_cls_session *session;
2378 struct Scsi_Host *shost;
2379
2380 session = transport->create_session(ep, cmds_max, queue_depth,
2381 initial_cmdsn);
2382 if (!session)
2383 return -ENOMEM;
2384
2385 session->creator = pid;
2386 shost = iscsi_session_to_shost(session);
2387 ev->r.c_session_ret.host_no = shost->host_no;
2388 ev->r.c_session_ret.sid = session->sid;
2389 ISCSI_DBG_TRANS_SESSION(session,
2390 "Completed creating transport session\n");
2391 return 0;
2392}
2393
2394static int
2395iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
2396{
2397 struct iscsi_cls_conn *conn;
2398 struct iscsi_cls_session *session;
2399
2400 session = iscsi_session_lookup(ev->u.c_conn.sid);
2401 if (!session) {
2402 printk(KERN_ERR "iscsi: invalid session %d.\n",
2403 ev->u.c_conn.sid);
2404 return -EINVAL;
2405 }
2406
2407 conn = transport->create_conn(session, ev->u.c_conn.cid);
2408 if (!conn) {
2409 iscsi_cls_session_printk(KERN_ERR, session,
2410 "couldn't create a new connection.");
2411 return -ENOMEM;
2412 }
2413
2414 ev->r.c_conn_ret.sid = session->sid;
2415 ev->r.c_conn_ret.cid = conn->cid;
2416
2417 ISCSI_DBG_TRANS_CONN(conn, "Completed creating transport conn\n");
2418 return 0;
2419}
2420
2421static int
2422iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
2423{
2424 struct iscsi_cls_conn *conn;
2425
2426 conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid);
2427 if (!conn)
2428 return -EINVAL;
2429
2430 ISCSI_DBG_TRANS_CONN(conn, "Destroying transport conn\n");
2431 if (transport->destroy_conn)
2432 transport->destroy_conn(conn);
2433
2434 return 0;
2435}
2436
2437static int
2438iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
2439{
2440 char *data = (char*)ev + sizeof(*ev);
2441 struct iscsi_cls_conn *conn;
2442 struct iscsi_cls_session *session;
2443 int err = 0, value = 0;
2444
2445 session = iscsi_session_lookup(ev->u.set_param.sid);
2446 conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
2447 if (!conn || !session)
2448 return -EINVAL;
2449
2450 switch (ev->u.set_param.param) {
2451 case ISCSI_PARAM_SESS_RECOVERY_TMO:
2452 sscanf(data, "%d", &value);
2453 session->recovery_tmo = value;
2454 break;
2455 default:
2456 err = transport->set_param(conn, ev->u.set_param.param,
2457 data, ev->u.set_param.len);
2458 }
2459
2460 return err;
2461}
2462
2463static int iscsi_if_ep_connect(struct iscsi_transport *transport,
2464 struct iscsi_uevent *ev, int msg_type)
2465{
2466 struct iscsi_endpoint *ep;
2467 struct sockaddr *dst_addr;
2468 struct Scsi_Host *shost = NULL;
2469 int non_blocking, err = 0;
2470
2471 if (!transport->ep_connect)
2472 return -EINVAL;
2473
2474 if (msg_type == ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST) {
2475 shost = scsi_host_lookup(ev->u.ep_connect_through_host.host_no);
2476 if (!shost) {
2477 printk(KERN_ERR "ep connect failed. Could not find "
2478 "host no %u\n",
2479 ev->u.ep_connect_through_host.host_no);
2480 return -ENODEV;
2481 }
2482 non_blocking = ev->u.ep_connect_through_host.non_blocking;
2483 } else
2484 non_blocking = ev->u.ep_connect.non_blocking;
2485
2486 dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
2487 ep = transport->ep_connect(shost, dst_addr, non_blocking);
2488 if (IS_ERR(ep)) {
2489 err = PTR_ERR(ep);
2490 goto release_host;
2491 }
2492
2493 ev->r.ep_connect_ret.handle = ep->id;
2494release_host:
2495 if (shost)
2496 scsi_host_put(shost);
2497 return err;
2498}
2499
2500static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
2501 u64 ep_handle)
2502{
2503 struct iscsi_cls_conn *conn;
2504 struct iscsi_endpoint *ep;
2505
2506 if (!transport->ep_disconnect)
2507 return -EINVAL;
2508
2509 ep = iscsi_lookup_endpoint(ep_handle);
2510 if (!ep)
2511 return -EINVAL;
2512 conn = ep->conn;
2513 if (conn) {
2514 mutex_lock(&conn->ep_mutex);
2515 conn->ep = NULL;
2516 mutex_unlock(&conn->ep_mutex);
2517 }
2518
2519 transport->ep_disconnect(ep);
2520 return 0;
2521}
2522
2523static int
2524iscsi_if_transport_ep(struct iscsi_transport *transport,
2525 struct iscsi_uevent *ev, int msg_type)
2526{
2527 struct iscsi_endpoint *ep;
2528 int rc = 0;
2529
2530 switch (msg_type) {
2531 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
2532 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
2533 rc = iscsi_if_ep_connect(transport, ev, msg_type);
2534 break;
2535 case ISCSI_UEVENT_TRANSPORT_EP_POLL:
2536 if (!transport->ep_poll)
2537 return -EINVAL;
2538
2539 ep = iscsi_lookup_endpoint(ev->u.ep_poll.ep_handle);
2540 if (!ep)
2541 return -EINVAL;
2542
2543 ev->r.retcode = transport->ep_poll(ep,
2544 ev->u.ep_poll.timeout_ms);
2545 break;
2546 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
2547 rc = iscsi_if_ep_disconnect(transport,
2548 ev->u.ep_disconnect.ep_handle);
2549 break;
2550 }
2551 return rc;
2552}
2553
2554static int
2555iscsi_tgt_dscvr(struct iscsi_transport *transport,
2556 struct iscsi_uevent *ev)
2557{
2558 struct Scsi_Host *shost;
2559 struct sockaddr *dst_addr;
2560 int err;
2561
2562 if (!transport->tgt_dscvr)
2563 return -EINVAL;
2564
2565 shost = scsi_host_lookup(ev->u.tgt_dscvr.host_no);
2566 if (!shost) {
2567 printk(KERN_ERR "target discovery could not find host no %u\n",
2568 ev->u.tgt_dscvr.host_no);
2569 return -ENODEV;
2570 }
2571
2572
2573 dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
2574 err = transport->tgt_dscvr(shost, ev->u.tgt_dscvr.type,
2575 ev->u.tgt_dscvr.enable, dst_addr);
2576 scsi_host_put(shost);
2577 return err;
2578}
2579
2580static int
2581iscsi_set_host_param(struct iscsi_transport *transport,
2582 struct iscsi_uevent *ev)
2583{
2584 char *data = (char*)ev + sizeof(*ev);
2585 struct Scsi_Host *shost;
2586 int err;
2587
2588 if (!transport->set_host_param)
2589 return -ENOSYS;
2590
2591 shost = scsi_host_lookup(ev->u.set_host_param.host_no);
2592 if (!shost) {
2593 printk(KERN_ERR "set_host_param could not find host no %u\n",
2594 ev->u.set_host_param.host_no);
2595 return -ENODEV;
2596 }
2597
2598 err = transport->set_host_param(shost, ev->u.set_host_param.param,
2599 data, ev->u.set_host_param.len);
2600 scsi_host_put(shost);
2601 return err;
2602}
2603
2604static int
2605iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev)
2606{
2607 struct Scsi_Host *shost;
2608 struct iscsi_path *params;
2609 int err;
2610
2611 if (!transport->set_path)
2612 return -ENOSYS;
2613
2614 shost = scsi_host_lookup(ev->u.set_path.host_no);
2615 if (!shost) {
2616 printk(KERN_ERR "set path could not find host no %u\n",
2617 ev->u.set_path.host_no);
2618 return -ENODEV;
2619 }
2620
2621 params = (struct iscsi_path *)((char *)ev + sizeof(*ev));
2622 err = transport->set_path(shost, params);
2623
2624 scsi_host_put(shost);
2625 return err;
2626}
2627
2628static int
2629iscsi_set_iface_params(struct iscsi_transport *transport,
2630 struct iscsi_uevent *ev, uint32_t len)
2631{
2632 char *data = (char *)ev + sizeof(*ev);
2633 struct Scsi_Host *shost;
2634 int err;
2635
2636 if (!transport->set_iface_param)
2637 return -ENOSYS;
2638
2639 shost = scsi_host_lookup(ev->u.set_iface_params.host_no);
2640 if (!shost) {
2641 printk(KERN_ERR "set_iface_params could not find host no %u\n",
2642 ev->u.set_iface_params.host_no);
2643 return -ENODEV;
2644 }
2645
2646 err = transport->set_iface_param(shost, data, len);
2647 scsi_host_put(shost);
2648 return err;
2649}
2650
2651static int
2652iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
2653{
2654 struct Scsi_Host *shost;
2655 struct sockaddr *dst_addr;
2656 int err;
2657
2658 if (!transport->send_ping)
2659 return -ENOSYS;
2660
2661 shost = scsi_host_lookup(ev->u.iscsi_ping.host_no);
2662 if (!shost) {
2663 printk(KERN_ERR "iscsi_ping could not find host no %u\n",
2664 ev->u.iscsi_ping.host_no);
2665 return -ENODEV;
2666 }
2667
2668 dst_addr = (struct sockaddr *)((char *)ev + sizeof(*ev));
2669 err = transport->send_ping(shost, ev->u.iscsi_ping.iface_num,
2670 ev->u.iscsi_ping.iface_type,
2671 ev->u.iscsi_ping.payload_size,
2672 ev->u.iscsi_ping.pid,
2673 dst_addr);
2674 scsi_host_put(shost);
2675 return err;
2676}
2677
2678static int
2679iscsi_get_chap(struct iscsi_transport *transport, struct nlmsghdr *nlh)
2680{
2681 struct iscsi_uevent *ev = nlmsg_data(nlh);
2682 struct Scsi_Host *shost = NULL;
2683 struct iscsi_chap_rec *chap_rec;
2684 struct iscsi_internal *priv;
2685 struct sk_buff *skbchap;
2686 struct nlmsghdr *nlhchap;
2687 struct iscsi_uevent *evchap;
2688 uint32_t chap_buf_size;
2689 int len, err = 0;
2690 char *buf;
2691
2692 if (!transport->get_chap)
2693 return -EINVAL;
2694
2695 priv = iscsi_if_transport_lookup(transport);
2696 if (!priv)
2697 return -EINVAL;
2698
2699 chap_buf_size = (ev->u.get_chap.num_entries * sizeof(*chap_rec));
2700 len = nlmsg_total_size(sizeof(*ev) + chap_buf_size);
2701
2702 shost = scsi_host_lookup(ev->u.get_chap.host_no);
2703 if (!shost) {
2704 printk(KERN_ERR "%s: failed. Cound not find host no %u\n",
2705 __func__, ev->u.get_chap.host_no);
2706 return -ENODEV;
2707 }
2708
2709 do {
2710 int actual_size;
2711
2712 skbchap = alloc_skb(len, GFP_KERNEL);
2713 if (!skbchap) {
2714 printk(KERN_ERR "can not deliver chap: OOM\n");
2715 err = -ENOMEM;
2716 goto exit_get_chap;
2717 }
2718
2719 nlhchap = __nlmsg_put(skbchap, 0, 0, 0,
2720 (len - sizeof(*nlhchap)), 0);
2721 evchap = nlmsg_data(nlhchap);
2722 memset(evchap, 0, sizeof(*evchap));
2723 evchap->transport_handle = iscsi_handle(transport);
2724 evchap->type = nlh->nlmsg_type;
2725 evchap->u.get_chap.host_no = ev->u.get_chap.host_no;
2726 evchap->u.get_chap.chap_tbl_idx = ev->u.get_chap.chap_tbl_idx;
2727 evchap->u.get_chap.num_entries = ev->u.get_chap.num_entries;
2728 buf = (char *) ((char *)evchap + sizeof(*evchap));
2729 memset(buf, 0, chap_buf_size);
2730
2731 err = transport->get_chap(shost, ev->u.get_chap.chap_tbl_idx,
2732 &evchap->u.get_chap.num_entries, buf);
2733
2734 actual_size = nlmsg_total_size(sizeof(*ev) + chap_buf_size);
2735 skb_trim(skbchap, NLMSG_ALIGN(actual_size));
2736 nlhchap->nlmsg_len = actual_size;
2737
2738 err = iscsi_multicast_skb(skbchap, ISCSI_NL_GRP_ISCSID,
2739 GFP_KERNEL);
2740 } while (err < 0 && err != -ECONNREFUSED);
2741
2742exit_get_chap:
2743 scsi_host_put(shost);
2744 return err;
2745}
2746
2747static int iscsi_delete_chap(struct iscsi_transport *transport,
2748 struct iscsi_uevent *ev)
2749{
2750 struct Scsi_Host *shost;
2751 int err = 0;
2752
2753 if (!transport->delete_chap)
2754 return -ENOSYS;
2755
2756 shost = scsi_host_lookup(ev->u.delete_chap.host_no);
2757 if (!shost) {
2758 printk(KERN_ERR "%s could not find host no %u\n",
2759 __func__, ev->u.delete_chap.host_no);
2760 return -ENODEV;
2761 }
2762
2763 err = transport->delete_chap(shost, ev->u.delete_chap.chap_tbl_idx);
2764 scsi_host_put(shost);
2765 return err;
2766}
2767
2768static const struct {
2769 enum iscsi_discovery_parent_type value;
2770 char *name;
2771} iscsi_discovery_parent_names[] = {
2772 {ISCSI_DISC_PARENT_UNKNOWN, "Unknown" },
2773 {ISCSI_DISC_PARENT_SENDTGT, "Sendtarget" },
2774 {ISCSI_DISC_PARENT_ISNS, "isns" },
2775};
2776
2777char *iscsi_get_discovery_parent_name(int parent_type)
2778{
2779 int i;
2780 char *state = "Unknown!";
2781
2782 for (i = 0; i < ARRAY_SIZE(iscsi_discovery_parent_names); i++) {
2783 if (iscsi_discovery_parent_names[i].value & parent_type) {
2784 state = iscsi_discovery_parent_names[i].name;
2785 break;
2786 }
2787 }
2788 return state;
2789}
2790EXPORT_SYMBOL_GPL(iscsi_get_discovery_parent_name);
2791
2792static int iscsi_set_flashnode_param(struct iscsi_transport *transport,
2793 struct iscsi_uevent *ev, uint32_t len)
2794{
2795 char *data = (char *)ev + sizeof(*ev);
2796 struct Scsi_Host *shost;
2797 struct iscsi_bus_flash_session *fnode_sess;
2798 struct iscsi_bus_flash_conn *fnode_conn;
2799 struct device *dev;
2800 uint32_t idx;
2801 int err = 0;
2802
2803 if (!transport->set_flashnode_param) {
2804 err = -ENOSYS;
2805 goto exit_set_fnode;
2806 }
2807
2808 shost = scsi_host_lookup(ev->u.set_flashnode.host_no);
2809 if (!shost) {
2810 pr_err("%s could not find host no %u\n",
2811 __func__, ev->u.set_flashnode.host_no);
2812 err = -ENODEV;
2813 goto put_host;
2814 }
2815
2816 idx = ev->u.set_flashnode.flashnode_idx;
2817 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
2818 if (!fnode_sess) {
2819 pr_err("%s could not find flashnode %u for host no %u\n",
2820 __func__, idx, ev->u.set_flashnode.host_no);
2821 err = -ENODEV;
2822 goto put_host;
2823 }
2824
2825 dev = iscsi_find_flashnode_conn(fnode_sess);
2826 if (!dev) {
2827 err = -ENODEV;
2828 goto put_sess;
2829 }
2830
2831 fnode_conn = iscsi_dev_to_flash_conn(dev);
2832 err = transport->set_flashnode_param(fnode_sess, fnode_conn, data, len);
2833 put_device(dev);
2834
2835put_sess:
2836 put_device(&fnode_sess->dev);
2837
2838put_host:
2839 scsi_host_put(shost);
2840
2841exit_set_fnode:
2842 return err;
2843}
2844
2845static int iscsi_new_flashnode(struct iscsi_transport *transport,
2846 struct iscsi_uevent *ev, uint32_t len)
2847{
2848 char *data = (char *)ev + sizeof(*ev);
2849 struct Scsi_Host *shost;
2850 int index;
2851 int err = 0;
2852
2853 if (!transport->new_flashnode) {
2854 err = -ENOSYS;
2855 goto exit_new_fnode;
2856 }
2857
2858 shost = scsi_host_lookup(ev->u.new_flashnode.host_no);
2859 if (!shost) {
2860 pr_err("%s could not find host no %u\n",
2861 __func__, ev->u.new_flashnode.host_no);
2862 err = -ENODEV;
2863 goto put_host;
2864 }
2865
2866 index = transport->new_flashnode(shost, data, len);
2867
2868 if (index >= 0)
2869 ev->r.new_flashnode_ret.flashnode_idx = index;
2870 else
2871 err = -EIO;
2872
2873put_host:
2874 scsi_host_put(shost);
2875
2876exit_new_fnode:
2877 return err;
2878}
2879
2880static int iscsi_del_flashnode(struct iscsi_transport *transport,
2881 struct iscsi_uevent *ev)
2882{
2883 struct Scsi_Host *shost;
2884 struct iscsi_bus_flash_session *fnode_sess;
2885 uint32_t idx;
2886 int err = 0;
2887
2888 if (!transport->del_flashnode) {
2889 err = -ENOSYS;
2890 goto exit_del_fnode;
2891 }
2892
2893 shost = scsi_host_lookup(ev->u.del_flashnode.host_no);
2894 if (!shost) {
2895 pr_err("%s could not find host no %u\n",
2896 __func__, ev->u.del_flashnode.host_no);
2897 err = -ENODEV;
2898 goto put_host;
2899 }
2900
2901 idx = ev->u.del_flashnode.flashnode_idx;
2902 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
2903 if (!fnode_sess) {
2904 pr_err("%s could not find flashnode %u for host no %u\n",
2905 __func__, idx, ev->u.del_flashnode.host_no);
2906 err = -ENODEV;
2907 goto put_host;
2908 }
2909
2910 err = transport->del_flashnode(fnode_sess);
2911 put_device(&fnode_sess->dev);
2912
2913put_host:
2914 scsi_host_put(shost);
2915
2916exit_del_fnode:
2917 return err;
2918}
2919
2920static int iscsi_login_flashnode(struct iscsi_transport *transport,
2921 struct iscsi_uevent *ev)
2922{
2923 struct Scsi_Host *shost;
2924 struct iscsi_bus_flash_session *fnode_sess;
2925 struct iscsi_bus_flash_conn *fnode_conn;
2926 struct device *dev;
2927 uint32_t idx;
2928 int err = 0;
2929
2930 if (!transport->login_flashnode) {
2931 err = -ENOSYS;
2932 goto exit_login_fnode;
2933 }
2934
2935 shost = scsi_host_lookup(ev->u.login_flashnode.host_no);
2936 if (!shost) {
2937 pr_err("%s could not find host no %u\n",
2938 __func__, ev->u.login_flashnode.host_no);
2939 err = -ENODEV;
2940 goto put_host;
2941 }
2942
2943 idx = ev->u.login_flashnode.flashnode_idx;
2944 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
2945 if (!fnode_sess) {
2946 pr_err("%s could not find flashnode %u for host no %u\n",
2947 __func__, idx, ev->u.login_flashnode.host_no);
2948 err = -ENODEV;
2949 goto put_host;
2950 }
2951
2952 dev = iscsi_find_flashnode_conn(fnode_sess);
2953 if (!dev) {
2954 err = -ENODEV;
2955 goto put_sess;
2956 }
2957
2958 fnode_conn = iscsi_dev_to_flash_conn(dev);
2959 err = transport->login_flashnode(fnode_sess, fnode_conn);
2960 put_device(dev);
2961
2962put_sess:
2963 put_device(&fnode_sess->dev);
2964
2965put_host:
2966 scsi_host_put(shost);
2967
2968exit_login_fnode:
2969 return err;
2970}
2971
2972static int iscsi_logout_flashnode(struct iscsi_transport *transport,
2973 struct iscsi_uevent *ev)
2974{
2975 struct Scsi_Host *shost;
2976 struct iscsi_bus_flash_session *fnode_sess;
2977 struct iscsi_bus_flash_conn *fnode_conn;
2978 struct device *dev;
2979 uint32_t idx;
2980 int err = 0;
2981
2982 if (!transport->logout_flashnode) {
2983 err = -ENOSYS;
2984 goto exit_logout_fnode;
2985 }
2986
2987 shost = scsi_host_lookup(ev->u.logout_flashnode.host_no);
2988 if (!shost) {
2989 pr_err("%s could not find host no %u\n",
2990 __func__, ev->u.logout_flashnode.host_no);
2991 err = -ENODEV;
2992 goto put_host;
2993 }
2994
2995 idx = ev->u.logout_flashnode.flashnode_idx;
2996 fnode_sess = iscsi_get_flashnode_by_index(shost, idx);
2997 if (!fnode_sess) {
2998 pr_err("%s could not find flashnode %u for host no %u\n",
2999 __func__, idx, ev->u.logout_flashnode.host_no);
3000 err = -ENODEV;
3001 goto put_host;
3002 }
3003
3004 dev = iscsi_find_flashnode_conn(fnode_sess);
3005 if (!dev) {
3006 err = -ENODEV;
3007 goto put_sess;
3008 }
3009
3010 fnode_conn = iscsi_dev_to_flash_conn(dev);
3011
3012 err = transport->logout_flashnode(fnode_sess, fnode_conn);
3013 put_device(dev);
3014
3015put_sess:
3016 put_device(&fnode_sess->dev);
3017
3018put_host:
3019 scsi_host_put(shost);
3020
3021exit_logout_fnode:
3022 return err;
3023}
3024
3025static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport,
3026 struct iscsi_uevent *ev)
3027{
3028 struct Scsi_Host *shost;
3029 struct iscsi_cls_session *session;
3030 int err = 0;
3031
3032 if (!transport->logout_flashnode_sid) {
3033 err = -ENOSYS;
3034 goto exit_logout_sid;
3035 }
3036
3037 shost = scsi_host_lookup(ev->u.logout_flashnode_sid.host_no);
3038 if (!shost) {
3039 pr_err("%s could not find host no %u\n",
3040 __func__, ev->u.logout_flashnode.host_no);
3041 err = -ENODEV;
3042 goto put_host;
3043 }
3044
3045 session = iscsi_session_lookup(ev->u.logout_flashnode_sid.sid);
3046 if (!session) {
3047 pr_err("%s could not find session id %u\n",
3048 __func__, ev->u.logout_flashnode_sid.sid);
3049 err = -EINVAL;
3050 goto put_host;
3051 }
3052
3053 err = transport->logout_flashnode_sid(session);
3054
3055put_host:
3056 scsi_host_put(shost);
3057
3058exit_logout_sid:
3059 return err;
3060}
3061
3062static int
3063iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
3064{
3065 int err = 0;
3066 struct iscsi_uevent *ev = nlmsg_data(nlh);
3067 struct iscsi_transport *transport = NULL;
3068 struct iscsi_internal *priv;
3069 struct iscsi_cls_session *session;
3070 struct iscsi_cls_conn *conn;
3071 struct iscsi_endpoint *ep = NULL;
3072
3073 if (nlh->nlmsg_type == ISCSI_UEVENT_PATH_UPDATE)
3074 *group = ISCSI_NL_GRP_UIP;
3075 else
3076 *group = ISCSI_NL_GRP_ISCSID;
3077
3078 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
3079 if (!priv)
3080 return -EINVAL;
3081 transport = priv->iscsi_transport;
3082
3083 if (!try_module_get(transport->owner))
3084 return -EINVAL;
3085
3086 switch (nlh->nlmsg_type) {
3087 case ISCSI_UEVENT_CREATE_SESSION:
3088 err = iscsi_if_create_session(priv, ep, ev,
3089 NETLINK_CB(skb).portid,
3090 ev->u.c_session.initial_cmdsn,
3091 ev->u.c_session.cmds_max,
3092 ev->u.c_session.queue_depth);
3093 break;
3094 case ISCSI_UEVENT_CREATE_BOUND_SESSION:
3095 ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle);
3096 if (!ep) {
3097 err = -EINVAL;
3098 break;
3099 }
3100
3101 err = iscsi_if_create_session(priv, ep, ev,
3102 NETLINK_CB(skb).portid,
3103 ev->u.c_bound_session.initial_cmdsn,
3104 ev->u.c_bound_session.cmds_max,
3105 ev->u.c_bound_session.queue_depth);
3106 break;
3107 case ISCSI_UEVENT_DESTROY_SESSION:
3108 session = iscsi_session_lookup(ev->u.d_session.sid);
3109 if (session)
3110 transport->destroy_session(session);
3111 else
3112 err = -EINVAL;
3113 break;
3114 case ISCSI_UEVENT_UNBIND_SESSION:
3115 session = iscsi_session_lookup(ev->u.d_session.sid);
3116 if (session)
3117 scsi_queue_work(iscsi_session_to_shost(session),
3118 &session->unbind_work);
3119 else
3120 err = -EINVAL;
3121 break;
3122 case ISCSI_UEVENT_CREATE_CONN:
3123 err = iscsi_if_create_conn(transport, ev);
3124 break;
3125 case ISCSI_UEVENT_DESTROY_CONN:
3126 err = iscsi_if_destroy_conn(transport, ev);
3127 break;
3128 case ISCSI_UEVENT_BIND_CONN:
3129 session = iscsi_session_lookup(ev->u.b_conn.sid);
3130 conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
3131
3132 if (conn && conn->ep)
3133 iscsi_if_ep_disconnect(transport, conn->ep->id);
3134
3135 if (!session || !conn) {
3136 err = -EINVAL;
3137 break;
3138 }
3139
3140 ev->r.retcode = transport->bind_conn(session, conn,
3141 ev->u.b_conn.transport_eph,
3142 ev->u.b_conn.is_leading);
3143 if (ev->r.retcode || !transport->ep_connect)
3144 break;
3145
3146 ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph);
3147 if (ep) {
3148 ep->conn = conn;
3149
3150 mutex_lock(&conn->ep_mutex);
3151 conn->ep = ep;
3152 mutex_unlock(&conn->ep_mutex);
3153 } else
3154 iscsi_cls_conn_printk(KERN_ERR, conn,
3155 "Could not set ep conn "
3156 "binding\n");
3157 break;
3158 case ISCSI_UEVENT_SET_PARAM:
3159 err = iscsi_set_param(transport, ev);
3160 break;
3161 case ISCSI_UEVENT_START_CONN:
3162 conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid);
3163 if (conn)
3164 ev->r.retcode = transport->start_conn(conn);
3165 else
3166 err = -EINVAL;
3167 break;
3168 case ISCSI_UEVENT_STOP_CONN:
3169 conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
3170 if (conn)
3171 transport->stop_conn(conn, ev->u.stop_conn.flag);
3172 else
3173 err = -EINVAL;
3174 break;
3175 case ISCSI_UEVENT_SEND_PDU:
3176 conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
3177 if (conn)
3178 ev->r.retcode = transport->send_pdu(conn,
3179 (struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
3180 (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size,
3181 ev->u.send_pdu.data_size);
3182 else
3183 err = -EINVAL;
3184 break;
3185 case ISCSI_UEVENT_GET_STATS:
3186 err = iscsi_if_get_stats(transport, nlh);
3187 break;
3188 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
3189 case ISCSI_UEVENT_TRANSPORT_EP_POLL:
3190 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
3191 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
3192 err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
3193 break;
3194 case ISCSI_UEVENT_TGT_DSCVR:
3195 err = iscsi_tgt_dscvr(transport, ev);
3196 break;
3197 case ISCSI_UEVENT_SET_HOST_PARAM:
3198 err = iscsi_set_host_param(transport, ev);
3199 break;
3200 case ISCSI_UEVENT_PATH_UPDATE:
3201 err = iscsi_set_path(transport, ev);
3202 break;
3203 case ISCSI_UEVENT_SET_IFACE_PARAMS:
3204 err = iscsi_set_iface_params(transport, ev,
3205 nlmsg_attrlen(nlh, sizeof(*ev)));
3206 break;
3207 case ISCSI_UEVENT_PING:
3208 err = iscsi_send_ping(transport, ev);
3209 break;
3210 case ISCSI_UEVENT_GET_CHAP:
3211 err = iscsi_get_chap(transport, nlh);
3212 break;
3213 case ISCSI_UEVENT_DELETE_CHAP:
3214 err = iscsi_delete_chap(transport, ev);
3215 break;
3216 case ISCSI_UEVENT_SET_FLASHNODE_PARAMS:
3217 err = iscsi_set_flashnode_param(transport, ev,
3218 nlmsg_attrlen(nlh,
3219 sizeof(*ev)));
3220 break;
3221 case ISCSI_UEVENT_NEW_FLASHNODE:
3222 err = iscsi_new_flashnode(transport, ev,
3223 nlmsg_attrlen(nlh, sizeof(*ev)));
3224 break;
3225 case ISCSI_UEVENT_DEL_FLASHNODE:
3226 err = iscsi_del_flashnode(transport, ev);
3227 break;
3228 case ISCSI_UEVENT_LOGIN_FLASHNODE:
3229 err = iscsi_login_flashnode(transport, ev);
3230 break;
3231 case ISCSI_UEVENT_LOGOUT_FLASHNODE:
3232 err = iscsi_logout_flashnode(transport, ev);
3233 break;
3234 case ISCSI_UEVENT_LOGOUT_FLASHNODE_SID:
3235 err = iscsi_logout_flashnode_sid(transport, ev);
3236 break;
3237 default:
3238 err = -ENOSYS;
3239 break;
3240 }
3241
3242 module_put(transport->owner);
3243 return err;
3244}
3245
3246
3247
3248
3249
3250static void
3251iscsi_if_rx(struct sk_buff *skb)
3252{
3253 mutex_lock(&rx_queue_mutex);
3254 while (skb->len >= NLMSG_HDRLEN) {
3255 int err;
3256 uint32_t rlen;
3257 struct nlmsghdr *nlh;
3258 struct iscsi_uevent *ev;
3259 uint32_t group;
3260
3261 nlh = nlmsg_hdr(skb);
3262 if (nlh->nlmsg_len < sizeof(*nlh) ||
3263 skb->len < nlh->nlmsg_len) {
3264 break;
3265 }
3266
3267 ev = nlmsg_data(nlh);
3268 rlen = NLMSG_ALIGN(nlh->nlmsg_len);
3269 if (rlen > skb->len)
3270 rlen = skb->len;
3271
3272 err = iscsi_if_recv_msg(skb, nlh, &group);
3273 if (err) {
3274 ev->type = ISCSI_KEVENT_IF_ERROR;
3275 ev->iferror = err;
3276 }
3277 do {
3278
3279
3280
3281
3282
3283
3284 if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
3285 break;
3286 if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
3287 break;
3288 err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
3289 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
3290 } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
3291 skb_pull(skb, rlen);
3292 }
3293 mutex_unlock(&rx_queue_mutex);
3294}
3295
3296#define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \
3297struct device_attribute dev_attr_##_prefix##_##_name = \
3298 __ATTR(_name,_mode,_show,_store)
3299
3300
3301
3302
3303#define iscsi_conn_attr_show(param) \
3304static ssize_t \
3305show_conn_param_##param(struct device *dev, \
3306 struct device_attribute *attr, char *buf) \
3307{ \
3308 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent); \
3309 struct iscsi_transport *t = conn->transport; \
3310 return t->get_conn_param(conn, param, buf); \
3311}
3312
3313#define iscsi_conn_attr(field, param) \
3314 iscsi_conn_attr_show(param) \
3315static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \
3316 NULL);
3317
3318iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH);
3319iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH);
3320iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN);
3321iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN);
3322iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN);
3323iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN);
3324iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT);
3325iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN);
3326iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
3327iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO);
3328iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO);
3329iscsi_conn_attr(local_port, ISCSI_PARAM_LOCAL_PORT);
3330iscsi_conn_attr(statsn, ISCSI_PARAM_STATSN);
3331iscsi_conn_attr(keepalive_tmo, ISCSI_PARAM_KEEPALIVE_TMO);
3332iscsi_conn_attr(max_segment_size, ISCSI_PARAM_MAX_SEGMENT_SIZE);
3333iscsi_conn_attr(tcp_timestamp_stat, ISCSI_PARAM_TCP_TIMESTAMP_STAT);
3334iscsi_conn_attr(tcp_wsf_disable, ISCSI_PARAM_TCP_WSF_DISABLE);
3335iscsi_conn_attr(tcp_nagle_disable, ISCSI_PARAM_TCP_NAGLE_DISABLE);
3336iscsi_conn_attr(tcp_timer_scale, ISCSI_PARAM_TCP_TIMER_SCALE);
3337iscsi_conn_attr(tcp_timestamp_enable, ISCSI_PARAM_TCP_TIMESTAMP_EN);
3338iscsi_conn_attr(fragment_disable, ISCSI_PARAM_IP_FRAGMENT_DISABLE);
3339iscsi_conn_attr(ipv4_tos, ISCSI_PARAM_IPV4_TOS);
3340iscsi_conn_attr(ipv6_traffic_class, ISCSI_PARAM_IPV6_TC);
3341iscsi_conn_attr(ipv6_flow_label, ISCSI_PARAM_IPV6_FLOW_LABEL);
3342iscsi_conn_attr(is_fw_assigned_ipv6, ISCSI_PARAM_IS_FW_ASSIGNED_IPV6);
3343iscsi_conn_attr(tcp_xmit_wsf, ISCSI_PARAM_TCP_XMIT_WSF);
3344iscsi_conn_attr(tcp_recv_wsf, ISCSI_PARAM_TCP_RECV_WSF);
3345
3346
3347#define iscsi_conn_ep_attr_show(param) \
3348static ssize_t show_conn_ep_param_##param(struct device *dev, \
3349 struct device_attribute *attr,\
3350 char *buf) \
3351{ \
3352 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent); \
3353 struct iscsi_transport *t = conn->transport; \
3354 struct iscsi_endpoint *ep; \
3355 ssize_t rc; \
3356 \
3357
3358
3359
3360 \
3361 mutex_lock(&conn->ep_mutex); \
3362 ep = conn->ep; \
3363 if (!ep && t->ep_connect) { \
3364 mutex_unlock(&conn->ep_mutex); \
3365 return -ENOTCONN; \
3366 } \
3367 \
3368 if (ep) \
3369 rc = t->get_ep_param(ep, param, buf); \
3370 else \
3371 rc = t->get_conn_param(conn, param, buf); \
3372 mutex_unlock(&conn->ep_mutex); \
3373 return rc; \
3374}
3375
3376#define iscsi_conn_ep_attr(field, param) \
3377 iscsi_conn_ep_attr_show(param) \
3378static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, \
3379 show_conn_ep_param_##param, NULL);
3380
3381iscsi_conn_ep_attr(address, ISCSI_PARAM_CONN_ADDRESS);
3382iscsi_conn_ep_attr(port, ISCSI_PARAM_CONN_PORT);
3383
3384static struct attribute *iscsi_conn_attrs[] = {
3385 &dev_attr_conn_max_recv_dlength.attr,
3386 &dev_attr_conn_max_xmit_dlength.attr,
3387 &dev_attr_conn_header_digest.attr,
3388 &dev_attr_conn_data_digest.attr,
3389 &dev_attr_conn_ifmarker.attr,
3390 &dev_attr_conn_ofmarker.attr,
3391 &dev_attr_conn_address.attr,
3392 &dev_attr_conn_port.attr,
3393 &dev_attr_conn_exp_statsn.attr,
3394 &dev_attr_conn_persistent_address.attr,
3395 &dev_attr_conn_persistent_port.attr,
3396 &dev_attr_conn_ping_tmo.attr,
3397 &dev_attr_conn_recv_tmo.attr,
3398 &dev_attr_conn_local_port.attr,
3399 &dev_attr_conn_statsn.attr,
3400 &dev_attr_conn_keepalive_tmo.attr,
3401 &dev_attr_conn_max_segment_size.attr,
3402 &dev_attr_conn_tcp_timestamp_stat.attr,
3403 &dev_attr_conn_tcp_wsf_disable.attr,
3404 &dev_attr_conn_tcp_nagle_disable.attr,
3405 &dev_attr_conn_tcp_timer_scale.attr,
3406 &dev_attr_conn_tcp_timestamp_enable.attr,
3407 &dev_attr_conn_fragment_disable.attr,
3408 &dev_attr_conn_ipv4_tos.attr,
3409 &dev_attr_conn_ipv6_traffic_class.attr,
3410 &dev_attr_conn_ipv6_flow_label.attr,
3411 &dev_attr_conn_is_fw_assigned_ipv6.attr,
3412 &dev_attr_conn_tcp_xmit_wsf.attr,
3413 &dev_attr_conn_tcp_recv_wsf.attr,
3414 NULL,
3415};
3416
3417static umode_t iscsi_conn_attr_is_visible(struct kobject *kobj,
3418 struct attribute *attr, int i)
3419{
3420 struct device *cdev = container_of(kobj, struct device, kobj);
3421 struct iscsi_cls_conn *conn = transport_class_to_conn(cdev);
3422 struct iscsi_transport *t = conn->transport;
3423 int param;
3424
3425 if (attr == &dev_attr_conn_max_recv_dlength.attr)
3426 param = ISCSI_PARAM_MAX_RECV_DLENGTH;
3427 else if (attr == &dev_attr_conn_max_xmit_dlength.attr)
3428 param = ISCSI_PARAM_MAX_XMIT_DLENGTH;
3429 else if (attr == &dev_attr_conn_header_digest.attr)
3430 param = ISCSI_PARAM_HDRDGST_EN;
3431 else if (attr == &dev_attr_conn_data_digest.attr)
3432 param = ISCSI_PARAM_DATADGST_EN;
3433 else if (attr == &dev_attr_conn_ifmarker.attr)
3434 param = ISCSI_PARAM_IFMARKER_EN;
3435 else if (attr == &dev_attr_conn_ofmarker.attr)
3436 param = ISCSI_PARAM_OFMARKER_EN;
3437 else if (attr == &dev_attr_conn_address.attr)
3438 param = ISCSI_PARAM_CONN_ADDRESS;
3439 else if (attr == &dev_attr_conn_port.attr)
3440 param = ISCSI_PARAM_CONN_PORT;
3441 else if (attr == &dev_attr_conn_exp_statsn.attr)
3442 param = ISCSI_PARAM_EXP_STATSN;
3443 else if (attr == &dev_attr_conn_persistent_address.attr)
3444 param = ISCSI_PARAM_PERSISTENT_ADDRESS;
3445 else if (attr == &dev_attr_conn_persistent_port.attr)
3446 param = ISCSI_PARAM_PERSISTENT_PORT;
3447 else if (attr == &dev_attr_conn_ping_tmo.attr)
3448 param = ISCSI_PARAM_PING_TMO;
3449 else if (attr == &dev_attr_conn_recv_tmo.attr)
3450 param = ISCSI_PARAM_RECV_TMO;
3451 else if (attr == &dev_attr_conn_local_port.attr)
3452 param = ISCSI_PARAM_LOCAL_PORT;
3453 else if (attr == &dev_attr_conn_statsn.attr)
3454 param = ISCSI_PARAM_STATSN;
3455 else if (attr == &dev_attr_conn_keepalive_tmo.attr)
3456 param = ISCSI_PARAM_KEEPALIVE_TMO;
3457 else if (attr == &dev_attr_conn_max_segment_size.attr)
3458 param = ISCSI_PARAM_MAX_SEGMENT_SIZE;
3459 else if (attr == &dev_attr_conn_tcp_timestamp_stat.attr)
3460 param = ISCSI_PARAM_TCP_TIMESTAMP_STAT;
3461 else if (attr == &dev_attr_conn_tcp_wsf_disable.attr)
3462 param = ISCSI_PARAM_TCP_WSF_DISABLE;
3463 else if (attr == &dev_attr_conn_tcp_nagle_disable.attr)
3464 param = ISCSI_PARAM_TCP_NAGLE_DISABLE;
3465 else if (attr == &dev_attr_conn_tcp_timer_scale.attr)
3466 param = ISCSI_PARAM_TCP_TIMER_SCALE;
3467 else if (attr == &dev_attr_conn_tcp_timestamp_enable.attr)
3468 param = ISCSI_PARAM_TCP_TIMESTAMP_EN;
3469 else if (attr == &dev_attr_conn_fragment_disable.attr)
3470 param = ISCSI_PARAM_IP_FRAGMENT_DISABLE;
3471 else if (attr == &dev_attr_conn_ipv4_tos.attr)
3472 param = ISCSI_PARAM_IPV4_TOS;
3473 else if (attr == &dev_attr_conn_ipv6_traffic_class.attr)
3474 param = ISCSI_PARAM_IPV6_TC;
3475 else if (attr == &dev_attr_conn_ipv6_flow_label.attr)
3476 param = ISCSI_PARAM_IPV6_FLOW_LABEL;
3477 else if (attr == &dev_attr_conn_is_fw_assigned_ipv6.attr)
3478 param = ISCSI_PARAM_IS_FW_ASSIGNED_IPV6;
3479 else if (attr == &dev_attr_conn_tcp_xmit_wsf.attr)
3480 param = ISCSI_PARAM_TCP_XMIT_WSF;
3481 else if (attr == &dev_attr_conn_tcp_recv_wsf.attr)
3482 param = ISCSI_PARAM_TCP_RECV_WSF;
3483 else {
3484 WARN_ONCE(1, "Invalid conn attr");
3485 return 0;
3486 }
3487
3488 return t->attr_is_visible(ISCSI_PARAM, param);
3489}
3490
3491static struct attribute_group iscsi_conn_group = {
3492 .attrs = iscsi_conn_attrs,
3493 .is_visible = iscsi_conn_attr_is_visible,
3494};
3495
3496
3497
3498
3499#define iscsi_session_attr_show(param, perm) \
3500static ssize_t \
3501show_session_param_##param(struct device *dev, \
3502 struct device_attribute *attr, char *buf) \
3503{ \
3504 struct iscsi_cls_session *session = \
3505 iscsi_dev_to_session(dev->parent); \
3506 struct iscsi_transport *t = session->transport; \
3507 \
3508 if (perm && !capable(CAP_SYS_ADMIN)) \
3509 return -EACCES; \
3510 return t->get_session_param(session, param, buf); \
3511}
3512
3513#define iscsi_session_attr(field, param, perm) \
3514 iscsi_session_attr_show(param, perm) \
3515static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \
3516 NULL);
3517iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME, 0);
3518iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, 0);
3519iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, 0);
3520iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, 0);
3521iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, 0);
3522iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, 0);
3523iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, 0);
3524iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, 0);
3525iscsi_session_attr(erl, ISCSI_PARAM_ERL, 0);
3526iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT, 0);
3527iscsi_session_attr(username, ISCSI_PARAM_USERNAME, 1);
3528iscsi_session_attr(username_in, ISCSI_PARAM_USERNAME_IN, 1);
3529iscsi_session_attr(password, ISCSI_PARAM_PASSWORD, 1);
3530iscsi_session_attr(password_in, ISCSI_PARAM_PASSWORD_IN, 1);
3531iscsi_session_attr(chap_out_idx, ISCSI_PARAM_CHAP_OUT_IDX, 1);
3532iscsi_session_attr(chap_in_idx, ISCSI_PARAM_CHAP_IN_IDX, 1);
3533iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 0);
3534iscsi_session_attr(abort_tmo, ISCSI_PARAM_ABORT_TMO, 0);
3535iscsi_session_attr(lu_reset_tmo, ISCSI_PARAM_LU_RESET_TMO, 0);
3536iscsi_session_attr(tgt_reset_tmo, ISCSI_PARAM_TGT_RESET_TMO, 0);
3537iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0);
3538iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0);
3539iscsi_session_attr(targetalias, ISCSI_PARAM_TARGET_ALIAS, 0);
3540iscsi_session_attr(boot_root, ISCSI_PARAM_BOOT_ROOT, 0);
3541iscsi_session_attr(boot_nic, ISCSI_PARAM_BOOT_NIC, 0);
3542iscsi_session_attr(boot_target, ISCSI_PARAM_BOOT_TARGET, 0);
3543iscsi_session_attr(auto_snd_tgt_disable, ISCSI_PARAM_AUTO_SND_TGT_DISABLE, 0);
3544iscsi_session_attr(discovery_session, ISCSI_PARAM_DISCOVERY_SESS, 0);
3545iscsi_session_attr(portal_type, ISCSI_PARAM_PORTAL_TYPE, 0);
3546iscsi_session_attr(chap_auth, ISCSI_PARAM_CHAP_AUTH_EN, 0);
3547iscsi_session_attr(discovery_logout, ISCSI_PARAM_DISCOVERY_LOGOUT_EN, 0);
3548iscsi_session_attr(bidi_chap, ISCSI_PARAM_BIDI_CHAP_EN, 0);
3549iscsi_session_attr(discovery_auth_optional,
3550 ISCSI_PARAM_DISCOVERY_AUTH_OPTIONAL, 0);
3551iscsi_session_attr(def_time2wait, ISCSI_PARAM_DEF_TIME2WAIT, 0);
3552iscsi_session_attr(def_time2retain, ISCSI_PARAM_DEF_TIME2RETAIN, 0);
3553iscsi_session_attr(isid, ISCSI_PARAM_ISID, 0);
3554iscsi_session_attr(tsid, ISCSI_PARAM_TSID, 0);
3555iscsi_session_attr(def_taskmgmt_tmo, ISCSI_PARAM_DEF_TASKMGMT_TMO, 0);
3556iscsi_session_attr(discovery_parent_idx, ISCSI_PARAM_DISCOVERY_PARENT_IDX, 0);
3557iscsi_session_attr(discovery_parent_type, ISCSI_PARAM_DISCOVERY_PARENT_TYPE, 0);
3558
3559static ssize_t
3560show_priv_session_state(struct device *dev, struct device_attribute *attr,
3561 char *buf)
3562{
3563 struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
3564 return sprintf(buf, "%s\n", iscsi_session_state_name(session->state));
3565}
3566static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state,
3567 NULL);
3568static ssize_t
3569show_priv_session_creator(struct device *dev, struct device_attribute *attr,
3570 char *buf)
3571{
3572 struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
3573 return sprintf(buf, "%d\n", session->creator);
3574}
3575static ISCSI_CLASS_ATTR(priv_sess, creator, S_IRUGO, show_priv_session_creator,
3576 NULL);
3577static ssize_t
3578show_priv_session_target_id(struct device *dev, struct device_attribute *attr,
3579 char *buf)
3580{
3581 struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
3582 return sprintf(buf, "%d\n", session->target_id);
3583}
3584static ISCSI_CLASS_ATTR(priv_sess, target_id, S_IRUGO,
3585 show_priv_session_target_id, NULL);
3586
3587#define iscsi_priv_session_attr_show(field, format) \
3588static ssize_t \
3589show_priv_session_##field(struct device *dev, \
3590 struct device_attribute *attr, char *buf) \
3591{ \
3592 struct iscsi_cls_session *session = \
3593 iscsi_dev_to_session(dev->parent); \
3594 if (session->field == -1) \
3595 return sprintf(buf, "off\n"); \
3596 return sprintf(buf, format"\n", session->field); \
3597}
3598
3599#define iscsi_priv_session_attr_store(field) \
3600static ssize_t \
3601store_priv_session_##field(struct device *dev, \
3602 struct device_attribute *attr, \
3603 const char *buf, size_t count) \
3604{ \
3605 int val; \
3606 char *cp; \
3607 struct iscsi_cls_session *session = \
3608 iscsi_dev_to_session(dev->parent); \
3609 if ((session->state == ISCSI_SESSION_FREE) || \
3610 (session->state == ISCSI_SESSION_FAILED)) \
3611 return -EBUSY; \
3612 if (strncmp(buf, "off", 3) == 0) \
3613 session->field = -1; \
3614 else { \
3615 val = simple_strtoul(buf, &cp, 0); \
3616 if (*cp != '\0' && *cp != '\n') \
3617 return -EINVAL; \
3618 session->field = val; \
3619 } \
3620 return count; \
3621}
3622
3623#define iscsi_priv_session_rw_attr(field, format) \
3624 iscsi_priv_session_attr_show(field, format) \
3625 iscsi_priv_session_attr_store(field) \
3626static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUSR, \
3627 show_priv_session_##field, \
3628 store_priv_session_##field)
3629iscsi_priv_session_rw_attr(recovery_tmo, "%d");
3630
3631static struct attribute *iscsi_session_attrs[] = {
3632 &dev_attr_sess_initial_r2t.attr,
3633 &dev_attr_sess_max_outstanding_r2t.attr,
3634 &dev_attr_sess_immediate_data.attr,
3635 &dev_attr_sess_first_burst_len.attr,
3636 &dev_attr_sess_max_burst_len.attr,
3637 &dev_attr_sess_data_pdu_in_order.attr,
3638 &dev_attr_sess_data_seq_in_order.attr,
3639 &dev_attr_sess_erl.attr,
3640 &dev_attr_sess_targetname.attr,
3641 &dev_attr_sess_tpgt.attr,
3642 &dev_attr_sess_password.attr,
3643 &dev_attr_sess_password_in.attr,
3644 &dev_attr_sess_username.attr,
3645 &dev_attr_sess_username_in.attr,
3646 &dev_attr_sess_fast_abort.attr,
3647 &dev_attr_sess_abort_tmo.attr,
3648 &dev_attr_sess_lu_reset_tmo.attr,
3649 &dev_attr_sess_tgt_reset_tmo.attr,
3650 &dev_attr_sess_ifacename.attr,
3651 &dev_attr_sess_initiatorname.attr,
3652 &dev_attr_sess_targetalias.attr,
3653 &dev_attr_sess_boot_root.attr,
3654 &dev_attr_sess_boot_nic.attr,
3655 &dev_attr_sess_boot_target.attr,
3656 &dev_attr_priv_sess_recovery_tmo.attr,
3657 &dev_attr_priv_sess_state.attr,
3658 &dev_attr_priv_sess_creator.attr,
3659 &dev_attr_sess_chap_out_idx.attr,
3660 &dev_attr_sess_chap_in_idx.attr,
3661 &dev_attr_priv_sess_target_id.attr,
3662 &dev_attr_sess_auto_snd_tgt_disable.attr,
3663 &dev_attr_sess_discovery_session.attr,
3664 &dev_attr_sess_portal_type.attr,
3665 &dev_attr_sess_chap_auth.attr,
3666 &dev_attr_sess_discovery_logout.attr,
3667 &dev_attr_sess_bidi_chap.attr,
3668 &dev_attr_sess_discovery_auth_optional.attr,
3669 &dev_attr_sess_def_time2wait.attr,
3670 &dev_attr_sess_def_time2retain.attr,
3671 &dev_attr_sess_isid.attr,
3672 &dev_attr_sess_tsid.attr,
3673 &dev_attr_sess_def_taskmgmt_tmo.attr,
3674 &dev_attr_sess_discovery_parent_idx.attr,
3675 &dev_attr_sess_discovery_parent_type.attr,
3676 NULL,
3677};
3678
3679static umode_t iscsi_session_attr_is_visible(struct kobject *kobj,
3680 struct attribute *attr, int i)
3681{
3682 struct device *cdev = container_of(kobj, struct device, kobj);
3683 struct iscsi_cls_session *session = transport_class_to_session(cdev);
3684 struct iscsi_transport *t = session->transport;
3685 int param;
3686
3687 if (attr == &dev_attr_sess_initial_r2t.attr)
3688 param = ISCSI_PARAM_INITIAL_R2T_EN;
3689 else if (attr == &dev_attr_sess_max_outstanding_r2t.attr)
3690 param = ISCSI_PARAM_MAX_R2T;
3691 else if (attr == &dev_attr_sess_immediate_data.attr)
3692 param = ISCSI_PARAM_IMM_DATA_EN;
3693 else if (attr == &dev_attr_sess_first_burst_len.attr)
3694 param = ISCSI_PARAM_FIRST_BURST;
3695 else if (attr == &dev_attr_sess_max_burst_len.attr)
3696 param = ISCSI_PARAM_MAX_BURST;
3697 else if (attr == &dev_attr_sess_data_pdu_in_order.attr)
3698 param = ISCSI_PARAM_PDU_INORDER_EN;
3699 else if (attr == &dev_attr_sess_data_seq_in_order.attr)
3700 param = ISCSI_PARAM_DATASEQ_INORDER_EN;
3701 else if (attr == &dev_attr_sess_erl.attr)
3702 param = ISCSI_PARAM_ERL;
3703 else if (attr == &dev_attr_sess_targetname.attr)
3704 param = ISCSI_PARAM_TARGET_NAME;
3705 else if (attr == &dev_attr_sess_tpgt.attr)
3706 param = ISCSI_PARAM_TPGT;
3707 else if (attr == &dev_attr_sess_chap_in_idx.attr)
3708 param = ISCSI_PARAM_CHAP_IN_IDX;
3709 else if (attr == &dev_attr_sess_chap_out_idx.attr)
3710 param = ISCSI_PARAM_CHAP_OUT_IDX;
3711 else if (attr == &dev_attr_sess_password.attr)
3712 param = ISCSI_PARAM_USERNAME;
3713 else if (attr == &dev_attr_sess_password_in.attr)
3714 param = ISCSI_PARAM_USERNAME_IN;
3715 else if (attr == &dev_attr_sess_username.attr)
3716 param = ISCSI_PARAM_PASSWORD;
3717 else if (attr == &dev_attr_sess_username_in.attr)
3718 param = ISCSI_PARAM_PASSWORD_IN;
3719 else if (attr == &dev_attr_sess_fast_abort.attr)
3720 param = ISCSI_PARAM_FAST_ABORT;
3721 else if (attr == &dev_attr_sess_abort_tmo.attr)
3722 param = ISCSI_PARAM_ABORT_TMO;
3723 else if (attr == &dev_attr_sess_lu_reset_tmo.attr)
3724 param = ISCSI_PARAM_LU_RESET_TMO;
3725 else if (attr == &dev_attr_sess_tgt_reset_tmo.attr)
3726 param = ISCSI_PARAM_TGT_RESET_TMO;
3727 else if (attr == &dev_attr_sess_ifacename.attr)
3728 param = ISCSI_PARAM_IFACE_NAME;
3729 else if (attr == &dev_attr_sess_initiatorname.attr)
3730 param = ISCSI_PARAM_INITIATOR_NAME;
3731 else if (attr == &dev_attr_sess_targetalias.attr)
3732 param = ISCSI_PARAM_TARGET_ALIAS;
3733 else if (attr == &dev_attr_sess_boot_root.attr)
3734 param = ISCSI_PARAM_BOOT_ROOT;
3735 else if (attr == &dev_attr_sess_boot_nic.attr)
3736 param = ISCSI_PARAM_BOOT_NIC;
3737 else if (attr == &dev_attr_sess_boot_target.attr)
3738 param = ISCSI_PARAM_BOOT_TARGET;
3739 else if (attr == &dev_attr_sess_auto_snd_tgt_disable.attr)
3740 param = ISCSI_PARAM_AUTO_SND_TGT_DISABLE;
3741 else if (attr == &dev_attr_sess_discovery_session.attr)
3742 param = ISCSI_PARAM_DISCOVERY_SESS;
3743 else if (attr == &dev_attr_sess_portal_type.attr)
3744 param = ISCSI_PARAM_PORTAL_TYPE;
3745 else if (attr == &dev_attr_sess_chap_auth.attr)
3746 param = ISCSI_PARAM_CHAP_AUTH_EN;
3747 else if (attr == &dev_attr_sess_discovery_logout.attr)
3748 param = ISCSI_PARAM_DISCOVERY_LOGOUT_EN;
3749 else if (attr == &dev_attr_sess_bidi_chap.attr)
3750 param = ISCSI_PARAM_BIDI_CHAP_EN;
3751 else if (attr == &dev_attr_sess_discovery_auth_optional.attr)
3752 param = ISCSI_PARAM_DISCOVERY_AUTH_OPTIONAL;
3753 else if (attr == &dev_attr_sess_def_time2wait.attr)
3754 param = ISCSI_PARAM_DEF_TIME2WAIT;
3755 else if (attr == &dev_attr_sess_def_time2retain.attr)
3756 param = ISCSI_PARAM_DEF_TIME2RETAIN;
3757 else if (attr == &dev_attr_sess_isid.attr)
3758 param = ISCSI_PARAM_ISID;
3759 else if (attr == &dev_attr_sess_tsid.attr)
3760 param = ISCSI_PARAM_TSID;
3761 else if (attr == &dev_attr_sess_def_taskmgmt_tmo.attr)
3762 param = ISCSI_PARAM_DEF_TASKMGMT_TMO;
3763 else if (attr == &dev_attr_sess_discovery_parent_idx.attr)
3764 param = ISCSI_PARAM_DISCOVERY_PARENT_IDX;
3765 else if (attr == &dev_attr_sess_discovery_parent_type.attr)
3766 param = ISCSI_PARAM_DISCOVERY_PARENT_TYPE;
3767 else if (attr == &dev_attr_priv_sess_recovery_tmo.attr)
3768 return S_IRUGO | S_IWUSR;
3769 else if (attr == &dev_attr_priv_sess_state.attr)
3770 return S_IRUGO;
3771 else if (attr == &dev_attr_priv_sess_creator.attr)
3772 return S_IRUGO;
3773 else if (attr == &dev_attr_priv_sess_target_id.attr)
3774 return S_IRUGO;
3775 else {
3776 WARN_ONCE(1, "Invalid session attr");
3777 return 0;
3778 }
3779
3780 return t->attr_is_visible(ISCSI_PARAM, param);
3781}
3782
3783static struct attribute_group iscsi_session_group = {
3784 .attrs = iscsi_session_attrs,
3785 .is_visible = iscsi_session_attr_is_visible,
3786};
3787
3788
3789
3790
3791#define iscsi_host_attr_show(param) \
3792static ssize_t \
3793show_host_param_##param(struct device *dev, \
3794 struct device_attribute *attr, char *buf) \
3795{ \
3796 struct Scsi_Host *shost = transport_class_to_shost(dev); \
3797 struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
3798 return priv->iscsi_transport->get_host_param(shost, param, buf); \
3799}
3800
3801#define iscsi_host_attr(field, param) \
3802 iscsi_host_attr_show(param) \
3803static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, \
3804 NULL);
3805
3806iscsi_host_attr(netdev, ISCSI_HOST_PARAM_NETDEV_NAME);
3807iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS);
3808iscsi_host_attr(ipaddress, ISCSI_HOST_PARAM_IPADDRESS);
3809iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME);
3810iscsi_host_attr(port_state, ISCSI_HOST_PARAM_PORT_STATE);
3811iscsi_host_attr(port_speed, ISCSI_HOST_PARAM_PORT_SPEED);
3812
3813static struct attribute *iscsi_host_attrs[] = {
3814 &dev_attr_host_netdev.attr,
3815 &dev_attr_host_hwaddress.attr,
3816 &dev_attr_host_ipaddress.attr,
3817 &dev_attr_host_initiatorname.attr,
3818 &dev_attr_host_port_state.attr,
3819 &dev_attr_host_port_speed.attr,
3820 NULL,
3821};
3822
3823static umode_t iscsi_host_attr_is_visible(struct kobject *kobj,
3824 struct attribute *attr, int i)
3825{
3826 struct device *cdev = container_of(kobj, struct device, kobj);
3827 struct Scsi_Host *shost = transport_class_to_shost(cdev);
3828 struct iscsi_internal *priv = to_iscsi_internal(shost->transportt);
3829 int param;
3830
3831 if (attr == &dev_attr_host_netdev.attr)
3832 param = ISCSI_HOST_PARAM_NETDEV_NAME;
3833 else if (attr == &dev_attr_host_hwaddress.attr)
3834 param = ISCSI_HOST_PARAM_HWADDRESS;
3835 else if (attr == &dev_attr_host_ipaddress.attr)
3836 param = ISCSI_HOST_PARAM_IPADDRESS;
3837 else if (attr == &dev_attr_host_initiatorname.attr)
3838 param = ISCSI_HOST_PARAM_INITIATOR_NAME;
3839 else if (attr == &dev_attr_host_port_state.attr)
3840 param = ISCSI_HOST_PARAM_PORT_STATE;
3841 else if (attr == &dev_attr_host_port_speed.attr)
3842 param = ISCSI_HOST_PARAM_PORT_SPEED;
3843 else {
3844 WARN_ONCE(1, "Invalid host attr");
3845 return 0;
3846 }
3847
3848 return priv->iscsi_transport->attr_is_visible(ISCSI_HOST_PARAM, param);
3849}
3850
3851static struct attribute_group iscsi_host_group = {
3852 .attrs = iscsi_host_attrs,
3853 .is_visible = iscsi_host_attr_is_visible,
3854};
3855
3856
3857static const struct {
3858 enum iscsi_port_speed value;
3859 char *name;
3860} iscsi_port_speed_names[] = {
3861 {ISCSI_PORT_SPEED_UNKNOWN, "Unknown" },
3862 {ISCSI_PORT_SPEED_10MBPS, "10 Mbps" },
3863 {ISCSI_PORT_SPEED_100MBPS, "100 Mbps" },
3864 {ISCSI_PORT_SPEED_1GBPS, "1 Gbps" },
3865 {ISCSI_PORT_SPEED_10GBPS, "10 Gbps" },
3866};
3867
3868char *iscsi_get_port_speed_name(struct Scsi_Host *shost)
3869{
3870 int i;
3871 char *speed = "Unknown!";
3872 struct iscsi_cls_host *ihost = shost->shost_data;
3873 uint32_t port_speed = ihost->port_speed;
3874
3875 for (i = 0; i < ARRAY_SIZE(iscsi_port_speed_names); i++) {
3876 if (iscsi_port_speed_names[i].value & port_speed) {
3877 speed = iscsi_port_speed_names[i].name;
3878 break;
3879 }
3880 }
3881 return speed;
3882}
3883EXPORT_SYMBOL_GPL(iscsi_get_port_speed_name);
3884
3885
3886static const struct {
3887 enum iscsi_port_state value;
3888 char *name;
3889} iscsi_port_state_names[] = {
3890 {ISCSI_PORT_STATE_DOWN, "LINK DOWN" },
3891 {ISCSI_PORT_STATE_UP, "LINK UP" },
3892};
3893
3894char *iscsi_get_port_state_name(struct Scsi_Host *shost)
3895{
3896 int i;
3897 char *state = "Unknown!";
3898 struct iscsi_cls_host *ihost = shost->shost_data;
3899 uint32_t port_state = ihost->port_state;
3900
3901 for (i = 0; i < ARRAY_SIZE(iscsi_port_state_names); i++) {
3902 if (iscsi_port_state_names[i].value & port_state) {
3903 state = iscsi_port_state_names[i].name;
3904 break;
3905 }
3906 }
3907 return state;
3908}
3909EXPORT_SYMBOL_GPL(iscsi_get_port_state_name);
3910
3911static int iscsi_session_match(struct attribute_container *cont,
3912 struct device *dev)
3913{
3914 struct iscsi_cls_session *session;
3915 struct Scsi_Host *shost;
3916 struct iscsi_internal *priv;
3917
3918 if (!iscsi_is_session_dev(dev))
3919 return 0;
3920
3921 session = iscsi_dev_to_session(dev);
3922 shost = iscsi_session_to_shost(session);
3923 if (!shost->transportt)
3924 return 0;
3925
3926 priv = to_iscsi_internal(shost->transportt);
3927 if (priv->session_cont.ac.class != &iscsi_session_class.class)
3928 return 0;
3929
3930 return &priv->session_cont.ac == cont;
3931}
3932
3933static int iscsi_conn_match(struct attribute_container *cont,
3934 struct device *dev)
3935{
3936 struct iscsi_cls_session *session;
3937 struct iscsi_cls_conn *conn;
3938 struct Scsi_Host *shost;
3939 struct iscsi_internal *priv;
3940
3941 if (!iscsi_is_conn_dev(dev))
3942 return 0;
3943
3944 conn = iscsi_dev_to_conn(dev);
3945 session = iscsi_dev_to_session(conn->dev.parent);
3946 shost = iscsi_session_to_shost(session);
3947
3948 if (!shost->transportt)
3949 return 0;
3950
3951 priv = to_iscsi_internal(shost->transportt);
3952 if (priv->conn_cont.ac.class != &iscsi_connection_class.class)
3953 return 0;
3954
3955 return &priv->conn_cont.ac == cont;
3956}
3957
3958static int iscsi_host_match(struct attribute_container *cont,
3959 struct device *dev)
3960{
3961 struct Scsi_Host *shost;
3962 struct iscsi_internal *priv;
3963
3964 if (!scsi_is_host_device(dev))
3965 return 0;
3966
3967 shost = dev_to_shost(dev);
3968 if (!shost->transportt ||
3969 shost->transportt->host_attrs.ac.class != &iscsi_host_class.class)
3970 return 0;
3971
3972 priv = to_iscsi_internal(shost->transportt);
3973 return &priv->t.host_attrs.ac == cont;
3974}
3975
3976struct scsi_transport_template *
3977iscsi_register_transport(struct iscsi_transport *tt)
3978{
3979 struct iscsi_internal *priv;
3980 unsigned long flags;
3981 int err;
3982
3983 BUG_ON(!tt);
3984
3985 priv = iscsi_if_transport_lookup(tt);
3986 if (priv)
3987 return NULL;
3988
3989 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
3990 if (!priv)
3991 return NULL;
3992 INIT_LIST_HEAD(&priv->list);
3993 priv->iscsi_transport = tt;
3994 priv->t.user_scan = iscsi_user_scan;
3995 priv->t.create_work_queue = 1;
3996
3997 priv->dev.class = &iscsi_transport_class;
3998 dev_set_name(&priv->dev, "%s", tt->name);
3999 err = device_register(&priv->dev);
4000 if (err)
4001 goto free_priv;
4002
4003 err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
4004 if (err)
4005 goto unregister_dev;
4006
4007
4008 priv->t.host_attrs.ac.class = &iscsi_host_class.class;
4009 priv->t.host_attrs.ac.match = iscsi_host_match;
4010 priv->t.host_attrs.ac.grp = &iscsi_host_group;
4011 priv->t.host_size = sizeof(struct iscsi_cls_host);
4012 transport_container_register(&priv->t.host_attrs);
4013
4014
4015 priv->conn_cont.ac.class = &iscsi_connection_class.class;
4016 priv->conn_cont.ac.match = iscsi_conn_match;
4017 priv->conn_cont.ac.grp = &iscsi_conn_group;
4018 transport_container_register(&priv->conn_cont);
4019
4020
4021 priv->session_cont.ac.class = &iscsi_session_class.class;
4022 priv->session_cont.ac.match = iscsi_session_match;
4023 priv->session_cont.ac.grp = &iscsi_session_group;
4024 transport_container_register(&priv->session_cont);
4025
4026 spin_lock_irqsave(&iscsi_transport_lock, flags);
4027 list_add(&priv->list, &iscsi_transports);
4028 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
4029
4030 printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
4031 return &priv->t;
4032
4033unregister_dev:
4034 device_unregister(&priv->dev);
4035 return NULL;
4036free_priv:
4037 kfree(priv);
4038 return NULL;
4039}
4040EXPORT_SYMBOL_GPL(iscsi_register_transport);
4041
4042int iscsi_unregister_transport(struct iscsi_transport *tt)
4043{
4044 struct iscsi_internal *priv;
4045 unsigned long flags;
4046
4047 BUG_ON(!tt);
4048
4049 mutex_lock(&rx_queue_mutex);
4050
4051 priv = iscsi_if_transport_lookup(tt);
4052 BUG_ON (!priv);
4053
4054 spin_lock_irqsave(&iscsi_transport_lock, flags);
4055 list_del(&priv->list);
4056 spin_unlock_irqrestore(&iscsi_transport_lock, flags);
4057
4058 transport_container_unregister(&priv->conn_cont);
4059 transport_container_unregister(&priv->session_cont);
4060 transport_container_unregister(&priv->t.host_attrs);
4061
4062 sysfs_remove_group(&priv->dev.kobj, &iscsi_transport_group);
4063 device_unregister(&priv->dev);
4064 mutex_unlock(&rx_queue_mutex);
4065
4066 return 0;
4067}
4068EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
4069
4070static __init int iscsi_transport_init(void)
4071{
4072 int err;
4073 struct netlink_kernel_cfg cfg = {
4074 .groups = 1,
4075 .input = iscsi_if_rx,
4076 };
4077 printk(KERN_INFO "Loading iSCSI transport class v%s.\n",
4078 ISCSI_TRANSPORT_VERSION);
4079
4080 atomic_set(&iscsi_session_nr, 0);
4081
4082 err = class_register(&iscsi_transport_class);
4083 if (err)
4084 return err;
4085
4086 err = class_register(&iscsi_endpoint_class);
4087 if (err)
4088 goto unregister_transport_class;
4089
4090 err = class_register(&iscsi_iface_class);
4091 if (err)
4092 goto unregister_endpoint_class;
4093
4094 err = transport_class_register(&iscsi_host_class);
4095 if (err)
4096 goto unregister_iface_class;
4097
4098 err = transport_class_register(&iscsi_connection_class);
4099 if (err)
4100 goto unregister_host_class;
4101
4102 err = transport_class_register(&iscsi_session_class);
4103 if (err)
4104 goto unregister_conn_class;
4105
4106 err = bus_register(&iscsi_flashnode_bus);
4107 if (err)
4108 goto unregister_session_class;
4109
4110 nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, &cfg);
4111 if (!nls) {
4112 err = -ENOBUFS;
4113 goto unregister_flashnode_bus;
4114 }
4115
4116 iscsi_eh_timer_workq = create_singlethread_workqueue("iscsi_eh");
4117 if (!iscsi_eh_timer_workq) {
4118 err = -ENOMEM;
4119 goto release_nls;
4120 }
4121
4122 return 0;
4123
4124release_nls:
4125 netlink_kernel_release(nls);
4126unregister_flashnode_bus:
4127 bus_unregister(&iscsi_flashnode_bus);
4128unregister_session_class:
4129 transport_class_unregister(&iscsi_session_class);
4130unregister_conn_class:
4131 transport_class_unregister(&iscsi_connection_class);
4132unregister_host_class:
4133 transport_class_unregister(&iscsi_host_class);
4134unregister_iface_class:
4135 class_unregister(&iscsi_iface_class);
4136unregister_endpoint_class:
4137 class_unregister(&iscsi_endpoint_class);
4138unregister_transport_class:
4139 class_unregister(&iscsi_transport_class);
4140 return err;
4141}
4142
4143static void __exit iscsi_transport_exit(void)
4144{
4145 destroy_workqueue(iscsi_eh_timer_workq);
4146 netlink_kernel_release(nls);
4147 bus_unregister(&iscsi_flashnode_bus);
4148 transport_class_unregister(&iscsi_connection_class);
4149 transport_class_unregister(&iscsi_session_class);
4150 transport_class_unregister(&iscsi_host_class);
4151 class_unregister(&iscsi_endpoint_class);
4152 class_unregister(&iscsi_iface_class);
4153 class_unregister(&iscsi_transport_class);
4154}
4155
4156module_init(iscsi_transport_init);
4157module_exit(iscsi_transport_exit);
4158
4159MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
4160 "Dmitry Yusupov <dmitry_yus@yahoo.com>, "
4161 "Alex Aizman <itn780@yahoo.com>");
4162MODULE_DESCRIPTION("iSCSI Transport Interface");
4163MODULE_LICENSE("GPL");
4164MODULE_VERSION(ISCSI_TRANSPORT_VERSION);
4165MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_ISCSI);
4166