Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Nov 2015 04:04:17 +0000 (20:04 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Nov 2015 04:04:17 +0000 (20:04 -0800)
Pull SCSI target updates from Nicholas Bellinger:
 "This series contains HCH's changes to absorb configfs attribute
  ->show() + ->store() function pointer usage from it's original
  tree-wide consumers, into common configfs code.

  It includes usb-gadget, target w/ drivers, netconsole and ocfs2
  changes to realize the improved simplicity, that now renders the
  original include/target/configfs_macros.h CPP magic for fabric drivers
  and others, unnecessary and obsolete.

  And with common code in place, new configfs attributes can be added
  easier than ever before.

  Note, there are further improvements in-flight from other folks for
  v4.5 code in configfs land, plus number of target fixes for post -rc1
  code"

In the meantime, a new user of the now-removed old configfs API came in
through the char/misc tree in commit 7bd1d4093c2f ("stm class: Introduce
an abstraction for System Trace Module devices").

This merge resolution comes from Alexander Shishkin, who updated his stm
class tracing abstraction to account for the removal of the old
show_attribute and store_attribute methods in commit 517982229f78
("configfs: remove old API") from this pull.  As Alexander says about
that patch:

 "There's no need to keep an extra wrapper structure per item and the
  awkward show_attribute/store_attribute item ops are no longer needed.

  This patch converts policy code to the new api, all the while making
  the code quite a bit smaller and easier on the eyes.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>"
That patch was folded into the merge so that the tree should be fully
bisectable.

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (23 commits)
  configfs: remove old API
  ocfs2/cluster: use per-attribute show and store methods
  ocfs2/cluster: move locking into attribute store methods
  netconsole: use per-attribute show and store methods
  target: use per-attribute show and store methods
  spear13xx_pcie_gadget: use per-attribute show and store methods
  dlm: use per-attribute show and store methods
  usb-gadget/f_serial: use per-attribute show and store methods
  usb-gadget/f_phonet: use per-attribute show and store methods
  usb-gadget/f_obex: use per-attribute show and store methods
  usb-gadget/f_uac2: use per-attribute show and store methods
  usb-gadget/f_uac1: use per-attribute show and store methods
  usb-gadget/f_mass_storage: use per-attribute show and store methods
  usb-gadget/f_sourcesink: use per-attribute show and store methods
  usb-gadget/f_printer: use per-attribute show and store methods
  usb-gadget/f_midi: use per-attribute show and store methods
  usb-gadget/f_loopback: use per-attribute show and store methods
  usb-gadget/ether: use per-attribute show and store methods
  usb-gadget/f_acm: use per-attribute show and store methods
  usb-gadget/f_hid: use per-attribute show and store methods
  ...

23 files changed:
1  2 
drivers/hwtracing/stm/policy.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/usb/gadget/function/f_acm.c
drivers/usb/gadget/function/f_ecm.c
drivers/usb/gadget/function/f_eem.c
drivers/usb/gadget/function/f_hid.c
drivers/usb/gadget/function/f_loopback.c
drivers/usb/gadget/function/f_mass_storage.c
drivers/usb/gadget/function/f_midi.c
drivers/usb/gadget/function/f_ncm.c
drivers/usb/gadget/function/f_obex.c
drivers/usb/gadget/function/f_phonet.c
drivers/usb/gadget/function/f_printer.c
drivers/usb/gadget/function/f_rndis.c
drivers/usb/gadget/function/f_serial.c
drivers/usb/gadget/function/f_sourcesink.c
drivers/usb/gadget/function/f_subset.c
drivers/usb/gadget/function/f_uac1.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/gadget/legacy/tcm_usb_gadget.c
drivers/vhost/scsi.c
fs/ocfs2/cluster/heartbeat.c
include/target/target_core_base.h

index 6498a9dbb7bd184802c6f270548c417b24e38e2d,0000000000000000000000000000000000000000..11ab6d01adf63d1490c8474801d358ada4f657a8
mode 100644,000000..100644
--- /dev/null
@@@ -1,529 -1,0 +1,472 @@@
- static ssize_t stp_policy_node_masters_show(struct stp_policy_node *policy_node,
-                                           char *page)
 +/*
 + * System Trace Module (STM) master/channel allocation policy management
 + * Copyright (c) 2014, Intel Corporation.
 + *
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms and conditions of the GNU General Public License,
 + * version 2, as published by the Free Software Foundation.
 + *
 + * This program is distributed in the hope it will be useful, but WITHOUT
 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 + * more details.
 + *
 + * A master/channel allocation policy allows mapping string identifiers to
 + * master and channel ranges, where allocation can be done.
 + */
 +
 +#define pr_fmt(fmt)   KBUILD_MODNAME ": " fmt
 +
 +#include <linux/types.h>
 +#include <linux/module.h>
 +#include <linux/device.h>
 +#include <linux/configfs.h>
 +#include <linux/slab.h>
 +#include <linux/stm.h>
 +#include "stm.h"
 +
 +/*
 + * STP Master/Channel allocation policy configfs layout.
 + */
 +
 +struct stp_policy {
 +      struct config_group     group;
 +      struct stm_device       *stm;
 +};
 +
 +struct stp_policy_node {
 +      struct config_group     group;
 +      struct stp_policy       *policy;
 +      unsigned int            first_master;
 +      unsigned int            last_master;
 +      unsigned int            first_channel;
 +      unsigned int            last_channel;
 +};
 +
 +static struct configfs_subsystem stp_policy_subsys;
 +
 +void stp_policy_node_get_ranges(struct stp_policy_node *policy_node,
 +                              unsigned int *mstart, unsigned int *mend,
 +                              unsigned int *cstart, unsigned int *cend)
 +{
 +      *mstart = policy_node->first_master;
 +      *mend   = policy_node->last_master;
 +      *cstart = policy_node->first_channel;
 +      *cend   = policy_node->last_channel;
 +}
 +
 +static inline char *stp_policy_node_name(struct stp_policy_node *policy_node)
 +{
 +      return policy_node->group.cg_item.ci_name ? : "<none>";
 +}
 +
 +static inline struct stp_policy *to_stp_policy(struct config_item *item)
 +{
 +      return item ?
 +              container_of(to_config_group(item), struct stp_policy, group) :
 +              NULL;
 +}
 +
 +static inline struct stp_policy_node *
 +to_stp_policy_node(struct config_item *item)
 +{
 +      return item ?
 +              container_of(to_config_group(item), struct stp_policy_node,
 +                           group) :
 +              NULL;
 +}
 +
- stp_policy_node_masters_store(struct stp_policy_node *policy_node,
-                             const char *page, size_t count)
++static ssize_t
++stp_policy_node_masters_show(struct config_item *item, char *page)
 +{
++      struct stp_policy_node *policy_node = to_stp_policy_node(item);
 +      ssize_t count;
 +
 +      count = sprintf(page, "%u %u\n", policy_node->first_master,
 +                      policy_node->last_master);
 +
 +      return count;
 +}
 +
 +static ssize_t
- stp_policy_node_channels_show(struct stp_policy_node *policy_node, char *page)
++stp_policy_node_masters_store(struct config_item *item, const char *page,
++                            size_t count)
 +{
++      struct stp_policy_node *policy_node = to_stp_policy_node(item);
 +      unsigned int first, last;
 +      struct stm_device *stm;
 +      char *p = (char *)page;
 +      ssize_t ret = -ENODEV;
 +
 +      if (sscanf(p, "%u %u", &first, &last) != 2)
 +              return -EINVAL;
 +
 +      mutex_lock(&stp_policy_subsys.su_mutex);
 +      stm = policy_node->policy->stm;
 +      if (!stm)
 +              goto unlock;
 +
 +      /* must be within [sw_start..sw_end], which is an inclusive range */
 +      if (first > INT_MAX || last > INT_MAX || first > last ||
 +          first < stm->data->sw_start ||
 +          last > stm->data->sw_end) {
 +              ret = -ERANGE;
 +              goto unlock;
 +      }
 +
 +      ret = count;
 +      policy_node->first_master = first;
 +      policy_node->last_master = last;
 +
 +unlock:
 +      mutex_unlock(&stp_policy_subsys.su_mutex);
 +
 +      return ret;
 +}
 +
 +static ssize_t
- stp_policy_node_channels_store(struct stp_policy_node *policy_node,
-                              const char *page, size_t count)
++stp_policy_node_channels_show(struct config_item *item, char *page)
 +{
++      struct stp_policy_node *policy_node = to_stp_policy_node(item);
 +      ssize_t count;
 +
 +      count = sprintf(page, "%u %u\n", policy_node->first_channel,
 +                      policy_node->last_channel);
 +
 +      return count;
 +}
 +
 +static ssize_t
- struct stp_policy_node_attribute {
-       struct configfs_attribute       attr;
-       ssize_t (*show)(struct stp_policy_node *, char *);
-       ssize_t (*store)(struct stp_policy_node *, const char *, size_t);
- };
- static ssize_t stp_policy_node_attr_show(struct config_item *item,
-                                        struct configfs_attribute *attr,
-                                        char *page)
- {
-       struct stp_policy_node *policy_node = to_stp_policy_node(item);
-       struct stp_policy_node_attribute *pn_attr =
-               container_of(attr, struct stp_policy_node_attribute, attr);
-       ssize_t count = 0;
-       if (pn_attr->show)
-               count = pn_attr->show(policy_node, page);
-       return count;
- }
- static ssize_t stp_policy_node_attr_store(struct config_item *item,
-                                         struct configfs_attribute *attr,
-                                         const char *page, size_t len)
- {
-       struct stp_policy_node *policy_node = to_stp_policy_node(item);
-       struct stp_policy_node_attribute *pn_attr =
-               container_of(attr, struct stp_policy_node_attribute, attr);
-       ssize_t count = -EINVAL;
-       if (pn_attr->store)
-               count = pn_attr->store(policy_node, page, len);
-       return count;
- }
++stp_policy_node_channels_store(struct config_item *item, const char *page,
++                             size_t count)
 +{
++      struct stp_policy_node *policy_node = to_stp_policy_node(item);
 +      unsigned int first, last;
 +      struct stm_device *stm;
 +      char *p = (char *)page;
 +      ssize_t ret = -ENODEV;
 +
 +      if (sscanf(p, "%u %u", &first, &last) != 2)
 +              return -EINVAL;
 +
 +      mutex_lock(&stp_policy_subsys.su_mutex);
 +      stm = policy_node->policy->stm;
 +      if (!stm)
 +              goto unlock;
 +
 +      if (first > INT_MAX || last > INT_MAX || first > last ||
 +          last >= stm->data->sw_nchannels) {
 +              ret = -ERANGE;
 +              goto unlock;
 +      }
 +
 +      ret = count;
 +      policy_node->first_channel = first;
 +      policy_node->last_channel = last;
 +
 +unlock:
 +      mutex_unlock(&stp_policy_subsys.su_mutex);
 +
 +      return ret;
 +}
 +
 +static void stp_policy_node_release(struct config_item *item)
 +{
 +      kfree(to_stp_policy_node(item));
 +}
 +
-       .show_attribute         = stp_policy_node_attr_show,
-       .store_attribute        = stp_policy_node_attr_store,
 +static struct configfs_item_operations stp_policy_node_item_ops = {
 +      .release                = stp_policy_node_release,
- static struct stp_policy_node_attribute stp_policy_node_attr_range = {
-       .attr   = {
-               .ca_owner = THIS_MODULE,
-               .ca_name = "masters",
-               .ca_mode = S_IRUGO | S_IWUSR,
-       },
-       .show   = stp_policy_node_masters_show,
-       .store  = stp_policy_node_masters_store,
- };
- static struct stp_policy_node_attribute stp_policy_node_attr_channels = {
-       .attr   = {
-               .ca_owner = THIS_MODULE,
-               .ca_name = "channels",
-               .ca_mode = S_IRUGO | S_IWUSR,
-       },
-       .show   = stp_policy_node_channels_show,
-       .store  = stp_policy_node_channels_store,
- };
 +};
 +
-       &stp_policy_node_attr_range.attr,
-       &stp_policy_node_attr_channels.attr,
++CONFIGFS_ATTR(stp_policy_node_, masters);
++CONFIGFS_ATTR(stp_policy_node_, channels);
 +
 +static struct configfs_attribute *stp_policy_node_attrs[] = {
- static struct configfs_attribute stp_policy_attr_device = {
-       .ca_owner = THIS_MODULE,
-       .ca_name = "device",
-       .ca_mode = S_IRUGO,
- };
- static struct configfs_attribute *stp_policy_attrs[] = {
-       &stp_policy_attr_device,
-       NULL,
- };
- static ssize_t stp_policy_attr_show(struct config_item *item,
-                                   struct configfs_attribute *attr,
-                                   char *page)
++      &stp_policy_node_attr_masters,
++      &stp_policy_node_attr_channels,
 +      NULL,
 +};
 +
 +static struct config_item_type stp_policy_type;
 +static struct config_item_type stp_policy_node_type;
 +
 +static struct config_group *
 +stp_policy_node_make(struct config_group *group, const char *name)
 +{
 +      struct stp_policy_node *policy_node, *parent_node;
 +      struct stp_policy *policy;
 +
 +      if (group->cg_item.ci_type == &stp_policy_type) {
 +              policy = container_of(group, struct stp_policy, group);
 +      } else {
 +              parent_node = container_of(group, struct stp_policy_node,
 +                                         group);
 +              policy = parent_node->policy;
 +      }
 +
 +      if (!policy->stm)
 +              return ERR_PTR(-ENODEV);
 +
 +      policy_node = kzalloc(sizeof(struct stp_policy_node), GFP_KERNEL);
 +      if (!policy_node)
 +              return ERR_PTR(-ENOMEM);
 +
 +      config_group_init_type_name(&policy_node->group, name,
 +                                  &stp_policy_node_type);
 +
 +      policy_node->policy = policy;
 +
 +      /* default values for the attributes */
 +      policy_node->first_master = policy->stm->data->sw_start;
 +      policy_node->last_master = policy->stm->data->sw_end;
 +      policy_node->first_channel = 0;
 +      policy_node->last_channel = policy->stm->data->sw_nchannels - 1;
 +
 +      return &policy_node->group;
 +}
 +
 +static void
 +stp_policy_node_drop(struct config_group *group, struct config_item *item)
 +{
 +      config_item_put(item);
 +}
 +
 +static struct configfs_group_operations stp_policy_node_group_ops = {
 +      .make_group     = stp_policy_node_make,
 +      .drop_item      = stp_policy_node_drop,
 +};
 +
 +static struct config_item_type stp_policy_node_type = {
 +      .ct_item_ops    = &stp_policy_node_item_ops,
 +      .ct_group_ops   = &stp_policy_node_group_ops,
 +      .ct_attrs       = stp_policy_node_attrs,
 +      .ct_owner       = THIS_MODULE,
 +};
 +
 +/*
 + * Root group: policies.
 + */
-       .show_attribute         = stp_policy_attr_show,
++static ssize_t stp_policy_device_show(struct config_item *item,
++                                    char *page)
 +{
 +      struct stp_policy *policy = to_stp_policy(item);
 +      ssize_t count;
 +
 +      count = sprintf(page, "%s\n",
 +                      (policy && policy->stm) ?
 +                      policy->stm->data->name :
 +                      "<none>");
 +
 +      return count;
 +}
 +
++CONFIGFS_ATTR_RO(stp_policy_, device);
++
++static struct configfs_attribute *stp_policy_attrs[] = {
++      &stp_policy_attr_device,
++      NULL,
++};
++
 +void stp_policy_unbind(struct stp_policy *policy)
 +{
 +      struct stm_device *stm = policy->stm;
 +
 +      if (WARN_ON_ONCE(!policy->stm))
 +              return;
 +
 +      mutex_lock(&stm->policy_mutex);
 +      stm->policy = NULL;
 +      mutex_unlock(&stm->policy_mutex);
 +
 +      policy->stm = NULL;
 +
 +      stm_put_device(stm);
 +}
 +
 +static void stp_policy_release(struct config_item *item)
 +{
 +      struct stp_policy *policy = to_stp_policy(item);
 +
 +      stp_policy_unbind(policy);
 +      kfree(policy);
 +}
 +
 +static struct configfs_item_operations stp_policy_item_ops = {
 +      .release                = stp_policy_release,
 +};
 +
 +static struct configfs_group_operations stp_policy_group_ops = {
 +      .make_group     = stp_policy_node_make,
 +};
 +
 +static struct config_item_type stp_policy_type = {
 +      .ct_item_ops    = &stp_policy_item_ops,
 +      .ct_group_ops   = &stp_policy_group_ops,
 +      .ct_attrs       = stp_policy_attrs,
 +      .ct_owner       = THIS_MODULE,
 +};
 +
 +static struct config_group *
 +stp_policies_make(struct config_group *group, const char *name)
 +{
 +      struct config_group *ret;
 +      struct stm_device *stm;
 +      char *devname, *p;
 +
 +      devname = kasprintf(GFP_KERNEL, "%s", name);
 +      if (!devname)
 +              return ERR_PTR(-ENOMEM);
 +
 +      /*
 +       * node must look like <device_name>.<policy_name>, where
 +       * <device_name> is the name of an existing stm device and
 +       * <policy_name> is an arbitrary string
 +       */
 +      p = strchr(devname, '.');
 +      if (!p) {
 +              kfree(devname);
 +              return ERR_PTR(-EINVAL);
 +      }
 +
 +      *p++ = '\0';
 +
 +      stm = stm_find_device(devname);
 +      kfree(devname);
 +
 +      if (!stm)
 +              return ERR_PTR(-ENODEV);
 +
 +      mutex_lock(&stm->policy_mutex);
 +      if (stm->policy) {
 +              ret = ERR_PTR(-EBUSY);
 +              goto unlock_policy;
 +      }
 +
 +      stm->policy = kzalloc(sizeof(*stm->policy), GFP_KERNEL);
 +      if (!stm->policy) {
 +              ret = ERR_PTR(-ENOMEM);
 +              goto unlock_policy;
 +      }
 +
 +      config_group_init_type_name(&stm->policy->group, name,
 +                                  &stp_policy_type);
 +      stm->policy->stm = stm;
 +
 +      ret = &stm->policy->group;
 +
 +unlock_policy:
 +      mutex_unlock(&stm->policy_mutex);
 +
 +      if (IS_ERR(ret))
 +              stm_put_device(stm);
 +
 +      return ret;
 +}
 +
 +static struct configfs_group_operations stp_policies_group_ops = {
 +      .make_group     = stp_policies_make,
 +};
 +
 +static struct config_item_type stp_policies_type = {
 +      .ct_group_ops   = &stp_policies_group_ops,
 +      .ct_owner       = THIS_MODULE,
 +};
 +
 +static struct configfs_subsystem stp_policy_subsys = {
 +      .su_group = {
 +              .cg_item = {
 +                      .ci_namebuf     = "stp-policy",
 +                      .ci_type        = &stp_policies_type,
 +              },
 +      },
 +};
 +
 +/*
 + * Lock the policy mutex from the outside
 + */
 +static struct stp_policy_node *
 +__stp_policy_node_lookup(struct stp_policy *policy, char *s)
 +{
 +      struct stp_policy_node *policy_node, *ret;
 +      struct list_head *head = &policy->group.cg_children;
 +      struct config_item *item;
 +      char *start, *end = s;
 +
 +      if (list_empty(head))
 +              return NULL;
 +
 +      /* return the first entry if everything else fails */
 +      item = list_entry(head->next, struct config_item, ci_entry);
 +      ret = to_stp_policy_node(item);
 +
 +next:
 +      for (;;) {
 +              start = strsep(&end, "/");
 +              if (!start)
 +                      break;
 +
 +              if (!*start)
 +                      continue;
 +
 +              list_for_each_entry(item, head, ci_entry) {
 +                      policy_node = to_stp_policy_node(item);
 +
 +                      if (!strcmp(start,
 +                                  policy_node->group.cg_item.ci_name)) {
 +                              ret = policy_node;
 +
 +                              if (!end)
 +                                      goto out;
 +
 +                              head = &policy_node->group.cg_children;
 +                              goto next;
 +                      }
 +              }
 +              break;
 +      }
 +
 +out:
 +      return ret;
 +}
 +
 +
 +struct stp_policy_node *
 +stp_policy_node_lookup(struct stm_device *stm, char *s)
 +{
 +      struct stp_policy_node *policy_node = NULL;
 +
 +      mutex_lock(&stp_policy_subsys.su_mutex);
 +
 +      mutex_lock(&stm->policy_mutex);
 +      if (stm->policy)
 +              policy_node = __stp_policy_node_lookup(stm->policy, s);
 +      mutex_unlock(&stm->policy_mutex);
 +
 +      if (policy_node)
 +              config_item_get(&policy_node->group.cg_item);
 +      mutex_unlock(&stp_policy_subsys.su_mutex);
 +
 +      return policy_node;
 +}
 +
 +void stp_policy_node_put(struct stp_policy_node *policy_node)
 +{
 +      config_item_put(&policy_node->group.cg_item);
 +}
 +
 +int __init stp_configfs_init(void)
 +{
 +      int err;
 +
 +      config_group_init(&stp_policy_subsys.su_group);
 +      mutex_init(&stp_policy_subsys.su_mutex);
 +      err = configfs_register_subsystem(&stp_policy_subsys);
 +
 +      return err;
 +}
 +
 +void __exit stp_configfs_exit(void)
 +{
 +      configfs_unregister_subsystem(&stp_policy_subsys);
 +}
index 47c4022fda7680e3107710bb703e83fa61affc15,231d29cc0419023392e414bfb6c4afe973dd2cd6..2e2fe818ca9f1acc42d74c8f4d0e0cfbaf810172
@@@ -43,9 -43,7 +43,7 @@@
  #include <linux/atomic.h>
  #include <scsi/scsi_proto.h>
  #include <scsi/scsi_tcq.h>
- #include <target/configfs_macros.h>
  #include <target/target_core_base.h>
- #include <target/target_core_fabric_configfs.h>
  #include <target/target_core_fabric.h>
  #include "ib_srpt.h"
  
@@@ -546,8 -544,7 +544,8 @@@ static int srpt_refresh_port(struct srp
        sport->sm_lid = port_attr.sm_lid;
        sport->lid = port_attr.lid;
  
 -      ret = ib_query_gid(sport->sdev->device, sport->port, 0, &sport->gid);
 +      ret = ib_query_gid(sport->sdev->device, sport->port, 0, &sport->gid,
 +                         NULL);
        if (ret)
                goto err_query_port;
  
@@@ -2823,7 -2820,7 +2821,7 @@@ static int srpt_cm_handler(struct ib_cm
  static int srpt_perform_rdmas(struct srpt_rdma_ch *ch,
                              struct srpt_send_ioctx *ioctx)
  {
 -      struct ib_send_wr wr;
 +      struct ib_rdma_wr wr;
        struct ib_send_wr *bad_wr;
        struct rdma_iu *riu;
        int i;
  
        for (i = 0; i < n_rdma; ++i, ++riu) {
                if (dir == DMA_FROM_DEVICE) {
 -                      wr.opcode = IB_WR_RDMA_WRITE;
 -                      wr.wr_id = encode_wr_id(i == n_rdma - 1 ?
 +                      wr.wr.opcode = IB_WR_RDMA_WRITE;
 +                      wr.wr.wr_id = encode_wr_id(i == n_rdma - 1 ?
                                                SRPT_RDMA_WRITE_LAST :
                                                SRPT_RDMA_MID,
                                                ioctx->ioctx.index);
                } else {
 -                      wr.opcode = IB_WR_RDMA_READ;
 -                      wr.wr_id = encode_wr_id(i == n_rdma - 1 ?
 +                      wr.wr.opcode = IB_WR_RDMA_READ;
 +                      wr.wr.wr_id = encode_wr_id(i == n_rdma - 1 ?
                                                SRPT_RDMA_READ_LAST :
                                                SRPT_RDMA_MID,
                                                ioctx->ioctx.index);
                }
 -              wr.next = NULL;
 -              wr.wr.rdma.remote_addr = riu->raddr;
 -              wr.wr.rdma.rkey = riu->rkey;
 -              wr.num_sge = riu->sge_cnt;
 -              wr.sg_list = riu->sge;
 +              wr.wr.next = NULL;
 +              wr.remote_addr = riu->raddr;
 +              wr.rkey = riu->rkey;
 +              wr.wr.num_sge = riu->sge_cnt;
 +              wr.wr.sg_list = riu->sge;
  
                /* only get completion event for the last rdma write */
                if (i == (n_rdma - 1) && dir == DMA_TO_DEVICE)
 -                      wr.send_flags = IB_SEND_SIGNALED;
 +                      wr.wr.send_flags = IB_SEND_SIGNALED;
  
 -              ret = ib_post_send(ch->qp, &wr, &bad_wr);
 +              ret = ib_post_send(ch->qp, &wr.wr, &bad_wr);
                if (ret)
                        break;
        }
                pr_err("%s[%d]: ib_post_send() returned %d for %d/%d\n",
                                 __func__, __LINE__, ret, i, n_rdma);
        if (ret && i > 0) {
 -              wr.num_sge = 0;
 -              wr.wr_id = encode_wr_id(SRPT_RDMA_ABORT, ioctx->ioctx.index);
 -              wr.send_flags = IB_SEND_SIGNALED;
 +              wr.wr.num_sge = 0;
 +              wr.wr.wr_id = encode_wr_id(SRPT_RDMA_ABORT, ioctx->ioctx.index);
 +              wr.wr.send_flags = IB_SEND_SIGNALED;
                while (ch->state == CH_LIVE &&
 -                      ib_post_send(ch->qp, &wr, &bad_wr) != 0) {
 +                      ib_post_send(ch->qp, &wr.wr, &bad_wr) != 0) {
                        pr_info("Trying to abort failed RDMA transfer [%d]\n",
                                ioctx->ioctx.index);
                        msleep(1000);
@@@ -3546,20 -3543,19 +3544,19 @@@ static void srpt_cleanup_nodeacl(struc
        spin_unlock_irq(&sport->port_acl_lock);
  }
  
- static ssize_t srpt_tpg_attrib_show_srp_max_rdma_size(
-       struct se_portal_group *se_tpg,
-       char *page)
+ static ssize_t srpt_tpg_attrib_srp_max_rdma_size_show(struct config_item *item,
+               char *page)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
  
        return sprintf(page, "%u\n", sport->port_attrib.srp_max_rdma_size);
  }
  
- static ssize_t srpt_tpg_attrib_store_srp_max_rdma_size(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+ static ssize_t srpt_tpg_attrib_srp_max_rdma_size_store(struct config_item *item,
+               const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long val;
        int ret;
        return count;
  }
  
- TF_TPG_ATTRIB_ATTR(srpt, srp_max_rdma_size, S_IRUGO | S_IWUSR);
- static ssize_t srpt_tpg_attrib_show_srp_max_rsp_size(
-       struct se_portal_group *se_tpg,
-       char *page)
+ static ssize_t srpt_tpg_attrib_srp_max_rsp_size_show(struct config_item *item,
+               char *page)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
  
        return sprintf(page, "%u\n", sport->port_attrib.srp_max_rsp_size);
  }
  
- static ssize_t srpt_tpg_attrib_store_srp_max_rsp_size(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+ static ssize_t srpt_tpg_attrib_srp_max_rsp_size_store(struct config_item *item,
+               const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long val;
        int ret;
        return count;
  }
  
- TF_TPG_ATTRIB_ATTR(srpt, srp_max_rsp_size, S_IRUGO | S_IWUSR);
- static ssize_t srpt_tpg_attrib_show_srp_sq_size(
-       struct se_portal_group *se_tpg,
-       char *page)
+ static ssize_t srpt_tpg_attrib_srp_sq_size_show(struct config_item *item,
+               char *page)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
  
        return sprintf(page, "%u\n", sport->port_attrib.srp_sq_size);
  }
  
- static ssize_t srpt_tpg_attrib_store_srp_sq_size(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+ static ssize_t srpt_tpg_attrib_srp_sq_size_store(struct config_item *item,
+               const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long val;
        int ret;
        return count;
  }
  
- TF_TPG_ATTRIB_ATTR(srpt, srp_sq_size, S_IRUGO | S_IWUSR);
+ CONFIGFS_ATTR(srpt_tpg_attrib_,  srp_max_rdma_size);
+ CONFIGFS_ATTR(srpt_tpg_attrib_,  srp_max_rsp_size);
+ CONFIGFS_ATTR(srpt_tpg_attrib_,  srp_sq_size);
  
  static struct configfs_attribute *srpt_tpg_attrib_attrs[] = {
-       &srpt_tpg_attrib_srp_max_rdma_size.attr,
-       &srpt_tpg_attrib_srp_max_rsp_size.attr,
-       &srpt_tpg_attrib_srp_sq_size.attr,
+       &srpt_tpg_attrib_attr_srp_max_rdma_size,
+       &srpt_tpg_attrib_attr_srp_max_rsp_size,
+       &srpt_tpg_attrib_attr_srp_sq_size,
        NULL,
  };
  
- static ssize_t srpt_tpg_show_enable(
-       struct se_portal_group *se_tpg,
-       char *page)
+ static ssize_t srpt_tpg_enable_show(struct config_item *item, char *page)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
  
        return snprintf(page, PAGE_SIZE, "%d\n", (sport->enabled) ? 1: 0);
  }
  
- static ssize_t srpt_tpg_store_enable(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+ static ssize_t srpt_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct srpt_port *sport = container_of(se_tpg, struct srpt_port, port_tpg_1);
        unsigned long tmp;
          int ret;
        return count;
  }
  
TF_TPG_BASE_ATTR(srpt, enable, S_IRUGO | S_IWUSR);
CONFIGFS_ATTR(srpt_tpg_, enable);
  
  static struct configfs_attribute *srpt_tpg_attrs[] = {
-       &srpt_tpg_enable.attr,
+       &srpt_tpg_attr_enable,
        NULL,
  };
  
@@@ -3782,16 -3772,15 +3773,15 @@@ static void srpt_drop_tport(struct se_w
        pr_debug("drop_tport(%s\n", config_item_name(&sport->port_wwn.wwn_group.cg_item));
  }
  
- static ssize_t srpt_wwn_show_attr_version(struct target_fabric_configfs *tf,
-                                             char *buf)
+ static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
  {
        return scnprintf(buf, PAGE_SIZE, "%s\n", DRV_VERSION);
  }
  
TF_WWN_ATTR_RO(srpt, version);
CONFIGFS_ATTR_RO(srpt_wwn_, version);
  
  static struct configfs_attribute *srpt_wwn_attrs[] = {
-       &srpt_wwn_version.attr,
+       &srpt_wwn_attr_version,
        NULL,
  };
  
index 22e723d12d36ff4a6a24b07b703ac6172cf799ba,68b289fc0d9213ffbbee1dce80eee7788ce4d87a..2fa1e80a3ce7bbdd941ddf30fb79e8860812a907
@@@ -428,18 -428,21 +428,18 @@@ static int acm_set_alt(struct usb_funct
        /* we know alt == 0, so this is an activation or a reset */
  
        if (intf == acm->ctrl_id) {
 -              if (acm->notify->driver_data) {
 -                      dev_vdbg(&cdev->gadget->dev,
 -                               "reset acm control interface %d\n", intf);
 -                      usb_ep_disable(acm->notify);
 -              }
 +              dev_vdbg(&cdev->gadget->dev,
 +                              "reset acm control interface %d\n", intf);
 +              usb_ep_disable(acm->notify);
  
                if (!acm->notify->desc)
                        if (config_ep_by_speed(cdev->gadget, f, acm->notify))
                                return -EINVAL;
  
                usb_ep_enable(acm->notify);
 -              acm->notify->driver_data = acm;
  
        } else if (intf == acm->data_id) {
 -              if (acm->port.in->driver_data) {
 +              if (acm->notify->enabled) {
                        dev_dbg(&cdev->gadget->dev,
                                "reset acm ttyGS%d\n", acm->port_num);
                        gserial_disconnect(&acm->port);
@@@ -472,6 -475,7 +472,6 @@@ static void acm_disable(struct usb_func
        dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num);
        gserial_disconnect(&acm->port);
        usb_ep_disable(acm->notify);
 -      acm->notify->driver_data = NULL;
  }
  
  /*-------------------------------------------------------------------------*/
@@@ -651,16 -655,19 +651,16 @@@ acm_bind(struct usb_configuration *c, s
        if (!ep)
                goto fail;
        acm->port.in = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc);
        if (!ep)
                goto fail;
        acm->port.out = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc);
        if (!ep)
                goto fail;
        acm->notify = ep;
 -      ep->driver_data = cdev; /* claim */
  
        /* allocate notification */
        acm->notify_req = gs_alloc_req(ep,
@@@ -702,6 -709,14 +702,6 @@@ fail
        if (acm->notify_req)
                gs_free_req(acm->notify, acm->notify_req);
  
 -      /* we might as well release our claims on endpoints */
 -      if (acm->notify)
 -              acm->notify->driver_data = NULL;
 -      if (acm->port.out)
 -              acm->port.out->driver_data = NULL;
 -      if (acm->port.in)
 -              acm->port.in->driver_data = NULL;
 -
        ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
  
        return status;
@@@ -761,21 -776,6 +761,6 @@@ static inline struct f_serial_opts *to_
                        func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_serial_opts);
- static ssize_t f_acm_attr_show(struct config_item *item,
-                                struct configfs_attribute *attr,
-                                char *page)
- {
-       struct f_serial_opts *opts = to_f_serial_opts(item);
-       struct f_serial_opts_attribute *f_serial_opts_attr =
-               container_of(attr, struct f_serial_opts_attribute, attr);
-       ssize_t ret = 0;
-       if (f_serial_opts_attr->show)
-               ret = f_serial_opts_attr->show(opts, page);
-       return ret;
- }
  static void acm_attr_release(struct config_item *item)
  {
        struct f_serial_opts *opts = to_f_serial_opts(item);
  
  static struct configfs_item_operations acm_item_ops = {
        .release                = acm_attr_release,
-       .show_attribute         = f_acm_attr_show,
  };
  
- static ssize_t f_acm_port_num_show(struct f_serial_opts *opts, char *page)
+ static ssize_t f_acm_port_num_show(struct config_item *item, char *page)
  {
-       return sprintf(page, "%u\n", opts->port_num);
+       return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
  }
  
- static struct f_serial_opts_attribute f_acm_port_num =
-       __CONFIGFS_ATTR_RO(port_num, f_acm_port_num_show);
+ CONFIGFS_ATTR_RO(f_acm_port_, num);
  
  static struct configfs_attribute *acm_attrs[] = {
-       &f_acm_port_num.attr,
+       &f_acm_port_attr_num,
        NULL,
  };
  
index 4abca70cdaab9d52e529dcc85b2dabb30137d7e1,0106de8e190488c6931e81ecc3c98cc0e973859f..7ad60ee419144fd89b6d109439dcacd99c6a3db7
@@@ -541,21 -541,24 +541,21 @@@ static int ecm_set_alt(struct usb_funct
                if (alt != 0)
                        goto fail;
  
 -              if (ecm->notify->driver_data) {
 -                      VDBG(cdev, "reset ecm control %d\n", intf);
 -                      usb_ep_disable(ecm->notify);
 -              }
 +              VDBG(cdev, "reset ecm control %d\n", intf);
 +              usb_ep_disable(ecm->notify);
                if (!(ecm->notify->desc)) {
                        VDBG(cdev, "init ecm ctrl %d\n", intf);
                        if (config_ep_by_speed(cdev->gadget, f, ecm->notify))
                                goto fail;
                }
                usb_ep_enable(ecm->notify);
 -              ecm->notify->driver_data = ecm;
  
        /* Data interface has two altsettings, 0 and 1 */
        } else if (intf == ecm->data_id) {
                if (alt > 1)
                        goto fail;
  
 -              if (ecm->port.in_ep->driver_data) {
 +              if (ecm->port.in_ep->enabled) {
                        DBG(cdev, "reset ecm\n");
                        gether_disconnect(&ecm->port);
                }
@@@ -615,7 -618,7 +615,7 @@@ static int ecm_get_alt(struct usb_funct
  
        if (intf == ecm->ctrl_id)
                return 0;
 -      return ecm->port.in_ep->driver_data ? 1 : 0;
 +      return ecm->port.in_ep->enabled ? 1 : 0;
  }
  
  static void ecm_disable(struct usb_function *f)
  
        DBG(cdev, "ecm deactivated\n");
  
 -      if (ecm->port.in_ep->driver_data)
 +      if (ecm->port.in_ep->enabled)
                gether_disconnect(&ecm->port);
  
 -      if (ecm->notify->driver_data) {
 -              usb_ep_disable(ecm->notify);
 -              ecm->notify->driver_data = NULL;
 -              ecm->notify->desc = NULL;
 -      }
 +      usb_ep_disable(ecm->notify);
 +      ecm->notify->desc = NULL;
  }
  
  /*-------------------------------------------------------------------------*/
@@@ -744,11 -750,13 +744,11 @@@ ecm_bind(struct usb_configuration *c, s
        if (!ep)
                goto fail;
        ecm->port.in_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc);
        if (!ep)
                goto fail;
        ecm->port.out_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        /* NOTE:  a status/notification endpoint is *OPTIONAL* but we
         * don't treat it that way.  It's simpler, and some newer CDC
        if (!ep)
                goto fail;
        ecm->notify = ep;
 -      ep->driver_data = cdev; /* claim */
  
        status = -ENOMEM;
  
@@@ -811,6 -820,14 +811,6 @@@ fail
                usb_ep_free_request(ecm->notify, ecm->notify_req);
        }
  
 -      /* we might as well release our claims on endpoints */
 -      if (ecm->notify)
 -              ecm->notify->driver_data = NULL;
 -      if (ecm->port.out_ep)
 -              ecm->port.out_ep->driver_data = NULL;
 -      if (ecm->port.in_ep)
 -              ecm->port.in_ep->driver_data = NULL;
 -
        ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
  
        return status;
@@@ -838,10 -855,10 +838,10 @@@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(e
  USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ecm);
  
  static struct configfs_attribute *ecm_attrs[] = {
-       &f_ecm_opts_dev_addr.attr,
-       &f_ecm_opts_host_addr.attr,
-       &f_ecm_opts_qmult.attr,
-       &f_ecm_opts_ifname.attr,
+       &ecm_opts_attr_dev_addr,
+       &ecm_opts_attr_host_addr,
+       &ecm_opts_attr_qmult,
+       &ecm_opts_attr_ifname,
        NULL,
  };
  
index 9a55757c729b2f59f1d512a8f4f67dffa89c5feb,f965403787e40e531c9cc1dfb144581701335613..cad35a502d3f73a64759cd8eb8d541d36104cbac
@@@ -195,8 -195,11 +195,8 @@@ static int eem_set_alt(struct usb_funct
                goto fail;
  
        if (intf == eem->ctrl_id) {
 -
 -              if (eem->port.in_ep->driver_data) {
 -                      DBG(cdev, "reset eem\n");
 -                      gether_disconnect(&eem->port);
 -              }
 +              DBG(cdev, "reset eem\n");
 +              gether_disconnect(&eem->port);
  
                if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) {
                        DBG(cdev, "init eem\n");
@@@ -234,7 -237,7 +234,7 @@@ static void eem_disable(struct usb_func
  
        DBG(cdev, "eem deactivated\n");
  
 -      if (eem->port.in_ep->driver_data)
 +      if (eem->port.in_ep->enabled)
                gether_disconnect(&eem->port);
  }
  
@@@ -290,11 -293,13 +290,11 @@@ static int eem_bind(struct usb_configur
        if (!ep)
                goto fail;
        eem->port.in_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc);
        if (!ep)
                goto fail;
        eem->port.out_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        status = -ENOMEM;
  
        return 0;
  
  fail:
 -      if (eem->port.out_ep)
 -              eem->port.out_ep->driver_data = NULL;
 -      if (eem->port.in_ep)
 -              eem->port.in_ep->driver_data = NULL;
 -
        ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
  
        return status;
@@@ -545,10 -555,10 +545,10 @@@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(e
  USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(eem);
  
  static struct configfs_attribute *eem_attrs[] = {
-       &f_eem_opts_dev_addr.attr,
-       &f_eem_opts_host_addr.attr,
-       &f_eem_opts_qmult.attr,
-       &f_eem_opts_ifname.attr,
+       &eem_opts_attr_dev_addr,
+       &eem_opts_attr_host_addr,
+       &eem_opts_attr_qmult,
+       &eem_opts_attr_ifname,
        NULL,
  };
  
index 21fcf18f53a0409ed00bc302ac62b4f012e5c766,d15b06167de041ecebeb687d8a85eed8a08189d8..99285b416308f84917a6500aad64daff34c2ce05
@@@ -492,7 -492,10 +492,7 @@@ static void hidg_disable(struct usb_fun
        struct f_hidg_req_list *list, *next;
  
        usb_ep_disable(hidg->in_ep);
 -      hidg->in_ep->driver_data = NULL;
 -
        usb_ep_disable(hidg->out_ep);
 -      hidg->out_ep->driver_data = NULL;
  
        list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
                list_del(&list->list);
@@@ -510,7 -513,8 +510,7 @@@ static int hidg_set_alt(struct usb_func
  
        if (hidg->in_ep != NULL) {
                /* restart endpoint */
 -              if (hidg->in_ep->driver_data != NULL)
 -                      usb_ep_disable(hidg->in_ep);
 +              usb_ep_disable(hidg->in_ep);
  
                status = config_ep_by_speed(f->config->cdev->gadget, f,
                                            hidg->in_ep);
  
        if (hidg->out_ep != NULL) {
                /* restart endpoint */
 -              if (hidg->out_ep->driver_data != NULL)
 -                      usb_ep_disable(hidg->out_ep);
 +              usb_ep_disable(hidg->out_ep);
  
                status = config_ep_by_speed(f->config->cdev->gadget, f,
                                            hidg->out_ep);
                                                hidg->out_ep->name, status);
                        } else {
                                usb_ep_disable(hidg->out_ep);
 -                              hidg->out_ep->driver_data = NULL;
                                status = -ENOMEM;
                                goto fail;
                        }
@@@ -608,11 -614,13 +608,11 @@@ static int hidg_bind(struct usb_configu
        ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
        if (!ep)
                goto fail;
 -      ep->driver_data = c->cdev;      /* claim */
        hidg->in_ep = ep;
  
        ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
        if (!ep)
                goto fail;
 -      ep->driver_data = c->cdev;      /* claim */
        hidg->out_ep = ep;
  
        /* preallocate request and buffer */
@@@ -705,9 -713,6 +705,6 @@@ static inline struct f_hid_opts *to_f_h
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_hid_opts);
- CONFIGFS_ATTR_OPS(f_hid_opts);
  static void hid_attr_release(struct config_item *item)
  {
        struct f_hid_opts *opts = to_f_hid_opts(item);
  
  static struct configfs_item_operations hidg_item_ops = {
        .release        = hid_attr_release,
-       .show_attribute = f_hid_opts_attr_show,
-       .store_attribute = f_hid_opts_attr_store,
  };
  
  #define F_HID_OPT(name, prec, limit)                                  \
- static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\
+ static ssize_t f_hid_opts_##name##_show(struct config_item *item, char *page)\
  {                                                                     \
+       struct f_hid_opts *opts = to_f_hid_opts(item);                  \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
        return result;                                                  \
  }                                                                     \
                                                                        \
- static ssize_t f_hid_opts_##name##_store(struct f_hid_opts *opts,     \
+ static ssize_t f_hid_opts_##name##_store(struct config_item *item,    \
                                         const char *page, size_t len)  \
  {                                                                     \
+       struct f_hid_opts *opts = to_f_hid_opts(item);                  \
        int ret;                                                        \
        u##prec num;                                                    \
                                                                        \
@@@ -761,16 -766,15 +758,15 @@@ end:                                                                    
        return ret;                                                     \
  }                                                                     \
                                                                        \
- static struct f_hid_opts_attribute f_hid_opts_##name =                        \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_hid_opts_##name##_show,\
-                       f_hid_opts_##name##_store)
+ CONFIGFS_ATTR(f_hid_opts_, name)
  
  F_HID_OPT(subclass, 8, 255);
  F_HID_OPT(protocol, 8, 255);
  F_HID_OPT(report_length, 16, 65535);
  
- static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page)
+ static ssize_t f_hid_opts_report_desc_show(struct config_item *item, char *page)
  {
+       struct f_hid_opts *opts = to_f_hid_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
        return result;
  }
  
- static ssize_t f_hid_opts_report_desc_store(struct f_hid_opts *opts,
+ static ssize_t f_hid_opts_report_desc_store(struct config_item *item,
                                            const char *page, size_t len)
  {
+       struct f_hid_opts *opts = to_f_hid_opts(item);
        int ret = -EBUSY;
        char *d;
  
@@@ -810,16 -815,13 +807,13 @@@ end
        return ret;
  }
  
- static struct f_hid_opts_attribute f_hid_opts_report_desc =
-       __CONFIGFS_ATTR(report_desc, S_IRUGO | S_IWUSR,
-                       f_hid_opts_report_desc_show,
-                       f_hid_opts_report_desc_store);
+ CONFIGFS_ATTR(f_hid_opts_, report_desc);
  
  static struct configfs_attribute *hid_attrs[] = {
-       &f_hid_opts_subclass.attr,
-       &f_hid_opts_protocol.attr,
-       &f_hid_opts_report_length.attr,
-       &f_hid_opts_report_desc.attr,
+       &f_hid_opts_attr_subclass,
+       &f_hid_opts_attr_protocol,
+       &f_hid_opts_attr_report_length,
+       &f_hid_opts_attr_report_desc,
        NULL,
  };
  
index 6b2102bc069973554db95d3311470b0545067727,b9d8f05300582d267a1878b3f151b27af013570e..23933bdf2d9d6cebc66750050ba704c9a20d109c
@@@ -34,9 -34,6 +34,9 @@@ struct f_loopback 
  
        struct usb_ep           *in_ep;
        struct usb_ep           *out_ep;
 +
 +      unsigned                qlen;
 +      unsigned                buflen;
  };
  
  static inline struct f_loopback *func_to_loop(struct usb_function *f)
        return container_of(f, struct f_loopback, function);
  }
  
 -static unsigned qlen;
 -static unsigned buflen;
 -
  /*-------------------------------------------------------------------------*/
  
  static struct usb_interface_descriptor loopback_intf = {
 -      .bLength =              sizeof loopback_intf,
 +      .bLength =              sizeof(loopback_intf),
        .bDescriptorType =      USB_DT_INTERFACE,
  
        .bNumEndpoints =        2,
@@@ -195,10 -195,12 +195,10 @@@ autoconf_fail
                        f->name, cdev->gadget->name);
                return -ENODEV;
        }
 -      loop->in_ep->driver_data = cdev;        /* claim */
  
        loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
        if (!loop->out_ep)
                goto autoconf_fail;
 -      loop->out_ep->driver_data = cdev;       /* claim */
  
        /* support high speed hardware */
        hs_loop_source_desc.bEndpointAddress =
@@@ -243,38 -245,22 +243,38 @@@ static void loopback_complete(struct us
        int                     status = req->status;
  
        switch (status) {
 -
        case 0:                         /* normal completion? */
                if (ep == loop->out_ep) {
 -                      req->zero = (req->actual < req->length);
 -                      req->length = req->actual;
 +                      /*
 +                       * We received some data from the host so let's
 +                       * queue it so host can read the from our in ep
 +                       */
 +                      struct usb_request *in_req = req->context;
 +
 +                      in_req->zero = (req->actual < req->length);
 +                      in_req->length = req->actual;
 +                      ep = loop->in_ep;
 +                      req = in_req;
 +              } else {
 +                      /*
 +                       * We have just looped back a bunch of data
 +                       * to host. Now let's wait for some more data.
 +                       */
 +                      req = req->context;
 +                      ep = loop->out_ep;
                }
  
 -              /* queue the buffer for some later OUT packet */
 -              req->length = buflen;
 +              /* queue the buffer back to host or for next bunch of data */
                status = usb_ep_queue(ep, req, GFP_ATOMIC);
 -              if (status == 0)
 +              if (status == 0) {
                        return;
 +              } else {
 +                      ERROR(cdev, "Unable to loop back buffer to %s: %d\n",
 +                            ep->name, status);
 +                      goto free_req;
 +              }
  
                /* "should never get here" */
 -              /* FALLTHROUGH */
 -
        default:
                ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name,
                                status, req->actual, req->length);
        case -ECONNABORTED:             /* hardware forced ep reset */
        case -ECONNRESET:               /* request dequeued */
        case -ESHUTDOWN:                /* disconnect from host */
 +free_req:
 +              usb_ep_free_request(ep == loop->in_ep ?
 +                                  loop->out_ep : loop->in_ep,
 +                                  req->context);
                free_ep_req(ep, req);
                return;
        }
@@@ -308,77 -290,53 +308,77 @@@ static void disable_loopback(struct f_l
  
  static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len)
  {
 -      return alloc_ep_req(ep, len, buflen);
 +      struct f_loopback       *loop = ep->driver_data;
 +
 +      return alloc_ep_req(ep, len, loop->buflen);
  }
  
 -static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop,
 -              struct usb_ep *ep)
 +static int alloc_requests(struct usb_composite_dev *cdev,
 +                        struct f_loopback *loop)
  {
 -      struct usb_request                      *req;
 -      unsigned                                i;
 -      int                                     result;
 -
 -      /*
 -       * one endpoint writes data back IN to the host while another endpoint
 -       * just reads OUT packets
 -       */
 -      result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
 -      if (result)
 -              goto fail0;
 -      result = usb_ep_enable(ep);
 -      if (result < 0)
 -              goto fail0;
 -      ep->driver_data = loop;
 +      struct usb_request *in_req, *out_req;
 +      int i;
 +      int result = 0;
  
        /*
         * allocate a bunch of read buffers and queue them all at once.
 -       * we buffer at most 'qlen' transfers; fewer if any need more
 -       * than 'buflen' bytes each.
 +       * we buffer at most 'qlen' transfers; We allocate buffers only
 +       * for out transfer and reuse them in IN transfers to implement
 +       * our loopback functionality
         */
 -      for (i = 0; i < qlen && result == 0; i++) {
 -              req = lb_alloc_ep_req(ep, 0);
 -              if (!req)
 -                      goto fail1;
 +      for (i = 0; i < loop->qlen && result == 0; i++) {
 +              result = -ENOMEM;
 +
 +              in_req = usb_ep_alloc_request(loop->in_ep, GFP_KERNEL);
 +              if (!in_req)
 +                      goto fail;
 +
 +              out_req = lb_alloc_ep_req(loop->out_ep, 0);
 +              if (!out_req)
 +                      goto fail_in;
  
 -              req->complete = loopback_complete;
 -              result = usb_ep_queue(ep, req, GFP_ATOMIC);
 +              in_req->complete = loopback_complete;
 +              out_req->complete = loopback_complete;
 +
 +              in_req->buf = out_req->buf;
 +              /* length will be set in complete routine */
 +              in_req->context = out_req;
 +              out_req->context = in_req;
 +
 +              result = usb_ep_queue(loop->out_ep, out_req, GFP_ATOMIC);
                if (result) {
                        ERROR(cdev, "%s queue req --> %d\n",
 -                                      ep->name, result);
 -                      goto fail1;
 +                                      loop->out_ep->name, result);
 +                      goto fail_out;
                }
        }
  
        return 0;
  
 -fail1:
 -      usb_ep_disable(ep);
 +fail_out:
 +      free_ep_req(loop->out_ep, out_req);
 +fail_in:
 +      usb_ep_free_request(loop->in_ep, in_req);
 +fail:
 +      return result;
 +}
 +
 +static int enable_endpoint(struct usb_composite_dev *cdev,
 +                         struct f_loopback *loop, struct usb_ep *ep)
 +{
 +      int                                     result;
 +
 +      result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
 +      if (result)
 +              goto out;
  
 -fail0:
 +      result = usb_ep_enable(ep);
 +      if (result < 0)
 +              goto out;
 +      ep->driver_data = loop;
 +      result = 0;
 +
 +out:
        return result;
  }
  
@@@ -389,24 -347,13 +389,24 @@@ enable_loopback(struct usb_composite_de
  
        result = enable_endpoint(cdev, loop, loop->in_ep);
        if (result)
 -              return result;
 +              goto out;
  
        result = enable_endpoint(cdev, loop, loop->out_ep);
        if (result)
 -              return result;
 +              goto disable_in;
 +
 +      result = alloc_requests(cdev, loop);
 +      if (result)
 +              goto disable_out;
  
        DBG(cdev, "%s enabled\n", loop->function.name);
 +      return 0;
 +
 +disable_out:
 +      usb_ep_disable(loop->out_ep);
 +disable_in:
 +      usb_ep_disable(loop->in_ep);
 +out:
        return result;
  }
  
@@@ -417,7 -364,8 +417,7 @@@ static int loopback_set_alt(struct usb_
        struct usb_composite_dev *cdev = f->config->cdev;
  
        /* we know alt is zero */
 -      if (loop->in_ep->driver_data)
 -              disable_loopback(loop);
 +      disable_loopback(loop);
        return enable_loopback(cdev, loop);
  }
  
@@@ -443,10 -391,10 +443,10 @@@ static struct usb_function *loopback_al
        lb_opts->refcnt++;
        mutex_unlock(&lb_opts->lock);
  
 -      buflen = lb_opts->bulk_buflen;
 -      qlen = lb_opts->qlen;
 -      if (!qlen)
 -              qlen = 32;
 +      loop->buflen = lb_opts->bulk_buflen;
 +      loop->qlen = lb_opts->qlen;
 +      if (!loop->qlen)
 +              loop->qlen = 32;
  
        loop->function.name = "loopback";
        loop->function.bind = loopback_bind;
@@@ -465,9 -413,6 +465,6 @@@ static inline struct f_lb_opts *to_f_lb
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_lb_opts);
- CONFIGFS_ATTR_OPS(f_lb_opts);
  static void lb_attr_release(struct config_item *item)
  {
        struct f_lb_opts *lb_opts = to_f_lb_opts(item);
  
  static struct configfs_item_operations lb_item_ops = {
        .release                = lb_attr_release,
-       .show_attribute         = f_lb_opts_attr_show,
-       .store_attribute        = f_lb_opts_attr_store,
  };
  
- static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page)
+ static ssize_t f_lb_opts_qlen_show(struct config_item *item, char *page)
  {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%d", opts->qlen);
 +      result = sprintf(page, "%d\n", opts->qlen);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_lb_opts_qlen_store(struct f_lb_opts *opts,
+ static ssize_t f_lb_opts_qlen_store(struct config_item *item,
                                    const char *page, size_t len)
  {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int ret;
        u32 num;
  
@@@ -515,25 -460,24 +512,24 @@@ end
        return ret;
  }
  
- static struct f_lb_opts_attribute f_lb_opts_qlen =
-       __CONFIGFS_ATTR(qlen, S_IRUGO | S_IWUSR,
-                       f_lb_opts_qlen_show,
-                       f_lb_opts_qlen_store);
+ CONFIGFS_ATTR(f_lb_opts_, qlen);
  
- static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page)
+ static ssize_t f_lb_opts_bulk_buflen_show(struct config_item *item, char *page)
  {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%d", opts->bulk_buflen);
 +      result = sprintf(page, "%d\n", opts->bulk_buflen);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_lb_opts_bulk_buflen_store(struct f_lb_opts *opts,
+ static ssize_t f_lb_opts_bulk_buflen_store(struct config_item *item,
                                    const char *page, size_t len)
  {
+       struct f_lb_opts *opts = to_f_lb_opts(item);
        int ret;
        u32 num;
  
@@@ -554,14 -498,11 +550,11 @@@ end
        return ret;
  }
  
- static struct f_lb_opts_attribute f_lb_opts_bulk_buflen =
-       __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
-                       f_lb_opts_bulk_buflen_show,
-                       f_lb_opts_bulk_buflen_store);
+ CONFIGFS_ATTR(f_lb_opts_, bulk_buflen);
  
  static struct configfs_attribute *lb_attrs[] = {
-       &f_lb_opts_qlen.attr,
-       &f_lb_opts_bulk_buflen.attr,
+       &f_lb_opts_attr_qlen,
+       &f_lb_opts_attr_bulk_buflen,
        NULL,
  };
  
index 5ec533826621c7cfcb0975f9084f0ec4df3b7cf1,1ab089f864080b3ecd9aae6735059930a827b009..223ccf89d2263fb6483a1a22116a3743c9d7ed8e
@@@ -2258,10 -2258,12 +2258,10 @@@ reset
                /* Disable the endpoints */
                if (fsg->bulk_in_enabled) {
                        usb_ep_disable(fsg->bulk_in);
 -                      fsg->bulk_in->driver_data = NULL;
                        fsg->bulk_in_enabled = 0;
                }
                if (fsg->bulk_out_enabled) {
                        usb_ep_disable(fsg->bulk_out);
 -                      fsg->bulk_out->driver_data = NULL;
                        fsg->bulk_out_enabled = 0;
                }
  
@@@ -2345,6 -2347,7 +2345,6 @@@ static void fsg_disable(struct usb_func
  
  static void handle_exception(struct fsg_common *common)
  {
 -      siginfo_t               info;
        int                     i;
        struct fsg_buffhd       *bh;
        enum fsg_state          old_state;
         * into a high-priority EXIT exception.
         */
        for (;;) {
 -              int sig =
 -                      dequeue_signal_lock(current, &current->blocked, &info);
 +              int sig = kernel_dequeue_signal(NULL);
                if (!sig)
                        break;
                if (sig != SIGUSR1) {
@@@ -2658,12 -2662,10 +2658,12 @@@ EXPORT_SYMBOL_GPL(fsg_common_put)
  /* check if fsg_num_buffers is within a valid range */
  static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
  {
 -      if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
 +#define FSG_MAX_NUM_BUFFERS   32
 +
 +      if (fsg_num_buffers >= 2 && fsg_num_buffers <= FSG_MAX_NUM_BUFFERS)
                return 0;
        pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
 -             fsg_num_buffers, 2, 4);
 +             fsg_num_buffers, 2, FSG_MAX_NUM_BUFFERS);
        return -EINVAL;
  }
  
@@@ -3068,11 -3070,13 +3068,11 @@@ static int fsg_bind(struct usb_configur
        ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
        if (!ep)
                goto autoconf_fail;
 -      ep->driver_data = fsg->common;  /* claim the endpoint */
        fsg->bulk_in = ep;
  
        ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
        if (!ep)
                goto autoconf_fail;
 -      ep->driver_data = fsg->common;  /* claim the endpoint */
        fsg->bulk_out = ep;
  
        /* Assume endpoint addresses are the same for both speeds */
@@@ -3140,9 -3144,6 +3140,6 @@@ static inline struct fsg_opts *to_fsg_o
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(fsg_lun_opts);
- CONFIGFS_ATTR_OPS(fsg_lun_opts);
  static void fsg_lun_attr_release(struct config_item *item)
  {
        struct fsg_lun_opts *lun_opts;
  
  static struct configfs_item_operations fsg_lun_item_ops = {
        .release                = fsg_lun_attr_release,
-       .show_attribute         = fsg_lun_opts_attr_show,
-       .store_attribute        = fsg_lun_opts_attr_store,
  };
  
- static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page)
+ static ssize_t fsg_lun_opts_file_show(struct config_item *item, char *page)
  {
-       struct fsg_opts *fsg_opts;
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
  
        return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page);
  }
  
- static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts,
+ static ssize_t fsg_lun_opts_file_store(struct config_item *item,
                                       const char *page, size_t len)
  {
-       struct fsg_opts *fsg_opts;
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
  
        return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len);
  }
  
- static struct fsg_lun_opts_attribute fsg_lun_opts_file =
-       __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show,
-                       fsg_lun_opts_file_store);
+ CONFIGFS_ATTR(fsg_lun_opts_, file);
  
- static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page)
+ static ssize_t fsg_lun_opts_ro_show(struct config_item *item, char *page)
  {
-       return fsg_show_ro(opts->lun, page);
+       return fsg_show_ro(to_fsg_lun_opts(item)->lun, page);
  }
  
- static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts,
+ static ssize_t fsg_lun_opts_ro_store(struct config_item *item,
                                       const char *page, size_t len)
  {
-       struct fsg_opts *fsg_opts;
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
  
        return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len);
  }
  
- static struct fsg_lun_opts_attribute fsg_lun_opts_ro =
-       __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show,
-                       fsg_lun_opts_ro_store);
+ CONFIGFS_ATTR(fsg_lun_opts_, ro);
  
- static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts,
+ static ssize_t fsg_lun_opts_removable_show(struct config_item *item,
                                           char *page)
  {
-       return fsg_show_removable(opts->lun, page);
+       return fsg_show_removable(to_fsg_lun_opts(item)->lun, page);
  }
  
- static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts,
+ static ssize_t fsg_lun_opts_removable_store(struct config_item *item,
                                       const char *page, size_t len)
  {
-       return fsg_store_removable(opts->lun, page, len);
+       return fsg_store_removable(to_fsg_lun_opts(item)->lun, page, len);
  }
  
- static struct fsg_lun_opts_attribute fsg_lun_opts_removable =
-       __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR,
-                       fsg_lun_opts_removable_show,
-                       fsg_lun_opts_removable_store);
+ CONFIGFS_ATTR(fsg_lun_opts_, removable);
  
- static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page)
+ static ssize_t fsg_lun_opts_cdrom_show(struct config_item *item, char *page)
  {
-       return fsg_show_cdrom(opts->lun, page);
+       return fsg_show_cdrom(to_fsg_lun_opts(item)->lun, page);
  }
  
- static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts,
+ static ssize_t fsg_lun_opts_cdrom_store(struct config_item *item,
                                       const char *page, size_t len)
  {
-       struct fsg_opts *fsg_opts;
-       fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
+       struct fsg_lun_opts *opts = to_fsg_lun_opts(item);
+       struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent);
  
        return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page,
                               len);
  }
  
- static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom =
-       __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show,
-                       fsg_lun_opts_cdrom_store);
+ CONFIGFS_ATTR(fsg_lun_opts_, cdrom);
  
- static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page)
+ static ssize_t fsg_lun_opts_nofua_show(struct config_item *item, char *page)
  {
-       return fsg_show_nofua(opts->lun, page);
+       return fsg_show_nofua(to_fsg_lun_opts(item)->lun, page);
  }
  
- static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts,
+ static ssize_t fsg_lun_opts_nofua_store(struct config_item *item,
                                       const char *page, size_t len)
  {
-       return fsg_store_nofua(opts->lun, page, len);
+       return fsg_store_nofua(to_fsg_lun_opts(item)->lun, page, len);
  }
  
- static struct fsg_lun_opts_attribute fsg_lun_opts_nofua =
-       __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show,
-                       fsg_lun_opts_nofua_store);
+ CONFIGFS_ATTR(fsg_lun_opts_, nofua);
  
  static struct configfs_attribute *fsg_lun_attrs[] = {
-       &fsg_lun_opts_file.attr,
-       &fsg_lun_opts_ro.attr,
-       &fsg_lun_opts_removable.attr,
-       &fsg_lun_opts_cdrom.attr,
-       &fsg_lun_opts_nofua.attr,
+       &fsg_lun_opts_attr_file,
+       &fsg_lun_opts_attr_ro,
+       &fsg_lun_opts_attr_removable,
+       &fsg_lun_opts_attr_cdrom,
+       &fsg_lun_opts_attr_nofua,
        NULL,
  };
  
@@@ -3348,9 -3332,6 +3328,6 @@@ static void fsg_lun_drop(struct config_
        config_item_put(item);
  }
  
- CONFIGFS_ATTR_STRUCT(fsg_opts);
- CONFIGFS_ATTR_OPS(fsg_opts);
  static void fsg_attr_release(struct config_item *item)
  {
        struct fsg_opts *opts = to_fsg_opts(item);
  
  static struct configfs_item_operations fsg_item_ops = {
        .release                = fsg_attr_release,
-       .show_attribute         = fsg_opts_attr_show,
-       .store_attribute        = fsg_opts_attr_store,
  };
  
- static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page)
+ static ssize_t fsg_opts_stall_show(struct config_item *item, char *page)
  {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
        return result;
  }
  
- static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page,
+ static ssize_t fsg_opts_stall_store(struct config_item *item, const char *page,
                                    size_t len)
  {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int ret;
        bool stall;
  
        return ret;
  }
  
- static struct fsg_opts_attribute fsg_opts_stall =
-       __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show,
-                       fsg_opts_stall_store);
+ CONFIGFS_ATTR(fsg_opts_, stall);
  
  #ifdef CONFIG_USB_GADGET_DEBUG_FILES
- static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page)
+ static ssize_t fsg_opts_num_buffers_show(struct config_item *item, char *page)
  {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
        return result;
  }
  
- static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts,
+ static ssize_t fsg_opts_num_buffers_store(struct config_item *item,
                                          const char *page, size_t len)
  {
+       struct fsg_opts *opts = to_fsg_opts(item);
        int ret;
        u8 num;
  
        return ret;
  }
  
- static struct fsg_opts_attribute fsg_opts_num_buffers =
-       __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR,
-                       fsg_opts_num_buffers_show,
-                       fsg_opts_num_buffers_store);
+ CONFIGFS_ATTR(fsg_opts_, num_buffers);
  #endif
  
  static struct configfs_attribute *fsg_attrs[] = {
-       &fsg_opts_stall.attr,
+       &fsg_opts_attr_stall,
  #ifdef CONFIG_USB_GADGET_DEBUG_FILES
-       &fsg_opts_num_buffers.attr,
+       &fsg_opts_attr_num_buffers,
  #endif
        NULL,
  };
index ce3c8a629266c12d6de7638f2c9900af4085cd83,0e2b8eda254e591328d2f299063ac171714e2093..42acb45e1ab42dd9436244bec16d4903603d6089
@@@ -302,7 -302,8 +302,7 @@@ static int f_midi_start_ep(struct f_mid
        int err;
        struct usb_composite_dev *cdev = f->config->cdev;
  
 -      if (ep->driver_data)
 -              usb_ep_disable(ep);
 +      usb_ep_disable(ep);
  
        err = config_ep_by_speed(midi->gadget, f, ep);
        if (err) {
@@@ -340,7 -341,8 +340,7 @@@ static int f_midi_set_alt(struct usb_fu
        if (err)
                return err;
  
 -      if (midi->out_ep->driver_data)
 -              usb_ep_disable(midi->out_ep);
 +      usb_ep_disable(midi->out_ep);
  
        err = config_ep_by_speed(midi->gadget, f, midi->out_ep);
        if (err) {
@@@ -545,16 -547,10 +545,16 @@@ static void f_midi_transmit(struct f_mi
                }
        }
  
 -      if (req->length > 0)
 -              usb_ep_queue(ep, req, GFP_ATOMIC);
 -      else
 +      if (req->length > 0) {
 +              int err;
 +
 +              err = usb_ep_queue(ep, req, GFP_ATOMIC);
 +              if (err < 0)
 +                      ERROR(midi, "%s queue req: %d\n",
 +                            midi->in_ep->name, err);
 +      } else {
                free_ep_req(ep, req);
 +      }
  }
  
  static void f_midi_in_tasklet(unsigned long data)
@@@ -761,10 -757,12 +761,10 @@@ static int f_midi_bind(struct usb_confi
        midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc);
        if (!midi->in_ep)
                goto fail;
 -      midi->in_ep->driver_data = cdev;        /* claim */
  
        midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc);
        if (!midi->out_ep)
                goto fail;
 -      midi->out_ep->driver_data = cdev;       /* claim */
  
        /* allocate temporary function list */
        midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
@@@ -891,6 -889,12 +891,6 @@@ fail_f_midi
  fail:
        f_midi_unregister_card(midi);
  fail_register:
 -      /* we might as well release our claims on endpoints */
 -      if (midi->out_ep)
 -              midi->out_ep->driver_data = NULL;
 -      if (midi->in_ep)
 -              midi->in_ep->driver_data = NULL;
 -
        ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
  
        return status;
@@@ -902,9 -906,6 +902,6 @@@ static inline struct f_midi_opts *to_f_
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_midi_opts);
- CONFIGFS_ATTR_OPS(f_midi_opts);
  static void midi_attr_release(struct config_item *item)
  {
        struct f_midi_opts *opts = to_f_midi_opts(item);
  
  static struct configfs_item_operations midi_item_ops = {
        .release        = midi_attr_release,
-       .show_attribute = f_midi_opts_attr_show,
-       .store_attribute = f_midi_opts_attr_store,
  };
  
  #define F_MIDI_OPT(name, test_limit, limit)                           \
- static ssize_t f_midi_opts_##name##_show(struct f_midi_opts *opts, char *page) \
+ static ssize_t f_midi_opts_##name##_show(struct config_item *item, char *page) \
  {                                                                     \
+       struct f_midi_opts *opts = to_f_midi_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
        return result;                                                  \
  }                                                                     \
                                                                        \
- static ssize_t f_midi_opts_##name##_store(struct f_midi_opts *opts,   \
+ static ssize_t f_midi_opts_##name##_store(struct config_item *item,   \
                                         const char *page, size_t len)  \
  {                                                                     \
+       struct f_midi_opts *opts = to_f_midi_opts(item);                \
        int ret;                                                        \
        u32 num;                                                        \
                                                                        \
@@@ -958,9 -959,7 +955,7 @@@ end:                                                                       
        return ret;                                                     \
  }                                                                     \
                                                                        \
- static struct f_midi_opts_attribute f_midi_opts_##name =              \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_midi_opts_##name##_show, \
-                       f_midi_opts_##name##_store)
+ CONFIGFS_ATTR(f_midi_opts_, name);
  
  F_MIDI_OPT(index, true, SNDRV_CARDS);
  F_MIDI_OPT(buflen, false, 0);
@@@ -968,8 -967,9 +963,9 @@@ F_MIDI_OPT(qlen, false, 0)
  F_MIDI_OPT(in_ports, true, MAX_PORTS);
  F_MIDI_OPT(out_ports, true, MAX_PORTS);
  
- static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page)
+ static ssize_t f_midi_opts_id_show(struct config_item *item, char *page)
  {
+       struct f_midi_opts *opts = to_f_midi_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
        return result;
  }
  
- static ssize_t f_midi_opts_id_store(struct f_midi_opts *opts,
+ static ssize_t f_midi_opts_id_store(struct config_item *item,
                                    const char *page, size_t len)
  {
+       struct f_midi_opts *opts = to_f_midi_opts(item);
        int ret;
        char *c;
  
        return ret;
  }
  
- static struct f_midi_opts_attribute f_midi_opts_id =
-       __CONFIGFS_ATTR(id, S_IRUGO | S_IWUSR, f_midi_opts_id_show,
-                       f_midi_opts_id_store);
+ CONFIGFS_ATTR(f_midi_opts_, id);
  
  static struct configfs_attribute *midi_attrs[] = {
-       &f_midi_opts_index.attr,
-       &f_midi_opts_buflen.attr,
-       &f_midi_opts_qlen.attr,
-       &f_midi_opts_in_ports.attr,
-       &f_midi_opts_out_ports.attr,
-       &f_midi_opts_id.attr,
+       &f_midi_opts_attr_index,
+       &f_midi_opts_attr_buflen,
+       &f_midi_opts_attr_qlen,
+       &f_midi_opts_attr_in_ports,
+       &f_midi_opts_attr_out_ports,
+       &f_midi_opts_attr_id,
        NULL,
  };
  
index b6f7ed7d48a7fa6a297ccfeca6440465593462be,01a99e5ce465f0eff9c3105d82bbf4588ee8ff6a..7ad798ace1e5b5d60c15712510fcf6b09ac81c86
@@@ -586,7 -586,7 +586,7 @@@ static void ncm_ep0out_complete(struct 
        unsigned                in_size;
        struct usb_function     *f = req->context;
        struct f_ncm            *ncm = func_to_ncm(f);
 -      struct usb_composite_dev *cdev = ep->driver_data;
 +      struct usb_composite_dev *cdev = f->config->cdev;
  
        req->context = NULL;
        if (req->status || req->actual != req->length) {
@@@ -803,8 -803,10 +803,8 @@@ static int ncm_set_alt(struct usb_funct
                if (alt != 0)
                        goto fail;
  
 -              if (ncm->notify->driver_data) {
 -                      DBG(cdev, "reset ncm control %d\n", intf);
 -                      usb_ep_disable(ncm->notify);
 -              }
 +              DBG(cdev, "reset ncm control %d\n", intf);
 +              usb_ep_disable(ncm->notify);
  
                if (!(ncm->notify->desc)) {
                        DBG(cdev, "init ncm ctrl %d\n", intf);
                                goto fail;
                }
                usb_ep_enable(ncm->notify);
 -              ncm->notify->driver_data = ncm;
  
        /* Data interface has two altsettings, 0 and 1 */
        } else if (intf == ncm->data_id) {
                if (alt > 1)
                        goto fail;
  
 -              if (ncm->port.in_ep->driver_data) {
 +              if (ncm->port.in_ep->enabled) {
                        DBG(cdev, "reset ncm\n");
                        ncm->timer_stopping = true;
                        ncm->netdev = NULL;
@@@ -882,7 -885,7 +882,7 @@@ static int ncm_get_alt(struct usb_funct
  
        if (intf == ncm->ctrl_id)
                return 0;
 -      return ncm->port.in_ep->driver_data ? 1 : 0;
 +      return ncm->port.in_ep->enabled ? 1 : 0;
  }
  
  static struct sk_buff *package_for_tx(struct f_ncm *ncm)
@@@ -1273,14 -1276,15 +1273,14 @@@ static void ncm_disable(struct usb_func
  
        DBG(cdev, "ncm deactivated\n");
  
 -      if (ncm->port.in_ep->driver_data) {
 +      if (ncm->port.in_ep->enabled) {
                ncm->timer_stopping = true;
                ncm->netdev = NULL;
                gether_disconnect(&ncm->port);
        }
  
 -      if (ncm->notify->driver_data) {
 +      if (ncm->notify->enabled) {
                usb_ep_disable(ncm->notify);
 -              ncm->notify->driver_data = NULL;
                ncm->notify->desc = NULL;
        }
  }
@@@ -1398,16 -1402,19 +1398,16 @@@ static int ncm_bind(struct usb_configur
        if (!ep)
                goto fail;
        ncm->port.in_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc);
        if (!ep)
                goto fail;
        ncm->port.out_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc);
        if (!ep)
                goto fail;
        ncm->notify = ep;
 -      ep->driver_data = cdev; /* claim */
  
        status = -ENOMEM;
  
@@@ -1461,6 -1468,14 +1461,6 @@@ fail
                usb_ep_free_request(ncm->notify, ncm->notify_req);
        }
  
 -      /* we might as well release our claims on endpoints */
 -      if (ncm->notify)
 -              ncm->notify->driver_data = NULL;
 -      if (ncm->port.out_ep)
 -              ncm->port.out_ep->driver_data = NULL;
 -      if (ncm->port.in_ep)
 -              ncm->port.in_ep->driver_data = NULL;
 -
        ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
  
        return status;
@@@ -1488,10 -1503,10 +1488,10 @@@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(n
  USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ncm);
  
  static struct configfs_attribute *ncm_attrs[] = {
-       &f_ncm_opts_dev_addr.attr,
-       &f_ncm_opts_host_addr.attr,
-       &f_ncm_opts_qmult.attr,
-       &f_ncm_opts_ifname.attr,
+       &ncm_opts_attr_dev_addr,
+       &ncm_opts_attr_host_addr,
+       &ncm_opts_attr_qmult,
+       &ncm_opts_attr_ifname,
        NULL,
  };
  
index 1c3d30ad2f92cb3edba2ab0eb3ca490378de86f1,f6f1e6bd9186fb25181c59feb4486d9cae733309..d6396e0909eeb45898541094cb2347b4d38bde24
@@@ -206,7 -206,7 +206,7 @@@ static int obex_set_alt(struct usb_func
                if (alt > 1)
                        goto fail;
  
 -              if (obex->port.in->driver_data) {
 +              if (obex->port.in->enabled) {
                        dev_dbg(&cdev->gadget->dev,
                                "reset obex ttyGS%d\n", obex->port_num);
                        gserial_disconnect(&obex->port);
@@@ -348,11 -348,13 +348,11 @@@ static int obex_bind(struct usb_configu
        if (!ep)
                goto fail;
        obex->port.in = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc);
        if (!ep)
                goto fail;
        obex->port.out = ep;
 -      ep->driver_data = cdev; /* claim */
  
        /* support all relevant hardware speeds... we expect that when
         * hardware is dual speed, all bulk-capable endpoints work at
        return 0;
  
  fail:
 -      /* we might as well release our claims on endpoints */
 -      if (obex->port.out)
 -              obex->port.out->driver_data = NULL;
 -      if (obex->port.in)
 -              obex->port.in->driver_data = NULL;
 -
        ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
  
        return status;
@@@ -387,22 -395,6 +387,6 @@@ static inline struct f_serial_opts *to_
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_serial_opts);
- static ssize_t f_obex_attr_show(struct config_item *item,
-                               struct configfs_attribute *attr,
-                               char *page)
- {
-       struct f_serial_opts *opts = to_f_serial_opts(item);
-       struct f_serial_opts_attribute *f_serial_opts_attr =
-               container_of(attr, struct f_serial_opts_attribute, attr);
-       ssize_t ret = 0;
-       if (f_serial_opts_attr->show)
-               ret = f_serial_opts_attr->show(opts, page);
-       return ret;
- }
  static void obex_attr_release(struct config_item *item)
  {
        struct f_serial_opts *opts = to_f_serial_opts(item);
  
  static struct configfs_item_operations obex_item_ops = {
        .release        = obex_attr_release,
-       .show_attribute = f_obex_attr_show,
  };
  
- static ssize_t f_obex_port_num_show(struct f_serial_opts *opts, char *page)
+ static ssize_t f_obex_port_num_show(struct config_item *item, char *page)
  {
-       return sprintf(page, "%u\n", opts->port_num);
+       return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
  }
  
- static struct f_serial_opts_attribute f_obex_port_num =
-       __CONFIGFS_ATTR_RO(port_num, f_obex_port_num_show);
+ CONFIGFS_ATTR_RO(f_obex_, port_num);
  
  static struct configfs_attribute *acm_attrs[] = {
-       &f_obex_port_num.attr,
+       &f_obex_attr_port_num,
        NULL,
  };
  
index 62a198754029e1f707147a12713f758a186cdd8e,c029ef6ba41983f5397e8054950b7167e0ea3d4b..157441dbfeba861d4d877f8009dca6fb44acd740
@@@ -418,7 -418,7 +418,7 @@@ static int pn_set_alt(struct usb_functi
  
                spin_lock(&port->lock);
  
 -              if (fp->in_ep->driver_data)
 +              if (fp->in_ep->enabled)
                        __pn_reset(f);
  
                if (alt == 1) {
@@@ -530,11 -530,13 +530,11 @@@ static int pn_bind(struct usb_configura
        if (!ep)
                goto err;
        fp->out_ep = ep;
 -      ep->driver_data = fp; /* Claim */
  
        ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc);
        if (!ep)
                goto err;
        fp->in_ep = ep;
 -      ep->driver_data = fp; /* Claim */
  
        pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress;
        pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress;
@@@ -573,6 -575,10 +573,6 @@@ err_req
                usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
        usb_free_all_descriptors(f);
  err:
 -      if (fp->out_ep)
 -              fp->out_ep->driver_data = NULL;
 -      if (fp->in_ep)
 -              fp->in_ep->driver_data = NULL;
        ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n");
        return status;
  }
@@@ -583,21 -589,6 +583,6 @@@ static inline struct f_phonet_opts *to_
                        func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_phonet_opts);
- static ssize_t f_phonet_attr_show(struct config_item *item,
-                               struct configfs_attribute *attr,
-                               char *page)
- {
-       struct f_phonet_opts *opts = to_f_phonet_opts(item);
-       struct f_phonet_opts_attribute *f_phonet_opts_attr =
-               container_of(attr, struct f_phonet_opts_attribute, attr);
-       ssize_t ret = 0;
-       if (f_phonet_opts_attr->show)
-               ret = f_phonet_opts_attr->show(opts, page);
-       return ret;
- }
  static void phonet_attr_release(struct config_item *item)
  {
        struct f_phonet_opts *opts = to_f_phonet_opts(item);
  
  static struct configfs_item_operations phonet_item_ops = {
        .release                = phonet_attr_release,
-       .show_attribute         = f_phonet_attr_show,
  };
  
- static ssize_t f_phonet_ifname_show(struct f_phonet_opts *opts, char *page)
+ static ssize_t f_phonet_ifname_show(struct config_item *item, char *page)
  {
-       return gether_get_ifname(opts->net, page, PAGE_SIZE);
+       return gether_get_ifname(to_f_phonet_opts(item)->net, page, PAGE_SIZE);
  }
  
- static struct f_phonet_opts_attribute f_phonet_ifname =
-       __CONFIGFS_ATTR_RO(ifname, f_phonet_ifname_show);
+ CONFIGFS_ATTR_RO(f_phonet_, ifname);
  
  static struct configfs_attribute *phonet_attrs[] = {
-       &f_phonet_ifname.attr,
+       &f_phonet_attr_ifname,
        NULL,
  };
  
index 7fb3209ed52c31c662b24b1799e78ff9a4d38700,3a378460bf3759a2cffe0e428ff52fa15843f8cd..0fbfb2b2aa08b3ade8e4b487d012188687b29e05
@@@ -1039,10 -1039,12 +1039,10 @@@ autoconf_fail
                        cdev->gadget->name);
                return -ENODEV;
        }
 -      in_ep->driver_data = in_ep;     /* claim */
  
        out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc);
        if (!out_ep)
                goto autoconf_fail;
 -      out_ep->driver_data = out_ep;   /* claim */
  
        /* assumes that all endpoints are dual-speed */
        hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
@@@ -1146,9 -1148,6 +1146,6 @@@ static inline struct f_printer_opt
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_printer_opts);
- CONFIGFS_ATTR_OPS(f_printer_opts);
  static void printer_attr_release(struct config_item *item)
  {
        struct f_printer_opts *opts = to_f_printer_opts(item);
  
  static struct configfs_item_operations printer_item_ops = {
        .release        = printer_attr_release,
-       .show_attribute = f_printer_opts_attr_show,
-       .store_attribute = f_printer_opts_attr_store,
  };
  
- static ssize_t f_printer_opts_pnp_string_show(struct f_printer_opts *opts,
+ static ssize_t f_printer_opts_pnp_string_show(struct config_item *item,
                                              char *page)
  {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
        return result;
  }
  
- static ssize_t f_printer_opts_pnp_string_store(struct f_printer_opts *opts,
+ static ssize_t f_printer_opts_pnp_string_store(struct config_item *item,
                                               const char *page, size_t len)
  {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int result, l;
  
        mutex_lock(&opts->lock);
        return result;
  }
  
- static struct f_printer_opts_attribute f_printer_opts_pnp_string =
-       __CONFIGFS_ATTR(pnp_string, S_IRUGO | S_IWUSR,
-                       f_printer_opts_pnp_string_show,
-                       f_printer_opts_pnp_string_store);
+ CONFIGFS_ATTR(f_printer_opts_, pnp_string);
  
- static ssize_t f_printer_opts_q_len_show(struct f_printer_opts *opts,
+ static ssize_t f_printer_opts_q_len_show(struct config_item *item,
                                         char *page)
  {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
        return result;
  }
  
- static ssize_t f_printer_opts_q_len_store(struct f_printer_opts *opts,
+ static ssize_t f_printer_opts_q_len_store(struct config_item *item,
                                          const char *page, size_t len)
  {
+       struct f_printer_opts *opts = to_f_printer_opts(item);
        int ret;
        u16 num;
  
        return ret;
  }
  
- static struct f_printer_opts_attribute f_printer_opts_q_len =
-       __CONFIGFS_ATTR(q_len, S_IRUGO | S_IWUSR, f_printer_opts_q_len_show,
-                       f_printer_opts_q_len_store);
+ CONFIGFS_ATTR(f_printer_opts_, q_len);
  
  static struct configfs_attribute *printer_attrs[] = {
-       &f_printer_opts_pnp_string.attr,
-       &f_printer_opts_q_len.attr,
+       &f_printer_opts_attr_pnp_string,
+       &f_printer_opts_attr_q_len,
        NULL,
  };
  
index fd301ed9e294fa480ad0336fc17833e772611765,a04b52678319c3619aef0829d1484d00194529fc..e587767e374cbc2fbae3b02879b5358c38d48e69
@@@ -543,20 -543,22 +543,20 @@@ static int rndis_set_alt(struct usb_fun
        /* we know alt == 0 */
  
        if (intf == rndis->ctrl_id) {
 -              if (rndis->notify->driver_data) {
 -                      VDBG(cdev, "reset rndis control %d\n", intf);
 -                      usb_ep_disable(rndis->notify);
 -              }
 +              VDBG(cdev, "reset rndis control %d\n", intf);
 +              usb_ep_disable(rndis->notify);
 +
                if (!rndis->notify->desc) {
                        VDBG(cdev, "init rndis ctrl %d\n", intf);
                        if (config_ep_by_speed(cdev->gadget, f, rndis->notify))
                                goto fail;
                }
                usb_ep_enable(rndis->notify);
 -              rndis->notify->driver_data = rndis;
  
        } else if (intf == rndis->data_id) {
                struct net_device       *net;
  
 -              if (rndis->port.in_ep->driver_data) {
 +              if (rndis->port.in_ep->enabled) {
                        DBG(cdev, "reset rndis\n");
                        gether_disconnect(&rndis->port);
                }
@@@ -610,7 -612,7 +610,7 @@@ static void rndis_disable(struct usb_fu
        struct f_rndis          *rndis = func_to_rndis(f);
        struct usb_composite_dev *cdev = f->config->cdev;
  
 -      if (!rndis->notify->driver_data)
 +      if (!rndis->notify->enabled)
                return;
  
        DBG(cdev, "rndis deactivated\n");
        gether_disconnect(&rndis->port);
  
        usb_ep_disable(rndis->notify);
 -      rndis->notify->driver_data = NULL;
  }
  
  /*-------------------------------------------------------------------------*/
@@@ -742,11 -745,13 +742,11 @@@ rndis_bind(struct usb_configuration *c
        if (!ep)
                goto fail;
        rndis->port.in_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
        if (!ep)
                goto fail;
        rndis->port.out_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        /* NOTE:  a status/notification endpoint is, strictly speaking,
         * optional.  We don't treat it that way though!  It's simpler,
        if (!ep)
                goto fail;
        rndis->notify = ep;
 -      ep->driver_data = cdev; /* claim */
  
        status = -ENOMEM;
  
@@@ -823,6 -829,14 +823,6 @@@ fail
                usb_ep_free_request(rndis->notify, rndis->notify_req);
        }
  
 -      /* we might as well release our claims on endpoints */
 -      if (rndis->notify)
 -              rndis->notify->driver_data = NULL;
 -      if (rndis->port.out_ep)
 -              rndis->port.out_ep->driver_data = NULL;
 -      if (rndis->port.in_ep)
 -              rndis->port.in_ep->driver_data = NULL;
 -
        ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
  
        return status;
@@@ -864,10 -878,10 +864,10 @@@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(r
  USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis);
  
  static struct configfs_attribute *rndis_attrs[] = {
-       &f_rndis_opts_dev_addr.attr,
-       &f_rndis_opts_host_addr.attr,
-       &f_rndis_opts_qmult.attr,
-       &f_rndis_opts_ifname.attr,
+       &rndis_opts_attr_dev_addr,
+       &rndis_opts_attr_host_addr,
+       &rndis_opts_attr_qmult,
+       &rndis_opts_attr_ifname,
        NULL,
  };
  
index ba705e047d7e0fca31ce8a2ede4d67f595efb5ca,ec837f4ea416223d8a1e816bd95256de0dda1c85..6bb44d613baba28106d31023d337edf6367b9333
@@@ -153,7 -153,7 +153,7 @@@ static int gser_set_alt(struct usb_func
  
        /* we know alt == 0, so this is an activation or a reset */
  
 -      if (gser->port.in->driver_data) {
 +      if (gser->port.in->enabled) {
                dev_dbg(&cdev->gadget->dev,
                        "reset generic ttyGS%d\n", gser->port_num);
                gserial_disconnect(&gser->port);
@@@ -219,11 -219,13 +219,11 @@@ static int gser_bind(struct usb_configu
        if (!ep)
                goto fail;
        gser->port.in = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc);
        if (!ep)
                goto fail;
        gser->port.out = ep;
 -      ep->driver_data = cdev; /* claim */
  
        /* support all relevant hardware speeds... we expect that when
         * hardware is dual speed, all bulk-capable endpoints work at
        return 0;
  
  fail:
 -      /* we might as well release our claims on endpoints */
 -      if (gser->port.out)
 -              gser->port.out->driver_data = NULL;
 -      if (gser->port.in)
 -              gser->port.in->driver_data = NULL;
 -
        ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
  
        return status;
@@@ -258,22 -266,6 +258,6 @@@ static inline struct f_serial_opts *to_
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_serial_opts);
- static ssize_t f_serial_attr_show(struct config_item *item,
-                                 struct configfs_attribute *attr,
-                                 char *page)
- {
-       struct f_serial_opts *opts = to_f_serial_opts(item);
-       struct f_serial_opts_attribute *f_serial_opts_attr =
-               container_of(attr, struct f_serial_opts_attribute, attr);
-       ssize_t ret = 0;
-       if (f_serial_opts_attr->show)
-               ret = f_serial_opts_attr->show(opts, page);
-       return ret;
- }
  static void serial_attr_release(struct config_item *item)
  {
        struct f_serial_opts *opts = to_f_serial_opts(item);
  
  static struct configfs_item_operations serial_item_ops = {
        .release        = serial_attr_release,
-       .show_attribute = f_serial_attr_show,
  };
  
- static ssize_t f_serial_port_num_show(struct f_serial_opts *opts, char *page)
+ static ssize_t f_serial_port_num_show(struct config_item *item, char *page)
  {
-       return sprintf(page, "%u\n", opts->port_num);
+       return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
  }
  
- static struct f_serial_opts_attribute f_serial_port_num =
-       __CONFIGFS_ATTR_RO(port_num, f_serial_port_num_show);
+ CONFIGFS_ATTR_RO(f_serial_, port_num);
  
  static struct configfs_attribute *acm_attrs[] = {
-       &f_serial_port_num.attr,
+       &f_serial_attr_port_num,
        NULL,
  };
  
index d7646d3acd63ecb4aa87362e069b54faff909844,878a5815450ed85f0740539c6e379270b9c93440..9f3ced62d9162c991c03b0db68d10fd0cbe06ea9
@@@ -50,13 -50,6 +50,13 @@@ struct f_sourcesink 
        struct usb_ep           *iso_in_ep;
        struct usb_ep           *iso_out_ep;
        int                     cur_alt;
 +
 +      unsigned pattern;
 +      unsigned isoc_interval;
 +      unsigned isoc_maxpacket;
 +      unsigned isoc_mult;
 +      unsigned isoc_maxburst;
 +      unsigned buflen;
  };
  
  static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
        return container_of(f, struct f_sourcesink, function);
  }
  
 -static unsigned pattern;
 -static unsigned isoc_interval;
 -static unsigned isoc_maxpacket;
 -static unsigned isoc_mult;
 -static unsigned isoc_maxburst;
 -static unsigned buflen;
 -
  /*-------------------------------------------------------------------------*/
  
  static struct usb_interface_descriptor source_sink_intf_alt0 = {
@@@ -298,9 -298,7 +298,9 @@@ static struct usb_gadget_strings *sourc
  
  static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
  {
 -      return alloc_ep_req(ep, len, buflen);
 +      struct f_sourcesink             *ss = ep->driver_data;
 +
 +      return alloc_ep_req(ep, len, ss->buflen);
  }
  
  void free_ep_req(struct usb_ep *ep, struct usb_request *req)
@@@ -313,9 -311,13 +313,9 @@@ static void disable_ep(struct usb_compo
  {
        int                     value;
  
 -      if (ep->driver_data) {
 -              value = usb_ep_disable(ep);
 -              if (value < 0)
 -                      DBG(cdev, "disable %s --> %d\n",
 -                                      ep->name, value);
 -              ep->driver_data = NULL;
 -      }
 +      value = usb_ep_disable(ep);
 +      if (value < 0)
 +              DBG(cdev, "disable %s --> %d\n", ep->name, value);
  }
  
  void disable_endpoints(struct usb_composite_dev *cdev,
@@@ -353,37 -355,42 +353,37 @@@ autoconf_fail
                        f->name, cdev->gadget->name);
                return -ENODEV;
        }
 -      ss->in_ep->driver_data = cdev;  /* claim */
  
        ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
        if (!ss->out_ep)
                goto autoconf_fail;
 -      ss->out_ep->driver_data = cdev; /* claim */
  
        /* sanity check the isoc module parameters */
 -      if (isoc_interval < 1)
 -              isoc_interval = 1;
 -      if (isoc_interval > 16)
 -              isoc_interval = 16;
 -      if (isoc_mult > 2)
 -              isoc_mult = 2;
 -      if (isoc_maxburst > 15)
 -              isoc_maxburst = 15;
 +      if (ss->isoc_interval < 1)
 +              ss->isoc_interval = 1;
 +      if (ss->isoc_interval > 16)
 +              ss->isoc_interval = 16;
 +      if (ss->isoc_mult > 2)
 +              ss->isoc_mult = 2;
 +      if (ss->isoc_maxburst > 15)
 +              ss->isoc_maxburst = 15;
  
        /* fill in the FS isoc descriptors from the module parameters */
 -      fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
 -                                              1023 : isoc_maxpacket;
 -      fs_iso_source_desc.bInterval = isoc_interval;
 -      fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
 -                                              1023 : isoc_maxpacket;
 -      fs_iso_sink_desc.bInterval = isoc_interval;
 +      fs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
 +                                              1023 : ss->isoc_maxpacket;
 +      fs_iso_source_desc.bInterval = ss->isoc_interval;
 +      fs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
 +                                              1023 : ss->isoc_maxpacket;
 +      fs_iso_sink_desc.bInterval = ss->isoc_interval;
  
        /* allocate iso endpoints */
        ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
        if (!ss->iso_in_ep)
                goto no_iso;
 -      ss->iso_in_ep->driver_data = cdev;      /* claim */
  
        ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
 -      if (ss->iso_out_ep) {
 -              ss->iso_out_ep->driver_data = cdev;     /* claim */
 -      } else {
 -              ss->iso_in_ep->driver_data = NULL;
 +      if (!ss->iso_out_ep) {
 +              usb_ep_autoconfig_release(ss->iso_in_ep);
                ss->iso_in_ep = NULL;
  no_iso:
                /*
                ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
        }
  
 -      if (isoc_maxpacket > 1024)
 -              isoc_maxpacket = 1024;
 +      if (ss->isoc_maxpacket > 1024)
 +              ss->isoc_maxpacket = 1024;
  
        /* support high speed hardware */
        hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
         * We assume that the user knows what they are doing and won't
         * give parameters that their UDC doesn't support.
         */
 -      hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
 -      hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
 -      hs_iso_source_desc.bInterval = isoc_interval;
 +      hs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
 +      hs_iso_source_desc.wMaxPacketSize |= ss->isoc_mult << 11;
 +      hs_iso_source_desc.bInterval = ss->isoc_interval;
        hs_iso_source_desc.bEndpointAddress =
                fs_iso_source_desc.bEndpointAddress;
  
 -      hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
 -      hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
 -      hs_iso_sink_desc.bInterval = isoc_interval;
 +      hs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
 +      hs_iso_sink_desc.wMaxPacketSize |= ss->isoc_mult << 11;
 +      hs_iso_sink_desc.bInterval = ss->isoc_interval;
        hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
  
        /* support super speed hardware */
         * We assume that the user knows what they are doing and won't
         * give parameters that their UDC doesn't support.
         */
 -      ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
 -      ss_iso_source_desc.bInterval = isoc_interval;
 -      ss_iso_source_comp_desc.bmAttributes = isoc_mult;
 -      ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
 -      ss_iso_source_comp_desc.wBytesPerInterval =
 -              isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
 +      ss_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
 +      ss_iso_source_desc.bInterval = ss->isoc_interval;
 +      ss_iso_source_comp_desc.bmAttributes = ss->isoc_mult;
 +      ss_iso_source_comp_desc.bMaxBurst = ss->isoc_maxburst;
 +      ss_iso_source_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
 +              (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
        ss_iso_source_desc.bEndpointAddress =
                fs_iso_source_desc.bEndpointAddress;
  
 -      ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
 -      ss_iso_sink_desc.bInterval = isoc_interval;
 -      ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
 -      ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
 -      ss_iso_sink_comp_desc.wBytesPerInterval =
 -              isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
 +      ss_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
 +      ss_iso_sink_desc.bInterval = ss->isoc_interval;
 +      ss_iso_sink_comp_desc.bmAttributes = ss->isoc_mult;
 +      ss_iso_sink_comp_desc.bMaxBurst = ss->isoc_maxburst;
 +      ss_iso_sink_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
 +              (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
        ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
  
        ret = usb_assign_descriptors(f, fs_source_sink_descs,
@@@ -482,13 -489,12 +482,13 @@@ static int check_read_data(struct f_sou
        unsigned                i;
        u8                      *buf = req->buf;
        struct usb_composite_dev *cdev = ss->function.config->cdev;
 +      int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize);
  
 -      if (pattern == 2)
 +      if (ss->pattern == 2)
                return 0;
  
        for (i = 0; i < req->actual; i++, buf++) {
 -              switch (pattern) {
 +              switch (ss->pattern) {
  
                /* all-zeroes has no synchronization issues */
                case 0:
                 * stutter for any reason, including buffer duplication...)
                 */
                case 1:
 -                      if (*buf == (u8)(i % 63))
 +                      if (*buf == (u8)((i % max_packet_size) % 63))
                                continue;
                        break;
                }
@@@ -519,16 -525,14 +519,16 @@@ static void reinit_write_data(struct us
  {
        unsigned        i;
        u8              *buf = req->buf;
 +      int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize);
 +      struct f_sourcesink *ss = ep->driver_data;
  
 -      switch (pattern) {
 +      switch (ss->pattern) {
        case 0:
                memset(req->buf, 0, req->length);
                break;
        case 1:
                for  (i = 0; i < req->length; i++)
 -                      *buf++ = (u8) (i % 63);
 +                      *buf++ = (u8) ((i % max_packet_size) % 63);
                break;
        case 2:
                break;
@@@ -552,7 -556,7 +552,7 @@@ static void source_sink_complete(struc
        case 0:                         /* normal completion? */
                if (ep == ss->out_ep) {
                        check_read_data(ss, req);
 -                      if (pattern != 2)
 +                      if (ss->pattern != 2)
                                memset(req->buf, 0x55, req->length);
                }
                break;
@@@ -601,16 -605,15 +601,16 @@@ static int source_sink_start_ep(struct 
                if (is_iso) {
                        switch (speed) {
                        case USB_SPEED_SUPER:
 -                              size = isoc_maxpacket * (isoc_mult + 1) *
 -                                              (isoc_maxburst + 1);
 +                              size = ss->isoc_maxpacket *
 +                                              (ss->isoc_mult + 1) *
 +                                              (ss->isoc_maxburst + 1);
                                break;
                        case USB_SPEED_HIGH:
 -                              size = isoc_maxpacket * (isoc_mult + 1);
 +                              size = ss->isoc_maxpacket * (ss->isoc_mult + 1);
                                break;
                        default:
 -                              size = isoc_maxpacket > 1023 ?
 -                                              1023 : isoc_maxpacket;
 +                              size = ss->isoc_maxpacket > 1023 ?
 +                                              1023 : ss->isoc_maxpacket;
                                break;
                        }
                        ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
                req->complete = source_sink_complete;
                if (is_in)
                        reinit_write_data(ep, req);
 -              else if (pattern != 2)
 +              else if (ss->pattern != 2)
                        memset(req->buf, 0x55, req->length);
  
                status = usb_ep_queue(ep, req, GFP_ATOMIC);
@@@ -680,6 -683,7 +680,6 @@@ enable_source_sink(struct usb_composite
  fail:
                ep = ss->in_ep;
                usb_ep_disable(ep);
 -              ep->driver_data = NULL;
                return result;
        }
  
  fail2:
                ep = ss->out_ep;
                usb_ep_disable(ep);
 -              ep->driver_data = NULL;
                goto fail;
        }
  
                if (result < 0) {
  fail3:
                        ep = ss->iso_in_ep;
 -                      if (ep) {
 +                      if (ep)
                                usb_ep_disable(ep);
 -                              ep->driver_data = NULL;
 -                      }
                        goto fail2;
                }
        }
                result = source_sink_start_ep(ss, false, true, speed);
                if (result < 0) {
                        usb_ep_disable(ep);
 -                      ep->driver_data = NULL;
                        goto fail3;
                }
        }
@@@ -755,7 -763,8 +755,7 @@@ static int sourcesink_set_alt(struct us
        struct f_sourcesink             *ss = func_to_ss(f);
        struct usb_composite_dev        *cdev = f->config->cdev;
  
 -      if (ss->in_ep->driver_data)
 -              disable_source_sink(ss);
 +      disable_source_sink(ss);
        return enable_source_sink(cdev, ss, alt);
  }
  
@@@ -863,12 -872,12 +863,12 @@@ static struct usb_function *source_sink
        ss_opts->refcnt++;
        mutex_unlock(&ss_opts->lock);
  
 -      pattern = ss_opts->pattern;
 -      isoc_interval = ss_opts->isoc_interval;
 -      isoc_maxpacket = ss_opts->isoc_maxpacket;
 -      isoc_mult = ss_opts->isoc_mult;
 -      isoc_maxburst = ss_opts->isoc_maxburst;
 -      buflen = ss_opts->bulk_buflen;
 +      ss->pattern = ss_opts->pattern;
 +      ss->isoc_interval = ss_opts->isoc_interval;
 +      ss->isoc_maxpacket = ss_opts->isoc_maxpacket;
 +      ss->isoc_mult = ss_opts->isoc_mult;
 +      ss->isoc_maxburst = ss_opts->isoc_maxburst;
 +      ss->buflen = ss_opts->bulk_buflen;
  
        ss->function.name = "source/sink";
        ss->function.bind = sourcesink_bind;
@@@ -889,9 -898,6 +889,6 @@@ static inline struct f_ss_opts *to_f_ss
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_ss_opts);
- CONFIGFS_ATTR_OPS(f_ss_opts);
  static void ss_attr_release(struct config_item *item)
  {
        struct f_ss_opts *ss_opts = to_f_ss_opts(item);
  
  static struct configfs_item_operations ss_item_ops = {
        .release                = ss_attr_release,
-       .show_attribute         = f_ss_opts_attr_show,
-       .store_attribute        = f_ss_opts_attr_store,
  };
  
- static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
+ static ssize_t f_ss_opts_pattern_show(struct config_item *item, char *page)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%u", opts->pattern);
 +      result = sprintf(page, "%u\n", opts->pattern);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_ss_opts_pattern_store(struct f_ss_opts *opts,
+ static ssize_t f_ss_opts_pattern_store(struct config_item *item,
                                       const char *page, size_t len)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
  
@@@ -944,25 -950,24 +941,24 @@@ end
        return ret;
  }
  
- static struct f_ss_opts_attribute f_ss_opts_pattern =
-       __CONFIGFS_ATTR(pattern, S_IRUGO | S_IWUSR,
-                       f_ss_opts_pattern_show,
-                       f_ss_opts_pattern_store);
+ CONFIGFS_ATTR(f_ss_opts_, pattern);
  
- static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
+ static ssize_t f_ss_opts_isoc_interval_show(struct config_item *item, char *page)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%u", opts->isoc_interval);
 +      result = sprintf(page, "%u\n", opts->isoc_interval);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_ss_opts_isoc_interval_store(struct f_ss_opts *opts,
+ static ssize_t f_ss_opts_isoc_interval_store(struct config_item *item,
                                       const char *page, size_t len)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
  
@@@ -988,25 -993,24 +984,24 @@@ end
        return ret;
  }
  
- static struct f_ss_opts_attribute f_ss_opts_isoc_interval =
-       __CONFIGFS_ATTR(isoc_interval, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_interval_show,
-                       f_ss_opts_isoc_interval_store);
+ CONFIGFS_ATTR(f_ss_opts_, isoc_interval);
  
- static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
+ static ssize_t f_ss_opts_isoc_maxpacket_show(struct config_item *item, char *page)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%u", opts->isoc_maxpacket);
 +      result = sprintf(page, "%u\n", opts->isoc_maxpacket);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_ss_opts_isoc_maxpacket_store(struct f_ss_opts *opts,
+ static ssize_t f_ss_opts_isoc_maxpacket_store(struct config_item *item,
                                       const char *page, size_t len)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u16 num;
  
        return ret;
  }
  
- static struct f_ss_opts_attribute f_ss_opts_isoc_maxpacket =
-       __CONFIGFS_ATTR(isoc_maxpacket, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_maxpacket_show,
-                       f_ss_opts_isoc_maxpacket_store);
+ CONFIGFS_ATTR(f_ss_opts_, isoc_maxpacket);
  
- static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
+ static ssize_t f_ss_opts_isoc_mult_show(struct config_item *item, char *page)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%u", opts->isoc_mult);
 +      result = sprintf(page, "%u\n", opts->isoc_mult);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_ss_opts_isoc_mult_store(struct f_ss_opts *opts,
+ static ssize_t f_ss_opts_isoc_mult_store(struct config_item *item,
                                       const char *page, size_t len)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
  
        return ret;
  }
  
- static struct f_ss_opts_attribute f_ss_opts_isoc_mult =
-       __CONFIGFS_ATTR(isoc_mult, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_mult_show,
-                       f_ss_opts_isoc_mult_store);
+ CONFIGFS_ATTR(f_ss_opts_, isoc_mult);
  
- static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
+ static ssize_t f_ss_opts_isoc_maxburst_show(struct config_item *item, char *page)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%u", opts->isoc_maxburst);
 +      result = sprintf(page, "%u\n", opts->isoc_maxburst);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_ss_opts_isoc_maxburst_store(struct f_ss_opts *opts,
+ static ssize_t f_ss_opts_isoc_maxburst_store(struct config_item *item,
                                       const char *page, size_t len)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
  
        return ret;
  }
  
- static struct f_ss_opts_attribute f_ss_opts_isoc_maxburst =
-       __CONFIGFS_ATTR(isoc_maxburst, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_maxburst_show,
-                       f_ss_opts_isoc_maxburst_store);
+ CONFIGFS_ATTR(f_ss_opts_, isoc_maxburst);
  
- static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
+ static ssize_t f_ss_opts_bulk_buflen_show(struct config_item *item, char *page)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
  
        mutex_lock(&opts->lock);
 -      result = sprintf(page, "%u", opts->bulk_buflen);
 +      result = sprintf(page, "%u\n", opts->bulk_buflen);
        mutex_unlock(&opts->lock);
  
        return result;
  }
  
- static ssize_t f_ss_opts_bulk_buflen_store(struct f_ss_opts *opts,
+ static ssize_t f_ss_opts_bulk_buflen_store(struct config_item *item,
                                           const char *page, size_t len)
  {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u32 num;
  
        return ret;
  }
  
- static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
-       __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
-                       f_ss_opts_bulk_buflen_show,
-                       f_ss_opts_bulk_buflen_store);
+ CONFIGFS_ATTR(f_ss_opts_, bulk_buflen);
  
  static struct configfs_attribute *ss_attrs[] = {
-       &f_ss_opts_pattern.attr,
-       &f_ss_opts_isoc_interval.attr,
-       &f_ss_opts_isoc_maxpacket.attr,
-       &f_ss_opts_isoc_mult.attr,
-       &f_ss_opts_isoc_maxburst.attr,
-       &f_ss_opts_bulk_buflen.attr,
+       &f_ss_opts_attr_pattern,
+       &f_ss_opts_attr_isoc_interval,
+       &f_ss_opts_attr_isoc_maxpacket,
+       &f_ss_opts_attr_isoc_mult,
+       &f_ss_opts_attr_isoc_maxburst,
+       &f_ss_opts_attr_bulk_buflen,
        NULL,
  };
  
index 2e66e624e6e13dfed2fde71fff294a10a986bb7a,055e4eaf80ae1609479b0d0d2f7f273920a00947..829c78de9ebac728919784951b89d05d7d942361
@@@ -262,7 -262,7 +262,7 @@@ static int geth_set_alt(struct usb_func
  
        /* we know alt == 0, so this is an activation or a reset */
  
 -      if (geth->port.in_ep->driver_data) {
 +      if (geth->port.in_ep->enabled) {
                DBG(cdev, "reset cdc subset\n");
                gether_disconnect(&geth->port);
        }
@@@ -343,11 -343,13 +343,11 @@@ geth_bind(struct usb_configuration *c, 
        if (!ep)
                goto fail;
        geth->port.in_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
        if (!ep)
                goto fail;
        geth->port.out_ep = ep;
 -      ep->driver_data = cdev; /* claim */
  
        /* support all relevant hardware speeds... we expect that when
         * hardware is dual speed, all bulk-capable endpoints work at
        return 0;
  
  fail:
 -      /* we might as well release our claims on endpoints */
 -      if (geth->port.out_ep)
 -              geth->port.out_ep->driver_data = NULL;
 -      if (geth->port.in_ep)
 -              geth->port.in_ep->driver_data = NULL;
 -
        ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
  
        return status;
@@@ -405,10 -413,10 +405,10 @@@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(g
  USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(gether);
  
  static struct configfs_attribute *gether_attrs[] = {
-       &f_gether_opts_dev_addr.attr,
-       &f_gether_opts_host_addr.attr,
-       &f_gether_opts_qmult.attr,
-       &f_gether_opts_ifname.attr,
+       &gether_opts_attr_dev_addr,
+       &gether_opts_attr_host_addr,
+       &gether_opts_attr_qmult,
+       &gether_opts_attr_ifname,
        NULL,
  };
  
index 8ee701924d29d0c5ad27edfed1b3e23c15b5c3e7,ad0103254e6d6341f935c214ce42f56edd5f2b73..6a2346b99f5591911f92200d68e880ff3b2e5d18
@@@ -593,6 -593,7 +593,6 @@@ static int f_audio_set_alt(struct usb_f
                                return err;
  
                        usb_ep_enable(out_ep);
 -                      out_ep->driver_data = audio;
                        audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
                        if (IS_ERR(audio->copy_buf))
                                return -ENOMEM;
@@@ -717,6 -718,7 +717,6 @@@ f_audio_bind(struct usb_configuration *
                goto fail;
        audio->out_ep = ep;
        audio->out_ep->desc = &as_out_ep_desc;
 -      ep->driver_data = cdev; /* claim */
  
        status = -ENOMEM;
  
  
  fail:
        gaudio_cleanup(&audio->card);
 -      if (ep)
 -              ep->driver_data = NULL;
        return status;
  }
  
@@@ -769,9 -773,6 +769,6 @@@ static inline struct f_uac1_opts *to_f_
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_uac1_opts);
- CONFIGFS_ATTR_OPS(f_uac1_opts);
  static void f_uac1_attr_release(struct config_item *item)
  {
        struct f_uac1_opts *opts = to_f_uac1_opts(item);
  
  static struct configfs_item_operations f_uac1_item_ops = {
        .release        = f_uac1_attr_release,
-       .show_attribute = f_uac1_opts_attr_show,
-       .store_attribute = f_uac1_opts_attr_store,
  };
  
  #define UAC1_INT_ATTRIBUTE(name)                                      \
- static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts,    \
+ static ssize_t f_uac1_opts_##name##_show(struct config_item *item,    \
                                         char *page)                    \
  {                                                                     \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
        return result;                                                  \
  }                                                                     \
                                                                        \
- static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts,   \
+ static ssize_t f_uac1_opts_##name##_store(struct config_item *item,           \
                                          const char *page, size_t len) \
  {                                                                     \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int ret;                                                        \
        u32 num;                                                        \
                                                                        \
@@@ -822,19 -823,17 +819,17 @@@ end:                                                                    
        return ret;                                                     \
  }                                                                     \
                                                                        \
- static struct f_uac1_opts_attribute f_uac1_opts_##name =              \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR,                        \
-                       f_uac1_opts_##name##_show,                      \
-                       f_uac1_opts_##name##_store)
+ CONFIGFS_ATTR(f_uac1_opts_, name)
  
  UAC1_INT_ATTRIBUTE(req_buf_size);
  UAC1_INT_ATTRIBUTE(req_count);
  UAC1_INT_ATTRIBUTE(audio_buf_size);
  
  #define UAC1_STR_ATTRIBUTE(name)                                      \
- static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts,    \
+ static ssize_t f_uac1_opts_##name##_show(struct config_item *item,    \
                                         char *page)                    \
  {                                                                     \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
        return result;                                                  \
  }                                                                     \
                                                                        \
- static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts,   \
+ static ssize_t f_uac1_opts_##name##_store(struct config_item *item,   \
                                          const char *page, size_t len) \
  {                                                                     \
+       struct f_uac1_opts *opts = to_f_uac1_opts(item);                \
        int ret = -EBUSY;                                               \
        char *tmp;                                                      \
                                                                        \
@@@ -870,22 -870,19 +866,19 @@@ end:                                                                    
        return ret;                                                     \
  }                                                                     \
                                                                        \
- static struct f_uac1_opts_attribute f_uac1_opts_##name =              \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR,                        \
-                       f_uac1_opts_##name##_show,                      \
-                       f_uac1_opts_##name##_store)
+ CONFIGFS_ATTR(f_uac1_opts_, name)
  
  UAC1_STR_ATTRIBUTE(fn_play);
  UAC1_STR_ATTRIBUTE(fn_cap);
  UAC1_STR_ATTRIBUTE(fn_cntl);
  
  static struct configfs_attribute *f_uac1_attrs[] = {
-       &f_uac1_opts_req_buf_size.attr,
-       &f_uac1_opts_req_count.attr,
-       &f_uac1_opts_audio_buf_size.attr,
-       &f_uac1_opts_fn_play.attr,
-       &f_uac1_opts_fn_cap.attr,
-       &f_uac1_opts_fn_cntl.attr,
+       &f_uac1_opts_attr_req_buf_size,
+       &f_uac1_opts_attr_req_count,
+       &f_uac1_opts_attr_audio_buf_size,
+       &f_uac1_opts_attr_fn_play,
+       &f_uac1_opts_attr_fn_cap,
+       &f_uac1_opts_attr_fn_cntl,
        NULL,
  };
  
index 63336e269898d07ac42c2ab66117c9aaed2ae142,0a5a1e1aac28f8caff7b5e02da63624dffaf2be4..044ca79d3cb5d3b8a4764e27c1a1749caa43c971
@@@ -1081,12 -1081,14 +1081,12 @@@ afunc_bind(struct usb_configuration *cf
                dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
                goto err;
        }
 -      agdev->out_ep->driver_data = agdev;
  
        agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
        if (!agdev->in_ep) {
                dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
                goto err;
        }
 -      agdev->in_ep->driver_data = agdev;
  
        uac2->p_prm.uac2 = uac2;
        uac2->c_prm.uac2 = uac2;
@@@ -1130,6 -1132,10 +1130,6 @@@ err_free_descs
  err:
        kfree(agdev->uac2.p_prm.rbuf);
        kfree(agdev->uac2.c_prm.rbuf);
 -      if (agdev->in_ep)
 -              agdev->in_ep->driver_data = NULL;
 -      if (agdev->out_ep)
 -              agdev->out_ep->driver_data = NULL;
        return -EINVAL;
  }
  
@@@ -1439,9 -1445,6 +1439,6 @@@ static inline struct f_uac2_opts *to_f_
                            func_inst.group);
  }
  
- CONFIGFS_ATTR_STRUCT(f_uac2_opts);
- CONFIGFS_ATTR_OPS(f_uac2_opts);
  static void f_uac2_attr_release(struct config_item *item)
  {
        struct f_uac2_opts *opts = to_f_uac2_opts(item);
  
  static struct configfs_item_operations f_uac2_item_ops = {
        .release        = f_uac2_attr_release,
-       .show_attribute = f_uac2_opts_attr_show,
-       .store_attribute = f_uac2_opts_attr_store,
  };
  
  #define UAC2_ATTRIBUTE(name)                                          \
- static ssize_t f_uac2_opts_##name##_show(struct f_uac2_opts *opts,    \
+ static ssize_t f_uac2_opts_##name##_show(struct config_item *item,    \
                                         char *page)                    \
  {                                                                     \
+       struct f_uac2_opts *opts = to_f_uac2_opts(item);                \
        int result;                                                     \
                                                                        \
        mutex_lock(&opts->lock);                                        \
        return result;                                                  \
  }                                                                     \
                                                                        \
- static ssize_t f_uac2_opts_##name##_store(struct f_uac2_opts *opts,   \
+ static ssize_t f_uac2_opts_##name##_store(struct config_item *item,   \
                                          const char *page, size_t len) \
  {                                                                     \
+       struct f_uac2_opts *opts = to_f_uac2_opts(item);                \
        int ret;                                                        \
        u32 num;                                                        \
                                                                        \
@@@ -1492,10 -1495,7 +1489,7 @@@ end:                                                                   
        return ret;                                                     \
  }                                                                     \
                                                                        \
- static struct f_uac2_opts_attribute f_uac2_opts_##name =              \
-       __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR,                        \
-                       f_uac2_opts_##name##_show,                      \
-                       f_uac2_opts_##name##_store)
+ CONFIGFS_ATTR(f_uac2_opts_, name)
  
  UAC2_ATTRIBUTE(p_chmask);
  UAC2_ATTRIBUTE(p_srate);
@@@ -1505,12 -1505,12 +1499,12 @@@ UAC2_ATTRIBUTE(c_srate)
  UAC2_ATTRIBUTE(c_ssize);
  
  static struct configfs_attribute *f_uac2_attrs[] = {
-       &f_uac2_opts_p_chmask.attr,
-       &f_uac2_opts_p_srate.attr,
-       &f_uac2_opts_p_ssize.attr,
-       &f_uac2_opts_c_chmask.attr,
-       &f_uac2_opts_c_srate.attr,
-       &f_uac2_opts_c_ssize.attr,
+       &f_uac2_opts_attr_p_chmask,
+       &f_uac2_opts_attr_p_srate,
+       &f_uac2_opts_attr_p_ssize,
+       &f_uac2_opts_attr_c_chmask,
+       &f_uac2_opts_attr_c_srate,
+       &f_uac2_opts_attr_c_ssize,
        NULL,
  };
  
@@@ -1577,6 -1577,11 +1571,6 @@@ static void afunc_unbind(struct usb_con
        prm = &agdev->uac2.c_prm;
        kfree(prm->rbuf);
        usb_free_all_descriptors(f);
 -
 -      if (agdev->in_ep)
 -              agdev->in_ep->driver_data = NULL;
 -      if (agdev->out_ep)
 -              agdev->out_ep->driver_data = NULL;
  }
  
  static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
index 778e42abb3cb8703fcf19b829e21f764ac798d1e,33833fe2e163122f912d62a0022c6a45f927791a..22e56158d5850236242375d036f70250b676dac7
@@@ -19,8 -19,6 +19,6 @@@
  #include <scsi/scsi_tcq.h>
  #include <target/target_core_base.h>
  #include <target/target_core_fabric.h>
- #include <target/target_core_fabric_configfs.h>
- #include <target/configfs_macros.h>
  #include <asm/unaligned.h>
  
  #include "tcm_usb_gadget.h"
@@@ -1467,23 -1465,21 +1465,21 @@@ static void usbg_drop_tport(struct se_w
  /*
   * If somebody feels like dropping the version property, go ahead.
   */
- static ssize_t usbg_wwn_show_attr_version(
-       struct target_fabric_configfs *tf,
-       char *page)
+ static ssize_t usbg_wwn_version_show(struct config_item *item, char *page)
  {
        return sprintf(page, "usb-gadget fabric module\n");
  }
- TF_WWN_ATTR_RO(usbg, version);
+ CONFIGFS_ATTR_RO(usbg_wwn_, version);
  
  static struct configfs_attribute *usbg_wwn_attrs[] = {
-       &usbg_wwn_version.attr,
+       &usbg_wwn_attr_version,
        NULL,
  };
  
- static ssize_t tcm_usbg_tpg_show_enable(
-               struct se_portal_group *se_tpg,
-               char *page)
+ static ssize_t tcm_usbg_tpg_enable_show(struct config_item *item, char *page)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
  
        return snprintf(page, PAGE_SIZE, "%u\n", tpg->gadget_connect);
  static int usbg_attach(struct usbg_tpg *);
  static void usbg_detach(struct usbg_tpg *);
  
- static ssize_t tcm_usbg_tpg_store_enable(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+ static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item,
+               const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg  *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
        unsigned long op;
        ssize_t ret;
  out:
        return count;
  }
- TF_TPG_BASE_ATTR(tcm_usbg, enable, S_IRUGO | S_IWUSR);
  
- static ssize_t tcm_usbg_tpg_show_nexus(
-               struct se_portal_group *se_tpg,
-               char *page)
+ static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
        struct tcm_usbg_nexus *tv_nexus;
        ssize_t ret;
        return ret;
  }
  
- static ssize_t tcm_usbg_tpg_store_nexus(
-               struct se_portal_group *se_tpg,
-               const char *page,
-               size_t count)
+ static ssize_t tcm_usbg_tpg_nexus_store(struct config_item *item,
+               const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
        unsigned char i_port[USBG_NAMELEN], *ptr;
        int ret;
                return ret;
        return count;
  }
- TF_TPG_BASE_ATTR(tcm_usbg, nexus, S_IRUGO | S_IWUSR);
+ CONFIGFS_ATTR(tcm_usbg_tpg_, enable);
+ CONFIGFS_ATTR(tcm_usbg_tpg_, nexus);
  
  static struct configfs_attribute *usbg_base_attrs[] = {
-       &tcm_usbg_tpg_enable.attr,
-       &tcm_usbg_tpg_nexus.attr,
+       &tcm_usbg_tpg_attr_enable,
+       &tcm_usbg_tpg_attr_nexus,
        NULL,
  };
  
@@@ -2018,6 -2012,14 +2012,6 @@@ static struct usb_configuration usbg_co
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
  };
  
 -static void give_back_ep(struct usb_ep **pep)
 -{
 -      struct usb_ep *ep = *pep;
 -      if (!ep)
 -              return;
 -      ep->driver_data = NULL;
 -}
 -
  static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
  {
        struct f_uas            *fu = to_f_uas(f);
                        &uasp_bi_ep_comp_desc);
        if (!ep)
                goto ep_fail;
 -
 -      ep->driver_data = fu;
        fu->ep_in = ep;
  
        ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc,
                        &uasp_bo_ep_comp_desc);
        if (!ep)
                goto ep_fail;
 -      ep->driver_data = fu;
        fu->ep_out = ep;
  
        ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc,
                        &uasp_status_in_ep_comp_desc);
        if (!ep)
                goto ep_fail;
 -      ep->driver_data = fu;
        fu->ep_status = ep;
  
        ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc,
                        &uasp_cmd_comp_desc);
        if (!ep)
                goto ep_fail;
 -      ep->driver_data = fu;
        fu->ep_cmd = ep;
  
        /* Assume endpoint addresses are the same for both speeds */
        return 0;
  ep_fail:
        pr_err("Can't claim all required eps\n");
 -
 -      give_back_ep(&fu->ep_in);
 -      give_back_ep(&fu->ep_out);
 -      give_back_ep(&fu->ep_status);
 -      give_back_ep(&fu->ep_cmd);
        return -ENOTSUPP;
  }
  
diff --combined drivers/vhost/scsi.c
index e25a23692822c16ce26f7a2b9b9f7f96153a6563,a971765eb9f2004d7b8680b3c89eb520d5ae8967..29cfc57d496e9497ebcf7bd5c5bd07a083bd91dc
@@@ -42,8 -42,6 +42,6 @@@
  #include <scsi/scsi_proto.h>
  #include <target/target_core_base.h>
  #include <target/target_core_fabric.h>
- #include <target/target_core_fabric_configfs.h>
- #include <target/configfs_macros.h>
  #include <linux/vhost.h>
  #include <linux/virtio_scsi.h>
  #include <linux/llist.h>
@@@ -166,7 -164,9 +164,7 @@@ enum 
  /* Note: can't set VIRTIO_F_VERSION_1 yet, since that implies ANY_LAYOUT. */
  enum {
        VHOST_SCSI_FEATURES = VHOST_FEATURES | (1ULL << VIRTIO_SCSI_F_HOTPLUG) |
 -                                             (1ULL << VIRTIO_SCSI_F_T10_PI) |
 -                                             (1ULL << VIRTIO_F_ANY_LAYOUT) |
 -                                             (1ULL << VIRTIO_F_VERSION_1)
 +                                             (1ULL << VIRTIO_SCSI_F_T10_PI)
  };
  
  #define VHOST_SCSI_MAX_TARGET 256
@@@ -1684,11 -1684,10 +1682,10 @@@ static void vhost_scsi_free_cmd_map_res
        }
  }
  
- static ssize_t vhost_scsi_tpg_attrib_store_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       const char *page,
-       size_t count)
+ static ssize_t vhost_scsi_tpg_attrib_fabric_prot_type_store(
+               struct config_item *item, const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
        unsigned long val;
        return count;
  }
  
- static ssize_t vhost_scsi_tpg_attrib_show_fabric_prot_type(
-       struct se_portal_group *se_tpg,
-       char *page)
+ static ssize_t vhost_scsi_tpg_attrib_fabric_prot_type_show(
+               struct config_item *item, char *page)
  {
+       struct se_portal_group *se_tpg = attrib_to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
  
        return sprintf(page, "%d\n", tpg->tv_fabric_prot_type);
  }
- TF_TPG_ATTRIB_ATTR(vhost_scsi, fabric_prot_type, S_IRUGO | S_IWUSR);
+ CONFIGFS_ATTR(vhost_scsi_tpg_attrib_, fabric_prot_type);
  
  static struct configfs_attribute *vhost_scsi_tpg_attrib_attrs[] = {
-       &vhost_scsi_tpg_attrib_fabric_prot_type.attr,
+       &vhost_scsi_tpg_attrib_attr_fabric_prot_type,
        NULL,
  };
  
@@@ -1867,9 -1867,9 +1865,9 @@@ static int vhost_scsi_drop_nexus(struc
        return 0;
  }
  
- static ssize_t vhost_scsi_tpg_show_nexus(struct se_portal_group *se_tpg,
-                                       char *page)
+ static ssize_t vhost_scsi_tpg_nexus_show(struct config_item *item, char *page)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
        struct vhost_scsi_nexus *tv_nexus;
        return ret;
  }
  
- static ssize_t vhost_scsi_tpg_store_nexus(struct se_portal_group *se_tpg,
-                                        const char *page,
-                                        size_t count)
+ static ssize_t vhost_scsi_tpg_nexus_store(struct config_item *item,
+               const char *page, size_t count)
  {
+       struct se_portal_group *se_tpg = to_tpg(item);
        struct vhost_scsi_tpg *tpg = container_of(se_tpg,
                                struct vhost_scsi_tpg, se_tpg);
        struct vhost_scsi_tport *tport_wwn = tpg->tport;
@@@ -1966,10 -1966,10 +1964,10 @@@ check_newline
        return count;
  }
  
TF_TPG_BASE_ATTR(vhost_scsi, nexus, S_IRUGO | S_IWUSR);
CONFIGFS_ATTR(vhost_scsi_tpg_, nexus);
  
  static struct configfs_attribute *vhost_scsi_tpg_attrs[] = {
-       &vhost_scsi_tpg_nexus.attr,
+       &vhost_scsi_tpg_attr_nexus,
        NULL,
  };
  
@@@ -2105,18 -2105,17 +2103,17 @@@ static void vhost_scsi_drop_tport(struc
  }
  
  static ssize_t
- vhost_scsi_wwn_show_attr_version(struct target_fabric_configfs *tf,
-                               char *page)
+ vhost_scsi_wwn_version_show(struct config_item *item, char *page)
  {
        return sprintf(page, "TCM_VHOST fabric module %s on %s/%s"
                "on "UTS_RELEASE"\n", VHOST_SCSI_VERSION, utsname()->sysname,
                utsname()->machine);
  }
  
TF_WWN_ATTR_RO(vhost_scsi, version);
CONFIGFS_ATTR_RO(vhost_scsi_wwn_, version);
  
  static struct configfs_attribute *vhost_scsi_wwn_attrs[] = {
-       &vhost_scsi_wwn_version.attr,
+       &vhost_scsi_wwn_attr_version,
        NULL,
  };
  
index ddddef0021a0f8cd94f456969099bc660ec1fdb5,e404386bd93e8535a32152fcc5936ede9ac5fa41..709fbbd44c65366ce1e31aebce0904b5966d53a6
@@@ -219,8 -219,7 +219,8 @@@ struct o2hb_region 
        unsigned                hr_unclean_stop:1,
                                hr_aborted_start:1,
                                hr_item_pinned:1,
 -                              hr_item_dropped:1;
 +                              hr_item_dropped:1,
 +                              hr_node_deleted:1;
  
        /* protected by the hr_callback_sem */
        struct task_struct      *hr_task;
@@@ -1079,13 -1078,7 +1079,13 @@@ static int o2hb_thread(void *data
        set_user_nice(current, MIN_NICE);
  
        /* Pin node */
 -      o2nm_depend_this_node();
 +      ret = o2nm_depend_this_node();
 +      if (ret) {
 +              mlog(ML_ERROR, "Node has been deleted, ret = %d\n", ret);
 +              reg->hr_node_deleted = 1;
 +              wake_up(&o2hb_steady_queue);
 +              return 0;
 +      }
  
        while (!kthread_should_stop() &&
               !reg->hr_unclean_stop && !reg->hr_aborted_start) {
@@@ -1480,16 -1473,17 +1480,17 @@@ static int o2hb_read_block_input(struc
        return 0;
  }
  
- static ssize_t o2hb_region_block_bytes_read(struct o2hb_region *reg,
+ static ssize_t o2hb_region_block_bytes_show(struct config_item *item,
                                            char *page)
  {
-       return sprintf(page, "%u\n", reg->hr_block_bytes);
+       return sprintf(page, "%u\n", to_o2hb_region(item)->hr_block_bytes);
  }
  
- static ssize_t o2hb_region_block_bytes_write(struct o2hb_region *reg,
+ static ssize_t o2hb_region_block_bytes_store(struct config_item *item,
                                             const char *page,
                                             size_t count)
  {
+       struct o2hb_region *reg = to_o2hb_region(item);
        int status;
        unsigned long block_bytes;
        unsigned int block_bits;
        return count;
  }
  
- static ssize_t o2hb_region_start_block_read(struct o2hb_region *reg,
+ static ssize_t o2hb_region_start_block_show(struct config_item *item,
                                            char *page)
  {
-       return sprintf(page, "%llu\n", reg->hr_start_block);
+       return sprintf(page, "%llu\n", to_o2hb_region(item)->hr_start_block);
  }
  
- static ssize_t o2hb_region_start_block_write(struct o2hb_region *reg,
+ static ssize_t o2hb_region_start_block_store(struct config_item *item,
                                             const char *page,
                                             size_t count)
  {
+       struct o2hb_region *reg = to_o2hb_region(item);
        unsigned long long tmp;
        char *p = (char *)page;
  
        return count;
  }
  
- static ssize_t o2hb_region_blocks_read(struct o2hb_region *reg,
-                                      char *page)
+ static ssize_t o2hb_region_blocks_show(struct config_item *item, char *page)
  {
-       return sprintf(page, "%d\n", reg->hr_blocks);
+       return sprintf(page, "%d\n", to_o2hb_region(item)->hr_blocks);
  }
  
- static ssize_t o2hb_region_blocks_write(struct o2hb_region *reg,
+ static ssize_t o2hb_region_blocks_store(struct config_item *item,
                                        const char *page,
                                        size_t count)
  {
+       struct o2hb_region *reg = to_o2hb_region(item);
        unsigned long tmp;
        char *p = (char *)page;
  
        return count;
  }
  
- static ssize_t o2hb_region_dev_read(struct o2hb_region *reg,
-                                   char *page)
+ static ssize_t o2hb_region_dev_show(struct config_item *item, char *page)
  {
        unsigned int ret = 0;
  
-       if (reg->hr_bdev)
-               ret = sprintf(page, "%s\n", reg->hr_dev_name);
+       if (to_o2hb_region(item)->hr_bdev)
+               ret = sprintf(page, "%s\n", to_o2hb_region(item)->hr_dev_name);
  
        return ret;
  }
  }
  
  /* this is acting as commit; we set up all of hr_bdev and hr_task or nothing */
- static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
+ static ssize_t o2hb_region_dev_store(struct config_item *item,
                                     const char *page,
                                     size_t count)
  {
+       struct o2hb_region *reg = to_o2hb_region(item);
        struct task_struct *hb_task;
        long fd;
        int sectsize;
        spin_unlock(&o2hb_live_lock);
  
        ret = wait_event_interruptible(o2hb_steady_queue,
 -                              atomic_read(&reg->hr_steady_iterations) == 0);
 +                              atomic_read(&reg->hr_steady_iterations) == 0 ||
 +                              reg->hr_node_deleted);
        if (ret) {
                atomic_set(&reg->hr_steady_iterations, 0);
                reg->hr_aborted_start = 1;
                goto out3;
        }
  
 +      if (reg->hr_node_deleted) {
 +              ret = -EINVAL;
 +              goto out3;
 +      }
 +
        /* Ok, we were woken.  Make sure it wasn't by drop_item() */
        spin_lock(&o2hb_live_lock);
        hb_task = reg->hr_task;
@@@ -1841,9 -1830,9 +1843,9 @@@ out
        return ret;
  }
  
- static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
-                                       char *page)
+ static ssize_t o2hb_region_pid_show(struct config_item *item, char *page)
  {
+       struct o2hb_region *reg = to_o2hb_region(item);
        pid_t pid = 0;
  
        spin_lock(&o2hb_live_lock);
        return sprintf(page, "%u\n", pid);
  }
  
- struct o2hb_region_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct o2hb_region *, char *);
-       ssize_t (*store)(struct o2hb_region *, const char *, size_t);
- };
- static struct o2hb_region_attribute o2hb_region_attr_block_bytes = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "block_bytes",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_block_bytes_read,
-       .store  = o2hb_region_block_bytes_write,
- };
- static struct o2hb_region_attribute o2hb_region_attr_start_block = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "start_block",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_start_block_read,
-       .store  = o2hb_region_start_block_write,
- };
- static struct o2hb_region_attribute o2hb_region_attr_blocks = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "blocks",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_blocks_read,
-       .store  = o2hb_region_blocks_write,
- };
- static struct o2hb_region_attribute o2hb_region_attr_dev = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "dev",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_region_dev_read,
-       .store  = o2hb_region_dev_write,
- };
- static struct o2hb_region_attribute o2hb_region_attr_pid = {
-        .attr   = { .ca_owner = THIS_MODULE,
-                    .ca_name = "pid",
-                    .ca_mode = S_IRUGO | S_IRUSR },
-        .show   = o2hb_region_pid_read,
- };
+ CONFIGFS_ATTR(o2hb_region_, block_bytes);
+ CONFIGFS_ATTR(o2hb_region_, start_block);
+ CONFIGFS_ATTR(o2hb_region_, blocks);
+ CONFIGFS_ATTR(o2hb_region_, dev);
+ CONFIGFS_ATTR_RO(o2hb_region_, pid);
  
  static struct configfs_attribute *o2hb_region_attrs[] = {
-       &o2hb_region_attr_block_bytes.attr,
-       &o2hb_region_attr_start_block.attr,
-       &o2hb_region_attr_blocks.attr,
-       &o2hb_region_attr_dev.attr,
-       &o2hb_region_attr_pid.attr,
+       &o2hb_region_attr_block_bytes,
+       &o2hb_region_attr_start_block,
+       &o2hb_region_attr_blocks,
+       &o2hb_region_attr_dev,
+       &o2hb_region_attr_pid,
        NULL,
  };
  
- static ssize_t o2hb_region_show(struct config_item *item,
-                               struct configfs_attribute *attr,
-                               char *page)
- {
-       struct o2hb_region *reg = to_o2hb_region(item);
-       struct o2hb_region_attribute *o2hb_region_attr =
-               container_of(attr, struct o2hb_region_attribute, attr);
-       ssize_t ret = 0;
-       if (o2hb_region_attr->show)
-               ret = o2hb_region_attr->show(reg, page);
-       return ret;
- }
- static ssize_t o2hb_region_store(struct config_item *item,
-                                struct configfs_attribute *attr,
-                                const char *page, size_t count)
- {
-       struct o2hb_region *reg = to_o2hb_region(item);
-       struct o2hb_region_attribute *o2hb_region_attr =
-               container_of(attr, struct o2hb_region_attribute, attr);
-       ssize_t ret = -EINVAL;
-       if (o2hb_region_attr->store)
-               ret = o2hb_region_attr->store(reg, page, count);
-       return ret;
- }
  static struct configfs_item_operations o2hb_region_item_ops = {
        .release                = o2hb_region_release,
-       .show_attribute         = o2hb_region_show,
-       .store_attribute        = o2hb_region_store,
  };
  
  static struct config_item_type o2hb_region_type = {
@@@ -2137,49 -2057,14 +2070,14 @@@ unlock
        spin_unlock(&o2hb_live_lock);
  }
  
- struct o2hb_heartbeat_group_attribute {
-       struct configfs_attribute attr;
-       ssize_t (*show)(struct o2hb_heartbeat_group *, char *);
-       ssize_t (*store)(struct o2hb_heartbeat_group *, const char *, size_t);
- };
- static ssize_t o2hb_heartbeat_group_show(struct config_item *item,
-                                        struct configfs_attribute *attr,
-                                        char *page)
- {
-       struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));
-       struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =
-               container_of(attr, struct o2hb_heartbeat_group_attribute, attr);
-       ssize_t ret = 0;
-       if (o2hb_heartbeat_group_attr->show)
-               ret = o2hb_heartbeat_group_attr->show(reg, page);
-       return ret;
- }
- static ssize_t o2hb_heartbeat_group_store(struct config_item *item,
-                                         struct configfs_attribute *attr,
-                                         const char *page, size_t count)
- {
-       struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));
-       struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =
-               container_of(attr, struct o2hb_heartbeat_group_attribute, attr);
-       ssize_t ret = -EINVAL;
-       if (o2hb_heartbeat_group_attr->store)
-               ret = o2hb_heartbeat_group_attr->store(reg, page, count);
-       return ret;
- }
- static ssize_t o2hb_heartbeat_group_threshold_show(struct o2hb_heartbeat_group *group,
-                                                    char *page)
+ static ssize_t o2hb_heartbeat_group_threshold_show(struct config_item *item,
+               char *page)
  {
        return sprintf(page, "%u\n", o2hb_dead_threshold);
  }
  
- static ssize_t o2hb_heartbeat_group_threshold_store(struct o2hb_heartbeat_group *group,
-                                                   const char *page,
-                                                   size_t count)
+ static ssize_t o2hb_heartbeat_group_threshold_store(struct config_item *item,
+               const char *page, size_t count)
  {
        unsigned long tmp;
        char *p = (char *)page;
        return count;
  }
  
- static
- ssize_t o2hb_heartbeat_group_mode_show(struct o2hb_heartbeat_group *group,
-                                      char *page)
+ static ssize_t o2hb_heartbeat_group_mode_show(struct config_item *item,
+               char *page)
  {
        return sprintf(page, "%s\n",
                       o2hb_heartbeat_mode_desc[o2hb_heartbeat_mode]);
  }
  
- static
- ssize_t o2hb_heartbeat_group_mode_store(struct o2hb_heartbeat_group *group,
-                                       const char *page, size_t count)
+ static ssize_t o2hb_heartbeat_group_mode_store(struct config_item *item,
+               const char *page, size_t count)
  {
        unsigned int i;
        int ret;
  
  }
  
- static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_threshold = {
-       .attr   = { .ca_owner = THIS_MODULE,
-                   .ca_name = "dead_threshold",
-                   .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_heartbeat_group_threshold_show,
-       .store  = o2hb_heartbeat_group_threshold_store,
- };
- static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_mode = {
-       .attr   = { .ca_owner = THIS_MODULE,
-               .ca_name = "mode",
-               .ca_mode = S_IRUGO | S_IWUSR },
-       .show   = o2hb_heartbeat_group_mode_show,
-       .store  = o2hb_heartbeat_group_mode_store,
- };
+ CONFIGFS_ATTR(o2hb_heartbeat_group_, threshold);
+ CONFIGFS_ATTR(o2hb_heartbeat_group_, mode);
  
  static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = {
-       &o2hb_heartbeat_group_attr_threshold.attr,
-       &o2hb_heartbeat_group_attr_mode.attr,
+       &o2hb_heartbeat_group_attr_threshold,
+       &o2hb_heartbeat_group_attr_mode,
        NULL,
  };
  
- static struct configfs_item_operations o2hb_heartbeat_group_item_ops = {
-       .show_attribute         = o2hb_heartbeat_group_show,
-       .store_attribute        = o2hb_heartbeat_group_store,
- };
  static struct configfs_group_operations o2hb_heartbeat_group_group_ops = {
        .make_item      = o2hb_heartbeat_group_make_item,
        .drop_item      = o2hb_heartbeat_group_drop_item,
  
  static struct config_item_type o2hb_heartbeat_group_type = {
        .ct_group_ops   = &o2hb_heartbeat_group_group_ops,
-       .ct_item_ops    = &o2hb_heartbeat_group_item_ops,
        .ct_attrs       = o2hb_heartbeat_group_attrs,
        .ct_owner       = THIS_MODULE,
  };
index 5f48754dc36ae0e15e06527c0cb63dc29324721e,8b9c727b533bfa69bf2239fd65c3bc70629e29e9..0a2c74008e5388f6d817272735882f40abc3a013
@@@ -563,6 -563,36 +563,36 @@@ struct se_node_acl 
        struct kref             acl_kref;
  };
  
+ static inline struct se_node_acl *acl_to_nacl(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_group);
+ }
+ static inline struct se_node_acl *attrib_to_nacl(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_attrib_group);
+ }
+ static inline struct se_node_acl *auth_to_nacl(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_auth_group);
+ }
+ static inline struct se_node_acl *param_to_nacl(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_param_group);
+ }
+ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_node_acl,
+                       acl_fabric_stat_group);
+ }
  struct se_session {
        unsigned                sess_tearing_down:1;
        u64                     sess_bin_isid;
@@@ -730,7 -760,6 +760,7 @@@ struct se_device 
  #define DF_EMULATED_VPD_UNIT_SERIAL           0x00000004
  #define DF_USING_UDEV_PATH                    0x00000008
  #define DF_USING_ALIAS                                0x00000010
 +#define DF_READ_ONLY                          0x00000020
        /* Physical device queue depth */
        u32                     queue_depth;
        /* Used for SPC-2 reservations enforce of ISIDs */
@@@ -821,6 -850,12 +851,12 @@@ struct se_tpg_np 
        struct config_group     tpg_np_group;
  };
  
+ static inline struct se_tpg_np *to_tpg_np(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_tpg_np,
+                       tpg_np_group);
+ }
  struct se_portal_group {
        /*
         * PROTOCOL IDENTIFIER value per SPC4, 7.5.1.
        struct config_group     tpg_param_group;
  };
  
+ static inline struct se_portal_group *to_tpg(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_group);
+ }
+ static inline struct se_portal_group *attrib_to_tpg(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_attrib_group);
+ }
+ static inline struct se_portal_group *auth_to_tpg(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_auth_group);
+ }
+ static inline struct se_portal_group *param_to_tpg(struct config_item *item)
+ {
+       return container_of(to_config_group(item), struct se_portal_group,
+                       tpg_param_group);
+ }
  struct se_wwn {
        struct target_fabric_configfs *wwn_tf;
        struct config_group     wwn_group;
This page took 0.100804 seconds and 5 git commands to generate.