USB: g_mass_storage: parts of fsg_dev moved to fsg_common structure
authorMichal Nazarewicz <m.nazarewicz@samsung.com>
Wed, 28 Oct 2009 15:57:20 +0000 (16:57 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 11 Dec 2009 19:55:19 +0000 (11:55 -0800)
In the final version, many fsg_dev structures will (be able to)
refer to a single fsg_common structure and so it is required
to move common data to another object which can be shared.

Situation where many fsg_dev structures refer single fsg_common
structure is when a single instance of MSF is used in several
USB configurations.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/f_mass_storage.c

index ed16a953875368679bc5d55d64656b74d42c8cc6..7750346b696c6e728ad4981aa01d64d0eb678249 100644 (file)
@@ -320,14 +320,32 @@ MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk");
 /*-------------------------------------------------------------------------*/
 
 
+/* Data shared by all the FSG instances. */
+struct fsg_common {
+       /* filesem protects: backing files in use */
+       struct rw_semaphore     filesem;
+
+       struct fsg_buffhd       *next_buffhd_to_fill;
+       struct fsg_buffhd       *next_buffhd_to_drain;
+       struct fsg_buffhd       buffhds[FSG_NUM_BUFFERS];
+
+       int                     cmnd_size;
+       u8                      cmnd[MAX_COMMAND_SIZE];
+
+       unsigned int            nluns;
+       unsigned int            lun;
+       struct fsg_lun          *luns;
+       struct fsg_lun          *curlun;
+};
+
+
 struct fsg_dev {
-       /* lock protects: state, all the req_busy's, and cbbuf_cmnd */
+       struct fsg_common       *common;
+
+       /* lock protects: state, all the req_busy's */
        spinlock_t              lock;
        struct usb_gadget       *gadget;
 
-       /* filesem protects: backing files in use */
-       struct rw_semaphore     filesem;
-
        /* reference counting: wait until all LUNs are released */
        struct kref             ref;
 
@@ -356,27 +374,16 @@ struct fsg_dev {
        struct usb_ep           *bulk_in;
        struct usb_ep           *bulk_out;
 
-       struct fsg_buffhd       *next_buffhd_to_fill;
-       struct fsg_buffhd       *next_buffhd_to_drain;
-       struct fsg_buffhd       buffhds[FSG_NUM_BUFFERS];
-
        int                     thread_wakeup_needed;
        struct completion       thread_notifier;
        struct task_struct      *thread_task;
 
-       int                     cmnd_size;
-       u8                      cmnd[MAX_COMMAND_SIZE];
        enum data_direction     data_dir;
        u32                     data_size;
        u32                     data_size_from_cmnd;
        u32                     tag;
-       unsigned int            lun;
        u32                     residue;
        u32                     usb_amount_left;
-
-       unsigned int            nluns;
-       struct fsg_lun          *luns;
-       struct fsg_lun          *curlun;
 };
 
 typedef void (*fsg_routine_t)(struct fsg_dev *);
@@ -674,7 +681,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                if (w_index != 0 || w_value != 0)
                        return -EDOM;
                VDBG(fsg, "get max LUN\n");
-               *(u8 *) req->buf = fsg->nluns - 1;
+               *(u8 *) req->buf = fsg->common->nluns - 1;
                return 1;
        }
 
@@ -903,7 +910,7 @@ static int sleep_thread(struct fsg_dev *fsg)
 
 static int do_read(struct fsg_dev *fsg)
 {
-       struct fsg_lun          *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->common->curlun;
        u32                     lba;
        struct fsg_buffhd       *bh;
        int                     rc;
@@ -915,15 +922,15 @@ static int do_read(struct fsg_dev *fsg)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       if (fsg->cmnd[0] == SC_READ_6)
-               lba = get_unaligned_be24(&fsg->cmnd[1]);
+       if (fsg->common->cmnd[0] == SC_READ_6)
+               lba = get_unaligned_be24(&fsg->common->cmnd[1]);
        else {
-               lba = get_unaligned_be32(&fsg->cmnd[2]);
+               lba = get_unaligned_be32(&fsg->common->cmnd[2]);
 
                /* We allow DPO (Disable Page Out = don't save data in the
                 * cache) and FUA (Force Unit Access = don't read from the
                 * cache), but we don't implement them. */
-               if ((fsg->cmnd[1] & ~0x18) != 0) {
+               if ((fsg->common->cmnd[1] & ~0x18) != 0) {
                        curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                        return -EINVAL;
                }
@@ -958,7 +965,7 @@ static int do_read(struct fsg_dev *fsg)
                                        partial_page);
 
                /* Wait for the next buffer to become available */
-               bh = fsg->next_buffhd_to_fill;
+               bh = fsg->common->next_buffhd_to_fill;
                while (bh->state != BUF_STATE_EMPTY) {
                        rc = sleep_thread(fsg);
                        if (rc)
@@ -1018,7 +1025,7 @@ static int do_read(struct fsg_dev *fsg)
                bh->inreq->zero = 0;
                start_transfer(fsg, fsg->bulk_in, bh->inreq,
                                &bh->inreq_busy, &bh->state);
-               fsg->next_buffhd_to_fill = bh->next;
+               fsg->common->next_buffhd_to_fill = bh->next;
        }
 
        return -EIO;            // No default reply
@@ -1029,7 +1036,7 @@ static int do_read(struct fsg_dev *fsg)
 
 static int do_write(struct fsg_dev *fsg)
 {
-       struct fsg_lun          *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->common->curlun;
        u32                     lba;
        struct fsg_buffhd       *bh;
        int                     get_some_more;
@@ -1050,20 +1057,20 @@ static int do_write(struct fsg_dev *fsg)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       if (fsg->cmnd[0] == SC_WRITE_6)
-               lba = get_unaligned_be24(&fsg->cmnd[1]);
+       if (fsg->common->cmnd[0] == SC_WRITE_6)
+               lba = get_unaligned_be24(&fsg->common->cmnd[1]);
        else {
-               lba = get_unaligned_be32(&fsg->cmnd[2]);
+               lba = get_unaligned_be32(&fsg->common->cmnd[2]);
 
                /* We allow DPO (Disable Page Out = don't save data in the
                 * cache) and FUA (Force Unit Access = write directly to the
                 * medium).  We don't implement DPO; we implement FUA by
                 * performing synchronous output. */
-               if ((fsg->cmnd[1] & ~0x18) != 0) {
+               if ((fsg->common->cmnd[1] & ~0x18) != 0) {
                        curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                        return -EINVAL;
                }
-               if (fsg->cmnd[1] & 0x08) {      // FUA
+               if (fsg->common->cmnd[1] & 0x08) {      // FUA
                        spin_lock(&curlun->filp->f_lock);
                        curlun->filp->f_flags |= O_SYNC;
                        spin_unlock(&curlun->filp->f_lock);
@@ -1082,7 +1089,7 @@ static int do_write(struct fsg_dev *fsg)
        while (amount_left_to_write > 0) {
 
                /* Queue a request for more data from the host */
-               bh = fsg->next_buffhd_to_fill;
+               bh = fsg->common->next_buffhd_to_fill;
                if (bh->state == BUF_STATE_EMPTY && get_some_more) {
 
                        /* Figure out how much we want to get:
@@ -1133,17 +1140,17 @@ static int do_write(struct fsg_dev *fsg)
                        bh->outreq->short_not_ok = 1;
                        start_transfer(fsg, fsg->bulk_out, bh->outreq,
                                        &bh->outreq_busy, &bh->state);
-                       fsg->next_buffhd_to_fill = bh->next;
+                       fsg->common->next_buffhd_to_fill = bh->next;
                        continue;
                }
 
                /* Write the received data to the backing file */
-               bh = fsg->next_buffhd_to_drain;
+               bh = fsg->common->next_buffhd_to_drain;
                if (bh->state == BUF_STATE_EMPTY && !get_some_more)
                        break;                  // We stopped early
                if (bh->state == BUF_STATE_FULL) {
                        smp_rmb();
-                       fsg->next_buffhd_to_drain = bh->next;
+                       fsg->common->next_buffhd_to_drain = bh->next;
                        bh->state = BUF_STATE_EMPTY;
 
                        /* Did something go wrong with the transfer? */
@@ -1218,7 +1225,7 @@ static int do_write(struct fsg_dev *fsg)
 
 static int do_synchronize_cache(struct fsg_dev *fsg)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->common->curlun;
        int             rc;
 
        /* We ignore the requested LBA and write out all file's
@@ -1244,10 +1251,10 @@ static void invalidate_sub(struct fsg_lun *curlun)
 
 static int do_verify(struct fsg_dev *fsg)
 {
-       struct fsg_lun          *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->common->curlun;
        u32                     lba;
        u32                     verification_length;
-       struct fsg_buffhd       *bh = fsg->next_buffhd_to_fill;
+       struct fsg_buffhd       *bh = fsg->common->next_buffhd_to_fill;
        loff_t                  file_offset, file_offset_tmp;
        u32                     amount_left;
        unsigned int            amount;
@@ -1255,7 +1262,7 @@ static int do_verify(struct fsg_dev *fsg)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       lba = get_unaligned_be32(&fsg->cmnd[2]);
+       lba = get_unaligned_be32(&fsg->common->cmnd[2]);
        if (lba >= curlun->num_sectors) {
                curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
                return -EINVAL;
@@ -1263,12 +1270,12 @@ static int do_verify(struct fsg_dev *fsg)
 
        /* We allow DPO (Disable Page Out = don't save data in the
         * cache) but we don't implement it. */
-       if ((fsg->cmnd[1] & ~0x10) != 0) {
+       if ((fsg->common->cmnd[1] & ~0x10) != 0) {
                curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                return -EINVAL;
        }
 
-       verification_length = get_unaligned_be16(&fsg->cmnd[7]);
+       verification_length = get_unaligned_be16(&fsg->common->cmnd[7]);
        if (unlikely(verification_length == 0))
                return -EIO;            // No default reply
 
@@ -1348,7 +1355,7 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        static char product_disk_id[] = "File-Stor Gadget";
        static char product_cdrom_id[] = "File-CD Gadget  ";
 
-       if (!fsg->curlun) {             // Unsupported LUNs are okay
+       if (!fsg->common->curlun) {             // Unsupported LUNs are okay
                fsg->bad_lun_okay = 1;
                memset(buf, 0, 36);
                buf[0] = 0x7f;          // Unsupported, no device-type
@@ -1374,7 +1381,7 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->common->curlun;
        u8              *buf = (u8 *) bh->buf;
        u32             sd, sdinfo;
        int             valid;
@@ -1428,9 +1435,9 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
-       u32             lba = get_unaligned_be32(&fsg->cmnd[2]);
-       int             pmi = fsg->cmnd[8];
+       struct fsg_lun  *curlun = fsg->common->curlun;
+       u32             lba = get_unaligned_be32(&fsg->common->cmnd[2]);
+       int             pmi = fsg->common->cmnd[8];
        u8              *buf = (u8 *) bh->buf;
 
        /* Check the PMI and LBA fields */
@@ -1448,12 +1455,12 @@ static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
-       int             msf = fsg->cmnd[1] & 0x02;
-       u32             lba = get_unaligned_be32(&fsg->cmnd[2]);
+       struct fsg_lun  *curlun = fsg->common->curlun;
+       int             msf = fsg->common->cmnd[1] & 0x02;
+       u32             lba = get_unaligned_be32(&fsg->common->cmnd[2]);
        u8              *buf = (u8 *) bh->buf;
 
-       if ((fsg->cmnd[1] & ~0x02) != 0) {              /* Mask away MSF */
+       if ((fsg->common->cmnd[1] & ~0x02) != 0) {      /* Mask away MSF */
                curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                return -EINVAL;
        }
@@ -1471,12 +1478,12 @@ static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
-       int             msf = fsg->cmnd[1] & 0x02;
-       int             start_track = fsg->cmnd[6];
+       struct fsg_lun  *curlun = fsg->common->curlun;
+       int             msf = fsg->common->cmnd[1] & 0x02;
+       int             start_track = fsg->common->cmnd[6];
        u8              *buf = (u8 *) bh->buf;
 
-       if ((fsg->cmnd[1] & ~0x02) != 0 ||              /* Mask away MSF */
+       if ((fsg->common->cmnd[1] & ~0x02) != 0 ||      /* Mask away MSF */
                        start_track > 1) {
                curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                return -EINVAL;
@@ -1499,8 +1506,8 @@ static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 
 static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
-       int             mscmnd = fsg->cmnd[0];
+       struct fsg_lun  *curlun = fsg->common->curlun;
+       int             mscmnd = fsg->common->cmnd[0];
        u8              *buf = (u8 *) bh->buf;
        u8              *buf0 = buf;
        int             pc, page_code;
@@ -1508,12 +1515,12 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        int             valid_page = 0;
        int             len, limit;
 
-       if ((fsg->cmnd[1] & ~0x08) != 0) {              // Mask away DBD
+       if ((fsg->common->cmnd[1] & ~0x08) != 0) {      // Mask away DBD
                curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                return -EINVAL;
        }
-       pc = fsg->cmnd[2] >> 6;
-       page_code = fsg->cmnd[2] & 0x3f;
+       pc = fsg->common->cmnd[2] >> 6;
+       page_code = fsg->common->cmnd[2] & 0x3f;
        if (pc == 3) {
                curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
                return -EINVAL;
@@ -1581,7 +1588,7 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 static int do_start_stop(struct fsg_dev *fsg)
 {
        if (!mod_data.removable) {
-               fsg->curlun->sense_data = SS_INVALID_COMMAND;
+               fsg->common->curlun->sense_data = SS_INVALID_COMMAND;
                return -EINVAL;
        }
        return 0;
@@ -1590,7 +1597,7 @@ static int do_start_stop(struct fsg_dev *fsg)
 
 static int do_prevent_allow(struct fsg_dev *fsg)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->common->curlun;
        int             prevent;
 
        if (!mod_data.removable) {
@@ -1598,8 +1605,8 @@ static int do_prevent_allow(struct fsg_dev *fsg)
                return -EINVAL;
        }
 
-       prevent = fsg->cmnd[4] & 0x01;
-       if ((fsg->cmnd[4] & ~0x01) != 0) {              // Mask away Prevent
+       prevent = fsg->common->cmnd[4] & 0x01;
+       if ((fsg->common->cmnd[4] & ~0x01) != 0) {      // Mask away Prevent
                curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                return -EINVAL;
        }
@@ -1614,7 +1621,7 @@ static int do_prevent_allow(struct fsg_dev *fsg)
 static int do_read_format_capacities(struct fsg_dev *fsg,
                        struct fsg_buffhd *bh)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->common->curlun;
        u8              *buf = (u8 *) bh->buf;
 
        buf[0] = buf[1] = buf[2] = 0;
@@ -1631,7 +1638,7 @@ static int do_read_format_capacities(struct fsg_dev *fsg,
 
 static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
-       struct fsg_lun  *curlun = fsg->curlun;
+       struct fsg_lun  *curlun = fsg->common->curlun;
 
        /* We don't support MODE SELECT */
        curlun->sense_data = SS_INVALID_COMMAND;
@@ -1688,7 +1695,7 @@ static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
 
 static int pad_with_zeros(struct fsg_dev *fsg)
 {
-       struct fsg_buffhd       *bh = fsg->next_buffhd_to_fill;
+       struct fsg_buffhd       *bh = fsg->common->next_buffhd_to_fill;
        u32                     nkeep = bh->inreq->length;
        u32                     nsend;
        int                     rc;
@@ -1710,7 +1717,7 @@ static int pad_with_zeros(struct fsg_dev *fsg)
                bh->inreq->zero = 0;
                start_transfer(fsg, fsg->bulk_in, bh->inreq,
                                &bh->inreq_busy, &bh->state);
-               bh = fsg->next_buffhd_to_fill = bh->next;
+               bh = fsg->common->next_buffhd_to_fill = bh->next;
                fsg->usb_amount_left -= nsend;
                nkeep = 0;
        }
@@ -1723,14 +1730,15 @@ static int throw_away_data(struct fsg_dev *fsg)
        u32                     amount;
        int                     rc;
 
-       while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY ||
-                       fsg->usb_amount_left > 0) {
+       for (bh = fsg->common->next_buffhd_to_drain;
+            bh->state != BUF_STATE_EMPTY || fsg->usb_amount_left > 0;
+            bh = fsg->common->next_buffhd_to_drain) {
 
                /* Throw away the data in a filled buffer */
                if (bh->state == BUF_STATE_FULL) {
                        smp_rmb();
                        bh->state = BUF_STATE_EMPTY;
-                       fsg->next_buffhd_to_drain = bh->next;
+                       fsg->common->next_buffhd_to_drain = bh->next;
 
                        /* A short packet or an error ends everything */
                        if (bh->outreq->actual != bh->outreq->length ||
@@ -1742,7 +1750,7 @@ static int throw_away_data(struct fsg_dev *fsg)
                }
 
                /* Try to submit another request if we need one */
-               bh = fsg->next_buffhd_to_fill;
+               bh = fsg->common->next_buffhd_to_fill;
                if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) {
                        amount = min(fsg->usb_amount_left, FSG_BUFLEN);
 
@@ -1753,7 +1761,7 @@ static int throw_away_data(struct fsg_dev *fsg)
                        bh->outreq->short_not_ok = 1;
                        start_transfer(fsg, fsg->bulk_out, bh->outreq,
                                        &bh->outreq_busy, &bh->state);
-                       fsg->next_buffhd_to_fill = bh->next;
+                       fsg->common->next_buffhd_to_fill = bh->next;
                        fsg->usb_amount_left -= amount;
                        continue;
                }
@@ -1769,7 +1777,7 @@ static int throw_away_data(struct fsg_dev *fsg)
 
 static int finish_reply(struct fsg_dev *fsg)
 {
-       struct fsg_buffhd       *bh = fsg->next_buffhd_to_fill;
+       struct fsg_buffhd       *bh = fsg->common->next_buffhd_to_fill;
        int                     rc = 0;
 
        switch (fsg->data_dir) {
@@ -1797,7 +1805,7 @@ static int finish_reply(struct fsg_dev *fsg)
                        bh->inreq->zero = 0;
                        start_transfer(fsg, fsg->bulk_in, bh->inreq,
                                        &bh->inreq_busy, &bh->state);
-                       fsg->next_buffhd_to_fill = bh->next;
+                       fsg->common->next_buffhd_to_fill = bh->next;
 
                /* For Bulk-only, if we're allowed to stall then send the
                 * short packet and halt the bulk-in endpoint.  If we can't
@@ -1806,7 +1814,7 @@ static int finish_reply(struct fsg_dev *fsg)
                        bh->inreq->zero = 1;
                        start_transfer(fsg, fsg->bulk_in, bh->inreq,
                                       &bh->inreq_busy, &bh->state);
-                       fsg->next_buffhd_to_fill = bh->next;
+                       fsg->common->next_buffhd_to_fill = bh->next;
                        rc = halt_bulk_in_endpoint(fsg);
                } else {
                        rc = pad_with_zeros(fsg);
@@ -1851,7 +1859,7 @@ static int finish_reply(struct fsg_dev *fsg)
 
 static int send_status(struct fsg_dev *fsg)
 {
-       struct fsg_lun          *curlun = fsg->curlun;
+       struct fsg_lun          *curlun = fsg->common->curlun;
        struct fsg_buffhd       *bh;
        struct bulk_cs_wrap     *csw;
        int                     rc;
@@ -1859,7 +1867,7 @@ static int send_status(struct fsg_dev *fsg)
        u32                     sd, sdinfo = 0;
 
        /* Wait for the next buffer to become available */
-       bh = fsg->next_buffhd_to_fill;
+       bh = fsg->common->next_buffhd_to_fill;
        while (bh->state != BUF_STATE_EMPTY) {
                rc = sleep_thread(fsg);
                if (rc)
@@ -1900,7 +1908,7 @@ static int send_status(struct fsg_dev *fsg)
        start_transfer(fsg, fsg->bulk_in, bh->inreq,
                       &bh->inreq_busy, &bh->state);
 
-       fsg->next_buffhd_to_fill = bh->next;
+       fsg->common->next_buffhd_to_fill = bh->next;
        return 0;
 }
 
@@ -1914,7 +1922,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
                int needs_medium, const char *name)
 {
        int                     i;
-       int                     lun = fsg->cmnd[1] >> 5;
+       int                     lun = fsg->common->cmnd[1] >> 5;
        static const char       dirletter[4] = {'u', 'o', 'i', 'n'};
        char                    hdlen[20];
        struct fsg_lun          *curlun;
@@ -1925,7 +1933,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
                                fsg->data_size);
        VDBG(fsg, "SCSI command: %s;  Dc=%d, D%c=%u;  Hc=%d%s\n",
                        name, cmnd_size, dirletter[(int) data_dir],
-                       fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen);
+                       fsg->data_size_from_cmnd, fsg->common->cmnd_size, hdlen);
 
        /* We can't reply at all until we know the correct data direction
         * and size. */
@@ -1954,7 +1962,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        }
 
        /* Verify the length of the command itself */
-       if (cmnd_size != fsg->cmnd_size) {
+       if (cmnd_size != fsg->common->cmnd_size) {
 
                /* Special case workaround: There are plenty of buggy SCSI
                 * implementations. Many have issues with cbw->Length
@@ -1968,11 +1976,11 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
                 * REQUEST SENSE with cbw->Length == 10 where it should
                 * be 6 as well.
                 */
-               if (cmnd_size <= fsg->cmnd_size) {
+               if (cmnd_size <= fsg->common->cmnd_size) {
                        DBG(fsg, "%s is buggy! Expected length %d "
-                                       "but we got %d\n", name,
-                                       cmnd_size, fsg->cmnd_size);
-                       cmnd_size = fsg->cmnd_size;
+                           "but we got %d\n", name,
+                           cmnd_size, fsg->common->cmnd_size);
+                       cmnd_size = fsg->common->cmnd_size;
                } else {
                        fsg->phase_error = 1;
                        return -EINVAL;
@@ -1980,27 +1988,27 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        }
 
        /* Check that the LUN values are consistent */
-       if (fsg->lun != lun)
+       if (fsg->common->lun != lun)
                DBG(fsg, "using LUN %d from CBW, not LUN %d from CDB\n",
-                   fsg->lun, lun);
+                   fsg->common->lun, lun);
 
        /* Check the LUN */
-       if (fsg->lun >= 0 && fsg->lun < fsg->nluns) {
-               fsg->curlun = curlun = &fsg->luns[fsg->lun];
-               if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
+       if (fsg->common->lun >= 0 && fsg->common->lun < fsg->common->nluns) {
+               fsg->common->curlun = curlun = &fsg->common->luns[fsg->common->lun];
+               if (fsg->common->cmnd[0] != SC_REQUEST_SENSE) {
                        curlun->sense_data = SS_NO_SENSE;
                        curlun->sense_data_info = 0;
                        curlun->info_valid = 0;
                }
        } else {
-               fsg->curlun = curlun = NULL;
+               fsg->common->curlun = curlun = NULL;
                fsg->bad_lun_okay = 0;
 
                /* INQUIRY and REQUEST SENSE commands are explicitly allowed
                 * to use unsupported LUNs; all others may not. */
-               if (fsg->cmnd[0] != SC_INQUIRY &&
-                               fsg->cmnd[0] != SC_REQUEST_SENSE) {
-                       DBG(fsg, "unsupported LUN %d\n", fsg->lun);
+               if (fsg->common->cmnd[0] != SC_INQUIRY &&
+                   fsg->common->cmnd[0] != SC_REQUEST_SENSE) {
+                       DBG(fsg, "unsupported LUN %d\n", fsg->common->lun);
                        return -EINVAL;
                }
        }
@@ -2008,17 +2016,17 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        /* If a unit attention condition exists, only INQUIRY and
         * REQUEST SENSE commands are allowed; anything else must fail. */
        if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
-                       fsg->cmnd[0] != SC_INQUIRY &&
-                       fsg->cmnd[0] != SC_REQUEST_SENSE) {
+                       fsg->common->cmnd[0] != SC_INQUIRY &&
+                       fsg->common->cmnd[0] != SC_REQUEST_SENSE) {
                curlun->sense_data = curlun->unit_attention_data;
                curlun->unit_attention_data = SS_NO_SENSE;
                return -EINVAL;
        }
 
        /* Check that only command bytes listed in the mask are non-zero */
-       fsg->cmnd[1] &= 0x1f;                   // Mask away the LUN
+       fsg->common->cmnd[1] &= 0x1f;                   // Mask away the LUN
        for (i = 1; i < cmnd_size; ++i) {
-               if (fsg->cmnd[i] && !(mask & (1 << i))) {
+               if (fsg->common->cmnd[i] && !(mask & (1 << i))) {
                        if (curlun)
                                curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                        return -EINVAL;
@@ -2044,10 +2052,10 @@ static int do_scsi_command(struct fsg_dev *fsg)
        int                     i;
        static char             unknown[16];
 
-       dump_cdb(fsg);
+       dump_cdb(fsg->common);
 
        /* Wait for the next buffer to become available for data or status */
-       bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill;
+       bh = fsg->common->next_buffhd_to_drain = fsg->common->next_buffhd_to_fill;
        while (bh->state != BUF_STATE_EMPTY) {
                rc = sleep_thread(fsg);
                if (rc)
@@ -2056,11 +2064,11 @@ static int do_scsi_command(struct fsg_dev *fsg)
        fsg->phase_error = 0;
        fsg->short_packet_received = 0;
 
-       down_read(&fsg->filesem);       // We're using the backing file
-       switch (fsg->cmnd[0]) {
+       down_read(&fsg->common->filesem);       // We're using the backing file
+       switch (fsg->common->cmnd[0]) {
 
        case SC_INQUIRY:
-               fsg->data_size_from_cmnd = fsg->cmnd[4];
+               fsg->data_size_from_cmnd = fsg->common->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
                                (1<<4), 0,
                                "INQUIRY")) == 0)
@@ -2068,7 +2076,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_MODE_SELECT_6:
-               fsg->data_size_from_cmnd = fsg->cmnd[4];
+               fsg->data_size_from_cmnd = fsg->common->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
                                (1<<1) | (1<<4), 0,
                                "MODE SELECT(6)")) == 0)
@@ -2076,7 +2084,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_MODE_SELECT_10:
-               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->common->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
                                (1<<1) | (3<<7), 0,
                                "MODE SELECT(10)")) == 0)
@@ -2084,7 +2092,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_MODE_SENSE_6:
-               fsg->data_size_from_cmnd = fsg->cmnd[4];
+               fsg->data_size_from_cmnd = fsg->common->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
                                (1<<1) | (1<<2) | (1<<4), 0,
                                "MODE SENSE(6)")) == 0)
@@ -2092,7 +2100,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_MODE_SENSE_10:
-               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->common->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (1<<1) | (1<<2) | (3<<7), 0,
                                "MODE SENSE(10)")) == 0)
@@ -2108,7 +2116,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_READ_6:
-               i = fsg->cmnd[4];
+               i = fsg->common->cmnd[4];
                fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
                                (7<<1) | (1<<4), 1,
@@ -2118,7 +2126,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
 
        case SC_READ_10:
                fsg->data_size_from_cmnd =
-                               get_unaligned_be16(&fsg->cmnd[7]) << 9;
+                               get_unaligned_be16(&fsg->common->cmnd[7]) << 9;
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (1<<1) | (0xf<<2) | (3<<7), 1,
                                "READ(10)")) == 0)
@@ -2127,7 +2135,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
 
        case SC_READ_12:
                fsg->data_size_from_cmnd =
-                               get_unaligned_be32(&fsg->cmnd[6]) << 9;
+                               get_unaligned_be32(&fsg->common->cmnd[6]) << 9;
                if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
                                (1<<1) | (0xf<<2) | (0xf<<6), 1,
                                "READ(12)")) == 0)
@@ -2145,7 +2153,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
        case SC_READ_HEADER:
                if (!mod_data.cdrom)
                        goto unknown_cmnd;
-               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->common->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (3<<7) | (0x1f<<1), 1,
                                "READ HEADER")) == 0)
@@ -2155,7 +2163,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
        case SC_READ_TOC:
                if (!mod_data.cdrom)
                        goto unknown_cmnd;
-               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->common->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (7<<6) | (1<<1), 1,
                                "READ TOC")) == 0)
@@ -2163,7 +2171,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_READ_FORMAT_CAPACITIES:
-               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
+               fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->common->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (3<<7), 1,
                                "READ FORMAT CAPACITIES")) == 0)
@@ -2171,7 +2179,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_REQUEST_SENSE:
-               fsg->data_size_from_cmnd = fsg->cmnd[4];
+               fsg->data_size_from_cmnd = fsg->common->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
                                (1<<4), 0,
                                "REQUEST SENSE")) == 0)
@@ -2212,7 +2220,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                break;
 
        case SC_WRITE_6:
-               i = fsg->cmnd[4];
+               i = fsg->common->cmnd[4];
                fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
                if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
                                (7<<1) | (1<<4), 1,
@@ -2222,7 +2230,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
 
        case SC_WRITE_10:
                fsg->data_size_from_cmnd =
-                               get_unaligned_be16(&fsg->cmnd[7]) << 9;
+                               get_unaligned_be16(&fsg->common->cmnd[7]) << 9;
                if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
                                (1<<1) | (0xf<<2) | (3<<7), 1,
                                "WRITE(10)")) == 0)
@@ -2231,7 +2239,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
 
        case SC_WRITE_12:
                fsg->data_size_from_cmnd =
-                               get_unaligned_be32(&fsg->cmnd[6]) << 9;
+                               get_unaligned_be32(&fsg->common->cmnd[6]) << 9;
                if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
                                (1<<1) | (0xf<<2) | (0xf<<6), 1,
                                "WRITE(12)")) == 0)
@@ -2251,15 +2259,15 @@ static int do_scsi_command(struct fsg_dev *fsg)
        default:
  unknown_cmnd:
                fsg->data_size_from_cmnd = 0;
-               sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
-               if ((reply = check_command(fsg, fsg->cmnd_size,
+               sprintf(unknown, "Unknown x%02x", fsg->common->cmnd[0]);
+               if ((reply = check_command(fsg, fsg->common->cmnd_size,
                                DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) {
-                       fsg->curlun->sense_data = SS_INVALID_COMMAND;
+                       fsg->common->curlun->sense_data = SS_INVALID_COMMAND;
                        reply = -EINVAL;
                }
                break;
        }
-       up_read(&fsg->filesem);
+       up_read(&fsg->common->filesem);
 
        if (reply == -EINTR || signal_pending(current))
                return -EINTR;
@@ -2328,8 +2336,8 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        }
 
        /* Save the command for later */
-       fsg->cmnd_size = cbw->Length;
-       memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size);
+       fsg->common->cmnd_size = cbw->Length;
+       memcpy(fsg->common->cmnd, cbw->CDB, fsg->common->cmnd_size);
        if (cbw->Flags & USB_BULK_IN_FLAG)
                fsg->data_dir = DATA_DIR_TO_HOST;
        else
@@ -2337,7 +2345,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        fsg->data_size = le32_to_cpu(cbw->DataTransferLength);
        if (fsg->data_size == 0)
                fsg->data_dir = DATA_DIR_NONE;
-       fsg->lun = cbw->Lun;
+       fsg->common->lun = cbw->Lun;
        fsg->tag = cbw->Tag;
        return 0;
 }
@@ -2349,7 +2357,7 @@ static int get_next_command(struct fsg_dev *fsg)
        int                     rc = 0;
 
        /* Wait for the next buffer to become available */
-       bh = fsg->next_buffhd_to_fill;
+       bh = fsg->common->next_buffhd_to_fill;
        while (bh->state != BUF_STATE_EMPTY) {
                rc = sleep_thread(fsg);
                if (rc)
@@ -2421,7 +2429,7 @@ static int do_set_interface(struct fsg_dev *fsg, int altsetting)
 reset:
        /* Deallocate the requests */
        for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
-               struct fsg_buffhd *bh = &fsg->buffhds[i];
+               struct fsg_buffhd *bh = &fsg->common->buffhds[i];
 
                if (bh->inreq) {
                        usb_ep_free_request(fsg->bulk_in, bh->inreq);
@@ -2466,7 +2474,7 @@ reset:
 
        /* Allocate the requests */
        for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
-               struct fsg_buffhd       *bh = &fsg->buffhds[i];
+               struct fsg_buffhd       *bh = &fsg->common->buffhds[i];
 
                if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0)
                        goto reset;
@@ -2479,8 +2487,8 @@ reset:
        }
 
        fsg->running = 1;
-       for (i = 0; i < fsg->nluns; ++i)
-               fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+       for (i = 0; i < fsg->common->nluns; ++i)
+               fsg->common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
        return rc;
 }
 
@@ -2532,7 +2540,6 @@ static void handle_exception(struct fsg_dev *fsg)
        siginfo_t               info;
        int                     sig;
        int                     i;
-       int                     num_active;
        struct fsg_buffhd       *bh;
        enum fsg_state          old_state;
        u8                      new_config;
@@ -2555,7 +2562,7 @@ static void handle_exception(struct fsg_dev *fsg)
 
        /* Cancel all the pending transfers */
        for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
-               bh = &fsg->buffhds[i];
+               bh = &fsg->common->buffhds[i];
                if (bh->inreq_busy)
                        usb_ep_dequeue(fsg->bulk_in, bh->inreq);
                if (bh->outreq_busy)
@@ -2564,9 +2571,9 @@ static void handle_exception(struct fsg_dev *fsg)
 
        /* Wait until everything is idle */
        for (;;) {
-               num_active = 0;
+               int num_active = 0;
                for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
-                       bh = &fsg->buffhds[i];
+                       bh = &fsg->common->buffhds[i];
                        num_active += bh->inreq_busy + bh->outreq_busy;
                }
                if (num_active == 0)
@@ -2586,11 +2593,11 @@ static void handle_exception(struct fsg_dev *fsg)
        spin_lock_irq(&fsg->lock);
 
        for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
-               bh = &fsg->buffhds[i];
+               bh = &fsg->common->buffhds[i];
                bh->state = BUF_STATE_EMPTY;
        }
-       fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain =
-                       &fsg->buffhds[0];
+       fsg->common->next_buffhd_to_fill = fsg->common->next_buffhd_to_drain =
+                       &fsg->common->buffhds[0];
 
        exception_req_tag = fsg->exception_req_tag;
        new_config = fsg->new_config;
@@ -2599,8 +2606,8 @@ static void handle_exception(struct fsg_dev *fsg)
        if (old_state == FSG_STATE_ABORT_BULK_OUT)
                fsg->state = FSG_STATE_STATUS_PHASE;
        else {
-               for (i = 0; i < fsg->nluns; ++i) {
-                       curlun = &fsg->luns[i];
+               for (i = 0; i < fsg->common->nluns; ++i) {
+                       curlun = &fsg->common->luns[i];
                        curlun->prevent_medium_removal = 0;
                        curlun->sense_data = curlun->unit_attention_data =
                                        SS_NO_SENSE;
@@ -2637,8 +2644,8 @@ static void handle_exception(struct fsg_dev *fsg)
                /* Technically this should go here, but it would only be
                 * a waste of time.  Ditto for the INTERFACE_CHANGE and
                 * CONFIG_CHANGE cases. */
-               // for (i = 0; i < fsg->nluns; ++i)
-               //      fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+               // for (i = 0; i < fsg->common->nluns; ++i)
+               //      fsg->common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
                break;
 
        case FSG_STATE_INTERFACE_CHANGE:
@@ -2662,8 +2669,8 @@ static void handle_exception(struct fsg_dev *fsg)
                break;
 
        case FSG_STATE_DISCONNECT:
-               for (i = 0; i < fsg->nluns; ++i)
-                       fsg_lun_fsync_sub(fsg->luns + i);
+               for (i = 0; i < fsg->common->nluns; ++i)
+                       fsg_lun_fsync_sub(&fsg->common->luns[i]);
                do_set_config(fsg, 0);          // Unconfigured state
                break;
 
@@ -2760,21 +2767,14 @@ static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
 
 /*-------------------------------------------------------------------------*/
 
-static void fsg_release(struct kref *ref)
+static void fsg_release(struct fsg_dev *fsg)
 {
-       struct fsg_dev  *fsg = container_of(ref, struct fsg_dev, ref);
-
-       kfree(fsg->luns);
+       kfree(fsg->common->luns);
        kfree(fsg);
 }
 
 static void lun_release(struct device *dev)
 {
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
-       struct fsg_dev          *fsg =
-               container_of(filesem, struct fsg_dev, filesem);
-
-       kref_put(&fsg->ref, fsg_release);
 }
 
 static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
@@ -2788,8 +2788,8 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
        clear_bit(REGISTERED, &fsg->atomic_bitflags);
 
        /* Unregister the sysfs attribute files and the LUNs */
-       for (i = 0; i < fsg->nluns; ++i) {
-               curlun = &fsg->luns[i];
+       for (i = 0; i < fsg->common->nluns; ++i) {
+               curlun = &fsg->common->luns[i];
                if (curlun->registered) {
                        device_remove_file(&curlun->dev, &dev_attr_ro);
                        device_remove_file(&curlun->dev, &dev_attr_file);
@@ -2810,7 +2810,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
 
        /* Free the data buffers */
        for (i = 0; i < FSG_NUM_BUFFERS; ++i)
-               kfree(fsg->buffhds[i].buf);
+               kfree(fsg->common->buffhds[i].buf);
 
        /* Free the request and buffer for endpoint 0 */
        if (req) {
@@ -2891,15 +2891,15 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
        /* Create the LUNs, open their backing files, and register the
         * LUN devices in sysfs. */
-       fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL);
-       if (!fsg->luns) {
+       fsg->common->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL);
+       if (!fsg->common->luns) {
                rc = -ENOMEM;
                goto out;
        }
-       fsg->nluns = i;
+       fsg->common->nluns = i;
 
-       for (i = 0; i < fsg->nluns; ++i) {
-               curlun = &fsg->luns[i];
+       for (i = 0; i < fsg->common->nluns; ++i) {
+               curlun = &fsg->common->luns[i];
                curlun->cdrom = !!mod_data.cdrom;
                curlun->ro = mod_data.cdrom || mod_data.ro[i];
                curlun->initially_ro = curlun->ro;
@@ -2907,7 +2907,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                curlun->dev.release = lun_release;
                curlun->dev.parent = &gadget->dev;
                curlun->dev.driver = &fsg_driver.driver;
-               dev_set_drvdata(&curlun->dev, &fsg->filesem);
+               dev_set_drvdata(&curlun->dev, &fsg->common->filesem);
                dev_set_name(&curlun->dev,"%s-lun%d",
                             dev_name(&gadget->dev), i);
 
@@ -2923,7 +2923,6 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                        goto out;
                }
                curlun->registered = 1;
-               kref_get(&fsg->ref);
 
                if (mod_data.file[i] && *mod_data.file[i]) {
                        if ((rc = fsg_lun_open(curlun,
@@ -2981,7 +2980,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 
        /* Allocate the data buffers */
        for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
-               struct fsg_buffhd       *bh = &fsg->buffhds[i];
+               struct fsg_buffhd       *bh = &fsg->common->buffhds[i];
 
                /* Allocate for the bulk-in endpoint.  We assume that
                 * the buffer will also work with the bulk-out (and
@@ -2991,7 +2990,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                        goto out;
                bh->next = bh + 1;
        }
-       fsg->buffhds[FSG_NUM_BUFFERS - 1].next = &fsg->buffhds[0];
+       fsg->common->buffhds[FSG_NUM_BUFFERS - 1].next = &fsg->common->buffhds[0];
 
        /* This should reflect the actual gadget power source */
        usb_gadget_set_selfpowered(gadget);
@@ -3019,11 +3018,11 @@ static int __init fsg_bind(struct usb_gadget *gadget)
        }
 
        INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
-       INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
+       INFO(fsg, "Number of LUNs=%d\n", fsg->common->nluns);
 
        pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
-       for (i = 0; i < fsg->nluns; ++i) {
-               curlun = &fsg->luns[i];
+       for (i = 0; i < fsg->common->nluns; ++i) {
+               curlun = &fsg->common->luns[i];
                if (fsg_lun_is_open(curlun)) {
                        p = NULL;
                        if (pathbuf) {
@@ -3092,9 +3091,15 @@ static int __init fsg_alloc(void)
        fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
        if (!fsg)
                return -ENOMEM;
+
+       fsg->common = kzalloc(sizeof *fsg->common, GFP_KERNEL);
+       if (!fsg->common) {
+               kfree(fsg);
+               return -ENOMEM;
+       }
+
        spin_lock_init(&fsg->lock);
-       init_rwsem(&fsg->filesem);
-       kref_init(&fsg->ref);
+       init_rwsem(&fsg->common->filesem);
        init_completion(&fsg->thread_notifier);
 
        the_fsg = fsg;
@@ -3111,7 +3116,7 @@ static int __init fsg_init(void)
                return rc;
        fsg = the_fsg;
        if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
-               kref_put(&fsg->ref, fsg_release);
+               fsg_release(fsg);
        return rc;
 }
 module_init(fsg_init);
@@ -3128,6 +3133,6 @@ static void __exit fsg_cleanup(void)
        /* Wait for the thread to finish up */
        wait_for_completion(&fsg->thread_notifier);
 
-       kref_put(&fsg->ref, fsg_release);
+       fsg_release(fsg);
 }
 module_exit(fsg_cleanup);