unsigned int nluns;
unsigned int lun;
- struct fsg_lun *luns;
+ struct fsg_lun **luns;
struct fsg_lun *curlun;
unsigned int bulk_out_maxpacket;
common->data_dir = DATA_DIR_NONE;
common->lun = cbw->Lun;
if (common->lun < common->nluns)
- common->curlun = &common->luns[common->lun];
+ common->curlun = common->luns[common->lun];
else
common->curlun = NULL;
common->tag = cbw->Tag;
common->running = 1;
for (i = 0; i < common->nluns; ++i)
- common->luns[i].unit_attention_data = SS_RESET_OCCURRED;
+ if (common->luns[i])
+ common->luns[i]->unit_attention_data =
+ SS_RESET_OCCURRED;
return rc;
}
common->state = FSG_STATE_STATUS_PHASE;
else {
for (i = 0; i < common->nluns; ++i) {
- curlun = &common->luns[i];
+ curlun = common->luns[i];
+ if (!curlun)
+ continue;
curlun->prevent_medium_removal = 0;
curlun->sense_data = SS_NO_SENSE;
curlun->unit_attention_data = SS_NO_SENSE;
* CONFIG_CHANGE cases.
*/
/* for (i = 0; i < common->nluns; ++i) */
- /* common->luns[i].unit_attention_data = */
- /* SS_RESET_OCCURRED; */
+ /* if (common->luns[i]) */
+ /* common->luns[i]->unit_attention_data = */
+ /* SS_RESET_OCCURRED; */
break;
case FSG_STATE_CONFIG_CHANGE:
if (!common->ops || !common->ops->thread_exits
|| common->ops->thread_exits(common) < 0) {
- struct fsg_lun *curlun = common->luns;
+ struct fsg_lun **curlun_it = common->luns;
unsigned i = common->nluns;
down_write(&common->filesem);
- for (; i--; ++curlun) {
- if (!fsg_lun_is_open(curlun))
+ for (; i--; ++curlun_it) {
+ struct fsg_lun *curlun = *curlun_it;
+ if (!curlun || !fsg_lun_is_open(curlun))
continue;
fsg_lun_close(curlun);
{
struct usb_gadget *gadget = cdev->gadget;
struct fsg_buffhd *bh;
- struct fsg_lun *curlun;
+ struct fsg_lun **curlun_it;
struct fsg_lun_config *lcfg;
int nluns, i, rc;
char *pathbuf;
* Create the LUNs, open their backing files, and register the
* LUN devices in sysfs.
*/
- curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL);
- if (unlikely(!curlun)) {
+ curlun_it = kcalloc(nluns, sizeof(*curlun_it), GFP_KERNEL);
+ if (unlikely(!curlun_it)) {
rc = -ENOMEM;
goto error_release;
}
- common->luns = curlun;
+ common->luns = curlun_it;
init_rwsem(&common->filesem);
- for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun, ++lcfg) {
+ for (i = 0, lcfg = cfg->luns; i < nluns; ++i, ++curlun_it, ++lcfg) {
+ struct fsg_lun *curlun;
+
+ curlun = kzalloc(sizeof(*curlun), GFP_KERNEL);
+ if (!curlun) {
+ rc = -ENOMEM;
+ common->nluns = i;
+ goto error_release;
+ }
+ *curlun_it = curlun;
+
curlun->cdrom = !!lcfg->cdrom;
curlun->ro = lcfg->cdrom || lcfg->ro;
curlun->initially_ro = curlun->ro;
INFO(common, "failed to register LUN%d: %d\n", i, rc);
common->nluns = i;
put_device(&curlun->dev);
+ kfree(curlun);
goto error_release;
}
snprintf(common->inquiry_string, sizeof common->inquiry_string,
"%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
/* Assume product name dependent on the first LUN */
- cfg->product_name ?: (common->luns->cdrom
+ cfg->product_name ?: ((*common->luns)->cdrom
? "File-CD Gadget"
: "File-Stor Gadget"),
i);
INFO(common, "Number of LUNs=%d\n", common->nluns);
pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
- for (i = 0, nluns = common->nluns, curlun = common->luns;
+ for (i = 0, nluns = common->nluns, curlun_it = common->luns;
i < nluns;
- ++curlun, ++i) {
+ ++curlun_it, ++i) {
+ struct fsg_lun *curlun = *curlun_it;
char *p = "(no medium)";
if (fsg_lun_is_open(curlun)) {
p = "(error)";
}
if (likely(common->luns)) {
- struct fsg_lun *lun = common->luns;
+ struct fsg_lun **lun_it = common->luns;
unsigned i = common->nluns;
/* In error recovery common->nluns may be zero. */
- for (; i; --i, ++lun) {
+ for (; i; --i, ++lun_it) {
+ struct fsg_lun *lun = *lun_it;
+ if (!lun)
+ continue;
device_remove_file(&lun->dev, &dev_attr_nofua);
device_remove_file(&lun->dev,
lun->cdrom
: &dev_attr_file_nonremovable);
fsg_lun_close(lun);
device_unregister(&lun->dev);
+ kfree(lun);
}
kfree(common->luns);