* [PATCH] Mass Storage Gadget: Handle eject request
@ 2010-04-20 8:34 fabien.chouteau
2010-04-21 9:10 ` Michał Nazarewicz
0 siblings, 1 reply; 3+ messages in thread
From: fabien.chouteau @ 2010-04-20 8:34 UTC (permalink / raw)
To: linux-usb
Cc: Fabien Chouteau, David Brownell, Greg Kroah-Hartman,
Michal Nazarewicz, Peter Korsgaard, linux-kernel
From: Fabien Chouteau <fabien.chouteau@barco.com>
Handle eject request + sysfs entries to detect ejected LUN and suspended gadget.
Signed-off-by: Fabien Chouteau <fabien.chouteau@barco.com>
---
drivers/usb/gadget/f_mass_storage.c | 75 +++++++++++++++++++++++++++++++++-
drivers/usb/gadget/storage_common.c | 19 +++++++++
2 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index f4911c0..af13a2f 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -1385,12 +1385,49 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
static int do_start_stop(struct fsg_common *common)
{
- if (!common->curlun) {
+ struct fsg_lun *curlun = common->curlun;
+ int loej, start;
+
+ if (!curlun) {
return -EINVAL;
- } else if (!common->curlun->removable) {
- common->curlun->sense_data = SS_INVALID_COMMAND;
+ } else if (!curlun->removable) {
+ curlun->sense_data = SS_INVALID_COMMAND;
return -EINVAL;
}
+
+ loej = common->cmnd[4] & 0x02;
+ start = common->cmnd[4] & 0x01;
+
+ if ((common->cmnd[1] & ~0x01) != 0 || /* Mask away Immed */
+ (common->cmnd[4] & ~0x03) != 0) { /* Mask LoEj, Start */
+ curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+ return -EINVAL;
+ }
+
+ if (!start) {
+ /* Are we allowed to unload the media? */
+ if (curlun->prevent_medium_removal) {
+ LDBG(curlun, "unload attempt prevented\n");
+ curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
+ return -EINVAL;
+ }
+ if (loej) { /* Simulate an unload/eject */
+ up_read(&common->filesem);
+ down_write(&common->filesem);
+ fsg_lun_close(curlun);
+ curlun->ejected = 1;
+ up_write(&common->filesem);
+ down_read(&common->filesem);
+ }
+ } else {
+
+ /* Our emulation doesn't support mounting; the medium is
+ * available for use as soon as it is loaded. */
+ if (!fsg_lun_is_open(curlun)) {
+ curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
+ return -EINVAL;
+ }
+ }
return 0;
}
@@ -2412,6 +2449,26 @@ static void fsg_disable(struct usb_function *f)
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
}
+static void fsg_suspend(struct usb_function *f)
+{
+ struct fsg_dev *fsg = fsg_from_func(f);
+ struct fsg_lun *curlun = fsg->common->luns;
+ int i;
+
+ for (i = 0; i < fsg->common->nluns; i++, curlun++)
+ curlun->suspended = 1;
+}
+
+static void fsg_resume(struct usb_function *f)
+{
+ struct fsg_dev *fsg = fsg_from_func(f);
+ struct fsg_lun *curlun = fsg->common->luns;
+ int i;
+
+ for (i = 0; i < fsg->common->nluns; i++, curlun++)
+ curlun->suspended = 0;
+}
+
/*-------------------------------------------------------------------------*/
@@ -2641,6 +2698,8 @@ static int fsg_main_thread(void *common_)
/* Write permission is checked per LUN in store_*() functions. */
static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
+static DEVICE_ATTR(ejected, 0444, fsg_show_ejected, NULL);
+static DEVICE_ATTR(suspended, 0444, fsg_show_suspended, NULL);
/****************************** FSG COMMON ******************************/
@@ -2747,6 +2806,12 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
rc = device_create_file(&curlun->dev, &dev_attr_file);
if (rc)
goto error_luns;
+ rc = device_create_file(&curlun->dev, &dev_attr_ejected);
+ if (rc)
+ goto error_luns;
+ rc = device_create_file(&curlun->dev, &dev_attr_suspended);
+ if (rc)
+ goto error_luns;
if (lcfg->filename) {
rc = fsg_lun_open(curlun, lcfg->filename);
@@ -2887,6 +2952,8 @@ static void fsg_common_release(struct kref *ref)
for (; i; --i, ++lun) {
device_remove_file(&lun->dev, &dev_attr_ro);
device_remove_file(&lun->dev, &dev_attr_file);
+ device_remove_file(&lun->dev, &dev_attr_ejected);
+ device_remove_file(&lun->dev, &dev_attr_suspended);
fsg_lun_close(lun);
device_unregister(&lun->dev);
}
@@ -2984,6 +3051,8 @@ static int fsg_add(struct usb_composite_dev *cdev,
fsg->function.setup = fsg_setup;
fsg->function.set_alt = fsg_set_alt;
fsg->function.disable = fsg_disable;
+ fsg->function.suspend = fsg_suspend;
+ fsg->function.resume = fsg_resume;
fsg->common = common;
/* Our caller holds a reference to common structure so we
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 868d8ee..e50fbb8 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -267,6 +267,8 @@ struct fsg_lun {
unsigned int removable:1;
unsigned int cdrom:1;
unsigned int prevent_medium_removal:1;
+ unsigned int ejected:1;
+ unsigned int suspended:1;
unsigned int registered:1;
unsigned int info_valid:1;
@@ -625,6 +627,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
curlun->filp = filp;
curlun->file_length = size;
curlun->num_sectors = num_sectors;
+ curlun->ejected = 0;
LDBG(curlun, "open backing file: %s\n", filename);
rc = 0;
@@ -776,3 +779,19 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
up_write(filesem);
return (rc < 0 ? rc : count);
}
+
+static ssize_t fsg_show_ejected(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fsg_lun *curlun = fsg_lun_from_dev(dev);
+
+ return sprintf(buf, "%d\n", curlun->ejected);
+}
+
+static ssize_t fsg_show_suspended(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fsg_lun *curlun = fsg_lun_from_dev(dev);
+
+ return sprintf(buf, "%d\n", curlun->suspended);
+}
--
1.7.0.5
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] Mass Storage Gadget: Handle eject request
2010-04-20 8:34 [PATCH] Mass Storage Gadget: Handle eject request fabien.chouteau
@ 2010-04-21 9:10 ` Michał Nazarewicz
[not found] ` <w2vfb5cec441004210535j3cd72f64gd2328242eeca21a1@mail.gmail.com>
0 siblings, 1 reply; 3+ messages in thread
From: Michał Nazarewicz @ 2010-04-21 9:10 UTC (permalink / raw)
To: fabien.chouteau, linux-usb
Cc: Fabien Chouteau, David Brownell, Greg Kroah-Hartman,
Peter Korsgaard, linux-kernel
On Tue, 20 Apr 2010 10:34:09 +0200, <fabien.chouteau@gmail.com> wrote:
> Handle eject request + sysfs entries to detect ejected LUN and suspended gadget.
> diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
> index f4911c0..af13a2f 100644
> --- a/drivers/usb/gadget/f_mass_storage.c
> +++ b/drivers/usb/gadget/f_mass_storage.c
> @@ -2412,6 +2449,26 @@ static void fsg_disable(struct usb_function *f)
> raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
> }
>+static void fsg_suspend(struct usb_function *f)
> +{
> + struct fsg_dev *fsg = fsg_from_func(f);
> + struct fsg_lun *curlun = fsg->common->luns;
> + int i;
> +
> + for (i = 0; i < fsg->common->nluns; i++, curlun++)
> + curlun->suspended = 1;
> +}
> +
> +static void fsg_resume(struct usb_function *f)
> +{
> + struct fsg_dev *fsg = fsg_from_func(f);
> + struct fsg_lun *curlun = fsg->common->luns;
> + int i;
> +
> + for (i = 0; i < fsg->common->nluns; i++, curlun++)
> + curlun->suspended = 0;
> +}
> +
Clearly, suspend seems like a state of the mass storage function
as a whole rather then attribute of each logical unit so I think
it'll be better to make it global for the mass storage function
rather then per-LUN.
Even more so, it's a state of the whole gadget so in my opinion the
whole code should be moved the the gadget rather then kept in
a function!
Going even further, I would propose an sysfs entry to be added to
the composite framework as a single generic interface rather then
hacking it in each gadget/function that might need to export this
information to user space.
This provided that there is no easy way of gaining that information
in user space through same other sysfs entry.
Other then that, the patch seems fine.
--
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michał "mina86" Nazarewicz (o o)
ooo +---[mina86@mina86.com]---[mina86@jabber.org]---ooO--(_)--Ooo--
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-04-21 13:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-20 8:34 [PATCH] Mass Storage Gadget: Handle eject request fabien.chouteau
2010-04-21 9:10 ` Michał Nazarewicz
[not found] ` <w2vfb5cec441004210535j3cd72f64gd2328242eeca21a1@mail.gmail.com>
2010-04-21 13:02 ` Michał Nazarewicz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox