[RFCv4 PATCH 09/13] usb: gadget: example port of mass storage to UFG: f_mass_storage: change array of fsg_lun to config_group

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx>
Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
 drivers/usb/gadget/f_mass_storage.c |   60 ++++++++++++++++++++++++++++------
 drivers/usb/gadget/f_mass_storage.h |    4 ++-
 2 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index a6b3a94..0c3d817 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2068,9 +2068,22 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 	if (common->data_size == 0)
 		common->data_dir = DATA_DIR_NONE;
 	common->lun = cbw->Lun;
-	if (common->lun >= 0 && common->lun < common->nluns)
-		common->curlun = &common->luns[common->lun];
-	else
+	if (common->lun >= 0 && common->lun < common->nluns) {
+		struct config_item *it;
+
+		mutex_lock(&common->group.cg_subsys->su_mutex);
+		list_for_each_entry(it, &common->group.cg_children, ci_entry) {
+			struct fsg_lun *lun;
+
+			lun = to_fsg_lun(it);
+			if (lun->n_lun == common->lun) {
+				common->curlun = lun;
+
+				break;
+			}
+		}
+		mutex_unlock(&common->group.cg_subsys->su_mutex);
+	} else
 		common->curlun = NULL;
 	common->tag = cbw->Tag;
 	return 0;
@@ -2130,6 +2143,7 @@ static int alloc_request(struct fsg_common *common, struct usb_ep *ep,
 /* Reset interface setting and re-init endpoint state (toggle etc). */
 static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
 {
+	struct config_item *item;
 	struct fsg_dev *fsg;
 	int i, rc = 0;
 
@@ -2214,8 +2228,14 @@ reset:
 	}
 
 	common->running = 1;
-	for (i = 0; i < common->nluns; ++i)
-		common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+	mutex_lock(&common->group.cg_subsys->su_mutex);
+	list_for_each_entry(item, &common->group.cg_children, ci_entry) {
+		struct fsg_lun *lun;
+
+		lun = to_fsg_lun(item);
+		lun->unit_attention_data = SS_RESET_OCCURRED;
+	}
+	mutex_unlock(&common->group.cg_subsys->su_mutex);
 	return rc;
 }
 
@@ -2246,7 +2266,6 @@ static void handle_exception(struct fsg_common *common)
 	int			i;
 	struct fsg_buffhd	*bh;
 	enum fsg_state		old_state;
-	struct fsg_lun		*curlun;
 	unsigned int		exception_req_tag;
 
 	/*
@@ -2314,14 +2333,20 @@ static void handle_exception(struct fsg_common *common)
 	if (old_state == FSG_STATE_ABORT_BULK_OUT)
 		common->state = FSG_STATE_STATUS_PHASE;
 	else {
-		for (i = 0; i < common->nluns; ++i) {
-			curlun = &common->luns[i];
+		struct config_item *it;
+
+		mutex_lock(&common->group.cg_subsys->su_mutex);
+		list_for_each_entry(it, &common->group.cg_children, ci_entry) {
+			struct fsg_lun *curlun;
+
+			curlun = to_fsg_lun(it);
 			curlun->prevent_medium_removal = 0;
 			curlun->sense_data = SS_NO_SENSE;
 			curlun->unit_attention_data = SS_NO_SENSE;
 			curlun->sense_data_info = 0;
 			curlun->info_valid = 0;
 		}
+		mutex_unlock(&common->group.cg_subsys->su_mutex);
 		common->state = FSG_STATE_IDLE;
 	}
 	spin_unlock_irq(&common->lock);
@@ -2454,17 +2479,25 @@ static int fsg_main_thread(void *common_)
 
 	if (!common->ops || !common->ops->thread_exits
 	 || common->ops->thread_exits(common) < 0) {
-		struct fsg_lun *curlun = common->luns;
-		unsigned i = common->nluns;
+		struct list_head *cursor;
 
 		down_write(&common->filesem);
-		for (; i--; ++curlun) {
+
+		mutex_lock(&common->group.cg_subsys->su_mutex);
+		list_for_each_prev(cursor, &common->group.cg_children) {
+			struct config_item *item;
+			struct fsg_lun *curlun;
+
+			item = list_entry(cursor, struct config_item, ci_entry);
+
+			curlun = to_fsg_lun(item);
 			if (!fsg_lun_is_open(curlun))
 				continue;
 
 			fsg_lun_close(curlun);
 			curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
 		}
+		mutex_unlock(&common->group.cg_subsys->su_mutex);
 		up_write(&common->filesem);
 	}
 
@@ -2626,6 +2659,7 @@ EXPORT_SYMBOL(fsg_common_init);
 static void fsg_common_release(struct kref *ref)
 {
 	struct fsg_common *common = container_of(ref, struct fsg_common, ref);
+	struct config_item *item;
 
 	/* If the thread isn't already dead, tell it to exit now */
 	if (common->state != FSG_STATE_TERMINATED) {
@@ -2633,6 +2667,10 @@ static void fsg_common_release(struct kref *ref)
 		wait_for_completion(&common->thread_notifier);
 	}
 
+	list_for_each_entry(item, &common->group.cg_children, ci_entry) {
+		struct fsg_lun *lun = to_fsg_lun(item);
+		fsg_lun_close(lun);
+	}
 	{
 		struct fsg_buffhd *bh = common->buffhds;
 		unsigned i = fsg_num_buffers;
diff --git a/drivers/usb/gadget/f_mass_storage.h b/drivers/usb/gadget/f_mass_storage.h
index df313e3..8c0e885 100644
--- a/drivers/usb/gadget/f_mass_storage.h
+++ b/drivers/usb/gadget/f_mass_storage.h
@@ -23,6 +23,9 @@ struct fsg_operations {
 
 /* Data shared by all the FSG instances. */
 struct fsg_common {
+	struct config_group	group;
+	enum ufg_hdr_type	type;
+
 	struct usb_gadget	*gadget;
 	struct usb_composite_dev *cdev;
 	struct fsg_dev		*fsg, *new_fsg;
@@ -47,7 +50,6 @@ struct fsg_common {
 
 	unsigned int		nluns;
 	unsigned int		lun;
-	struct fsg_lun		*luns;
 	struct fsg_lun		*curlun;
 
 	unsigned int		bulk_out_maxpacket;
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux