switch open-coded instances of d_make_root() to new helper
[linux-2.6.git] / drivers / usb / gadget / f_fs.c
index 474f2d9..d825b24 100644 (file)
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- *
- * This program is distributed in the hope that 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 
@@ -29,8 +20,8 @@
 
 #include <linux/blkdev.h>
 #include <linux/pagemap.h>
+#include <linux/export.h>
 #include <asm/unaligned.h>
-#include <linux/smp_lock.h>
 
 #include <linux/usb/composite.h>
 #include <linux/usb/functionfs.h>
 
 /* Debugging ****************************************************************/
 
-#define ffs_printk(level, fmt, args...) printk(level "f_fs: " fmt "\n", ## args)
-
-#define FERR(...)  ffs_printk(KERN_ERR,  __VA_ARGS__)
-#define FINFO(...) ffs_printk(KERN_INFO, __VA_ARGS__)
-
-#ifdef DEBUG
-#  define FDBG(...) ffs_printk(KERN_DEBUG, __VA_ARGS__)
-#else
-#  define FDBG(...) do { } while (0)
-#endif /* DEBUG */
-
-#ifdef VERBOSE_DEBUG
-#  define FVDBG FDBG
-#else
-#  define FVDBG(...) do { } while (0)
-#endif /* VERBOSE_DEBUG */
-
-#define ENTER()    FVDBG("%s()", __func__)
-
 #ifdef VERBOSE_DEBUG
+#  define pr_vdebug pr_debug
 #  define ffs_dump_mem(prefix, ptr, len) \
-       print_hex_dump_bytes("f_fs" prefix ": ", DUMP_PREFIX_NONE, ptr, len)
+       print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)
 #else
+#  define pr_vdebug(...)                 do { } while (0)
 #  define ffs_dump_mem(prefix, ptr, len) do { } while (0)
-#endif
+#endif /* VERBOSE_DEBUG */
+
+#define ENTER()    pr_vdebug("%s()\n", __func__)
 
 
 /* The data structure and setup file ****************************************/
@@ -384,6 +360,14 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len)
        req->buf      = data;
        req->length   = len;
 
+       /*
+        * UDC layer requires to provide a buffer even for ZLP, but should
+        * not use it at all. Let's provide some poisoned pointer to catch
+        * possible bug in the driver.
+        */
+       if (req->buf == NULL)
+               req->buf = (void *)0xDEADBABE;
+
        INIT_COMPLETION(ffs->ep0req_completion);
 
        ret = usb_ep_queue(ffs->gadget->ep0, req, GFP_ATOMIC);
@@ -403,12 +387,12 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len)
 static int __ffs_ep0_stall(struct ffs_data *ffs)
 {
        if (ffs->ev.can_stall) {
-               FVDBG("ep0 stall\n");
+               pr_vdebug("ep0 stall\n");
                usb_ep_set_halt(ffs->gadget->ep0);
                ffs->setup_state = FFS_NO_SETUP;
                return -EL2HLT;
        } else {
-               FDBG("bogus ep0 stall!\n");
+               pr_debug("bogus ep0 stall!\n");
                return -ESRCH;
        }
 }
@@ -442,14 +426,14 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
                }
 
                data = ffs_prepare_buffer(buf, len);
-               if (unlikely(IS_ERR(data))) {
+               if (IS_ERR(data)) {
                        ret = PTR_ERR(data);
                        break;
                }
 
                /* Handle data */
                if (ffs->state == FFS_READ_DESCRIPTORS) {
-                       FINFO("read descriptors");
+                       pr_info("read descriptors\n");
                        ret = __ffs_data_got_descs(ffs, data, len);
                        if (unlikely(ret < 0))
                                break;
@@ -457,7 +441,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
                        ffs->state = FFS_READ_STRINGS;
                        ret = len;
                } else {
-                       FINFO("read strings");
+                       pr_info("read strings\n");
                        ret = __ffs_data_got_strings(ffs, data, len);
                        if (unlikely(ret < 0))
                                break;
@@ -515,7 +499,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
                spin_unlock_irq(&ffs->ev.waitq.lock);
 
                data = ffs_prepare_buffer(buf, len);
-               if (unlikely(IS_ERR(data))) {
+               if (IS_ERR(data)) {
                        ret = PTR_ERR(data);
                        break;
                }
@@ -1053,7 +1037,6 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
 {
        struct ffs_sb_fill_data *data = _data;
        struct inode    *inode;
-       struct dentry   *d;
        struct ffs_data *ffs;
 
        ENTER();
@@ -1061,7 +1044,7 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
        /* Initialise data */
        ffs = ffs_data_new();
        if (unlikely(!ffs))
-               goto enomem0;
+               goto Enomem;
 
        ffs->sb              = sb;
        ffs->dev_name        = data->dev_name;
@@ -1080,27 +1063,18 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
                                  &simple_dir_operations,
                                  &simple_dir_inode_operations,
                                  &data->perms);
-       if (unlikely(!inode))
-               goto enomem1;
-       d = d_alloc_root(inode);
-       if (unlikely(!d))
-               goto enomem2;
-       sb->s_root = d;
+       sb->s_root = d_make_root(inode);
+       if (unlikely(!sb->s_root))
+               goto Enomem;
 
        /* EP0 file */
        if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs,
                                         &ffs_ep0_operations, NULL)))
-               goto enomem3;
+               goto Enomem;
 
        return 0;
 
-enomem3:
-       dput(d);
-enomem2:
-       iput(inode);
-enomem1:
-       ffs_data_put(ffs);
-enomem0:
+Enomem:
        return -ENOMEM;
 }
 
@@ -1123,7 +1097,7 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts)
                /* Value limit */
                eq = strchr(opts, '=');
                if (unlikely(!eq)) {
-                       FERR("'=' missing in %s", opts);
+                       pr_err("'=' missing in %s\n", opts);
                        return -EINVAL;
                }
                *eq = 0;
@@ -1131,7 +1105,7 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts)
                /* Parse value */
                value = simple_strtoul(eq + 1, &end, 0);
                if (unlikely(*end != ',' && *end != 0)) {
-                       FERR("%s: invalid value: %s", opts, eq + 1);
+                       pr_err("%s: invalid value: %s\n", opts, eq + 1);
                        return -EINVAL;
                }
 
@@ -1166,7 +1140,7 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts)
 
                default:
 invalid:
-                       FERR("%s: invalid option", opts);
+                       pr_err("%s: invalid option\n", opts);
                        return -EINVAL;
                }
 
@@ -1212,14 +1186,11 @@ ffs_fs_mount(struct file_system_type *t, int flags,
 static void
 ffs_fs_kill_sb(struct super_block *sb)
 {
-       void *ptr;
-
        ENTER();
 
        kill_litter_super(sb);
-       ptr = xchg(&sb->s_fs_info, NULL);
-       if (ptr)
-               ffs_data_put(ptr);
+       if (sb->s_fs_info)
+               ffs_data_put(sb->s_fs_info);
 }
 
 static struct file_system_type ffs_fs_type = {
@@ -1240,9 +1211,9 @@ static int functionfs_init(void)
 
        ret = register_filesystem(&ffs_fs_type);
        if (likely(!ret))
-               FINFO("file system registered");
+               pr_info("file system registered\n");
        else
-               FERR("failed registering file system (%d)", ret);
+               pr_err("failed registering file system (%d)\n", ret);
 
        return ret;
 }
@@ -1251,7 +1222,7 @@ static void functionfs_cleanup(void)
 {
        ENTER();
 
-       FINFO("unloading");
+       pr_info("unloading\n");
        unregister_filesystem(&ffs_fs_type);
 }
 
@@ -1281,7 +1252,7 @@ static void ffs_data_put(struct ffs_data *ffs)
        ENTER();
 
        if (unlikely(atomic_dec_and_test(&ffs->ref))) {
-               FINFO("%s(): freeing", __func__);
+               pr_info("%s(): freeing\n", __func__);
                ffs_data_clear(ffs);
                BUG_ON(mutex_is_locked(&ffs->mutex) ||
                       spin_is_locked(&ffs->ev.waitq.lock) ||
@@ -1424,7 +1395,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
        ENTER();
 
        count = ffs->eps_count;
-       epfiles = kzalloc(count * sizeof *epfiles, GFP_KERNEL);
+       epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL);
        if (!epfiles)
                return -ENOMEM;
 
@@ -1552,7 +1523,8 @@ static int ffs_func_eps_enable(struct ffs_function *func)
                ds = ep->descs[ep->descs[1] ? 1 : 0];
 
                ep->ep->driver_data = ep;
-               ret = usb_ep_enable(ep->ep, ds);
+               ep->ep->desc = ds;
+               ret = usb_ep_enable(ep->ep);
                if (likely(!ret)) {
                        epfile->ep = ep;
                        epfile->in = usb_endpoint_dir_in(ds);
@@ -1601,14 +1573,14 @@ static int __must_check ffs_do_desc(char *data, unsigned len,
 
        /* At least two bytes are required: length and type */
        if (len < 2) {
-               FVDBG("descriptor too short");
+               pr_vdebug("descriptor too short\n");
                return -EINVAL;
        }
 
        /* If we have at least as many bytes as the descriptor takes? */
        length = _ds->bLength;
        if (len < length) {
-               FVDBG("descriptor longer then available data");
+               pr_vdebug("descriptor longer then available data\n");
                return -EINVAL;
        }
 
@@ -1616,15 +1588,15 @@ static int __must_check ffs_do_desc(char *data, unsigned len,
 #define __entity_check_STRING(val)     (val)
 #define __entity_check_ENDPOINT(val)   ((val) & USB_ENDPOINT_NUMBER_MASK)
 #define __entity(type, val) do {                                       \
-               FVDBG("entity " #type "(%02x)", (val));                 \
+               pr_vdebug("entity " #type "(%02x)\n", (val));           \
                if (unlikely(!__entity_check_ ##type(val))) {           \
-                       FVDBG("invalid entity's value");                \
+                       pr_vdebug("invalid entity's value\n");          \
                        return -EINVAL;                                 \
                }                                                       \
                ret = entity(FFS_ ##type, &val, _ds, priv);             \
                if (unlikely(ret < 0)) {                                \
-                       FDBG("entity " #type "(%02x); ret = %d",        \
-                            (val), ret);                               \
+                       pr_debug("entity " #type "(%02x); ret = %d\n",  \
+                                (val), ret);                           \
                        return ret;                                     \
                }                                                       \
        } while (0)
@@ -1636,13 +1608,13 @@ static int __must_check ffs_do_desc(char *data, unsigned len,
        case USB_DT_STRING:
        case USB_DT_DEVICE_QUALIFIER:
                /* function can't have any of those */
-               FVDBG("descriptor reserved for gadget: %d",
+               pr_vdebug("descriptor reserved for gadget: %d\n",
                      _ds->bDescriptorType);
                return -EINVAL;
 
        case USB_DT_INTERFACE: {
                struct usb_interface_descriptor *ds = (void *)_ds;
-               FVDBG("interface descriptor");
+               pr_vdebug("interface descriptor\n");
                if (length != sizeof *ds)
                        goto inv_length;
 
@@ -1654,7 +1626,7 @@ static int __must_check ffs_do_desc(char *data, unsigned len,
 
        case USB_DT_ENDPOINT: {
                struct usb_endpoint_descriptor *ds = (void *)_ds;
-               FVDBG("endpoint descriptor");
+               pr_vdebug("endpoint descriptor\n");
                if (length != USB_DT_ENDPOINT_SIZE &&
                    length != USB_DT_ENDPOINT_AUDIO_SIZE)
                        goto inv_length;
@@ -1669,7 +1641,7 @@ static int __must_check ffs_do_desc(char *data, unsigned len,
 
        case USB_DT_INTERFACE_ASSOCIATION: {
                struct usb_interface_assoc_descriptor *ds = (void *)_ds;
-               FVDBG("interface association descriptor");
+               pr_vdebug("interface association descriptor\n");
                if (length != sizeof *ds)
                        goto inv_length;
                if (ds->iFunction)
@@ -1683,17 +1655,17 @@ static int __must_check ffs_do_desc(char *data, unsigned len,
        case USB_DT_SECURITY:
        case USB_DT_CS_RADIO_CONTROL:
                /* TODO */
-               FVDBG("unimplemented descriptor: %d", _ds->bDescriptorType);
+               pr_vdebug("unimplemented descriptor: %d\n", _ds->bDescriptorType);
                return -EINVAL;
 
        default:
                /* We should never be here */
-               FVDBG("unknown descriptor: %d", _ds->bDescriptorType);
+               pr_vdebug("unknown descriptor: %d\n", _ds->bDescriptorType);
                return -EINVAL;
 
 inv_length:
-               FVDBG("invalid length: %d (descriptor %d)",
-                     _ds->bLength, _ds->bDescriptorType);
+               pr_vdebug("invalid length: %d (descriptor %d)\n",
+                         _ds->bLength, _ds->bDescriptorType);
                return -EINVAL;
        }
 
@@ -1723,7 +1695,8 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
                /* Record "descriptor" entity */
                ret = entity(FFS_DESCRIPTOR, (u8 *)num, (void *)data, priv);
                if (unlikely(ret < 0)) {
-                       FDBG("entity DESCRIPTOR(%02lx); ret = %d", num, ret);
+                       pr_debug("entity DESCRIPTOR(%02lx); ret = %d\n",
+                                num, ret);
                        return ret;
                }
 
@@ -1732,7 +1705,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
 
                ret = ffs_do_desc(data, len, entity, priv);
                if (unlikely(ret < 0)) {
-                       FDBG("%s returns %d", __func__, ret);
+                       pr_debug("%s returns %d\n", __func__, ret);
                        return ret;
                }
 
@@ -2025,11 +1998,11 @@ static void __ffs_event_add(struct ffs_data *ffs,
                        if ((*ev == rem_type1 || *ev == rem_type2) == neg)
                                *out++ = *ev;
                        else
-                               FVDBG("purging event %d", *ev);
+                               pr_vdebug("purging event %d\n", *ev);
                ffs->ev.count = out - ffs->ev.types;
        }
 
-       FVDBG("adding event %d", type);
+       pr_vdebug("adding event %d\n", type);
        ffs->ev.types[ffs->ev.count++] = type;
        wake_up_locked(&ffs->ev.waitq);
 }
@@ -2076,9 +2049,9 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
        ffs_ep = func->eps + idx;
 
        if (unlikely(ffs_ep->descs[isHS])) {
-               FVDBG("two %sspeed descriptors for EP %d",
-                     isHS ? "high" : "full",
-                     ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+               pr_vdebug("two %sspeed descriptors for EP %d\n",
+                         isHS ? "high" : "full",
+                         ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
                return -EINVAL;
        }
        ffs_ep->descs[isHS] = ds;
@@ -2092,7 +2065,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
                struct usb_request *req;
                struct usb_ep *ep;
 
-               FVDBG("autoconfig");
+               pr_vdebug("autoconfig\n");
                ep = usb_ep_autoconfig(func->gadget, ds);
                if (unlikely(!ep))
                        return -ENOTSUPP;
@@ -2162,7 +2135,7 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep,
                break;
        }
 
-       FVDBG("%02x -> %02x", *valuep, newValue);
+       pr_vdebug("%02x -> %02x\n", *valuep, newValue);
        *valuep = newValue;
        return 0;
 }
@@ -2327,11 +2300,11 @@ static int ffs_func_setup(struct usb_function *f,
 
        ENTER();
 
-       FVDBG("creq->bRequestType = %02x", creq->bRequestType);
-       FVDBG("creq->bRequest     = %02x", creq->bRequest);
-       FVDBG("creq->wValue       = %04x", le16_to_cpu(creq->wValue));
-       FVDBG("creq->wIndex       = %04x", le16_to_cpu(creq->wIndex));
-       FVDBG("creq->wLength      = %04x", le16_to_cpu(creq->wLength));
+       pr_vdebug("creq->bRequestType = %02x\n", creq->bRequestType);
+       pr_vdebug("creq->bRequest     = %02x\n", creq->bRequest);
+       pr_vdebug("creq->wValue       = %04x\n", le16_to_cpu(creq->wValue));
+       pr_vdebug("creq->wIndex       = %04x\n", le16_to_cpu(creq->wIndex));
+       pr_vdebug("creq->wLength      = %04x\n", le16_to_cpu(creq->wLength));
 
        /*
         * Most requests directed to interface go through here
@@ -2431,7 +2404,7 @@ static char *ffs_prepare_buffer(const char * __user buf, size_t len)
                return ERR_PTR(-EFAULT);
        }
 
-       FVDBG("Buffer from user space:");
+       pr_vdebug("Buffer from user space:\n");
        ffs_dump_mem("", data, len);
 
        return data;