Lines Matching +full:dbg +full:- +full:halt
1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
3 * f_mass_storage.c -- Mass Storage USB Composite Function
5 * Copyright (C) 2003-2008 Alan Stern
13 * appearing to the host as a disk drive or as a CD-ROM drive. In
16 * double-buffering for increased throughput.
20 * <Documentation/usb/mass-storage.rst> file.
34 * ->filename The path to the backing file for the LUN.
37 * ->ro Flag specifying access to the LUN shall be
38 * read-only. This is implied if CD-ROM
42 * ->removable Flag specifying that LUN shall be indicated as
44 * ->cdrom Flag specifying that LUN shall be reported as
45 * being a CD-ROM.
46 * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12)
57 * can_stall Set to permit function to halt bulk endpoints.
65 * structure causes error). The CD-ROM emulation includes a single
69 * This function is heavily based on "File-backed Storage Gadget" by
72 * "Information technology - Small Computer System Interface - 2"
73 * document from X3T9.2 Project 375D, Revision 10L, 7-SEP-93,
74 * available at <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>.
79 * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
87 * callbacks from the controller driver: bulk- and interrupt-request
88 * completion notifications, endpoint-0 events, and disconnect events.
97 * for pending signals/exceptions -- all this polling is necessary since
111 * provides no way to deregister the gadget when thread dies -- maybe
118 * pipeline as being a long one. Each buffer head contains a bulk-in and
119 * a bulk-out request pointer (since the buffer can be used for both
120 * output and input -- directions always are given from the host's
125 * (fsg->next_buffhd_to_fill) that points to the next buffer head to use.
138 * halt on a bulk endpoint. However, under certain circumstances the
139 * Bulk-only specification requires a stall. In such cases the driver
140 * will halt the endpoint and set a flag indicating that it should clear
141 * the halt in software during the next device reset. Hopefully this
143 * specification allows the bulk-out endpoint to halt when the host sends
145 * The driver will always use the "no-stall" approach for OUT transfers.
147 * One subtle point concerns sending status-stage responses for ep0
155 * tag value of the request associated with a long-running exception
156 * (device-reset, interface-change, or configuration-change). When the
157 * exception handler is finished, the status-stage response is submitted
160 * status-stage response.
202 /*------------------------------------------------------------------------*/
212 /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
219 .language = 0x0409, /* en-us */
228 /*-------------------------------------------------------------------------*/
247 struct usb_ep *ep0; /* Copy of gadget->ep0 */
248 struct usb_request *ep0req; /* Copy of cdev->req */
294 struct usb_gadget *gadget; /* Copy of cdev->gadget */
312 if (common->fsg) in __fsg_is_set()
314 ERROR(common, "common->fsg is NULL in %s at %u\n", func, line); in __fsg_is_set()
328 return common->state > FSG_STATE_NORMAL; in exception_in_progress()
331 /* Make bulk-out requests be divisible by the maxpacket size */
337 bh->bulk_out_intended_length = length; in set_bulk_out_req_length()
338 rem = length % common->bulk_out_maxpacket; in set_bulk_out_req_length()
340 length += common->bulk_out_maxpacket - rem; in set_bulk_out_req_length()
341 bh->outreq->length = length; in set_bulk_out_req_length()
345 /*-------------------------------------------------------------------------*/
351 if (ep == fsg->bulk_in) in fsg_set_halt()
352 name = "bulk-in"; in fsg_set_halt()
353 else if (ep == fsg->bulk_out) in fsg_set_halt()
354 name = "bulk-out"; in fsg_set_halt()
356 name = ep->name; in fsg_set_halt()
357 DBG(fsg, "%s set halt\n", name); in fsg_set_halt()
362 /*-------------------------------------------------------------------------*/
372 * Do nothing if a higher-priority exception is already in progress. in __raise_exception()
373 * If a lower-or-equal priority exception is in progress, preempt it in __raise_exception()
376 spin_lock_irqsave(&common->lock, flags); in __raise_exception()
377 if (common->state <= new_state) { in __raise_exception()
378 common->exception_req_tag = common->ep0_req_tag; in __raise_exception()
379 common->state = new_state; in __raise_exception()
380 common->exception_arg = arg; in __raise_exception()
381 if (common->thread_task) in __raise_exception()
383 common->thread_task); in __raise_exception()
385 spin_unlock_irqrestore(&common->lock, flags); in __raise_exception()
393 /*-------------------------------------------------------------------------*/
399 rc = usb_ep_queue(common->ep0, common->ep0req, GFP_ATOMIC); in ep0_queue()
400 common->ep0->driver_data = common; in ep0_queue()
401 if (rc != 0 && rc != -ESHUTDOWN) { in ep0_queue()
403 WARNING(common, "error in submission: %s --> %d\n", in ep0_queue()
404 common->ep0->name, rc); in ep0_queue()
410 /*-------------------------------------------------------------------------*/
416 struct fsg_common *common = ep->driver_data; in bulk_in_complete()
417 struct fsg_buffhd *bh = req->context; in bulk_in_complete()
419 if (req->status || req->actual != req->length) in bulk_in_complete()
420 DBG(common, "%s --> %d, %u/%u\n", __func__, in bulk_in_complete()
421 req->status, req->actual, req->length); in bulk_in_complete()
422 if (req->status == -ECONNRESET) /* Request was cancelled */ in bulk_in_complete()
426 smp_store_release(&bh->state, BUF_STATE_EMPTY); in bulk_in_complete()
427 wake_up(&common->io_wait); in bulk_in_complete()
432 struct fsg_common *common = ep->driver_data; in bulk_out_complete()
433 struct fsg_buffhd *bh = req->context; in bulk_out_complete()
435 dump_msg(common, "bulk-out", req->buf, req->actual); in bulk_out_complete()
436 if (req->status || req->actual != bh->bulk_out_intended_length) in bulk_out_complete()
437 DBG(common, "%s --> %d, %u/%u\n", __func__, in bulk_out_complete()
438 req->status, req->actual, bh->bulk_out_intended_length); in bulk_out_complete()
439 if (req->status == -ECONNRESET) /* Request was cancelled */ in bulk_out_complete()
443 smp_store_release(&bh->state, BUF_STATE_FULL); in bulk_out_complete()
444 wake_up(&common->io_wait); in bulk_out_complete()
449 int i = ARRAY_SIZE(common->luns) - 1; in _fsg_common_get_max_lun()
451 while (i >= 0 && !common->luns[i]) in _fsg_common_get_max_lun()
452 --i; in _fsg_common_get_max_lun()
461 struct usb_request *req = fsg->common->ep0req; in fsg_setup()
462 u16 w_index = le16_to_cpu(ctrl->wIndex); in fsg_setup()
463 u16 w_value = le16_to_cpu(ctrl->wValue); in fsg_setup()
464 u16 w_length = le16_to_cpu(ctrl->wLength); in fsg_setup()
466 if (!fsg_is_set(fsg->common)) in fsg_setup()
467 return -EOPNOTSUPP; in fsg_setup()
469 ++fsg->common->ep0_req_tag; /* Record arrival of a new request */ in fsg_setup()
470 req->context = NULL; in fsg_setup()
471 req->length = 0; in fsg_setup()
472 dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); in fsg_setup()
474 switch (ctrl->bRequest) { in fsg_setup()
477 if (ctrl->bRequestType != in fsg_setup()
480 if (w_index != fsg->interface_number || w_value != 0 || in fsg_setup()
482 return -EDOM; in fsg_setup()
488 DBG(fsg, "bulk reset request\n"); in fsg_setup()
489 raise_exception(fsg->common, FSG_STATE_PROTOCOL_RESET); in fsg_setup()
493 if (ctrl->bRequestType != in fsg_setup()
496 if (w_index != fsg->interface_number || w_value != 0 || in fsg_setup()
498 return -EDOM; in fsg_setup()
500 *(u8 *)req->buf = _fsg_common_get_max_lun(fsg->common); in fsg_setup()
503 req->length = min((u16)1, w_length); in fsg_setup()
504 return ep0_queue(fsg->common); in fsg_setup()
508 "unknown class-specific control req %02x.%02x v%04x i%04x l%u\n", in fsg_setup()
509 ctrl->bRequestType, ctrl->bRequest, in fsg_setup()
510 le16_to_cpu(ctrl->wValue), w_index, w_length); in fsg_setup()
511 return -EOPNOTSUPP; in fsg_setup()
515 /*-------------------------------------------------------------------------*/
525 if (ep == fsg->bulk_in) in start_transfer()
526 dump_msg(fsg, "bulk-in", req->buf, req->length); in start_transfer()
532 req->status = rc; in start_transfer()
535 * Note: currently the net2280 driver fails zero-length in start_transfer()
538 if (rc != -ESHUTDOWN && in start_transfer()
539 !(rc == -EOPNOTSUPP && req->length == 0)) in start_transfer()
540 WARNING(fsg, "error in submission: %s --> %d\n", in start_transfer()
541 ep->name, rc); in start_transfer()
552 bh->state = BUF_STATE_SENDING; in start_in_transfer()
553 rc = start_transfer(common->fsg, common->fsg->bulk_in, bh->inreq); in start_in_transfer()
555 bh->state = BUF_STATE_EMPTY; in start_in_transfer()
556 if (rc == -ESHUTDOWN) { in start_in_transfer()
557 common->running = 0; in start_in_transfer()
570 bh->state = BUF_STATE_RECEIVING; in start_out_transfer()
571 rc = start_transfer(common->fsg, common->fsg->bulk_out, bh->outreq); in start_out_transfer()
573 bh->state = BUF_STATE_FULL; in start_out_transfer()
574 if (rc == -ESHUTDOWN) { in start_out_transfer()
575 common->running = 0; in start_out_transfer()
590 * synchronize with the smp_store_release(&bh->state) in in sleep_thread()
593 rc = wait_event_freezable(common->io_wait, in sleep_thread()
594 bh && smp_load_acquire(&bh->state) >= in sleep_thread()
597 rc = wait_event_interruptible(common->io_wait, in sleep_thread()
598 bh && smp_load_acquire(&bh->state) >= in sleep_thread()
600 return rc ? -EINTR : 0; in sleep_thread()
604 /*-------------------------------------------------------------------------*/
608 struct fsg_lun *curlun = common->curlun; in do_read()
621 if (common->cmnd[0] == READ_6) in do_read()
622 lba = get_unaligned_be24(&common->cmnd[1]); in do_read()
624 if (common->cmnd[0] == READ_16) in do_read()
625 lba = get_unaligned_be64(&common->cmnd[2]); in do_read()
627 lba = get_unaligned_be32(&common->cmnd[2]); in do_read()
634 if ((common->cmnd[1] & ~0x18) != 0) { in do_read()
635 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_read()
636 return -EINVAL; in do_read()
639 if (lba >= curlun->num_sectors) { in do_read()
640 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; in do_read()
641 return -EINVAL; in do_read()
643 file_offset = ((loff_t) lba) << curlun->blkbits; in do_read()
646 amount_left = common->data_size_from_cmnd; in do_read()
648 return -EIO; /* No default reply */ in do_read()
659 curlun->file_length - file_offset); in do_read()
662 bh = common->next_buffhd_to_fill; in do_read()
672 curlun->sense_data = in do_read()
674 curlun->sense_data_info = in do_read()
675 file_offset >> curlun->blkbits; in do_read()
676 curlun->info_valid = 1; in do_read()
677 bh->inreq->length = 0; in do_read()
678 bh->state = BUF_STATE_FULL; in do_read()
684 nread = kernel_read(curlun->filp, bh->buf, amount, in do_read()
686 VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, in do_read()
689 return -EINTR; in do_read()
697 nread = round_down(nread, curlun->blksize); in do_read()
700 amount_left -= nread; in do_read()
701 common->residue -= nread; in do_read()
706 * bulk-in maxpacket size. in do_read()
708 bh->inreq->length = nread; in do_read()
709 bh->state = BUF_STATE_FULL; in do_read()
713 curlun->sense_data = SS_UNRECOVERED_READ_ERROR; in do_read()
714 curlun->sense_data_info = in do_read()
715 file_offset >> curlun->blkbits; in do_read()
716 curlun->info_valid = 1; in do_read()
724 bh->inreq->zero = 0; in do_read()
726 /* Don't know what to do if common->fsg is NULL */ in do_read()
727 return -EIO; in do_read()
728 common->next_buffhd_to_fill = bh->next; in do_read()
731 return -EIO; /* No default reply */ in do_read()
735 /*-------------------------------------------------------------------------*/
739 struct fsg_lun *curlun = common->curlun; in do_write()
749 if (curlun->ro) { in do_write()
750 curlun->sense_data = SS_WRITE_PROTECTED; in do_write()
751 return -EINVAL; in do_write()
753 spin_lock(&curlun->filp->f_lock); in do_write()
754 curlun->filp->f_flags &= ~O_SYNC; /* Default is not to wait */ in do_write()
755 spin_unlock(&curlun->filp->f_lock); in do_write()
761 if (common->cmnd[0] == WRITE_6) in do_write()
762 lba = get_unaligned_be24(&common->cmnd[1]); in do_write()
764 if (common->cmnd[0] == WRITE_16) in do_write()
765 lba = get_unaligned_be64(&common->cmnd[2]); in do_write()
767 lba = get_unaligned_be32(&common->cmnd[2]); in do_write()
775 if (common->cmnd[1] & ~0x18) { in do_write()
776 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_write()
777 return -EINVAL; in do_write()
779 if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */ in do_write()
780 spin_lock(&curlun->filp->f_lock); in do_write()
781 curlun->filp->f_flags |= O_SYNC; in do_write()
782 spin_unlock(&curlun->filp->f_lock); in do_write()
785 if (lba >= curlun->num_sectors) { in do_write()
786 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; in do_write()
787 return -EINVAL; in do_write()
792 file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits; in do_write()
793 amount_left_to_req = common->data_size_from_cmnd; in do_write()
794 amount_left_to_write = common->data_size_from_cmnd; in do_write()
799 bh = common->next_buffhd_to_fill; in do_write()
800 if (bh->state == BUF_STATE_EMPTY && get_some_more) { in do_write()
810 if (usb_offset >= curlun->file_length) { in do_write()
812 curlun->sense_data = in do_write()
814 curlun->sense_data_info = in do_write()
815 usb_offset >> curlun->blkbits; in do_write()
816 curlun->info_valid = 1; in do_write()
822 common->usb_amount_left -= amount; in do_write()
823 amount_left_to_req -= amount; in do_write()
830 * the bulk-out maxpacket size. in do_write()
834 /* Dunno what to do if common->fsg is NULL */ in do_write()
835 return -EIO; in do_write()
836 common->next_buffhd_to_fill = bh->next; in do_write()
841 bh = common->next_buffhd_to_drain; in do_write()
842 if (bh->state == BUF_STATE_EMPTY && !get_some_more) in do_write()
850 common->next_buffhd_to_drain = bh->next; in do_write()
851 bh->state = BUF_STATE_EMPTY; in do_write()
854 if (bh->outreq->status != 0) { in do_write()
855 curlun->sense_data = SS_COMMUNICATION_FAILURE; in do_write()
856 curlun->sense_data_info = in do_write()
857 file_offset >> curlun->blkbits; in do_write()
858 curlun->info_valid = 1; in do_write()
862 amount = bh->outreq->actual; in do_write()
863 if (curlun->file_length - file_offset < amount) { in do_write()
866 (unsigned long long)curlun->file_length); in do_write()
867 amount = curlun->file_length - file_offset; in do_write()
874 amount = min(amount, bh->bulk_out_intended_length); in do_write()
877 amount = round_down(amount, curlun->blksize); in do_write()
883 nwritten = kernel_write(curlun->filp, bh->buf, amount, in do_write()
885 VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, in do_write()
888 return -EINTR; /* Interrupted! */ in do_write()
897 nwritten = round_down(nwritten, curlun->blksize); in do_write()
900 amount_left_to_write -= nwritten; in do_write()
901 common->residue -= nwritten; in do_write()
905 curlun->sense_data = SS_WRITE_ERROR; in do_write()
906 curlun->sense_data_info = in do_write()
907 file_offset >> curlun->blkbits; in do_write()
908 curlun->info_valid = 1; in do_write()
914 if (bh->outreq->actual < bh->bulk_out_intended_length) { in do_write()
915 common->short_packet_received = 1; in do_write()
920 return -EIO; /* No default reply */ in do_write()
924 /*-------------------------------------------------------------------------*/
928 struct fsg_lun *curlun = common->curlun; in do_synchronize_cache()
935 curlun->sense_data = SS_WRITE_ERROR; in do_synchronize_cache()
940 /*-------------------------------------------------------------------------*/
944 struct file *filp = curlun->filp; in invalidate_sub()
948 rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); in invalidate_sub()
949 VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); in invalidate_sub()
954 struct fsg_lun *curlun = common->curlun; in do_verify()
957 struct fsg_buffhd *bh = common->next_buffhd_to_fill; in do_verify()
967 lba = get_unaligned_be32(&common->cmnd[2]); in do_verify()
968 if (lba >= curlun->num_sectors) { in do_verify()
969 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; in do_verify()
970 return -EINVAL; in do_verify()
977 if (common->cmnd[1] & ~0x10) { in do_verify()
978 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_verify()
979 return -EINVAL; in do_verify()
982 verification_length = get_unaligned_be16(&common->cmnd[7]); in do_verify()
984 return -EIO; /* No default reply */ in do_verify()
987 amount_left = verification_length << curlun->blkbits; in do_verify()
988 file_offset = ((loff_t) lba) << curlun->blkbits; in do_verify()
993 return -EINTR; in do_verify()
997 return -EINTR; in do_verify()
1009 curlun->file_length - file_offset); in do_verify()
1011 curlun->sense_data = in do_verify()
1013 curlun->sense_data_info = in do_verify()
1014 file_offset >> curlun->blkbits; in do_verify()
1015 curlun->info_valid = 1; in do_verify()
1021 nread = kernel_read(curlun->filp, bh->buf, amount, in do_verify()
1023 VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, in do_verify()
1027 return -EINTR; in do_verify()
1035 nread = round_down(nread, curlun->blksize); in do_verify()
1038 curlun->sense_data = SS_UNRECOVERED_READ_ERROR; in do_verify()
1039 curlun->sense_data_info = in do_verify()
1040 file_offset >> curlun->blkbits; in do_verify()
1041 curlun->info_valid = 1; in do_verify()
1045 amount_left -= nread; in do_verify()
1051 /*-------------------------------------------------------------------------*/
1055 struct fsg_lun *curlun = common->curlun; in do_inquiry()
1056 u8 *buf = (u8 *) bh->buf; in do_inquiry()
1059 common->bad_lun_okay = 1; in do_inquiry()
1061 buf[0] = TYPE_NO_LUN; /* Unsupported, no device-type */ in do_inquiry()
1066 buf[0] = curlun->cdrom ? TYPE_ROM : TYPE_DISK; in do_inquiry()
1067 buf[1] = curlun->removable ? 0x80 : 0; in do_inquiry()
1069 buf[3] = 2; /* SCSI-2 INQUIRY data format */ in do_inquiry()
1074 if (curlun->inquiry_string[0]) in do_inquiry()
1075 memcpy(buf + 8, curlun->inquiry_string, in do_inquiry()
1076 sizeof(curlun->inquiry_string)); in do_inquiry()
1078 memcpy(buf + 8, common->inquiry_string, in do_inquiry()
1079 sizeof(common->inquiry_string)); in do_inquiry()
1085 struct fsg_lun *curlun = common->curlun; in do_request_sense()
1086 u8 *buf = (u8 *) bh->buf; in do_request_sense()
1091 * From the SCSI-2 spec., section 7.9 (Unit attention condition): in do_request_sense()
1106 if (curlun && curlun->unit_attention_data != SS_NO_SENSE) { in do_request_sense()
1107 curlun->sense_data = curlun->unit_attention_data; in do_request_sense()
1108 curlun->unit_attention_data = SS_NO_SENSE; in do_request_sense()
1113 common->bad_lun_okay = 1; in do_request_sense()
1118 sd = curlun->sense_data; in do_request_sense()
1119 sdinfo = curlun->sense_data_info; in do_request_sense()
1120 valid = curlun->info_valid << 7; in do_request_sense()
1121 curlun->sense_data = SS_NO_SENSE; in do_request_sense()
1122 curlun->sense_data_info = 0; in do_request_sense()
1123 curlun->info_valid = 0; in do_request_sense()
1130 buf[7] = 18 - 8; /* Additional sense length */ in do_request_sense()
1138 struct fsg_lun *curlun = common->curlun; in do_read_capacity()
1139 u32 lba = get_unaligned_be32(&common->cmnd[2]); in do_read_capacity()
1140 int pmi = common->cmnd[8]; in do_read_capacity()
1141 u8 *buf = (u8 *)bh->buf; in do_read_capacity()
1146 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_read_capacity()
1147 return -EINVAL; in do_read_capacity()
1150 if (curlun->num_sectors < 0x100000000ULL) in do_read_capacity()
1151 max_lba = curlun->num_sectors - 1; in do_read_capacity()
1155 put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ in do_read_capacity()
1161 struct fsg_lun *curlun = common->curlun; in do_read_capacity_16()
1162 u64 lba = get_unaligned_be64(&common->cmnd[2]); in do_read_capacity_16()
1163 int pmi = common->cmnd[14]; in do_read_capacity_16()
1164 u8 *buf = (u8 *)bh->buf; in do_read_capacity_16()
1168 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_read_capacity_16()
1169 return -EINVAL; in do_read_capacity_16()
1172 put_unaligned_be64(curlun->num_sectors - 1, &buf[0]); in do_read_capacity_16()
1174 put_unaligned_be32(curlun->blksize, &buf[8]); /* Block length */ in do_read_capacity_16()
1177 memset(&buf[12], 0, 32 - 12); in do_read_capacity_16()
1183 struct fsg_lun *curlun = common->curlun; in do_read_header()
1184 int msf = common->cmnd[1] & 0x02; in do_read_header()
1185 u32 lba = get_unaligned_be32(&common->cmnd[2]); in do_read_header()
1186 u8 *buf = (u8 *)bh->buf; in do_read_header()
1188 if (common->cmnd[1] & ~0x02) { /* Mask away MSF */ in do_read_header()
1189 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_read_header()
1190 return -EINVAL; in do_read_header()
1192 if (lba >= curlun->num_sectors) { in do_read_header()
1193 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; in do_read_header()
1194 return -EINVAL; in do_read_header()
1205 struct fsg_lun *curlun = common->curlun; in do_read_toc()
1206 int msf = common->cmnd[1] & 0x02; in do_read_toc()
1207 int start_track = common->cmnd[6]; in do_read_toc()
1208 u8 *buf = (u8 *)bh->buf; in do_read_toc()
1212 format = common->cmnd[2] & 0xf; in do_read_toc()
1214 if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ in do_read_toc()
1216 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_read_toc()
1217 return -EINVAL; in do_read_toc()
1221 * Check if CDB is old style SFF-8020i in do_read_toc()
1223 * Mac OS-X host sends us this. in do_read_toc()
1226 format = (common->cmnd[9] >> 6) & 0x3; in do_read_toc()
1230 case 1: /* Multi-session info */ in do_read_toc()
1233 buf[1] = len - 2; /* TOC Length excludes length field */ in do_read_toc()
1240 buf[13] = 0x16; /* Lead-out track is data */ in do_read_toc()
1241 buf[14] = 0xAA; /* Lead-out track number */ in do_read_toc()
1242 store_cdrom_address(&buf[16], msf, curlun->num_sectors); in do_read_toc()
1249 buf[1] = len - 2; /* TOC Length excludes length field */ in do_read_toc()
1258 /* 2 - Track number 0 -> TOC */ in do_read_toc()
1260 /* 4, 5, 6 - Min, sec, frame is zero */ in do_read_toc()
1264 buf -= 11; /* go back to A2 descriptor */ in do_read_toc()
1266 /* For A2, 7, 8, 9, 10 - zero, Pmin, Psec, Pframe of Lead out */ in do_read_toc()
1267 store_cdrom_address(&buf[7], msf, curlun->num_sectors); in do_read_toc()
1271 /* PMA, ATIP, CD-TEXT not supported/required */ in do_read_toc()
1272 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_read_toc()
1273 return -EINVAL; in do_read_toc()
1279 struct fsg_lun *curlun = common->curlun; in do_mode_sense()
1280 int mscmnd = common->cmnd[0]; in do_mode_sense()
1281 u8 *buf = (u8 *) bh->buf; in do_mode_sense()
1288 if ((common->cmnd[1] & ~0x08) != 0) { /* Mask away DBD */ in do_mode_sense()
1289 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_mode_sense()
1290 return -EINVAL; in do_mode_sense()
1292 pc = common->cmnd[2] >> 6; in do_mode_sense()
1293 page_code = common->cmnd[2] & 0x3f; in do_mode_sense()
1295 curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; in do_mode_sense()
1296 return -EINVAL; in do_mode_sense()
1309 buf[2] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ in do_mode_sense()
1313 buf[3] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ in do_mode_sense()
1349 len = buf - buf0; in do_mode_sense()
1351 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_mode_sense()
1352 return -EINVAL; in do_mode_sense()
1357 buf0[0] = len - 1; in do_mode_sense()
1359 put_unaligned_be16(len - 2, buf0); in do_mode_sense()
1365 struct fsg_lun *curlun = common->curlun; in do_start_stop()
1369 return -EINVAL; in do_start_stop()
1370 } else if (!curlun->removable) { in do_start_stop()
1371 curlun->sense_data = SS_INVALID_COMMAND; in do_start_stop()
1372 return -EINVAL; in do_start_stop()
1373 } else if ((common->cmnd[1] & ~0x01) != 0 || /* Mask away Immed */ in do_start_stop()
1374 (common->cmnd[4] & ~0x03) != 0) { /* Mask LoEj, Start */ in do_start_stop()
1375 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_start_stop()
1376 return -EINVAL; in do_start_stop()
1379 loej = common->cmnd[4] & 0x02; in do_start_stop()
1380 start = common->cmnd[4] & 0x01; in do_start_stop()
1388 curlun->sense_data = SS_MEDIUM_NOT_PRESENT; in do_start_stop()
1389 return -EINVAL; in do_start_stop()
1395 if (curlun->prevent_medium_removal) { in do_start_stop()
1397 curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED; in do_start_stop()
1398 return -EINVAL; in do_start_stop()
1404 up_read(&common->filesem); in do_start_stop()
1405 down_write(&common->filesem); in do_start_stop()
1407 up_write(&common->filesem); in do_start_stop()
1408 down_read(&common->filesem); in do_start_stop()
1415 struct fsg_lun *curlun = common->curlun; in do_prevent_allow()
1418 if (!common->curlun) { in do_prevent_allow()
1419 return -EINVAL; in do_prevent_allow()
1420 } else if (!common->curlun->removable) { in do_prevent_allow()
1421 common->curlun->sense_data = SS_INVALID_COMMAND; in do_prevent_allow()
1422 return -EINVAL; in do_prevent_allow()
1425 prevent = common->cmnd[4] & 0x01; in do_prevent_allow()
1426 if ((common->cmnd[4] & ~0x01) != 0) { /* Mask away Prevent */ in do_prevent_allow()
1427 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in do_prevent_allow()
1428 return -EINVAL; in do_prevent_allow()
1431 if (curlun->prevent_medium_removal && !prevent) in do_prevent_allow()
1433 curlun->prevent_medium_removal = prevent; in do_prevent_allow()
1440 struct fsg_lun *curlun = common->curlun; in do_read_format_capacities()
1441 u8 *buf = (u8 *) bh->buf; in do_read_format_capacities()
1447 put_unaligned_be32(curlun->num_sectors, &buf[0]); in do_read_format_capacities()
1449 put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */ in do_read_format_capacities()
1456 struct fsg_lun *curlun = common->curlun; in do_mode_select()
1460 curlun->sense_data = SS_INVALID_COMMAND; in do_mode_select()
1461 return -EINVAL; in do_mode_select()
1465 /*-------------------------------------------------------------------------*/
1471 rc = fsg_set_halt(fsg, fsg->bulk_in); in halt_bulk_in_endpoint()
1472 if (rc == -EAGAIN) in halt_bulk_in_endpoint()
1473 VDBG(fsg, "delayed bulk-in endpoint halt\n"); in halt_bulk_in_endpoint()
1475 if (rc != -EAGAIN) { in halt_bulk_in_endpoint()
1476 WARNING(fsg, "usb_ep_set_halt -> %d\n", rc); in halt_bulk_in_endpoint()
1483 return -EINTR; in halt_bulk_in_endpoint()
1484 rc = usb_ep_set_halt(fsg->bulk_in); in halt_bulk_in_endpoint()
1493 DBG(fsg, "bulk-in set wedge\n"); in wedge_bulk_in_endpoint()
1494 rc = usb_ep_set_wedge(fsg->bulk_in); in wedge_bulk_in_endpoint()
1495 if (rc == -EAGAIN) in wedge_bulk_in_endpoint()
1496 VDBG(fsg, "delayed bulk-in endpoint wedge\n"); in wedge_bulk_in_endpoint()
1498 if (rc != -EAGAIN) { in wedge_bulk_in_endpoint()
1499 WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc); in wedge_bulk_in_endpoint()
1506 return -EINTR; in wedge_bulk_in_endpoint()
1507 rc = usb_ep_set_wedge(fsg->bulk_in); in wedge_bulk_in_endpoint()
1518 for (bh = common->next_buffhd_to_drain; in throw_away_data()
1519 bh->state != BUF_STATE_EMPTY || common->usb_amount_left > 0; in throw_away_data()
1520 bh = common->next_buffhd_to_drain) { in throw_away_data()
1523 bh2 = common->next_buffhd_to_fill; in throw_away_data()
1524 if (bh2->state == BUF_STATE_EMPTY && in throw_away_data()
1525 common->usb_amount_left > 0) { in throw_away_data()
1526 amount = min(common->usb_amount_left, FSG_BUFLEN); in throw_away_data()
1531 * the bulk-out maxpacket size. in throw_away_data()
1535 /* Dunno what to do if common->fsg is NULL */ in throw_away_data()
1536 return -EIO; in throw_away_data()
1537 common->next_buffhd_to_fill = bh2->next; in throw_away_data()
1538 common->usb_amount_left -= amount; in throw_away_data()
1548 bh->state = BUF_STATE_EMPTY; in throw_away_data()
1549 common->next_buffhd_to_drain = bh->next; in throw_away_data()
1552 if (bh->outreq->actual < bh->bulk_out_intended_length || in throw_away_data()
1553 bh->outreq->status != 0) { in throw_away_data()
1555 return -EINTR; in throw_away_data()
1563 struct fsg_buffhd *bh = common->next_buffhd_to_fill; in finish_reply()
1566 switch (common->data_dir) { in finish_reply()
1577 if (!common->can_stall) { in finish_reply()
1580 fsg_set_halt(common->fsg, common->fsg->bulk_out); in finish_reply()
1581 rc = halt_bulk_in_endpoint(common->fsg); in finish_reply()
1583 /* Don't know what to do if common->fsg is NULL */ in finish_reply()
1584 rc = -EIO; in finish_reply()
1590 if (common->data_size == 0) { in finish_reply()
1593 /* Don't know what to do if common->fsg is NULL */ in finish_reply()
1595 rc = -EIO; in finish_reply()
1598 } else if (common->residue == 0) { in finish_reply()
1599 bh->inreq->zero = 0; in finish_reply()
1601 return -EIO; in finish_reply()
1602 common->next_buffhd_to_fill = bh->next; in finish_reply()
1605 * For Bulk-only, mark the end of the data with a short in finish_reply()
1606 * packet. If we are allowed to stall, halt the bulk-in in finish_reply()
1607 * endpoint. (Note: This violates the Bulk-Only Transport in finish_reply()
1609 * don't halt the endpoint. Presumably nobody will mind.) in finish_reply()
1612 bh->inreq->zero = 1; in finish_reply()
1614 rc = -EIO; in finish_reply()
1615 common->next_buffhd_to_fill = bh->next; in finish_reply()
1616 if (common->can_stall) in finish_reply()
1617 rc = halt_bulk_in_endpoint(common->fsg); in finish_reply()
1623 * There may still be outstanding bulk-out requests. in finish_reply()
1626 if (common->residue == 0) { in finish_reply()
1630 } else if (common->short_packet_received) { in finish_reply()
1632 rc = -EINTR; in finish_reply()
1638 * bulk-out packets, in which case the host wouldn't see a in finish_reply()
1640 * clear the halt -- leading to problems later on. in finish_reply()
1643 } else if (common->can_stall) { in finish_reply()
1645 fsg_set_halt(common->fsg, in finish_reply()
1646 common->fsg->bulk_out); in finish_reply()
1648 rc = -EINTR; in finish_reply()
1665 struct fsg_lun *curlun = common->curlun; in send_status()
1673 bh = common->next_buffhd_to_fill; in send_status()
1679 sd = curlun->sense_data; in send_status()
1680 sdinfo = curlun->sense_data_info; in send_status()
1681 } else if (common->bad_lun_okay) in send_status()
1686 if (common->phase_error) { in send_status()
1687 DBG(common, "sending phase-error status\n"); in send_status()
1691 DBG(common, "sending command-failure status\n"); in send_status()
1698 /* Store and send the Bulk-only CSW */ in send_status()
1699 csw = (void *)bh->buf; in send_status()
1701 csw->Signature = cpu_to_le32(US_BULK_CS_SIGN); in send_status()
1702 csw->Tag = common->tag; in send_status()
1703 csw->Residue = cpu_to_le32(common->residue); in send_status()
1704 csw->Status = status; in send_status()
1706 bh->inreq->length = US_BULK_CS_WRAP_LEN; in send_status()
1707 bh->inreq->zero = 0; in send_status()
1709 /* Don't know what to do if common->fsg is NULL */ in send_status()
1712 common->next_buffhd_to_fill = bh->next; in send_status()
1717 /*-------------------------------------------------------------------------*/
1728 unsigned int lun = common->cmnd[1] >> 5; in check_command()
1734 if (common->data_dir != DATA_DIR_UNKNOWN) in check_command()
1735 sprintf(hdlen, ", H%c=%u", dirletter[(int) common->data_dir], in check_command()
1736 common->data_size); in check_command()
1739 common->data_size_from_cmnd, common->cmnd_size, hdlen); in check_command()
1745 if (common->data_size_from_cmnd == 0) in check_command()
1747 if (common->data_size < common->data_size_from_cmnd) { in check_command()
1753 common->data_size_from_cmnd = common->data_size; in check_command()
1754 common->phase_error = 1; in check_command()
1756 common->residue = common->data_size; in check_command()
1757 common->usb_amount_left = common->data_size; in check_command()
1760 if (common->data_dir != data_dir && common->data_size_from_cmnd > 0) { in check_command()
1761 common->phase_error = 1; in check_command()
1762 return -EINVAL; in check_command()
1766 if (cmnd_size != common->cmnd_size) { in check_command()
1770 * implementations. Many have issues with cbw->Length in check_command()
1775 * Examples of such cases would be MS-Windows, which issues in check_command()
1776 * REQUEST SENSE with cbw->Length == 12 where it should in check_command()
1778 * REQUEST SENSE with cbw->Length == 10 where it should in check_command()
1781 if (cmnd_size <= common->cmnd_size) { in check_command()
1782 DBG(common, "%s is buggy! Expected length %d " in check_command()
1784 cmnd_size, common->cmnd_size); in check_command()
1785 cmnd_size = common->cmnd_size; in check_command()
1787 common->phase_error = 1; in check_command()
1788 return -EINVAL; in check_command()
1793 if (common->lun != lun) in check_command()
1794 DBG(common, "using LUN %u from CBW, not LUN %u from CDB\n", in check_command()
1795 common->lun, lun); in check_command()
1798 curlun = common->curlun; in check_command()
1800 if (common->cmnd[0] != REQUEST_SENSE) { in check_command()
1801 curlun->sense_data = SS_NO_SENSE; in check_command()
1802 curlun->sense_data_info = 0; in check_command()
1803 curlun->info_valid = 0; in check_command()
1806 common->bad_lun_okay = 0; in check_command()
1812 if (common->cmnd[0] != INQUIRY && in check_command()
1813 common->cmnd[0] != REQUEST_SENSE) { in check_command()
1814 DBG(common, "unsupported LUN %u\n", common->lun); in check_command()
1815 return -EINVAL; in check_command()
1823 if (curlun && curlun->unit_attention_data != SS_NO_SENSE && in check_command()
1824 common->cmnd[0] != INQUIRY && in check_command()
1825 common->cmnd[0] != REQUEST_SENSE) { in check_command()
1826 curlun->sense_data = curlun->unit_attention_data; in check_command()
1827 curlun->unit_attention_data = SS_NO_SENSE; in check_command()
1828 return -EINVAL; in check_command()
1831 /* Check that only command bytes listed in the mask are non-zero */ in check_command()
1832 common->cmnd[1] &= 0x1f; /* Mask away the LUN */ in check_command()
1834 if (common->cmnd[i] && !(mask & (1 << i))) { in check_command()
1836 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; in check_command()
1837 return -EINVAL; in check_command()
1844 curlun->sense_data = SS_MEDIUM_NOT_PRESENT; in check_command()
1845 return -EINVAL; in check_command()
1856 if (common->curlun) in check_command_size_in_blocks()
1857 common->data_size_from_cmnd <<= common->curlun->blkbits; in check_command_size_in_blocks()
1866 int reply = -EINVAL; in do_scsi_command()
1873 bh = common->next_buffhd_to_fill; in do_scsi_command()
1874 common->next_buffhd_to_drain = bh; in do_scsi_command()
1879 common->phase_error = 0; in do_scsi_command()
1880 common->short_packet_received = 0; in do_scsi_command()
1882 down_read(&common->filesem); /* We're using the backing file */ in do_scsi_command()
1883 switch (common->cmnd[0]) { in do_scsi_command()
1886 common->data_size_from_cmnd = common->cmnd[4]; in do_scsi_command()
1895 common->data_size_from_cmnd = common->cmnd[4]; in do_scsi_command()
1904 common->data_size_from_cmnd = in do_scsi_command()
1905 get_unaligned_be16(&common->cmnd[7]); in do_scsi_command()
1914 common->data_size_from_cmnd = common->cmnd[4]; in do_scsi_command()
1923 common->data_size_from_cmnd = in do_scsi_command()
1924 get_unaligned_be16(&common->cmnd[7]); in do_scsi_command()
1933 common->data_size_from_cmnd = 0; in do_scsi_command()
1936 "PREVENT-ALLOW MEDIUM REMOVAL"); in do_scsi_command()
1942 i = common->cmnd[4]; in do_scsi_command()
1943 common->data_size_from_cmnd = (i == 0) ? 256 : i; in do_scsi_command()
1953 common->data_size_from_cmnd = in do_scsi_command()
1954 get_unaligned_be16(&common->cmnd[7]); in do_scsi_command()
1964 common->data_size_from_cmnd = in do_scsi_command()
1965 get_unaligned_be32(&common->cmnd[6]); in do_scsi_command()
1975 common->data_size_from_cmnd = in do_scsi_command()
1976 get_unaligned_be32(&common->cmnd[10]); in do_scsi_command()
1986 common->data_size_from_cmnd = 8; in do_scsi_command()
1995 if (!common->curlun || !common->curlun->cdrom) in do_scsi_command()
1997 common->data_size_from_cmnd = in do_scsi_command()
1998 get_unaligned_be16(&common->cmnd[7]); in do_scsi_command()
2007 if (!common->curlun || !common->curlun->cdrom) in do_scsi_command()
2009 common->data_size_from_cmnd = in do_scsi_command()
2010 get_unaligned_be16(&common->cmnd[7]); in do_scsi_command()
2019 common->data_size_from_cmnd = in do_scsi_command()
2020 get_unaligned_be16(&common->cmnd[7]); in do_scsi_command()
2029 common->data_size_from_cmnd = common->cmnd[4]; in do_scsi_command()
2038 switch (common->cmnd[1] & 0x1f) { in do_scsi_command()
2041 common->data_size_from_cmnd = in do_scsi_command()
2042 get_unaligned_be32(&common->cmnd[10]); in do_scsi_command()
2057 common->data_size_from_cmnd = 0; in do_scsi_command()
2060 "START-STOP UNIT"); in do_scsi_command()
2066 common->data_size_from_cmnd = 0; in do_scsi_command()
2075 common->data_size_from_cmnd = 0; in do_scsi_command()
2082 * Although optional, this command is used by MS-Windows. We in do_scsi_command()
2086 common->data_size_from_cmnd = 0; in do_scsi_command()
2095 i = common->cmnd[4]; in do_scsi_command()
2096 common->data_size_from_cmnd = (i == 0) ? 256 : i; in do_scsi_command()
2106 common->data_size_from_cmnd = in do_scsi_command()
2107 get_unaligned_be16(&common->cmnd[7]); in do_scsi_command()
2117 common->data_size_from_cmnd = in do_scsi_command()
2118 get_unaligned_be32(&common->cmnd[6]); in do_scsi_command()
2128 common->data_size_from_cmnd = in do_scsi_command()
2129 get_unaligned_be32(&common->cmnd[10]); in do_scsi_command()
2151 common->data_size_from_cmnd = 0; in do_scsi_command()
2152 sprintf(unknown, "Unknown x%02x", common->cmnd[0]); in do_scsi_command()
2153 reply = check_command(common, common->cmnd_size, in do_scsi_command()
2156 common->curlun->sense_data = SS_INVALID_COMMAND; in do_scsi_command()
2157 reply = -EINVAL; in do_scsi_command()
2161 up_read(&common->filesem); in do_scsi_command()
2163 if (reply == -EINTR || signal_pending(current)) in do_scsi_command()
2164 return -EINTR; in do_scsi_command()
2167 if (reply == -EINVAL) in do_scsi_command()
2169 if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) { in do_scsi_command()
2170 reply = min((u32)reply, common->data_size_from_cmnd); in do_scsi_command()
2171 bh->inreq->length = reply; in do_scsi_command()
2172 bh->state = BUF_STATE_FULL; in do_scsi_command()
2173 common->residue -= reply; in do_scsi_command()
2180 /*-------------------------------------------------------------------------*/
2184 struct usb_request *req = bh->outreq; in received_cbw()
2185 struct bulk_cb_wrap *cbw = req->buf; in received_cbw()
2186 struct fsg_common *common = fsg->common; in received_cbw()
2189 if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) in received_cbw()
2190 return -EINVAL; in received_cbw()
2193 if (req->actual != US_BULK_CB_WRAP_LEN || in received_cbw()
2194 cbw->Signature != cpu_to_le32( in received_cbw()
2196 DBG(fsg, "invalid CBW: len %u sig 0x%x\n", in received_cbw()
2197 req->actual, in received_cbw()
2198 le32_to_cpu(cbw->Signature)); in received_cbw()
2201 * The Bulk-only spec says we MUST stall the IN endpoint in received_cbw()
2205 * Clear-Feature(HALT) requests. in received_cbw()
2207 * We aren't required to halt the OUT endpoint; instead in received_cbw()
2212 set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); in received_cbw()
2213 return -EINVAL; in received_cbw()
2217 if (cbw->Lun >= ARRAY_SIZE(common->luns) || in received_cbw()
2218 cbw->Flags & ~US_BULK_FLAG_IN || cbw->Length <= 0 || in received_cbw()
2219 cbw->Length > MAX_COMMAND_SIZE) { in received_cbw()
2220 DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " in received_cbw()
2222 cbw->Lun, cbw->Flags, cbw->Length); in received_cbw()
2228 if (common->can_stall) { in received_cbw()
2229 fsg_set_halt(fsg, fsg->bulk_out); in received_cbw()
2232 return -EINVAL; in received_cbw()
2236 common->cmnd_size = cbw->Length; in received_cbw()
2237 memcpy(common->cmnd, cbw->CDB, common->cmnd_size); in received_cbw()
2238 if (cbw->Flags & US_BULK_FLAG_IN) in received_cbw()
2239 common->data_dir = DATA_DIR_TO_HOST; in received_cbw()
2241 common->data_dir = DATA_DIR_FROM_HOST; in received_cbw()
2242 common->data_size = le32_to_cpu(cbw->DataTransferLength); in received_cbw()
2243 if (common->data_size == 0) in received_cbw()
2244 common->data_dir = DATA_DIR_NONE; in received_cbw()
2245 common->lun = cbw->Lun; in received_cbw()
2246 if (common->lun < ARRAY_SIZE(common->luns)) in received_cbw()
2247 common->curlun = common->luns[common->lun]; in received_cbw()
2249 common->curlun = NULL; in received_cbw()
2250 common->tag = cbw->Tag; in received_cbw()
2260 bh = common->next_buffhd_to_fill; in get_next_command()
2265 /* Queue a request to read a Bulk-only CBW */ in get_next_command()
2268 /* Don't know what to do if common->fsg is NULL */ in get_next_command()
2269 return -EIO; in get_next_command()
2282 rc = fsg_is_set(common) ? received_cbw(common->fsg, bh) : -EIO; in get_next_command()
2283 bh->state = BUF_STATE_EMPTY; in get_next_command()
2289 /*-------------------------------------------------------------------------*/
2297 ERROR(common, "can't allocate request for %s\n", ep->name); in alloc_request()
2298 return -ENOMEM; in alloc_request()
2301 /* Reset interface setting and re-init endpoint state (toggle etc). */
2307 if (common->running) in do_set_interface()
2308 DBG(common, "reset interface\n"); in do_set_interface()
2312 if (common->fsg) { in do_set_interface()
2313 fsg = common->fsg; in do_set_interface()
2315 for (i = 0; i < common->fsg_num_buffers; ++i) { in do_set_interface()
2316 struct fsg_buffhd *bh = &common->buffhds[i]; in do_set_interface()
2318 if (bh->inreq) { in do_set_interface()
2319 usb_ep_free_request(fsg->bulk_in, bh->inreq); in do_set_interface()
2320 bh->inreq = NULL; in do_set_interface()
2322 if (bh->outreq) { in do_set_interface()
2323 usb_ep_free_request(fsg->bulk_out, bh->outreq); in do_set_interface()
2324 bh->outreq = NULL; in do_set_interface()
2329 if (fsg->bulk_in_enabled) { in do_set_interface()
2330 usb_ep_disable(fsg->bulk_in); in do_set_interface()
2331 fsg->bulk_in_enabled = 0; in do_set_interface()
2333 if (fsg->bulk_out_enabled) { in do_set_interface()
2334 usb_ep_disable(fsg->bulk_out); in do_set_interface()
2335 fsg->bulk_out_enabled = 0; in do_set_interface()
2338 common->fsg = NULL; in do_set_interface()
2339 wake_up(&common->fsg_wait); in do_set_interface()
2342 common->running = 0; in do_set_interface()
2346 common->fsg = new_fsg; in do_set_interface()
2347 fsg = common->fsg; in do_set_interface()
2350 rc = config_ep_by_speed(common->gadget, &(fsg->function), fsg->bulk_in); in do_set_interface()
2353 rc = usb_ep_enable(fsg->bulk_in); in do_set_interface()
2356 fsg->bulk_in->driver_data = common; in do_set_interface()
2357 fsg->bulk_in_enabled = 1; in do_set_interface()
2359 rc = config_ep_by_speed(common->gadget, &(fsg->function), in do_set_interface()
2360 fsg->bulk_out); in do_set_interface()
2363 rc = usb_ep_enable(fsg->bulk_out); in do_set_interface()
2366 fsg->bulk_out->driver_data = common; in do_set_interface()
2367 fsg->bulk_out_enabled = 1; in do_set_interface()
2368 common->bulk_out_maxpacket = usb_endpoint_maxp(fsg->bulk_out->desc); in do_set_interface()
2369 clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); in do_set_interface()
2372 for (i = 0; i < common->fsg_num_buffers; ++i) { in do_set_interface()
2373 struct fsg_buffhd *bh = &common->buffhds[i]; in do_set_interface()
2375 rc = alloc_request(common, fsg->bulk_in, &bh->inreq); in do_set_interface()
2378 rc = alloc_request(common, fsg->bulk_out, &bh->outreq); in do_set_interface()
2381 bh->inreq->buf = bh->outreq->buf = bh->buf; in do_set_interface()
2382 bh->inreq->context = bh->outreq->context = bh; in do_set_interface()
2383 bh->inreq->complete = bulk_in_complete; in do_set_interface()
2384 bh->outreq->complete = bulk_out_complete; in do_set_interface()
2387 common->running = 1; in do_set_interface()
2388 for (i = 0; i < ARRAY_SIZE(common->luns); ++i) in do_set_interface()
2389 if (common->luns[i]) in do_set_interface()
2390 common->luns[i]->unit_attention_data = in do_set_interface()
2402 __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, fsg); in fsg_set_alt()
2411 if (fsg->bulk_in_enabled) { in fsg_disable()
2412 usb_ep_disable(fsg->bulk_in); in fsg_disable()
2413 fsg->bulk_in_enabled = 0; in fsg_disable()
2415 if (fsg->bulk_out_enabled) { in fsg_disable()
2416 usb_ep_disable(fsg->bulk_out); in fsg_disable()
2417 fsg->bulk_out_enabled = 0; in fsg_disable()
2420 __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); in fsg_disable()
2424 /*-------------------------------------------------------------------------*/
2437 * into a high-priority EXIT exception. in handle_exception()
2444 spin_lock_irq(&common->lock); in handle_exception()
2445 if (common->state < FSG_STATE_EXIT) in handle_exception()
2446 DBG(common, "Main thread exiting on signal\n"); in handle_exception()
2447 common->state = FSG_STATE_EXIT; in handle_exception()
2448 spin_unlock_irq(&common->lock); in handle_exception()
2453 if (likely(common->fsg)) { in handle_exception()
2454 for (i = 0; i < common->fsg_num_buffers; ++i) { in handle_exception()
2455 bh = &common->buffhds[i]; in handle_exception()
2456 if (bh->state == BUF_STATE_SENDING) in handle_exception()
2457 usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); in handle_exception()
2458 if (bh->state == BUF_STATE_RECEIVING) in handle_exception()
2459 usb_ep_dequeue(common->fsg->bulk_out, in handle_exception()
2460 bh->outreq); in handle_exception()
2468 if (common->fsg->bulk_in_enabled) in handle_exception()
2469 usb_ep_fifo_flush(common->fsg->bulk_in); in handle_exception()
2470 if (common->fsg->bulk_out_enabled) in handle_exception()
2471 usb_ep_fifo_flush(common->fsg->bulk_out); in handle_exception()
2478 spin_lock_irq(&common->lock); in handle_exception()
2480 for (i = 0; i < common->fsg_num_buffers; ++i) { in handle_exception()
2481 bh = &common->buffhds[i]; in handle_exception()
2482 bh->state = BUF_STATE_EMPTY; in handle_exception()
2484 common->next_buffhd_to_fill = &common->buffhds[0]; in handle_exception()
2485 common->next_buffhd_to_drain = &common->buffhds[0]; in handle_exception()
2486 exception_req_tag = common->exception_req_tag; in handle_exception()
2487 new_fsg = common->exception_arg; in handle_exception()
2488 old_state = common->state; in handle_exception()
2489 common->state = FSG_STATE_NORMAL; in handle_exception()
2492 for (i = 0; i < ARRAY_SIZE(common->luns); ++i) { in handle_exception()
2493 curlun = common->luns[i]; in handle_exception()
2496 curlun->prevent_medium_removal = 0; in handle_exception()
2497 curlun->sense_data = SS_NO_SENSE; in handle_exception()
2498 curlun->unit_attention_data = SS_NO_SENSE; in handle_exception()
2499 curlun->sense_data_info = 0; in handle_exception()
2500 curlun->info_valid = 0; in handle_exception()
2503 spin_unlock_irq(&common->lock); in handle_exception()
2516 * In case we were forced against our will to halt a in handle_exception()
2517 * bulk endpoint, clear the halt now. (The SuperH UDC in handle_exception()
2523 &common->fsg->atomic_bitflags)) in handle_exception()
2524 usb_ep_clear_halt(common->fsg->bulk_in); in handle_exception()
2526 if (common->ep0_req_tag == exception_req_tag) in handle_exception()
2534 /* for (i = 0; i < common->ARRAY_SIZE(common->luns); ++i) */ in handle_exception()
2535 /* if (common->luns[i]) */ in handle_exception()
2536 /* common->luns[i]->unit_attention_data = */ in handle_exception()
2543 usb_composite_setup_continue(common->cdev); in handle_exception()
2548 spin_lock_irq(&common->lock); in handle_exception()
2549 common->state = FSG_STATE_TERMINATED; /* Stop the thread */ in handle_exception()
2550 spin_unlock_irq(&common->lock); in handle_exception()
2559 /*-------------------------------------------------------------------------*/
2579 while (common->state != FSG_STATE_TERMINATED) { in fsg_main_thread()
2585 if (!common->running) { in fsg_main_thread()
2599 spin_lock_irq(&common->lock); in fsg_main_thread()
2600 common->thread_task = NULL; in fsg_main_thread()
2601 spin_unlock_irq(&common->lock); in fsg_main_thread()
2605 down_write(&common->filesem); in fsg_main_thread()
2606 for (i = 0; i < ARRAY_SIZE(common->luns); i++) { in fsg_main_thread()
2607 struct fsg_lun *curlun = common->luns[i]; in fsg_main_thread()
2612 up_write(&common->filesem); in fsg_main_thread()
2615 kthread_complete_and_exit(&common->thread_notifier, 0); in fsg_main_thread()
2704 return ERR_PTR(-ENOMEM); in fsg_common_setup()
2705 common->free_storage_on_release = 1; in fsg_common_setup()
2707 common->free_storage_on_release = 0; in fsg_common_setup()
2709 init_rwsem(&common->filesem); in fsg_common_setup()
2710 spin_lock_init(&common->lock); in fsg_common_setup()
2711 init_completion(&common->thread_notifier); in fsg_common_setup()
2712 init_waitqueue_head(&common->io_wait); in fsg_common_setup()
2713 init_waitqueue_head(&common->fsg_wait); in fsg_common_setup()
2714 common->state = FSG_STATE_TERMINATED; in fsg_common_setup()
2715 memset(common->luns, 0, sizeof(common->luns)); in fsg_common_setup()
2722 common->sysfs = sysfs; in fsg_common_set_sysfs()
2730 while (n--) { in _fsg_common_free_buffers()
2731 kfree(bh->buf); in _fsg_common_free_buffers()
2745 return -ENOMEM; in fsg_common_set_num_buffers()
2752 bh->next = bh + 1; in fsg_common_set_num_buffers()
2755 bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL); in fsg_common_set_num_buffers()
2756 if (unlikely(!bh->buf)) in fsg_common_set_num_buffers()
2758 } while (--i); in fsg_common_set_num_buffers()
2759 bh->next = buffhds; in fsg_common_set_num_buffers()
2761 _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); in fsg_common_set_num_buffers()
2762 common->fsg_num_buffers = n; in fsg_common_set_num_buffers()
2763 common->buffhds = buffhds; in fsg_common_set_num_buffers()
2769 * "buf"s pointed to by heads after n - i are NULL in fsg_common_set_num_buffers()
2774 return -ENOMEM; in fsg_common_set_num_buffers()
2780 if (device_is_registered(&lun->dev)) in fsg_common_remove_lun()
2781 device_unregister(&lun->dev); in fsg_common_remove_lun()
2792 if (common->luns[i]) { in _fsg_common_remove_luns()
2793 fsg_common_remove_lun(common->luns[i]); in _fsg_common_remove_luns()
2794 common->luns[i] = NULL; in _fsg_common_remove_luns()
2800 _fsg_common_remove_luns(common, ARRAY_SIZE(common->luns)); in fsg_common_remove_luns()
2806 _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); in fsg_common_free_buffers()
2807 common->buffhds = NULL; in fsg_common_free_buffers()
2816 common->gadget = cdev->gadget; in fsg_common_set_cdev()
2817 common->ep0 = cdev->gadget->ep0; in fsg_common_set_cdev()
2818 common->ep0req = cdev->req; in fsg_common_set_cdev()
2819 common->cdev = cdev; in fsg_common_set_cdev()
2830 * halt bulk endpoints correctly. If one of them is present, in fsg_common_set_cdev()
2833 common->can_stall = can_stall && in fsg_common_set_cdev()
2834 gadget_is_stall_supported(common->gadget); in fsg_common_set_cdev()
2855 return lun->cdrom ? S_IRUGO : (S_IWUSR | S_IRUGO); in fsg_lun_dev_is_visible()
2857 return lun->removable ? (S_IWUSR | S_IRUGO) : S_IRUGO; in fsg_lun_dev_is_visible()
2858 return attr->mode; in fsg_lun_dev_is_visible()
2877 int rc = -ENOMEM; in fsg_common_create_lun()
2879 if (id >= ARRAY_SIZE(common->luns)) in fsg_common_create_lun()
2880 return -ENODEV; in fsg_common_create_lun()
2882 if (common->luns[id]) in fsg_common_create_lun()
2883 return -EBUSY; in fsg_common_create_lun()
2885 if (!cfg->filename && !cfg->removable) { in fsg_common_create_lun()
2887 return -EINVAL; in fsg_common_create_lun()
2892 return -ENOMEM; in fsg_common_create_lun()
2894 lun->name_pfx = name_pfx; in fsg_common_create_lun()
2896 lun->cdrom = !!cfg->cdrom; in fsg_common_create_lun()
2897 lun->ro = cfg->cdrom || cfg->ro; in fsg_common_create_lun()
2898 lun->initially_ro = lun->ro; in fsg_common_create_lun()
2899 lun->removable = !!cfg->removable; in fsg_common_create_lun()
2901 if (!common->sysfs) { in fsg_common_create_lun()
2903 lun->name = name; in fsg_common_create_lun()
2905 lun->dev.release = fsg_lun_release; in fsg_common_create_lun()
2906 lun->dev.parent = &common->gadget->dev; in fsg_common_create_lun()
2907 lun->dev.groups = fsg_lun_dev_groups; in fsg_common_create_lun()
2908 dev_set_drvdata(&lun->dev, &common->filesem); in fsg_common_create_lun()
2909 dev_set_name(&lun->dev, "%s", name); in fsg_common_create_lun()
2910 lun->name = dev_name(&lun->dev); in fsg_common_create_lun()
2912 rc = device_register(&lun->dev); in fsg_common_create_lun()
2915 put_device(&lun->dev); in fsg_common_create_lun()
2920 common->luns[id] = lun; in fsg_common_create_lun()
2922 if (cfg->filename) { in fsg_common_create_lun()
2923 rc = fsg_lun_open(lun, cfg->filename); in fsg_common_create_lun()
2930 p = file_path(lun->filp, pathbuf, PATH_MAX); in fsg_common_create_lun()
2936 lun->removable ? "removable " : "", in fsg_common_create_lun()
2937 lun->ro ? "read only " : "", in fsg_common_create_lun()
2938 lun->cdrom ? "CD-ROM " : "", in fsg_common_create_lun()
2945 if (device_is_registered(&lun->dev)) in fsg_common_create_lun()
2946 device_unregister(&lun->dev); in fsg_common_create_lun()
2947 common->luns[id] = NULL; in fsg_common_create_lun()
2961 for (i = 0; i < cfg->nluns; ++i) { in fsg_common_create_luns()
2963 rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL); in fsg_common_create_luns()
2968 pr_info("Number of LUNs=%d\n", cfg->nluns); in fsg_common_create_luns()
2985 snprintf(common->inquiry_string, sizeof(common->inquiry_string), in fsg_common_set_inquiry_string()
2986 "%-8s%-16s%04x", vn ?: "Linux", in fsg_common_set_inquiry_string()
2988 pn ?: ((*common->luns)->cdrom in fsg_common_set_inquiry_string()
2989 ? "File-CD Gadget" in fsg_common_set_inquiry_string()
2990 : "File-Stor Gadget"), in fsg_common_set_inquiry_string()
3000 if (common->state != FSG_STATE_TERMINATED) { in fsg_common_release()
3002 wait_for_completion(&common->thread_notifier); in fsg_common_release()
3005 for (i = 0; i < ARRAY_SIZE(common->luns); ++i) { in fsg_common_release()
3006 struct fsg_lun *lun = common->luns[i]; in fsg_common_release()
3010 if (device_is_registered(&lun->dev)) in fsg_common_release()
3011 device_unregister(&lun->dev); in fsg_common_release()
3015 _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); in fsg_common_release()
3016 if (common->free_storage_on_release) in fsg_common_release()
3021 /*-------------------------------------------------------------------------*/
3026 struct fsg_common *common = fsg->common; in fsg_bind()
3027 struct usb_gadget *gadget = c->cdev->gadget; in fsg_bind()
3038 return -EINVAL; in fsg_bind()
3041 opts = fsg_opts_from_func_inst(f->fi); in fsg_bind()
3042 if (!opts->no_configfs) { in fsg_bind()
3043 ret = fsg_common_set_cdev(fsg->common, c->cdev, in fsg_bind()
3044 fsg->common->can_stall); in fsg_bind()
3047 fsg_common_set_inquiry_string(fsg->common, NULL, NULL); in fsg_bind()
3050 if (!common->thread_task) { in fsg_bind()
3051 common->state = FSG_STATE_NORMAL; in fsg_bind()
3052 common->thread_task = in fsg_bind()
3053 kthread_run(fsg_main_thread, common, "file-storage"); in fsg_bind()
3054 if (IS_ERR(common->thread_task)) { in fsg_bind()
3055 ret = PTR_ERR(common->thread_task); in fsg_bind()
3056 common->thread_task = NULL; in fsg_bind()
3057 common->state = FSG_STATE_TERMINATED; in fsg_bind()
3060 DBG(common, "I/O thread pid: %d\n", in fsg_bind()
3061 task_pid_nr(common->thread_task)); in fsg_bind()
3064 fsg->gadget = gadget; in fsg_bind()
3071 fsg->interface_number = i; in fsg_bind()
3077 fsg->bulk_in = ep; in fsg_bind()
3082 fsg->bulk_out = ep; in fsg_bind()
3110 i = -ENOTSUPP; in fsg_bind()
3113 if (fsg->common->state != FSG_STATE_TERMINATED) { in fsg_bind()
3114 raise_exception(fsg->common, FSG_STATE_EXIT); in fsg_bind()
3115 wait_for_completion(&fsg->common->thread_notifier); in fsg_bind()
3125 struct fsg_common *common = fsg->common; in fsg_unbind()
3127 DBG(fsg, "unbind\n"); in fsg_unbind()
3128 if (fsg->common->fsg == fsg) { in fsg_unbind()
3129 __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); in fsg_unbind()
3131 wait_event(common->fsg_wait, common->fsg != fsg); in fsg_unbind()
3134 usb_free_all_descriptors(&fsg->function); in fsg_unbind()
3163 struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); in fsg_lun_opts_file_show()
3165 return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page); in fsg_lun_opts_file_show()
3172 struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); in fsg_lun_opts_file_store()
3174 return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len); in fsg_lun_opts_file_store()
3181 return fsg_show_ro(to_fsg_lun_opts(item)->lun, page); in fsg_lun_opts_ro_show()
3188 struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); in fsg_lun_opts_ro_store()
3190 return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len); in fsg_lun_opts_ro_store()
3198 return fsg_show_removable(to_fsg_lun_opts(item)->lun, page); in fsg_lun_opts_removable_show()
3204 return fsg_store_removable(to_fsg_lun_opts(item)->lun, page, len); in fsg_lun_opts_removable_store()
3211 return fsg_show_cdrom(to_fsg_lun_opts(item)->lun, page); in fsg_lun_opts_cdrom_show()
3218 struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); in fsg_lun_opts_cdrom_store()
3220 return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page, in fsg_lun_opts_cdrom_store()
3228 return fsg_show_nofua(to_fsg_lun_opts(item)->lun, page); in fsg_lun_opts_nofua_show()
3234 return fsg_store_nofua(to_fsg_lun_opts(item)->lun, page, len); in fsg_lun_opts_nofua_store()
3242 return fsg_show_inquiry_string(to_fsg_lun_opts(item)->lun, page); in fsg_lun_opts_inquiry_string_show()
3248 return fsg_store_inquiry_string(to_fsg_lun_opts(item)->lun, page, len); in fsg_lun_opts_inquiry_string_store()
3257 struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); in fsg_lun_opts_forced_eject_store()
3259 return fsg_store_forced_eject(opts->lun, &fsg_opts->common->filesem, in fsg_lun_opts_forced_eject_store()
3295 return ERR_PTR(-EINVAL); in fsg_lun_make()
3303 fsg_opts = to_fsg_opts(&group->cg_item); in fsg_lun_make()
3305 return ERR_PTR(-ERANGE); in fsg_lun_make()
3308 mutex_lock(&fsg_opts->lock); in fsg_lun_make()
3309 if (fsg_opts->refcnt || fsg_opts->common->luns[num]) { in fsg_lun_make()
3310 ret = -EBUSY; in fsg_lun_make()
3316 ret = -ENOMEM; in fsg_lun_make()
3323 ret = fsg_common_create_lun(fsg_opts->common, &config, num, name, in fsg_lun_make()
3324 (const char **)&group->cg_item.ci_name); in fsg_lun_make()
3329 opts->lun = fsg_opts->common->luns[num]; in fsg_lun_make()
3330 opts->lun_id = num; in fsg_lun_make()
3331 mutex_unlock(&fsg_opts->lock); in fsg_lun_make()
3333 config_group_init_type_name(&opts->group, name, &fsg_lun_type); in fsg_lun_make()
3335 return &opts->group; in fsg_lun_make()
3337 mutex_unlock(&fsg_opts->lock); in fsg_lun_make()
3347 fsg_opts = to_fsg_opts(&group->cg_item); in fsg_lun_drop()
3349 mutex_lock(&fsg_opts->lock); in fsg_lun_drop()
3350 if (fsg_opts->refcnt) { in fsg_lun_drop()
3353 gadget = group->cg_item.ci_parent->ci_parent; in fsg_lun_drop()
3357 fsg_common_remove_lun(lun_opts->lun); in fsg_lun_drop()
3358 fsg_opts->common->luns[lun_opts->lun_id] = NULL; in fsg_lun_drop()
3359 lun_opts->lun_id = 0; in fsg_lun_drop()
3360 mutex_unlock(&fsg_opts->lock); in fsg_lun_drop()
3369 usb_put_function_instance(&opts->func_inst); in fsg_attr_release()
3381 mutex_lock(&opts->lock); in fsg_opts_stall_show()
3382 result = sprintf(page, "%d", opts->common->can_stall); in fsg_opts_stall_show()
3383 mutex_unlock(&opts->lock); in fsg_opts_stall_show()
3395 mutex_lock(&opts->lock); in fsg_opts_stall_store()
3397 if (opts->refcnt) { in fsg_opts_stall_store()
3398 mutex_unlock(&opts->lock); in fsg_opts_stall_store()
3399 return -EBUSY; in fsg_opts_stall_store()
3404 opts->common->can_stall = stall; in fsg_opts_stall_store()
3408 mutex_unlock(&opts->lock); in fsg_opts_stall_store()
3421 mutex_lock(&opts->lock); in fsg_opts_num_buffers_show()
3422 result = sprintf(page, "%d", opts->common->fsg_num_buffers); in fsg_opts_num_buffers_show()
3423 mutex_unlock(&opts->lock); in fsg_opts_num_buffers_show()
3435 mutex_lock(&opts->lock); in fsg_opts_num_buffers_store()
3436 if (opts->refcnt) { in fsg_opts_num_buffers_store()
3437 ret = -EBUSY; in fsg_opts_num_buffers_store()
3444 ret = fsg_common_set_num_buffers(opts->common, num); in fsg_opts_num_buffers_store()
3450 mutex_unlock(&opts->lock); in fsg_opts_num_buffers_store()
3482 fsg_common_release(opts->common); in fsg_free_inst()
3494 return ERR_PTR(-ENOMEM); in fsg_alloc_inst()
3495 mutex_init(&opts->lock); in fsg_alloc_inst()
3496 opts->func_inst.free_func_inst = fsg_free_inst; in fsg_alloc_inst()
3497 opts->common = fsg_common_setup(opts->common); in fsg_alloc_inst()
3498 if (IS_ERR(opts->common)) { in fsg_alloc_inst()
3499 rc = PTR_ERR(opts->common); in fsg_alloc_inst()
3503 rc = fsg_common_set_num_buffers(opts->common, in fsg_alloc_inst()
3512 rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0", in fsg_alloc_inst()
3513 (const char **)&opts->func_inst.group.cg_item.ci_name); in fsg_alloc_inst()
3517 opts->lun0.lun = opts->common->luns[0]; in fsg_alloc_inst()
3518 opts->lun0.lun_id = 0; in fsg_alloc_inst()
3520 config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type); in fsg_alloc_inst()
3522 config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type); in fsg_alloc_inst()
3523 configfs_add_default_group(&opts->lun0.group, &opts->func_inst.group); in fsg_alloc_inst()
3525 return &opts->func_inst; in fsg_alloc_inst()
3528 fsg_common_free_buffers(opts->common); in fsg_alloc_inst()
3530 kfree(opts->common); in fsg_alloc_inst()
3542 opts = container_of(f->fi, struct fsg_opts, func_inst); in fsg_free()
3544 mutex_lock(&opts->lock); in fsg_free()
3545 opts->refcnt--; in fsg_free()
3546 mutex_unlock(&opts->lock); in fsg_free()
3554 struct fsg_common *common = opts->common; in fsg_alloc()
3559 return ERR_PTR(-ENOMEM); in fsg_alloc()
3561 mutex_lock(&opts->lock); in fsg_alloc()
3562 opts->refcnt++; in fsg_alloc()
3563 mutex_unlock(&opts->lock); in fsg_alloc()
3565 fsg->function.name = FSG_DRIVER_DESC; in fsg_alloc()
3566 fsg->function.bind = fsg_bind; in fsg_alloc()
3567 fsg->function.unbind = fsg_unbind; in fsg_alloc()
3568 fsg->function.setup = fsg_setup; in fsg_alloc()
3569 fsg->function.set_alt = fsg_set_alt; in fsg_alloc()
3570 fsg->function.disable = fsg_disable; in fsg_alloc()
3571 fsg->function.free_func = fsg_free; in fsg_alloc()
3573 fsg->common = common; in fsg_alloc()
3575 return &fsg->function; in fsg_alloc()
3594 cfg->nluns = in fsg_config_from_params()
3595 min(params->luns ?: (params->file_count ?: 1u), in fsg_config_from_params()
3597 for (i = 0, lun = cfg->luns; i < cfg->nluns; ++i, ++lun) { in fsg_config_from_params()
3598 lun->ro = !!params->ro[i]; in fsg_config_from_params()
3599 lun->cdrom = !!params->cdrom[i]; in fsg_config_from_params()
3600 lun->removable = !!params->removable[i]; in fsg_config_from_params()
3601 lun->filename = in fsg_config_from_params()
3602 params->file_count > i && params->file[i][0] in fsg_config_from_params()
3603 ? params->file[i] in fsg_config_from_params()
3608 cfg->vendor_name = NULL; in fsg_config_from_params()
3609 cfg->product_name = NULL; in fsg_config_from_params()
3611 cfg->ops = NULL; in fsg_config_from_params()
3612 cfg->private_data = NULL; in fsg_config_from_params()
3615 cfg->can_stall = params->stall; in fsg_config_from_params()
3616 cfg->fsg_num_buffers = fsg_num_buffers; in fsg_config_from_params()