204 #include <linux/device.h>
205 #include <linux/fcntl.h>
207 #include <linux/fs.h>
212 #include <linux/slab.h>
214 #include <linux/string.h>
216 #include <linux/utsname.h>
218 #include <linux/usb/ch9.h>
227 #define FSG_DRIVER_DESC "Mass Storage Function"
228 #define FSG_DRIVER_VERSION "2009/09/11"
230 static const char fsg_string_interface[] =
"Mass Storage";
232 #define FSG_NO_DEVICE_STRINGS 1
234 #define FSG_NO_INTR_EP 1
368 #define IGNORE_BULK_OUT 0
379 ERROR(common,
"common->fsg is NULL in %s at %u\n", func, line);
384 #define fsg_is_set(common) likely(__fsg_is_set(common, __func__, __LINE__))
414 static int fsg_set_halt(
struct fsg_dev *fsg,
struct usb_ep *ep)
424 DBG(fsg,
"%s set halt\n", name);
425 return usb_ep_set_halt(ep);
434 static void wakeup_thread(
struct fsg_common *common)
452 if (common->
state <= new_state) {
459 spin_unlock_irqrestore(&common->
lock, flags);
465 static int ep0_queue(
struct fsg_common *common)
473 WARNING(common,
"error in submission: %s --> %d\n",
474 common->
ep0->name, rc);
490 DBG(common,
"%s --> %d, %u/%u\n", __func__,
493 usb_ep_fifo_flush(ep);
497 spin_lock(&common->
lock);
500 wakeup_thread(common);
501 spin_unlock(&common->
lock);
511 DBG(common,
"%s --> %d, %u/%u\n", __func__,
514 usb_ep_fifo_flush(ep);
518 spin_lock(&common->
lock);
521 wakeup_thread(common);
522 spin_unlock(&common->
lock);
528 struct fsg_dev *fsg = fsg_from_func(f);
537 ++fsg->
common->ep0_req_tag;
540 dump_msg(fsg,
"ep0-setup", (
u8 *) ctrl,
sizeof(*ctrl));
556 DBG(fsg,
"bulk reset request\n");
567 VDBG(fsg,
"get max LUN\n");
572 return ep0_queue(fsg->
common);
576 "unknown class-specific control req %02x.%02x v%04x i%04x l%u\n",
588 static void start_transfer(
struct fsg_dev *fsg,
struct usb_ep *ep,
597 spin_lock_irq(&fsg->
common->lock);
600 spin_unlock_irq(&fsg->
common->lock);
614 WARNING(fsg,
"error in submission: %s --> %d\n",
623 start_transfer(common->
fsg, common->
fsg->bulk_in,
632 start_transfer(common->
fsg, common->
fsg->bulk_out,
637 static int sleep_thread(
struct fsg_common *common)
677 lba = get_unaligned_be24(&common->
cmnd[1]);
686 if ((common->
cmnd[1] & ~0x18) != 0) {
695 file_offset = ((loff_t) lba) << curlun->
blkbits;
710 amount =
min((loff_t)amount,
716 rc = sleep_thread(common);
729 file_offset >> curlun->
blkbits;
731 bh->
inreq->length = 0;
739 (
char __user *)bh->
buf,
740 amount, &file_offset_tmp);
741 VLDBG(curlun,
"file read %u @ %llu -> %d\n", amount,
742 (
unsigned long long)file_offset, (
int)nread);
747 LDBG(curlun,
"error in file read: %d\n", (
int)nread);
749 }
else if (nread < amount) {
750 LDBG(curlun,
"partial file read: %d/%u\n",
754 file_offset += nread;
755 amount_left -= nread;
763 bh->
inreq->length = nread;
767 if (nread < amount) {
770 file_offset >> curlun->
blkbits;
775 if (amount_left == 0)
780 if (!start_in_transfer(common, bh))
798 u32 amount_left_to_req, amount_left_to_write;
808 spin_lock(&curlun->
filp->f_lock);
810 spin_unlock(&curlun->
filp->f_lock);
817 lba = get_unaligned_be24(&common->
cmnd[1]);
827 if (common->
cmnd[1] & ~0x18) {
831 if (!curlun->
nofua && (common->
cmnd[1] & 0x08)) {
832 spin_lock(&curlun->
filp->f_lock);
834 spin_unlock(&curlun->
filp->f_lock);
844 file_offset = usb_offset = ((loff_t) lba) << curlun->
blkbits;
848 while (amount_left_to_write > 0) {
873 usb_offset += amount;
875 amount_left_to_req -= amount;
876 if (amount_left_to_req == 0)
884 set_bulk_out_req_length(common, bh, amount);
885 if (!start_out_transfer(common, bh))
902 if (bh->
outreq->status != 0) {
905 file_offset >> curlun->
blkbits;
910 amount = bh->
outreq->actual;
913 "write %u @ %llu beyond end %llu\n",
914 amount, (
unsigned long long)file_offset,
932 (
char __user *)bh->
buf,
933 amount, &file_offset_tmp);
934 VLDBG(curlun,
"file write %u @ %llu -> %d\n", amount,
935 (
unsigned long long)file_offset, (
int)nwritten);
940 LDBG(curlun,
"error in file write: %d\n",
943 }
else if (nwritten < amount) {
944 LDBG(curlun,
"partial file write: %d/%u\n",
945 (
int)nwritten, amount);
948 file_offset += nwritten;
949 amount_left_to_write -= nwritten;
953 if (nwritten < amount) {
956 file_offset >> curlun->
blkbits;
971 rc = sleep_thread(common);
982 static int do_synchronize_cache(
struct fsg_common *common)
989 rc = fsg_lun_fsync_sub(curlun);
998 static void invalidate_sub(
struct fsg_lun *curlun)
1005 VLDBG(curlun,
"invalidate_mapping_pages -> %ld\n", rc);
1008 static int do_verify(
struct fsg_common *common)
1012 u32 verification_length;
1016 unsigned int amount;
1033 if (common->
cmnd[1] & ~0x10) {
1038 verification_length = get_unaligned_be16(&common->
cmnd[7]);
1039 if (
unlikely(verification_length == 0))
1043 amount_left = verification_length << curlun->
blkbits;
1044 file_offset = ((loff_t) lba) << curlun->
blkbits;
1047 fsg_lun_fsync_sub(curlun);
1051 invalidate_sub(curlun);
1056 while (amount_left > 0) {
1064 amount =
min((loff_t)amount,
1070 file_offset >> curlun->
blkbits;
1078 (
char __user *) bh->
buf,
1079 amount, &file_offset_tmp);
1080 VLDBG(curlun,
"file read %u @ %llu -> %d\n", amount,
1081 (
unsigned long long) file_offset,
1087 LDBG(curlun,
"error in file verify: %d\n", (
int)nread);
1089 }
else if (nread < amount) {
1090 LDBG(curlun,
"partial file verify: %d/%u\n",
1091 (
int)nread, amount);
1097 file_offset >> curlun->
blkbits;
1101 file_offset += nread;
1102 amount_left -= nread;
1179 buf[0] =
valid | 0x70;
1192 int pmi = common->
cmnd[8];
1196 if (pmi > 1 || (pmi == 0 && lba != 0)) {
1210 int msf = common->
cmnd[1] & 0x02;
1214 if (common->
cmnd[1] & ~0x02) {
1225 store_cdrom_address(&buf[4], msf, lba);
1232 int msf = common->
cmnd[1] & 0x02;
1233 int start_track = common->
cmnd[6];
1236 if ((common->
cmnd[1] & ~0x02) != 0 ||
1248 store_cdrom_address(&buf[8], msf, 0);
1252 store_cdrom_address(&buf[16], msf, curlun->
num_sectors);
1259 int mscmnd = common->
cmnd[0];
1263 int changeable_values, all_pages;
1267 if ((common->
cmnd[1] & ~0x08) != 0) {
1271 pc = common->
cmnd[2] >> 6;
1277 changeable_values = (pc == 1);
1288 buf[2] = (curlun->
ro ? 0x80 : 0x00);
1292 buf[3] = (curlun->
ro ? 0x80 : 0x00);
1309 if (!changeable_values) {
1313 put_unaligned_be16(0xffff, &buf[4]);
1316 put_unaligned_be16(0xffff, &buf[8]);
1318 put_unaligned_be16(0xffff, &buf[10]);
1329 if (!valid_page || len >
limit) {
1338 put_unaligned_be16(len - 2, buf0);
1342 static int do_start_stop(
struct fsg_common *common)
1352 }
else if ((common->
cmnd[1] & ~0x01) != 0 ||
1353 (common->
cmnd[4] & ~0x03) != 0) {
1358 loej = common->
cmnd[4] & 0x02;
1359 start = common->
cmnd[4] & 0x01;
1375 LDBG(curlun,
"unload attempt prevented\n");
1384 if (common->
ops && common->
ops->pre_eject) {
1385 int r = common->
ops->pre_eject(common, curlun,
1386 curlun - common->
luns);
1395 fsg_lun_close(curlun);
1399 return common->
ops && common->
ops->post_eject
1400 ?
min(0, common->
ops->post_eject(common, curlun,
1401 curlun - common->
luns))
1405 static int do_prevent_allow(
struct fsg_common *common)
1412 }
else if (!common->
curlun->removable) {
1417 prevent = common->
cmnd[4] & 0x01;
1418 if ((common->
cmnd[4] & ~0x01) != 0) {
1424 fsg_lun_fsync_sub(curlun);
1429 static int do_read_format_capacities(
struct fsg_common *common,
1435 buf[0] = buf[1] = buf[2] = 0;
1459 static int halt_bulk_in_endpoint(
struct fsg_dev *fsg)
1463 rc = fsg_set_halt(fsg, fsg->
bulk_in);
1465 VDBG(fsg,
"delayed bulk-in endpoint halt\n");
1468 WARNING(fsg,
"usb_ep_set_halt -> %d\n", rc);
1476 rc = usb_ep_set_halt(fsg->
bulk_in);
1481 static int wedge_bulk_in_endpoint(
struct fsg_dev *fsg)
1485 DBG(fsg,
"bulk-in set wedge\n");
1486 rc = usb_ep_set_wedge(fsg->
bulk_in);
1488 VDBG(fsg,
"delayed bulk-in endpoint wedge\n");
1491 WARNING(fsg,
"usb_ep_set_wedge -> %d\n", rc);
1499 rc = usb_ep_set_wedge(fsg->
bulk_in);
1504 static int throw_away_data(
struct fsg_common *common)
1522 bh->
outreq->status != 0) {
1523 raise_exception(common,
1541 set_bulk_out_req_length(common, bh, amount);
1542 if (!start_out_transfer(common, bh))
1551 rc = sleep_thread(common);
1558 static int finish_reply(
struct fsg_common *common)
1577 fsg_set_halt(common->
fsg, common->
fsg->bulk_out);
1578 rc = halt_bulk_in_endpoint(common->
fsg);
1595 }
else if (common->
residue == 0) {
1596 bh->
inreq->zero = 0;
1597 if (!start_in_transfer(common, bh))
1609 bh->
inreq->zero = 1;
1610 if (!start_in_transfer(common, bh))
1614 rc = halt_bulk_in_endpoint(common->
fsg);
1642 fsg_set_halt(common->
fsg,
1643 common->
fsg->bulk_out);
1653 rc = throw_away_data(common);
1660 static int send_status(
struct fsg_common *common)
1672 rc = sleep_thread(common);
1686 DBG(common,
"sending phase-error status\n");
1690 DBG(common,
"sending command-failure status\n");
1692 VDBG(common,
" sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
1698 csw = (
void *)bh->
buf;
1706 bh->
inreq->zero = 0;
1707 if (!start_in_transfer(common, bh))
1722 static int check_command(
struct fsg_common *common,
int cmnd_size,
1724 int needs_medium,
const char *name)
1727 int lun = common->
cmnd[1] >> 5;
1728 static const char dirletter[4] = {
'u',
'o',
'i',
'n'};
1736 VDBG(common,
"SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n",
1737 name, cmnd_size, dirletter[(
int) data_dir],
1780 if (cmnd_size <= common->cmnd_size) {
1781 DBG(common,
"%s is buggy! Expected length %d "
1782 "but we got %d\n", name,
1792 if (common->
lun != lun)
1793 DBG(common,
"using LUN %d from CBW, not LUN %d from CDB\n",
1813 DBG(common,
"unsupported LUN %d\n", common->
lun);
1831 common->
cmnd[1] &= 0x1f;
1832 for (i = 1; i < cmnd_size; ++
i) {
1833 if (common->
cmnd[i] && !(mask & (1 << i))) {
1851 static int check_command_size_in_blocks(
struct fsg_common *common,
1853 unsigned int mask,
int needs_medium,
const char *name)
1857 return check_command(common, cmnd_size, data_dir,
1858 mask, needs_medium, name);
1861 static int do_scsi_command(
struct fsg_common *common)
1875 rc = sleep_thread(common);
1883 switch (common->
cmnd[0]) {
1891 reply = do_inquiry(common, bh);
1900 reply = do_mode_select(common, bh);
1905 get_unaligned_be16(&common->
cmnd[7]);
1910 reply = do_mode_select(common, bh);
1916 (1<<1) | (1<<2) | (1<<4), 0,
1919 reply = do_mode_sense(common, bh);
1924 get_unaligned_be16(&common->
cmnd[7]);
1926 (1<<1) | (1<<2) | (3<<7), 0,
1929 reply = do_mode_sense(common, bh);
1936 "PREVENT-ALLOW MEDIUM REMOVAL");
1938 reply = do_prevent_allow(common);
1942 i = common->
cmnd[4];
1944 reply = check_command_size_in_blocks(common, 6,
1954 get_unaligned_be16(&common->
cmnd[7]);
1955 reply = check_command_size_in_blocks(common, 10,
1957 (1<<1) | (0xf<<2) | (3<<7), 1,
1966 reply = check_command_size_in_blocks(common, 12,
1968 (1<<1) | (0xf<<2) | (0xf<<6), 1,
1977 (0xf<<2) | (1<<8), 1,
1980 reply = do_read_capacity(common, bh);
1987 get_unaligned_be16(&common->
cmnd[7]);
1989 (3<<7) | (0x1f<<1), 1,
1992 reply = do_read_header(common, bh);
1999 get_unaligned_be16(&common->
cmnd[7]);
2004 reply = do_read_toc(common, bh);
2009 get_unaligned_be16(&common->
cmnd[7]);
2012 "READ FORMAT CAPACITIES");
2014 reply = do_read_format_capacities(common, bh);
2023 reply = do_request_sense(common, bh);
2032 reply = do_start_stop(common);
2038 (0xf<<2) | (3<<7), 1,
2039 "SYNCHRONIZE CACHE");
2041 reply = do_synchronize_cache(common);
2058 (1<<1) | (0xf<<2) | (3<<7), 1,
2061 reply = do_verify(common);
2065 i = common->
cmnd[4];
2067 reply = check_command_size_in_blocks(common, 6,
2077 get_unaligned_be16(&common->
cmnd[7]);
2078 reply = check_command_size_in_blocks(common, 10,
2080 (1<<1) | (0xf<<2) | (3<<7), 1,
2089 reply = check_command_size_in_blocks(common, 12,
2091 (1<<1) | (0xf<<2) | (0xf<<6), 1,
2112 sprintf(unknown,
"Unknown x%02x", common->
cmnd[0]);
2113 reply = check_command(common, common->
cmnd_size,
2131 bh->
inreq->length = reply;
2156 DBG(fsg,
"invalid CBW: len %u sig 0x%x\n",
2171 wedge_bulk_in_endpoint(fsg);
2179 DBG(fsg,
"non-meaningful CBW: lun = %u, flags = 0x%x, "
2189 halt_bulk_in_endpoint(fsg);
2205 if (common->
lun >= 0 && common->
lun < common->
nluns)
2213 static int get_next_command(
struct fsg_common *common)
2221 rc = sleep_thread(common);
2228 if (!start_out_transfer(common, bh))
2240 rc = sleep_thread(common);
2257 *preq = usb_ep_alloc_request(ep,
GFP_ATOMIC);
2260 ERROR(common,
"can't allocate request for %s\n", ep->
name);
2271 DBG(common,
"reset interface\n");
2309 common->
fsg = new_fsg;
2316 rc = usb_ep_enable(fsg->
bulk_in);
2346 bh->
inreq->complete = bulk_in_complete;
2347 bh->
outreq->complete = bulk_out_complete;
2351 for (i = 0; i < common->
nluns; ++
i)
2359 static int fsg_set_alt(
struct usb_function *f,
unsigned intf,
unsigned alt)
2361 struct fsg_dev *fsg = fsg_from_func(f);
2362 fsg->
common->new_fsg = fsg;
2369 struct fsg_dev *fsg = fsg_from_func(f);
2384 unsigned int exception_req_tag;
2397 DBG(common,
"Main thread exiting on signal\n");
2407 usb_ep_dequeue(common->
fsg->bulk_in, bh->
inreq);
2409 usb_ep_dequeue(common->
fsg->bulk_out,
2420 if (num_active == 0)
2422 if (sleep_thread(common))
2427 if (common->
fsg->bulk_in_enabled)
2428 usb_ep_fifo_flush(common->
fsg->bulk_in);
2429 if (common->
fsg->bulk_out_enabled)
2430 usb_ep_fifo_flush(common->
fsg->bulk_out);
2437 spin_lock_irq(&common->
lock);
2446 old_state = common->
state;
2451 for (i = 0; i < common->
nluns; ++
i) {
2452 curlun = &common->
luns[
i];
2461 spin_unlock_irq(&common->
lock);
2464 switch (old_state) {
2466 send_status(common);
2467 spin_lock_irq(&common->
lock);
2470 spin_unlock_irq(&common->
lock);
2482 &common->
fsg->atomic_bitflags))
2483 usb_ep_clear_halt(common->
fsg->bulk_in);
2499 do_set_interface(common, common->
new_fsg);
2506 do_set_interface(common,
NULL);
2507 spin_lock_irq(&common->
lock);
2509 spin_unlock_irq(&common->
lock);
2525 static int fsg_main_thread(
void *common_)
2550 if (exception_in_progress(common) || signal_pending(
current)) {
2556 sleep_thread(common);
2560 if (get_next_command(common))
2563 spin_lock_irq(&common->
lock);
2564 if (!exception_in_progress(common))
2566 spin_unlock_irq(&common->
lock);
2568 if (do_scsi_command(common) || finish_reply(common))
2571 spin_lock_irq(&common->
lock);
2572 if (!exception_in_progress(common))
2574 spin_unlock_irq(&common->
lock);
2576 if (send_status(common))
2579 spin_lock_irq(&common->
lock);
2580 if (!exception_in_progress(common))
2582 spin_unlock_irq(&common->
lock);
2585 spin_lock_irq(&common->
lock);
2587 spin_unlock_irq(&common->
lock);
2589 if (!common->
ops || !common->
ops->thread_exits
2590 || common->
ops->thread_exits(common) < 0) {
2592 unsigned i = common->
nluns;
2595 for (; i--; ++curlun) {
2599 fsg_lun_close(curlun);
2624 static void fsg_common_release(
struct kref *ref);
2626 static void fsg_lun_release(
struct device *
dev)
2631 static inline void fsg_common_get(
struct fsg_common *common)
2633 kref_get(&common->
ref);
2636 static inline void fsg_common_put(
struct fsg_common *common)
2638 kref_put(&common->
ref, fsg_common_release);
2648 struct fsg_lun_config *lcfg;
2652 rc = fsg_num_buffers_validate();
2659 dev_err(&gadget->
dev,
"invalid number of LUNs: %u\n", nluns);
2665 common = kzalloc(
sizeof *common,
GFP_KERNEL);
2670 memset(common, 0,
sizeof *common);
2674 common->
buffhds = kcalloc(fsg_num_buffers,
2686 common->
ep0 = gadget->
ep0;
2696 fsg_intf_desc.iInterface =
rc;
2703 curlun = kcalloc(nluns,
sizeof(*curlun),
GFP_KERNEL);
2708 common->
luns = curlun;
2712 for (i = 0, lcfg = cfg->
luns; i < nluns; ++i, ++curlun, ++lcfg) {
2713 curlun->
cdrom = !!lcfg->cdrom;
2714 curlun->
ro = lcfg->cdrom || lcfg->ro;
2717 curlun->
dev.release = fsg_lun_release;
2718 curlun->
dev.parent = &gadget->
dev;
2725 INFO(common,
"failed to register LUN%d: %d\n", i, rc);
2733 ? &dev_attr_ro_cdrom
2740 : &dev_attr_file_nonremovable);
2747 if (lcfg->filename) {
2748 rc = fsg_lun_open(curlun, lcfg->filename);
2752 ERROR(common,
"no file given for LUN%d\n", i);
2762 goto buffhds_first_it;
2779 i = usb_gadget_controller_number(gadget);
2783 WARNING(common,
"controller '%s' not recognized\n",
2792 ?
"File-Stor Gadget"
2793 :
"File-CD Gadget"),
2805 kref_init(&common->
ref);
2819 INFO(common,
"Number of LUNs=%d\n", common->
nluns);
2822 for (i = 0, nluns = common->
nluns, curlun = common->
luns;
2825 char *
p =
"(no medium)";
2835 LINFO(curlun,
"LUN: %s%s%sfile: %s\n",
2837 curlun->
ro ?
"read only " :
"",
2838 curlun->
cdrom ?
"CD-ROM " :
"",
2843 DBG(common,
"I/O thread pid: %d\n", task_pid_nr(common->
thread_task));
2850 common->
nluns = i + 1;
2854 fsg_common_release(&common->
ref);
2858 static void fsg_common_release(
struct kref *ref)
2870 unsigned i = common->
nluns;
2873 for (;
i; --
i, ++
lun) {
2877 ? &dev_attr_ro_cdrom
2882 : &dev_attr_file_nonremovable);
2895 }
while (++bh, --i);
2908 struct fsg_dev *fsg = fsg_from_func(f);
2911 DBG(fsg,
"unbind\n");
2912 if (fsg->
common->fsg == fsg) {
2919 fsg_common_put(common);
2920 usb_free_descriptors(fsg->
function.descriptors);
2921 usb_free_descriptors(fsg->
function.hs_descriptors);
2922 usb_free_descriptors(fsg->
function.ss_descriptors);
2928 struct fsg_dev *fsg = fsg_from_func(f);
2939 fsg_intf_desc.bInterfaceNumber =
i;
2960 if (gadget_is_dualspeed(gadget)) {
2962 fsg_hs_bulk_in_desc.bEndpointAddress =
2963 fsg_fs_bulk_in_desc.bEndpointAddress;
2964 fsg_hs_bulk_out_desc.bEndpointAddress =
2965 fsg_fs_bulk_out_desc.bEndpointAddress;
2973 if (gadget_is_superspeed(gadget)) {
2979 fsg_ss_bulk_in_desc.bEndpointAddress =
2980 fsg_fs_bulk_in_desc.bEndpointAddress;
2981 fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
2983 fsg_ss_bulk_out_desc.bEndpointAddress =
2984 fsg_fs_bulk_out_desc.bEndpointAddress;
2985 fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
2998 ERROR(fsg,
"unable to autoconfigure all endpoints\n");
3022 fsg->
function.strings = fsg_strings_array;
3026 fsg->
function.set_alt = fsg_set_alt;
3027 fsg->
function.disable = fsg_disable;
3042 fsg_common_get(fsg->
common);
3062 #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \
3063 module_param_array_named(prefix ## name, params.name, type, \
3064 &prefix ## params.name ## _count, \
3066 MODULE_PARM_DESC(prefix ## name, desc)
3068 #define _FSG_MODULE_PARAM(prefix, params, name, type, desc) \
3069 module_param_named(prefix ## name, params.name, type, \
3071 MODULE_PARM_DESC(prefix ## name, desc)
3073 #define FSG_MODULE_PARAMETERS(prefix, params) \
3074 _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \
3075 "names of backing files or devices"); \
3076 _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \
3077 "true to force read-only"); \
3078 _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool, \
3079 "true to simulate removable media"); \
3080 _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \
3081 "true to simulate CD-ROM instead of disk"); \
3082 _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \
3083 "true to ignore SCSI WRITE(10,12) FUA bit"); \
3084 _FSG_MODULE_PARAM(prefix, params, luns, uint, \
3085 "number of LUNs"); \
3086 _FSG_MODULE_PARAM(prefix, params, stall, bool, \
3087 "false to prevent bulk stalls")
3090 fsg_config_from_params(
struct fsg_config *cfg,
3093 struct fsg_lun_config *
lun;
3099 (
unsigned)FSG_MAX_LUNS);
3100 for (i = 0, lun = cfg->
luns; i < cfg->nluns; ++i, ++lun) {
3101 lun->ro = !!params->
ro[
i];
3102 lun->cdrom = !!params->
cdrom[
i];
3123 fsg_common_from_params(
struct fsg_common *common,
3128 fsg_common_from_params(
struct fsg_common *common,
3133 fsg_config_from_params(&cfg, params);
3134 return fsg_common_init(common, cdev, &cfg);