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>
217 #include <linux/usb/ch9.h>
226 #define FSG_DRIVER_DESC "Mass Storage Function"
227 #define FSG_DRIVER_VERSION "2009/09/11"
229 static const char fsg_string_interface[] =
"Mass Storage";
231 #define FSG_NO_DEVICE_STRINGS 1
233 #define FSG_NO_INTR_EP 1
336 struct fsg_lun_config {
366 #define IGNORE_BULK_OUT 0
377 ERROR(common,
"common->fsg is NULL in %s at %u\n", func, line);
382 #define fsg_is_set(common) likely(__fsg_is_set(common, __func__, __LINE__))
412 static int fsg_set_halt(
struct fsg_dev *fsg,
struct usb_ep *ep)
422 DBG(fsg,
"%s set halt\n", name);
423 return usb_ep_set_halt(ep);
432 static void wakeup_thread(
struct fsg_common *common)
450 if (common->
state <= new_state) {
457 spin_unlock_irqrestore(&common->
lock, flags);
463 static int ep0_queue(
struct fsg_common *common)
471 WARNING(common,
"error in submission: %s --> %d\n",
472 common->
ep0->name, rc);
488 DBG(common,
"%s --> %d, %u/%u\n", __func__,
491 usb_ep_fifo_flush(ep);
495 spin_lock(&common->
lock);
498 wakeup_thread(common);
499 spin_unlock(&common->
lock);
509 DBG(common,
"%s --> %d, %u/%u\n", __func__,
512 usb_ep_fifo_flush(ep);
516 spin_lock(&common->
lock);
519 wakeup_thread(common);
520 spin_unlock(&common->
lock);
526 struct fsg_dev *fsg = fsg_from_func(f);
535 ++fsg->
common->ep0_req_tag;
538 dump_msg(fsg,
"ep0-setup", (
u8 *) ctrl,
sizeof(*ctrl));
554 DBG(fsg,
"bulk reset request\n");
565 VDBG(fsg,
"get max LUN\n");
570 return ep0_queue(fsg->
common);
574 "unknown class-specific control req %02x.%02x v%04x i%04x l%u\n",
586 static void start_transfer(
struct fsg_dev *fsg,
struct usb_ep *ep,
595 spin_lock_irq(&fsg->
common->lock);
598 spin_unlock_irq(&fsg->
common->lock);
612 WARNING(fsg,
"error in submission: %s --> %d\n",
621 start_transfer(common->
fsg, common->
fsg->bulk_in,
630 start_transfer(common->
fsg, common->
fsg->bulk_out,
635 static int sleep_thread(
struct fsg_common *common)
675 lba = get_unaligned_be24(&common->
cmnd[1]);
684 if ((common->
cmnd[1] & ~0x18) != 0) {
693 file_offset = ((loff_t) lba) << curlun->
blkbits;
708 amount =
min((loff_t)amount,
714 rc = sleep_thread(common);
727 file_offset >> curlun->
blkbits;
729 bh->
inreq->length = 0;
737 (
char __user *)bh->
buf,
738 amount, &file_offset_tmp);
739 VLDBG(curlun,
"file read %u @ %llu -> %d\n", amount,
740 (
unsigned long long)file_offset, (
int)nread);
745 LDBG(curlun,
"error in file read: %d\n", (
int)nread);
747 }
else if (nread < amount) {
748 LDBG(curlun,
"partial file read: %d/%u\n",
752 file_offset += nread;
753 amount_left -= nread;
761 bh->
inreq->length = nread;
765 if (nread < amount) {
768 file_offset >> curlun->
blkbits;
773 if (amount_left == 0)
778 if (!start_in_transfer(common, bh))
796 u32 amount_left_to_req, amount_left_to_write;
806 spin_lock(&curlun->
filp->f_lock);
808 spin_unlock(&curlun->
filp->f_lock);
815 lba = get_unaligned_be24(&common->
cmnd[1]);
825 if (common->
cmnd[1] & ~0x18) {
829 if (!curlun->
nofua && (common->
cmnd[1] & 0x08)) {
830 spin_lock(&curlun->
filp->f_lock);
832 spin_unlock(&curlun->
filp->f_lock);
842 file_offset = usb_offset = ((loff_t) lba) << curlun->
blkbits;
846 while (amount_left_to_write > 0) {
871 usb_offset += amount;
873 amount_left_to_req -= amount;
874 if (amount_left_to_req == 0)
882 set_bulk_out_req_length(common, bh, amount);
883 if (!start_out_transfer(common, bh))
900 if (bh->
outreq->status != 0) {
903 file_offset >> curlun->
blkbits;
908 amount = bh->
outreq->actual;
911 "write %u @ %llu beyond end %llu\n",
912 amount, (
unsigned long long)file_offset,
930 (
char __user *)bh->
buf,
931 amount, &file_offset_tmp);
932 VLDBG(curlun,
"file write %u @ %llu -> %d\n", amount,
933 (
unsigned long long)file_offset, (
int)nwritten);
938 LDBG(curlun,
"error in file write: %d\n",
941 }
else if (nwritten < amount) {
942 LDBG(curlun,
"partial file write: %d/%u\n",
943 (
int)nwritten, amount);
946 file_offset += nwritten;
947 amount_left_to_write -= nwritten;
951 if (nwritten < amount) {
954 file_offset >> curlun->
blkbits;
969 rc = sleep_thread(common);
980 static int do_synchronize_cache(
struct fsg_common *common)
987 rc = fsg_lun_fsync_sub(curlun);
996 static void invalidate_sub(
struct fsg_lun *curlun)
1003 VLDBG(curlun,
"invalidate_mapping_pages -> %ld\n", rc);
1006 static int do_verify(
struct fsg_common *common)
1010 u32 verification_length;
1014 unsigned int amount;
1031 if (common->
cmnd[1] & ~0x10) {
1036 verification_length = get_unaligned_be16(&common->
cmnd[7]);
1037 if (
unlikely(verification_length == 0))
1041 amount_left = verification_length << curlun->
blkbits;
1042 file_offset = ((loff_t) lba) << curlun->
blkbits;
1045 fsg_lun_fsync_sub(curlun);
1049 invalidate_sub(curlun);
1054 while (amount_left > 0) {
1062 amount =
min((loff_t)amount,
1068 file_offset >> curlun->
blkbits;
1076 (
char __user *) bh->
buf,
1077 amount, &file_offset_tmp);
1078 VLDBG(curlun,
"file read %u @ %llu -> %d\n", amount,
1079 (
unsigned long long) file_offset,
1085 LDBG(curlun,
"error in file verify: %d\n", (
int)nread);
1087 }
else if (nread < amount) {
1088 LDBG(curlun,
"partial file verify: %d/%u\n",
1089 (
int)nread, amount);
1095 file_offset >> curlun->
blkbits;
1099 file_offset += nread;
1100 amount_left -= nread;
1177 buf[0] =
valid | 0x70;
1190 int pmi = common->
cmnd[8];
1194 if (pmi > 1 || (pmi == 0 && lba != 0)) {
1208 int msf = common->
cmnd[1] & 0x02;
1212 if (common->
cmnd[1] & ~0x02) {
1223 store_cdrom_address(&buf[4], msf, lba);
1230 int msf = common->
cmnd[1] & 0x02;
1231 int start_track = common->
cmnd[6];
1234 if ((common->
cmnd[1] & ~0x02) != 0 ||
1246 store_cdrom_address(&buf[8], msf, 0);
1250 store_cdrom_address(&buf[16], msf, curlun->
num_sectors);
1257 int mscmnd = common->
cmnd[0];
1261 int changeable_values, all_pages;
1265 if ((common->
cmnd[1] & ~0x08) != 0) {
1269 pc = common->
cmnd[2] >> 6;
1275 changeable_values = (pc == 1);
1286 buf[2] = (curlun->
ro ? 0x80 : 0x00);
1290 buf[3] = (curlun->
ro ? 0x80 : 0x00);
1307 if (!changeable_values) {
1311 put_unaligned_be16(0xffff, &buf[4]);
1314 put_unaligned_be16(0xffff, &buf[8]);
1316 put_unaligned_be16(0xffff, &buf[10]);
1327 if (!valid_page || len >
limit) {
1336 put_unaligned_be16(len - 2, buf0);
1340 static int do_start_stop(
struct fsg_common *common)
1350 }
else if ((common->
cmnd[1] & ~0x01) != 0 ||
1351 (common->
cmnd[4] & ~0x03) != 0) {
1356 loej = common->
cmnd[4] & 0x02;
1357 start = common->
cmnd[4] & 0x01;
1373 LDBG(curlun,
"unload attempt prevented\n");
1382 if (common->
ops && common->
ops->pre_eject) {
1383 int r = common->
ops->pre_eject(common, curlun,
1384 curlun - common->
luns);
1393 fsg_lun_close(curlun);
1397 return common->
ops && common->
ops->post_eject
1398 ?
min(0, common->
ops->post_eject(common, curlun,
1399 curlun - common->
luns))
1403 static int do_prevent_allow(
struct fsg_common *common)
1410 }
else if (!common->
curlun->removable) {
1415 prevent = common->
cmnd[4] & 0x01;
1416 if ((common->
cmnd[4] & ~0x01) != 0) {
1422 fsg_lun_fsync_sub(curlun);
1427 static int do_read_format_capacities(
struct fsg_common *common,
1433 buf[0] = buf[1] = buf[2] = 0;
1457 static int halt_bulk_in_endpoint(
struct fsg_dev *fsg)
1461 rc = fsg_set_halt(fsg, fsg->
bulk_in);
1463 VDBG(fsg,
"delayed bulk-in endpoint halt\n");
1466 WARNING(fsg,
"usb_ep_set_halt -> %d\n", rc);
1474 rc = usb_ep_set_halt(fsg->
bulk_in);
1479 static int wedge_bulk_in_endpoint(
struct fsg_dev *fsg)
1483 DBG(fsg,
"bulk-in set wedge\n");
1484 rc = usb_ep_set_wedge(fsg->
bulk_in);
1486 VDBG(fsg,
"delayed bulk-in endpoint wedge\n");
1489 WARNING(fsg,
"usb_ep_set_wedge -> %d\n", rc);
1497 rc = usb_ep_set_wedge(fsg->
bulk_in);
1502 static int throw_away_data(
struct fsg_common *common)
1520 bh->
outreq->status != 0) {
1521 raise_exception(common,
1539 set_bulk_out_req_length(common, bh, amount);
1540 if (!start_out_transfer(common, bh))
1549 rc = sleep_thread(common);
1556 static int finish_reply(
struct fsg_common *common)
1575 fsg_set_halt(common->
fsg, common->
fsg->bulk_out);
1576 rc = halt_bulk_in_endpoint(common->
fsg);
1593 }
else if (common->
residue == 0) {
1594 bh->
inreq->zero = 0;
1595 if (!start_in_transfer(common, bh))
1607 bh->
inreq->zero = 1;
1608 if (!start_in_transfer(common, bh))
1612 rc = halt_bulk_in_endpoint(common->
fsg);
1640 fsg_set_halt(common->
fsg,
1641 common->
fsg->bulk_out);
1651 rc = throw_away_data(common);
1658 static int send_status(
struct fsg_common *common)
1670 rc = sleep_thread(common);
1684 DBG(common,
"sending phase-error status\n");
1688 DBG(common,
"sending command-failure status\n");
1690 VDBG(common,
" sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
1696 csw = (
void *)bh->
buf;
1704 bh->
inreq->zero = 0;
1705 if (!start_in_transfer(common, bh))
1720 static int check_command(
struct fsg_common *common,
int cmnd_size,
1722 int needs_medium,
const char *name)
1725 int lun = common->
cmnd[1] >> 5;
1726 static const char dirletter[4] = {
'u',
'o',
'i',
'n'};
1734 VDBG(common,
"SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n",
1735 name, cmnd_size, dirletter[(
int) data_dir],
1778 if (cmnd_size <= common->cmnd_size) {
1779 DBG(common,
"%s is buggy! Expected length %d "
1780 "but we got %d\n", name,
1790 if (common->
lun != lun)
1791 DBG(common,
"using LUN %d from CBW, not LUN %d from CDB\n",
1811 DBG(common,
"unsupported LUN %d\n", common->
lun);
1829 common->
cmnd[1] &= 0x1f;
1830 for (i = 1; i < cmnd_size; ++
i) {
1831 if (common->
cmnd[i] && !(mask & (1 << i))) {
1849 static int check_command_size_in_blocks(
struct fsg_common *common,
1851 unsigned int mask,
int needs_medium,
const char *name)
1855 return check_command(common, cmnd_size, data_dir,
1856 mask, needs_medium, name);
1859 static int do_scsi_command(
struct fsg_common *common)
1873 rc = sleep_thread(common);
1881 switch (common->
cmnd[0]) {
1889 reply = do_inquiry(common, bh);
1898 reply = do_mode_select(common, bh);
1903 get_unaligned_be16(&common->
cmnd[7]);
1908 reply = do_mode_select(common, bh);
1914 (1<<1) | (1<<2) | (1<<4), 0,
1917 reply = do_mode_sense(common, bh);
1922 get_unaligned_be16(&common->
cmnd[7]);
1924 (1<<1) | (1<<2) | (3<<7), 0,
1927 reply = do_mode_sense(common, bh);
1934 "PREVENT-ALLOW MEDIUM REMOVAL");
1936 reply = do_prevent_allow(common);
1940 i = common->
cmnd[4];
1942 reply = check_command_size_in_blocks(common, 6,
1952 get_unaligned_be16(&common->
cmnd[7]);
1953 reply = check_command_size_in_blocks(common, 10,
1955 (1<<1) | (0xf<<2) | (3<<7), 1,
1964 reply = check_command_size_in_blocks(common, 12,
1966 (1<<1) | (0xf<<2) | (0xf<<6), 1,
1975 (0xf<<2) | (1<<8), 1,
1978 reply = do_read_capacity(common, bh);
1985 get_unaligned_be16(&common->
cmnd[7]);
1987 (3<<7) | (0x1f<<1), 1,
1990 reply = do_read_header(common, bh);
1997 get_unaligned_be16(&common->
cmnd[7]);
2002 reply = do_read_toc(common, bh);
2007 get_unaligned_be16(&common->
cmnd[7]);
2010 "READ FORMAT CAPACITIES");
2012 reply = do_read_format_capacities(common, bh);
2021 reply = do_request_sense(common, bh);
2030 reply = do_start_stop(common);
2036 (0xf<<2) | (3<<7), 1,
2037 "SYNCHRONIZE CACHE");
2039 reply = do_synchronize_cache(common);
2056 (1<<1) | (0xf<<2) | (3<<7), 1,
2059 reply = do_verify(common);
2063 i = common->
cmnd[4];
2065 reply = check_command_size_in_blocks(common, 6,
2075 get_unaligned_be16(&common->
cmnd[7]);
2076 reply = check_command_size_in_blocks(common, 10,
2078 (1<<1) | (0xf<<2) | (3<<7), 1,
2087 reply = check_command_size_in_blocks(common, 12,
2089 (1<<1) | (0xf<<2) | (0xf<<6), 1,
2110 sprintf(unknown,
"Unknown x%02x", common->
cmnd[0]);
2111 reply = check_command(common, common->
cmnd_size,
2129 bh->
inreq->length = reply;
2154 DBG(fsg,
"invalid CBW: len %u sig 0x%x\n",
2169 wedge_bulk_in_endpoint(fsg);
2177 DBG(fsg,
"non-meaningful CBW: lun = %u, flags = 0x%x, "
2187 halt_bulk_in_endpoint(fsg);
2203 if (common->
lun >= 0 && common->
lun < common->
nluns)
2211 static int get_next_command(
struct fsg_common *common)
2219 rc = sleep_thread(common);
2226 if (!start_out_transfer(common, bh))
2238 rc = sleep_thread(common);
2255 *preq = usb_ep_alloc_request(ep,
GFP_ATOMIC);
2258 ERROR(common,
"can't allocate request for %s\n", ep->
name);
2269 DBG(common,
"reset interface\n");
2307 common->
fsg = new_fsg;
2314 rc = usb_ep_enable(fsg->
bulk_in);
2344 bh->
inreq->complete = bulk_in_complete;
2345 bh->
outreq->complete = bulk_out_complete;
2349 for (i = 0; i < common->
nluns; ++
i)
2357 static int fsg_set_alt(
struct usb_function *f,
unsigned intf,
unsigned alt)
2359 struct fsg_dev *fsg = fsg_from_func(f);
2360 fsg->
common->new_fsg = fsg;
2367 struct fsg_dev *fsg = fsg_from_func(f);
2382 unsigned int exception_req_tag;
2395 DBG(common,
"Main thread exiting on signal\n");
2405 usb_ep_dequeue(common->
fsg->bulk_in, bh->
inreq);
2407 usb_ep_dequeue(common->
fsg->bulk_out,
2418 if (num_active == 0)
2420 if (sleep_thread(common))
2425 if (common->
fsg->bulk_in_enabled)
2426 usb_ep_fifo_flush(common->
fsg->bulk_in);
2427 if (common->
fsg->bulk_out_enabled)
2428 usb_ep_fifo_flush(common->
fsg->bulk_out);
2435 spin_lock_irq(&common->
lock);
2444 old_state = common->
state;
2449 for (i = 0; i < common->
nluns; ++
i) {
2450 curlun = &common->
luns[
i];
2459 spin_unlock_irq(&common->
lock);
2462 switch (old_state) {
2464 send_status(common);
2465 spin_lock_irq(&common->
lock);
2468 spin_unlock_irq(&common->
lock);
2480 &common->
fsg->atomic_bitflags))
2481 usb_ep_clear_halt(common->
fsg->bulk_in);
2497 do_set_interface(common, common->
new_fsg);
2504 do_set_interface(common,
NULL);
2505 spin_lock_irq(&common->
lock);
2507 spin_unlock_irq(&common->
lock);
2523 static int fsg_main_thread(
void *common_)
2548 if (exception_in_progress(common) || signal_pending(
current)) {
2554 sleep_thread(common);
2558 if (get_next_command(common))
2561 spin_lock_irq(&common->
lock);
2562 if (!exception_in_progress(common))
2564 spin_unlock_irq(&common->
lock);
2566 if (do_scsi_command(common) || finish_reply(common))
2569 spin_lock_irq(&common->
lock);
2570 if (!exception_in_progress(common))
2572 spin_unlock_irq(&common->
lock);
2574 if (send_status(common))
2577 spin_lock_irq(&common->
lock);
2578 if (!exception_in_progress(common))
2580 spin_unlock_irq(&common->
lock);
2583 spin_lock_irq(&common->
lock);
2585 spin_unlock_irq(&common->
lock);
2587 if (!common->
ops || !common->
ops->thread_exits
2588 || common->
ops->thread_exits(common) < 0) {
2590 unsigned i = common->
nluns;
2593 for (; i--; ++curlun) {
2597 fsg_lun_close(curlun);
2622 static void fsg_common_release(
struct kref *ref);
2624 static void fsg_lun_release(
struct device *
dev)
2629 static inline void fsg_common_get(
struct fsg_common *common)
2631 kref_get(&common->
ref);
2634 static inline void fsg_common_put(
struct fsg_common *common)
2636 kref_put(&common->
ref, fsg_common_release);
2646 struct fsg_lun_config *lcfg;
2650 rc = fsg_num_buffers_validate();
2657 dev_err(&gadget->
dev,
"invalid number of LUNs: %u\n", nluns);
2663 common = kzalloc(
sizeof *common,
GFP_KERNEL);
2668 memset(common, 0,
sizeof *common);
2672 common->
buffhds = kcalloc(fsg_num_buffers,
2684 common->
ep0 = gadget->
ep0;
2694 fsg_intf_desc.iInterface =
rc;
2701 curlun = kcalloc(nluns,
sizeof(*curlun),
GFP_KERNEL);
2706 common->
luns = curlun;
2710 for (i = 0, lcfg = cfg->
luns; i < nluns; ++i, ++curlun, ++lcfg) {
2711 curlun->
cdrom = !!lcfg->cdrom;
2712 curlun->
ro = lcfg->cdrom || lcfg->ro;
2715 curlun->
dev.release = fsg_lun_release;
2716 curlun->
dev.parent = &gadget->
dev;
2723 INFO(common,
"failed to register LUN%d: %d\n", i, rc);
2731 ? &dev_attr_ro_cdrom
2738 : &dev_attr_file_nonremovable);
2745 if (lcfg->filename) {
2746 rc = fsg_lun_open(curlun, lcfg->filename);
2750 ERROR(common,
"no file given for LUN%d\n", i);
2760 goto buffhds_first_it;
2774 i = get_default_bcdDevice();
2779 ?
"File-Stor Gadget"
2780 :
"File-CD Gadget"),
2792 kref_init(&common->
ref);
2806 INFO(common,
"Number of LUNs=%d\n", common->
nluns);
2809 for (i = 0, nluns = common->
nluns, curlun = common->
luns;
2812 char *
p =
"(no medium)";
2822 LINFO(curlun,
"LUN: %s%s%sfile: %s\n",
2824 curlun->
ro ?
"read only " :
"",
2825 curlun->
cdrom ?
"CD-ROM " :
"",
2830 DBG(common,
"I/O thread pid: %d\n", task_pid_nr(common->
thread_task));
2837 common->
nluns = i + 1;
2841 fsg_common_release(&common->
ref);
2845 static void fsg_common_release(
struct kref *ref)
2857 unsigned i = common->
nluns;
2860 for (;
i; --
i, ++
lun) {
2864 ? &dev_attr_ro_cdrom
2869 : &dev_attr_file_nonremovable);
2882 }
while (++bh, --i);
2895 struct fsg_dev *fsg = fsg_from_func(f);
2898 DBG(fsg,
"unbind\n");
2899 if (fsg->
common->fsg == fsg) {
2906 fsg_common_put(common);
2907 usb_free_descriptors(fsg->
function.descriptors);
2908 usb_free_descriptors(fsg->
function.hs_descriptors);
2909 usb_free_descriptors(fsg->
function.ss_descriptors);
2915 struct fsg_dev *fsg = fsg_from_func(f);
2926 fsg_intf_desc.bInterfaceNumber =
i;
2947 if (gadget_is_dualspeed(gadget)) {
2949 fsg_hs_bulk_in_desc.bEndpointAddress =
2950 fsg_fs_bulk_in_desc.bEndpointAddress;
2951 fsg_hs_bulk_out_desc.bEndpointAddress =
2952 fsg_fs_bulk_out_desc.bEndpointAddress;
2960 if (gadget_is_superspeed(gadget)) {
2966 fsg_ss_bulk_in_desc.bEndpointAddress =
2967 fsg_fs_bulk_in_desc.bEndpointAddress;
2968 fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
2970 fsg_ss_bulk_out_desc.bEndpointAddress =
2971 fsg_fs_bulk_out_desc.bEndpointAddress;
2972 fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
2985 ERROR(fsg,
"unable to autoconfigure all endpoints\n");
3009 fsg->
function.strings = fsg_strings_array;
3013 fsg->
function.set_alt = fsg_set_alt;
3014 fsg->
function.disable = fsg_disable;
3029 fsg_common_get(fsg->
common);
3049 #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \
3050 module_param_array_named(prefix ## name, params.name, type, \
3051 &prefix ## params.name ## _count, \
3053 MODULE_PARM_DESC(prefix ## name, desc)
3055 #define _FSG_MODULE_PARAM(prefix, params, name, type, desc) \
3056 module_param_named(prefix ## name, params.name, type, \
3058 MODULE_PARM_DESC(prefix ## name, desc)
3060 #define FSG_MODULE_PARAMETERS(prefix, params) \
3061 _FSG_MODULE_PARAM_ARRAY(prefix, params, file, charp, \
3062 "names of backing files or devices"); \
3063 _FSG_MODULE_PARAM_ARRAY(prefix, params, ro, bool, \
3064 "true to force read-only"); \
3065 _FSG_MODULE_PARAM_ARRAY(prefix, params, removable, bool, \
3066 "true to simulate removable media"); \
3067 _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool, \
3068 "true to simulate CD-ROM instead of disk"); \
3069 _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool, \
3070 "true to ignore SCSI WRITE(10,12) FUA bit"); \
3071 _FSG_MODULE_PARAM(prefix, params, luns, uint, \
3072 "number of LUNs"); \
3073 _FSG_MODULE_PARAM(prefix, params, stall, bool, \
3074 "false to prevent bulk stalls")
3077 fsg_config_from_params(
struct fsg_config *cfg,
3080 struct fsg_lun_config *
lun;
3086 (
unsigned)FSG_MAX_LUNS);
3087 for (i = 0, lun = cfg->
luns; i < cfg->nluns; ++i, ++lun) {
3088 lun->ro = !!params->
ro[
i];
3089 lun->cdrom = !!params->
cdrom[
i];
3109 fsg_common_from_params(
struct fsg_common *common,
3114 fsg_common_from_params(
struct fsg_common *common,
3119 fsg_config_from_params(&cfg, params);
3120 return fsg_common_init(common, cdev, &cfg);