aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_iscsi.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2011-07-25 14:48:40 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-08-27 10:36:00 -0400
commit8d07913dbe79568eafe5bb73806a08aac294d4e6 (patch)
tree125b845b1157dbe44640f83bfdfe36c187d061a9 /drivers/scsi/scsi_transport_iscsi.c
parent2bab08fc770ccd6c56859371356a4a905e8c0bd4 (diff)
[SCSI] iscsi class: add iface representation
A iscsi host can have multiple interfaces. This patch adds a new iface iscsi class for this. It exports the network settings now, and will be extended to also export iscsi initiator port settings like the isid and initiator name for drivers that can support multiple initiator ports. Based on patch from Lalit Chandivade. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c189
1 files changed, 188 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 212a8d846748..4d5e64f429e7 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -270,6 +270,185 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
270} 270}
271EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); 271EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
272 272
273/*
274 * Interface to display network param to sysfs
275 */
276
277static void iscsi_iface_release(struct device *dev)
278{
279 struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
280 struct device *parent = iface->dev.parent;
281
282 kfree(iface);
283 put_device(parent);
284}
285
286
287static struct class iscsi_iface_class = {
288 .name = "iscsi_iface",
289 .dev_release = iscsi_iface_release,
290};
291
292#define ISCSI_IFACE_ATTR(_prefix, _name, _mode, _show, _store) \
293struct device_attribute dev_attr_##_prefix##_##_name = \
294 __ATTR(_name, _mode, _show, _store)
295
296/* iface attrs show */
297#define iscsi_iface_attr_show(type, name, param_type, param) \
298static ssize_t \
299show_##type##_##name(struct device *dev, struct device_attribute *attr, \
300 char *buf) \
301{ \
302 struct iscsi_iface *iface = iscsi_dev_to_iface(dev); \
303 struct iscsi_transport *t = iface->transport; \
304 return t->get_iface_param(iface, param_type, param, buf); \
305} \
306
307#define iscsi_iface_net_attr(type, name, param) \
308 iscsi_iface_attr_show(type, name, ISCSI_NET_PARAM, param) \
309static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);
310
311/* generic read only ipvi4 attribute */
312iscsi_iface_net_attr(ipv4_iface, ipaddress, ISCSI_NET_PARAM_IPV4_ADDR);
313iscsi_iface_net_attr(ipv4_iface, gateway, ISCSI_NET_PARAM_IPV4_GW);
314iscsi_iface_net_attr(ipv4_iface, subnet, ISCSI_NET_PARAM_IPV4_SUBNET);
315iscsi_iface_net_attr(ipv4_iface, bootproto, ISCSI_NET_PARAM_IPV4_BOOTPROTO);
316
317/* generic read only ipv6 attribute */
318iscsi_iface_net_attr(ipv6_iface, ipaddress, ISCSI_NET_PARAM_IPV6_ADDR);
319iscsi_iface_net_attr(ipv6_iface, link_local_addr, ISCSI_NET_PARAM_IPV6_LINKLOCAL);
320iscsi_iface_net_attr(ipv6_iface, router_addr, ISCSI_NET_PARAM_IPV6_ROUTER);
321iscsi_iface_net_attr(ipv6_iface, ipaddr_autocfg,
322 ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG);
323iscsi_iface_net_attr(ipv6_iface, linklocal_autocfg,
324 ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG);
325
326/* common read only iface attribute */
327iscsi_iface_net_attr(iface, enabled, ISCSI_NET_PARAM_IFACE_ENABLE);
328iscsi_iface_net_attr(iface, vlan, ISCSI_NET_PARAM_VLAN_ID);
329
330static mode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
331 struct attribute *attr, int i)
332{
333 struct device *dev = container_of(kobj, struct device, kobj);
334 struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
335 struct iscsi_transport *t = iface->transport;
336
337 if (attr == &dev_attr_iface_enabled.attr)
338 return (t->iface_param_mask & ISCSI_NET_IFACE_ENABLE) ?
339 S_IRUGO : 0;
340 else if (attr == &dev_attr_iface_vlan.attr)
341 return (t->iface_param_mask & ISCSI_NET_VLAN_ID) ? S_IRUGO : 0;
342
343 if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
344 if (attr == &dev_attr_ipv4_iface_ipaddress.attr)
345 return (t->iface_param_mask & ISCSI_NET_IPV4_ADDR) ?
346 S_IRUGO : 0;
347 else if (attr == &dev_attr_ipv4_iface_gateway.attr)
348 return (t->iface_param_mask & ISCSI_NET_IPV4_GW) ?
349 S_IRUGO : 0;
350 else if (attr == &dev_attr_ipv4_iface_subnet.attr)
351 return (t->iface_param_mask & ISCSI_NET_IPV4_SUBNET) ?
352 S_IRUGO : 0;
353 else if (attr == &dev_attr_ipv4_iface_bootproto.attr)
354 return (t->iface_param_mask & ISCSI_NET_IPV4_BOOTPROTO) ?
355 S_IRUGO : 0;
356 } else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) {
357 if (attr == &dev_attr_ipv6_iface_ipaddress.attr)
358 return (t->iface_param_mask & ISCSI_NET_IPV6_ADDR) ?
359 S_IRUGO : 0;
360 else if (attr == &dev_attr_ipv6_iface_link_local_addr.attr)
361 return (t->iface_param_mask & ISCSI_NET_IPV6_LINKLOCAL) ?
362 S_IRUGO : 0;
363 else if (attr == &dev_attr_ipv6_iface_router_addr.attr)
364 return (t->iface_param_mask & ISCSI_NET_IPV6_ROUTER) ?
365 S_IRUGO : 0;
366 else if (attr == &dev_attr_ipv6_iface_ipaddr_autocfg.attr)
367 return (t->iface_param_mask & ISCSI_NET_IPV6_ADDR_AUTOCFG) ?
368 S_IRUGO : 0;
369 else if (attr == &dev_attr_ipv6_iface_linklocal_autocfg.attr)
370 return (t->iface_param_mask & ISCSI_NET_IPV6_LINKLOCAL_AUTOCFG) ?
371 S_IRUGO : 0;
372 }
373
374 return 0;
375}
376
377static struct attribute *iscsi_iface_attrs[] = {
378 &dev_attr_iface_enabled.attr,
379 &dev_attr_iface_vlan.attr,
380 &dev_attr_ipv4_iface_ipaddress.attr,
381 &dev_attr_ipv4_iface_gateway.attr,
382 &dev_attr_ipv4_iface_subnet.attr,
383 &dev_attr_ipv4_iface_bootproto.attr,
384 &dev_attr_ipv6_iface_ipaddress.attr,
385 &dev_attr_ipv6_iface_link_local_addr.attr,
386 &dev_attr_ipv6_iface_router_addr.attr,
387 &dev_attr_ipv6_iface_ipaddr_autocfg.attr,
388 &dev_attr_ipv6_iface_linklocal_autocfg.attr,
389 NULL,
390};
391
392static struct attribute_group iscsi_iface_group = {
393 .attrs = iscsi_iface_attrs,
394 .is_visible = iscsi_iface_attr_is_visible,
395};
396
397struct iscsi_iface *
398iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
399 uint32_t iface_type, uint32_t iface_num, int dd_size)
400{
401 struct iscsi_iface *iface;
402 int err;
403
404 iface = kzalloc(sizeof(*iface) + dd_size, GFP_KERNEL);
405 if (!iface)
406 return NULL;
407
408 iface->transport = transport;
409 iface->iface_type = iface_type;
410 iface->iface_num = iface_num;
411 iface->dev.release = iscsi_iface_release;
412 iface->dev.class = &iscsi_iface_class;
413 /* parent reference released in iscsi_iface_release */
414 iface->dev.parent = get_device(&shost->shost_gendev);
415 if (iface_type == ISCSI_IFACE_TYPE_IPV4)
416 dev_set_name(&iface->dev, "ipv4-iface-%u-%u", shost->host_no,
417 iface_num);
418 else
419 dev_set_name(&iface->dev, "ipv6-iface-%u-%u", shost->host_no,
420 iface_num);
421
422 err = device_register(&iface->dev);
423 if (err)
424 goto free_iface;
425
426 err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
427 if (err)
428 goto unreg_iface;
429
430 if (dd_size)
431 iface->dd_data = &iface[1];
432 return iface;
433
434unreg_iface:
435 device_unregister(&iface->dev);
436 return NULL;
437
438free_iface:
439 put_device(iface->dev.parent);
440 kfree(iface);
441 return NULL;
442}
443EXPORT_SYMBOL_GPL(iscsi_create_iface);
444
445void iscsi_destroy_iface(struct iscsi_iface *iface)
446{
447 sysfs_remove_group(&iface->dev.kobj, &iscsi_iface_group);
448 device_unregister(&iface->dev);
449}
450EXPORT_SYMBOL_GPL(iscsi_destroy_iface);
451
273static int iscsi_setup_host(struct transport_container *tc, struct device *dev, 452static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
274 struct device *cdev) 453 struct device *cdev)
275{ 454{
@@ -2175,6 +2354,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
2175 2354
2176 BUG_ON(count > ISCSI_SESSION_ATTRS); 2355 BUG_ON(count > ISCSI_SESSION_ATTRS);
2177 priv->session_attrs[count] = NULL; 2356 priv->session_attrs[count] = NULL;
2357 count = 0;
2178 2358
2179 spin_lock_irqsave(&iscsi_transport_lock, flags); 2359 spin_lock_irqsave(&iscsi_transport_lock, flags);
2180 list_add(&priv->list, &iscsi_transports); 2360 list_add(&priv->list, &iscsi_transports);
@@ -2237,10 +2417,14 @@ static __init int iscsi_transport_init(void)
2237 if (err) 2417 if (err)
2238 goto unregister_transport_class; 2418 goto unregister_transport_class;
2239 2419
2240 err = transport_class_register(&iscsi_host_class); 2420 err = class_register(&iscsi_iface_class);
2241 if (err) 2421 if (err)
2242 goto unregister_endpoint_class; 2422 goto unregister_endpoint_class;
2243 2423
2424 err = transport_class_register(&iscsi_host_class);
2425 if (err)
2426 goto unregister_iface_class;
2427
2244 err = transport_class_register(&iscsi_connection_class); 2428 err = transport_class_register(&iscsi_connection_class);
2245 if (err) 2429 if (err)
2246 goto unregister_host_class; 2430 goto unregister_host_class;
@@ -2270,6 +2454,8 @@ unregister_conn_class:
2270 transport_class_unregister(&iscsi_connection_class); 2454 transport_class_unregister(&iscsi_connection_class);
2271unregister_host_class: 2455unregister_host_class:
2272 transport_class_unregister(&iscsi_host_class); 2456 transport_class_unregister(&iscsi_host_class);
2457unregister_iface_class:
2458 class_unregister(&iscsi_iface_class);
2273unregister_endpoint_class: 2459unregister_endpoint_class:
2274 class_unregister(&iscsi_endpoint_class); 2460 class_unregister(&iscsi_endpoint_class);
2275unregister_transport_class: 2461unregister_transport_class:
@@ -2285,6 +2471,7 @@ static void __exit iscsi_transport_exit(void)
2285 transport_class_unregister(&iscsi_session_class); 2471 transport_class_unregister(&iscsi_session_class);
2286 transport_class_unregister(&iscsi_host_class); 2472 transport_class_unregister(&iscsi_host_class);
2287 class_unregister(&iscsi_endpoint_class); 2473 class_unregister(&iscsi_endpoint_class);
2474 class_unregister(&iscsi_iface_class);
2288 class_unregister(&iscsi_transport_class); 2475 class_unregister(&iscsi_transport_class);
2289} 2476}
2290 2477