Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270971
b: refs/heads/master
c: 8d07913
h: refs/heads/master
i:
  270969: 158086b
  270967: c6d07b8
v: v3
  • Loading branch information
Mike Christie authored and James Bottomley committed Aug 27, 2011
1 parent ad874e9 commit 47f9dfd
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2bab08fc770ccd6c56859371356a4a905e8c0bd4
refs/heads/master: 8d07913dbe79568eafe5bb73806a08aac294d4e6
189 changes: 188 additions & 1 deletion trunk/drivers/scsi/scsi_transport_iscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,185 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
}
EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);

/*
* Interface to display network param to sysfs
*/

static void iscsi_iface_release(struct device *dev)
{
struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
struct device *parent = iface->dev.parent;

kfree(iface);
put_device(parent);
}


static struct class iscsi_iface_class = {
.name = "iscsi_iface",
.dev_release = iscsi_iface_release,
};

#define ISCSI_IFACE_ATTR(_prefix, _name, _mode, _show, _store) \
struct device_attribute dev_attr_##_prefix##_##_name = \
__ATTR(_name, _mode, _show, _store)

/* iface attrs show */
#define iscsi_iface_attr_show(type, name, param_type, param) \
static ssize_t \
show_##type##_##name(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct iscsi_iface *iface = iscsi_dev_to_iface(dev); \
struct iscsi_transport *t = iface->transport; \
return t->get_iface_param(iface, param_type, param, buf); \
} \

#define iscsi_iface_net_attr(type, name, param) \
iscsi_iface_attr_show(type, name, ISCSI_NET_PARAM, param) \
static ISCSI_IFACE_ATTR(type, name, S_IRUGO, show_##type##_##name, NULL);

/* generic read only ipvi4 attribute */
iscsi_iface_net_attr(ipv4_iface, ipaddress, ISCSI_NET_PARAM_IPV4_ADDR);
iscsi_iface_net_attr(ipv4_iface, gateway, ISCSI_NET_PARAM_IPV4_GW);
iscsi_iface_net_attr(ipv4_iface, subnet, ISCSI_NET_PARAM_IPV4_SUBNET);
iscsi_iface_net_attr(ipv4_iface, bootproto, ISCSI_NET_PARAM_IPV4_BOOTPROTO);

/* generic read only ipv6 attribute */
iscsi_iface_net_attr(ipv6_iface, ipaddress, ISCSI_NET_PARAM_IPV6_ADDR);
iscsi_iface_net_attr(ipv6_iface, link_local_addr, ISCSI_NET_PARAM_IPV6_LINKLOCAL);
iscsi_iface_net_attr(ipv6_iface, router_addr, ISCSI_NET_PARAM_IPV6_ROUTER);
iscsi_iface_net_attr(ipv6_iface, ipaddr_autocfg,
ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG);
iscsi_iface_net_attr(ipv6_iface, linklocal_autocfg,
ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG);

/* common read only iface attribute */
iscsi_iface_net_attr(iface, enabled, ISCSI_NET_PARAM_IFACE_ENABLE);
iscsi_iface_net_attr(iface, vlan, ISCSI_NET_PARAM_VLAN_ID);

static mode_t iscsi_iface_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int i)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct iscsi_iface *iface = iscsi_dev_to_iface(dev);
struct iscsi_transport *t = iface->transport;

if (attr == &dev_attr_iface_enabled.attr)
return (t->iface_param_mask & ISCSI_NET_IFACE_ENABLE) ?
S_IRUGO : 0;
else if (attr == &dev_attr_iface_vlan.attr)
return (t->iface_param_mask & ISCSI_NET_VLAN_ID) ? S_IRUGO : 0;

if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {
if (attr == &dev_attr_ipv4_iface_ipaddress.attr)
return (t->iface_param_mask & ISCSI_NET_IPV4_ADDR) ?
S_IRUGO : 0;
else if (attr == &dev_attr_ipv4_iface_gateway.attr)
return (t->iface_param_mask & ISCSI_NET_IPV4_GW) ?
S_IRUGO : 0;
else if (attr == &dev_attr_ipv4_iface_subnet.attr)
return (t->iface_param_mask & ISCSI_NET_IPV4_SUBNET) ?
S_IRUGO : 0;
else if (attr == &dev_attr_ipv4_iface_bootproto.attr)
return (t->iface_param_mask & ISCSI_NET_IPV4_BOOTPROTO) ?
S_IRUGO : 0;
} else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) {
if (attr == &dev_attr_ipv6_iface_ipaddress.attr)
return (t->iface_param_mask & ISCSI_NET_IPV6_ADDR) ?
S_IRUGO : 0;
else if (attr == &dev_attr_ipv6_iface_link_local_addr.attr)
return (t->iface_param_mask & ISCSI_NET_IPV6_LINKLOCAL) ?
S_IRUGO : 0;
else if (attr == &dev_attr_ipv6_iface_router_addr.attr)
return (t->iface_param_mask & ISCSI_NET_IPV6_ROUTER) ?
S_IRUGO : 0;
else if (attr == &dev_attr_ipv6_iface_ipaddr_autocfg.attr)
return (t->iface_param_mask & ISCSI_NET_IPV6_ADDR_AUTOCFG) ?
S_IRUGO : 0;
else if (attr == &dev_attr_ipv6_iface_linklocal_autocfg.attr)
return (t->iface_param_mask & ISCSI_NET_IPV6_LINKLOCAL_AUTOCFG) ?
S_IRUGO : 0;
}

return 0;
}

static struct attribute *iscsi_iface_attrs[] = {
&dev_attr_iface_enabled.attr,
&dev_attr_iface_vlan.attr,
&dev_attr_ipv4_iface_ipaddress.attr,
&dev_attr_ipv4_iface_gateway.attr,
&dev_attr_ipv4_iface_subnet.attr,
&dev_attr_ipv4_iface_bootproto.attr,
&dev_attr_ipv6_iface_ipaddress.attr,
&dev_attr_ipv6_iface_link_local_addr.attr,
&dev_attr_ipv6_iface_router_addr.attr,
&dev_attr_ipv6_iface_ipaddr_autocfg.attr,
&dev_attr_ipv6_iface_linklocal_autocfg.attr,
NULL,
};

static struct attribute_group iscsi_iface_group = {
.attrs = iscsi_iface_attrs,
.is_visible = iscsi_iface_attr_is_visible,
};

struct iscsi_iface *
iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
uint32_t iface_type, uint32_t iface_num, int dd_size)
{
struct iscsi_iface *iface;
int err;

iface = kzalloc(sizeof(*iface) + dd_size, GFP_KERNEL);
if (!iface)
return NULL;

iface->transport = transport;
iface->iface_type = iface_type;
iface->iface_num = iface_num;
iface->dev.release = iscsi_iface_release;
iface->dev.class = &iscsi_iface_class;
/* parent reference released in iscsi_iface_release */
iface->dev.parent = get_device(&shost->shost_gendev);
if (iface_type == ISCSI_IFACE_TYPE_IPV4)
dev_set_name(&iface->dev, "ipv4-iface-%u-%u", shost->host_no,
iface_num);
else
dev_set_name(&iface->dev, "ipv6-iface-%u-%u", shost->host_no,
iface_num);

err = device_register(&iface->dev);
if (err)
goto free_iface;

err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
if (err)
goto unreg_iface;

if (dd_size)
iface->dd_data = &iface[1];
return iface;

unreg_iface:
device_unregister(&iface->dev);
return NULL;

free_iface:
put_device(iface->dev.parent);
kfree(iface);
return NULL;
}
EXPORT_SYMBOL_GPL(iscsi_create_iface);

void iscsi_destroy_iface(struct iscsi_iface *iface)
{
sysfs_remove_group(&iface->dev.kobj, &iscsi_iface_group);
device_unregister(&iface->dev);
}
EXPORT_SYMBOL_GPL(iscsi_destroy_iface);

static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
struct device *cdev)
{
Expand Down Expand Up @@ -2175,6 +2354,7 @@ iscsi_register_transport(struct iscsi_transport *tt)

BUG_ON(count > ISCSI_SESSION_ATTRS);
priv->session_attrs[count] = NULL;
count = 0;

spin_lock_irqsave(&iscsi_transport_lock, flags);
list_add(&priv->list, &iscsi_transports);
Expand Down Expand Up @@ -2237,10 +2417,14 @@ static __init int iscsi_transport_init(void)
if (err)
goto unregister_transport_class;

err = transport_class_register(&iscsi_host_class);
err = class_register(&iscsi_iface_class);
if (err)
goto unregister_endpoint_class;

err = transport_class_register(&iscsi_host_class);
if (err)
goto unregister_iface_class;

err = transport_class_register(&iscsi_connection_class);
if (err)
goto unregister_host_class;
Expand Down Expand Up @@ -2270,6 +2454,8 @@ static __init int iscsi_transport_init(void)
transport_class_unregister(&iscsi_connection_class);
unregister_host_class:
transport_class_unregister(&iscsi_host_class);
unregister_iface_class:
class_unregister(&iscsi_iface_class);
unregister_endpoint_class:
class_unregister(&iscsi_endpoint_class);
unregister_transport_class:
Expand All @@ -2285,6 +2471,7 @@ static void __exit iscsi_transport_exit(void)
transport_class_unregister(&iscsi_session_class);
transport_class_unregister(&iscsi_host_class);
class_unregister(&iscsi_endpoint_class);
class_unregister(&iscsi_iface_class);
class_unregister(&iscsi_transport_class);
}

Expand Down
21 changes: 19 additions & 2 deletions trunk/include/scsi/iscsi_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,27 @@ enum iscsi_net_param {
ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG = 11,
ISCSI_NET_PARAM_IFACE_ENABLE = 12,
ISCSI_NET_PARAM_VLAN_ID = 13,
ISCSI_NET_IFACE_TYPE = 14,
ISCSI_NET_IFACE_NAME = 15,
ISCSI_NET_PARAM_IFACE_TYPE = 14,
ISCSI_NET_PARAM_IFACE_NAME = 15,
};

#define ISCSI_NET_IPV4_ADDR (1ULL << ISCSI_NET_PARAM_IPV4_ADDR)
#define ISCSI_NET_IPV4_SUBNET (1ULL << ISCSI_NET_PARAM_IPV4_SUBNET)
#define ISCSI_NET_IPV4_GW (1ULL << ISCSI_NET_PARAM_IPV4_GW)
#define ISCSI_NET_IPV4_BOOTPROTO (1ULL << ISCSI_NET_PARAM_IPV4_BOOTPROTO)
#define ISCSI_NET_MAC (1ULL << ISCSI_NET_PARAM_MAC)
#define ISCSI_NET_IPV6_LINKLOCAL (1ULL << ISCSI_NET_PARAM_IPV6_LINKLOCAL)
#define ISCSI_NET_IPV6_ADDR (1ULL << ISCSI_NET_PARAM_IPV6_ADDR)
#define ISCSI_NET_IPV6_ROUTER (1ULL << ISCSI_NET_PARAM_IPV6_ROUTER)
#define ISCSI_NET_IPV6_ADDR_AUTOCFG \
(1ULL << ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG)
#define ISCSI_NET_IPV6_LINKLOCAL_AUTOCFG \
(1ULL << ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG)
#define ISCSI_NET_IPV6_ROUTER_AUTOCFG \
(1ULL << ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG)
#define ISCSI_NET_IFACE_ENABLE (1ULL << ISCSI_NET_PARAM_IFACE_ENABLE)
#define ISCSI_NET_VLAN_ID (1ULL << ISCSI_NET_PARAM_VLAN_ID)

/*
* Common error codes
*/
Expand Down
26 changes: 26 additions & 0 deletions trunk/include/scsi/scsi_transport_iscsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct iscsi_cls_conn;
struct iscsi_conn;
struct iscsi_task;
struct sockaddr;
struct iscsi_iface;

/**
* struct iscsi_transport - iSCSI Transport template
Expand Down Expand Up @@ -87,6 +88,8 @@ struct iscsi_transport {
/* LLD sets this to indicate what values it can export to sysfs */
uint64_t param_mask;
uint64_t host_param_mask;
uint64_t iface_param_mask;

struct iscsi_cls_session *(*create_session) (struct iscsi_endpoint *ep,
uint16_t cmds_max, uint16_t qdepth,
uint32_t sn);
Expand Down Expand Up @@ -138,6 +141,9 @@ struct iscsi_transport {
uint32_t enable, struct sockaddr *dst_addr);
int (*set_path) (struct Scsi_Host *shost, struct iscsi_path *params);
int (*set_iface_param) (struct Scsi_Host *shost, char *data, int count);
int (*get_iface_param) (struct iscsi_iface *iface,
enum iscsi_param_type param_type,
int param, char *buf);
};

/*
Expand Down Expand Up @@ -229,6 +235,20 @@ struct iscsi_endpoint {
struct iscsi_cls_conn *conn;
};

struct iscsi_iface {
struct device dev;
struct iscsi_transport *transport;
uint32_t iface_type; /* IPv4 or IPv6 */
uint32_t iface_num; /* iface number, 0 - n */
void *dd_data; /* LLD private data */
};

#define iscsi_dev_to_iface(_dev) \
container_of(_dev, struct iscsi_iface, dev)

#define iscsi_iface_to_shost(_iface) \
dev_to_shost(_iface->dev.parent)

/*
* session and connection functions that can be used by HW iSCSI LLDs
*/
Expand Down Expand Up @@ -262,5 +282,11 @@ extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
extern int iscsi_block_scsi_eh(struct scsi_cmnd *cmd);
extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost,
struct iscsi_transport *t,
uint32_t iface_type,
uint32_t iface_num, int dd_size);
extern void iscsi_destroy_iface(struct iscsi_iface *iface);
extern struct iscsi_iface *iscsi_lookup_iface(int handle);

#endif

0 comments on commit 47f9dfd

Please sign in to comment.