Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 207987
b: refs/heads/master
c: 8876f5e
h: refs/heads/master
i:
  207985: 95bd494
  207983: 9336811
v: v3
  • Loading branch information
Michal Nazarewicz authored and Greg Kroah-Hartman committed Aug 10, 2010
1 parent 252d619 commit 9cd20df
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 41 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3f3e12d050052032a51f75e72e540322e2a7da2b
refs/heads/master: 8876f5e7d3b2a320777dd4f6f5301d474c97a06c
109 changes: 70 additions & 39 deletions trunk/drivers/usb/gadget/f_mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,27 @@ static const char fsg_string_interface[] = "Mass Storage";
/*-------------------------------------------------------------------------*/

struct fsg_dev;
struct fsg_common;

/* FSF callback functions */
struct fsg_operations {
/* Callback function to call when thread exits. If no
* callback is set or it returns value lower then zero MSF
* will force eject all LUNs it operates on (including those
* marked as non-removable or with prevent_medium_removal flag
* set). */
int (*thread_exits)(struct fsg_common *common);

/* Called prior to ejection. Negative return means error,
* zero means to continue with ejection, positive means not to
* eject. */
int (*pre_eject)(struct fsg_common *common,
struct fsg_lun *lun, int num);
/* Called after ejection. Negative return means error, zero
* or positive is just a success. */
int (*post_eject)(struct fsg_common *common,
struct fsg_lun *lun, int num);
};


/* Data shared by all the FSG instances. */
Expand Down Expand Up @@ -368,8 +389,8 @@ struct fsg_common {
struct completion thread_notifier;
struct task_struct *thread_task;

/* Callback function to call when thread exits. */
int (*thread_exits)(struct fsg_common *common);
/* Callback functions. */
const struct fsg_operations *ops;
/* Gadget's private data. */
void *private_data;

Expand All @@ -393,12 +414,8 @@ struct fsg_config {
const char *lun_name_format;
const char *thread_name;

/* Callback function to call when thread exits. If no
* callback is set or it returns value lower then zero MSF
* will force eject all LUNs it operates on (including those
* marked as non-removable or with prevent_medium_removal flag
* set). */
int (*thread_exits)(struct fsg_common *common);
/* Callback functions. */
const struct fsg_operations *ops;
/* Gadget's private data. */
void *private_data;

Expand Down Expand Up @@ -434,6 +451,7 @@ static inline int __fsg_is_set(struct fsg_common *common,
if (common->fsg)
return 1;
ERROR(common, "common->fsg is NULL in %s at %u\n", func, line);
WARN_ON(1);
return 0;
}

Expand Down Expand Up @@ -1392,43 +1410,55 @@ static int do_start_stop(struct fsg_common *common)
} else if (!curlun->removable) {
curlun->sense_data = SS_INVALID_COMMAND;
return -EINVAL;
}

loej = common->cmnd[4] & 0x02;
start = common->cmnd[4] & 0x01;

/* eject code from file_storage.c:do_start_stop() */

if ((common->cmnd[1] & ~0x01) != 0 || /* Mask away Immed */
(common->cmnd[4] & ~0x03) != 0) { /* Mask LoEj, Start */
} else 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);
up_write(&common->filesem);
down_read(&common->filesem);
}
} else {
loej = common->cmnd[4] & 0x02;
start = common->cmnd[4] & 0x01;

/* Our emulation doesn't support mounting; the medium is
* available for use as soon as it is loaded. */
/* Our emulation doesn't support mounting; the medium is
* available for use as soon as it is loaded. */
if (start) {
if (!fsg_lun_is_open(curlun)) {
curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
return -EINVAL;
}
return 0;
}
return 0;

/* 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)
return 0;

/* Simulate an unload/eject */
if (common->ops && common->ops->pre_eject) {
int r = common->ops->pre_eject(common, curlun,
curlun - common->luns);
if (unlikely(r < 0))
return r;
else if (r)
return 0;
}

up_read(&common->filesem);
down_write(&common->filesem);
fsg_lun_close(curlun);
up_write(&common->filesem);
down_read(&common->filesem);

return common->ops && common->ops->post_eject
? min(0, common->ops->post_eject(common, curlun,
curlun - common->luns))
: 0;
}


Expand Down Expand Up @@ -2607,7 +2637,8 @@ static int fsg_main_thread(void *common_)
common->thread_task = NULL;
spin_unlock_irq(&common->lock);

if (!common->thread_exits || common->thread_exits(common) < 0) {
if (!common->ops || !common->ops->thread_exits
|| common->ops->thread_exits(common) < 0) {
struct fsg_lun *curlun = common->luns;
unsigned i = common->nluns;

Expand Down Expand Up @@ -2683,6 +2714,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
common->free_storage_on_release = 0;
}

common->ops = cfg->ops;
common->private_data = cfg->private_data;

common->gadget = gadget;
Expand Down Expand Up @@ -2804,7 +2836,6 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,


/* Tell the thread to start working */
common->thread_exits = cfg->thread_exits;
common->thread_task =
kthread_create(fsg_main_thread, common,
OR(cfg->thread_name, "file-storage"));
Expand Down Expand Up @@ -3100,8 +3131,8 @@ fsg_config_from_params(struct fsg_config *cfg,
cfg->product_name = 0;
cfg->release = 0xffff;

cfg->thread_exits = 0;
cfg->private_data = 0;
cfg->ops = NULL;
cfg->private_data = NULL;

/* Finalise */
cfg->can_stall = params->stall;
Expand Down
5 changes: 4 additions & 1 deletion trunk/drivers/usb/gadget/mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ static int msg_thread_exits(struct fsg_common *common)

static int __init msg_do_config(struct usb_configuration *c)
{
static const struct fsg_operations ops = {
.thread_exits = msg_thread_exits,
};
static struct fsg_common common;

struct fsg_common *retp;
Expand All @@ -155,7 +158,7 @@ static int __init msg_do_config(struct usb_configuration *c)
}

fsg_config_from_params(&config, &mod_data);
config.thread_exits = msg_thread_exits;
config.ops = &ops;

retp = fsg_common_init(&common, c->cdev, &config);
if (IS_ERR(retp))
Expand Down

0 comments on commit 9cd20df

Please sign in to comment.