diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-11-29 04:51:07 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-11-29 04:51:07 -0500 |
commit | 0d2cd91bf7b1a7cc1d638296111fcc2bcf5c0bb4 (patch) | |
tree | d2ca69347816c27f9dc352581f5d0fe76811cd49 /drivers/usb/gadget/f_mass_storage.c | |
parent | 3d95fd6ad8d3cf582a70ed65660017114b6e4065 (diff) | |
parent | caca6a03d365883564885f2c1da3e88dcf65d139 (diff) |
Merge commit 'v3.2-rc3' into next
Diffstat (limited to 'drivers/usb/gadget/f_mass_storage.c')
-rw-r--r-- | drivers/usb/gadget/f_mass_storage.c | 202 |
1 files changed, 115 insertions, 87 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 5b9339582007..c39d58860fa0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -112,8 +112,7 @@ | |||
112 | * is not loaded (an empty string as "filename" in the fsg_config | 112 | * is not loaded (an empty string as "filename" in the fsg_config |
113 | * structure causes error). The CD-ROM emulation includes a single | 113 | * structure causes error). The CD-ROM emulation includes a single |
114 | * data track and no audio tracks; hence there need be only one | 114 | * data track and no audio tracks; hence there need be only one |
115 | * backing file per LUN. Note also that the CD-ROM block length is | 115 | * backing file per LUN. |
116 | * set to 512 rather than the more common value 2048. | ||
117 | * | 116 | * |
118 | * | 117 | * |
119 | * MSF includes support for module parameters. If gadget using it | 118 | * MSF includes support for module parameters. If gadget using it |
@@ -363,7 +362,7 @@ struct fsg_common { | |||
363 | 362 | ||
364 | struct fsg_buffhd *next_buffhd_to_fill; | 363 | struct fsg_buffhd *next_buffhd_to_fill; |
365 | struct fsg_buffhd *next_buffhd_to_drain; | 364 | struct fsg_buffhd *next_buffhd_to_drain; |
366 | struct fsg_buffhd buffhds[FSG_NUM_BUFFERS]; | 365 | struct fsg_buffhd *buffhds; |
367 | 366 | ||
368 | int cmnd_size; | 367 | int cmnd_size; |
369 | u8 cmnd[MAX_COMMAND_SIZE]; | 368 | u8 cmnd[MAX_COMMAND_SIZE]; |
@@ -625,7 +624,8 @@ static int fsg_setup(struct usb_function *f, | |||
625 | if (ctrl->bRequestType != | 624 | if (ctrl->bRequestType != |
626 | (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 625 | (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
627 | break; | 626 | break; |
628 | if (w_index != fsg->interface_number || w_value != 0) | 627 | if (w_index != fsg->interface_number || w_value != 0 || |
628 | w_length != 0) | ||
629 | return -EDOM; | 629 | return -EDOM; |
630 | 630 | ||
631 | /* | 631 | /* |
@@ -640,7 +640,8 @@ static int fsg_setup(struct usb_function *f, | |||
640 | if (ctrl->bRequestType != | 640 | if (ctrl->bRequestType != |
641 | (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 641 | (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
642 | break; | 642 | break; |
643 | if (w_index != fsg->interface_number || w_value != 0) | 643 | if (w_index != fsg->interface_number || w_value != 0 || |
644 | w_length != 1) | ||
644 | return -EDOM; | 645 | return -EDOM; |
645 | VDBG(fsg, "get max LUN\n"); | 646 | VDBG(fsg, "get max LUN\n"); |
646 | *(u8 *)req->buf = fsg->common->nluns - 1; | 647 | *(u8 *)req->buf = fsg->common->nluns - 1; |
@@ -745,7 +746,6 @@ static int do_read(struct fsg_common *common) | |||
745 | u32 amount_left; | 746 | u32 amount_left; |
746 | loff_t file_offset, file_offset_tmp; | 747 | loff_t file_offset, file_offset_tmp; |
747 | unsigned int amount; | 748 | unsigned int amount; |
748 | unsigned int partial_page; | ||
749 | ssize_t nread; | 749 | ssize_t nread; |
750 | 750 | ||
751 | /* | 751 | /* |
@@ -771,7 +771,7 @@ static int do_read(struct fsg_common *common) | |||
771 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 771 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
772 | return -EINVAL; | 772 | return -EINVAL; |
773 | } | 773 | } |
774 | file_offset = ((loff_t) lba) << 9; | 774 | file_offset = ((loff_t) lba) << curlun->blkbits; |
775 | 775 | ||
776 | /* Carry out the file reads */ | 776 | /* Carry out the file reads */ |
777 | amount_left = common->data_size_from_cmnd; | 777 | amount_left = common->data_size_from_cmnd; |
@@ -784,18 +784,10 @@ static int do_read(struct fsg_common *common) | |||
784 | * Try to read the remaining amount. | 784 | * Try to read the remaining amount. |
785 | * But don't read more than the buffer size. | 785 | * But don't read more than the buffer size. |
786 | * And don't try to read past the end of the file. | 786 | * And don't try to read past the end of the file. |
787 | * Finally, if we're not at a page boundary, don't read past | ||
788 | * the next page. | ||
789 | * If this means reading 0 then we were asked to read past | ||
790 | * the end of file. | ||
791 | */ | 787 | */ |
792 | amount = min(amount_left, FSG_BUFLEN); | 788 | amount = min(amount_left, FSG_BUFLEN); |
793 | amount = min((loff_t)amount, | 789 | amount = min((loff_t)amount, |
794 | curlun->file_length - file_offset); | 790 | curlun->file_length - file_offset); |
795 | partial_page = file_offset & (PAGE_CACHE_SIZE - 1); | ||
796 | if (partial_page > 0) | ||
797 | amount = min(amount, (unsigned int)PAGE_CACHE_SIZE - | ||
798 | partial_page); | ||
799 | 791 | ||
800 | /* Wait for the next buffer to become available */ | 792 | /* Wait for the next buffer to become available */ |
801 | bh = common->next_buffhd_to_fill; | 793 | bh = common->next_buffhd_to_fill; |
@@ -812,7 +804,8 @@ static int do_read(struct fsg_common *common) | |||
812 | if (amount == 0) { | 804 | if (amount == 0) { |
813 | curlun->sense_data = | 805 | curlun->sense_data = |
814 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 806 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
815 | curlun->sense_data_info = file_offset >> 9; | 807 | curlun->sense_data_info = |
808 | file_offset >> curlun->blkbits; | ||
816 | curlun->info_valid = 1; | 809 | curlun->info_valid = 1; |
817 | bh->inreq->length = 0; | 810 | bh->inreq->length = 0; |
818 | bh->state = BUF_STATE_FULL; | 811 | bh->state = BUF_STATE_FULL; |
@@ -835,18 +828,25 @@ static int do_read(struct fsg_common *common) | |||
835 | } else if (nread < amount) { | 828 | } else if (nread < amount) { |
836 | LDBG(curlun, "partial file read: %d/%u\n", | 829 | LDBG(curlun, "partial file read: %d/%u\n", |
837 | (int)nread, amount); | 830 | (int)nread, amount); |
838 | nread -= (nread & 511); /* Round down to a block */ | 831 | nread = round_down(nread, curlun->blksize); |
839 | } | 832 | } |
840 | file_offset += nread; | 833 | file_offset += nread; |
841 | amount_left -= nread; | 834 | amount_left -= nread; |
842 | common->residue -= nread; | 835 | common->residue -= nread; |
836 | |||
837 | /* | ||
838 | * Except at the end of the transfer, nread will be | ||
839 | * equal to the buffer size, which is divisible by the | ||
840 | * bulk-in maxpacket size. | ||
841 | */ | ||
843 | bh->inreq->length = nread; | 842 | bh->inreq->length = nread; |
844 | bh->state = BUF_STATE_FULL; | 843 | bh->state = BUF_STATE_FULL; |
845 | 844 | ||
846 | /* If an error occurred, report it and its position */ | 845 | /* If an error occurred, report it and its position */ |
847 | if (nread < amount) { | 846 | if (nread < amount) { |
848 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 847 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
849 | curlun->sense_data_info = file_offset >> 9; | 848 | curlun->sense_data_info = |
849 | file_offset >> curlun->blkbits; | ||
850 | curlun->info_valid = 1; | 850 | curlun->info_valid = 1; |
851 | break; | 851 | break; |
852 | } | 852 | } |
@@ -877,7 +877,6 @@ static int do_write(struct fsg_common *common) | |||
877 | u32 amount_left_to_req, amount_left_to_write; | 877 | u32 amount_left_to_req, amount_left_to_write; |
878 | loff_t usb_offset, file_offset, file_offset_tmp; | 878 | loff_t usb_offset, file_offset, file_offset_tmp; |
879 | unsigned int amount; | 879 | unsigned int amount; |
880 | unsigned int partial_page; | ||
881 | ssize_t nwritten; | 880 | ssize_t nwritten; |
882 | int rc; | 881 | int rc; |
883 | 882 | ||
@@ -921,7 +920,7 @@ static int do_write(struct fsg_common *common) | |||
921 | 920 | ||
922 | /* Carry out the file writes */ | 921 | /* Carry out the file writes */ |
923 | get_some_more = 1; | 922 | get_some_more = 1; |
924 | file_offset = usb_offset = ((loff_t) lba) << 9; | 923 | file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits; |
925 | amount_left_to_req = common->data_size_from_cmnd; | 924 | amount_left_to_req = common->data_size_from_cmnd; |
926 | amount_left_to_write = common->data_size_from_cmnd; | 925 | amount_left_to_write = common->data_size_from_cmnd; |
927 | 926 | ||
@@ -933,41 +932,21 @@ static int do_write(struct fsg_common *common) | |||
933 | 932 | ||
934 | /* | 933 | /* |
935 | * Figure out how much we want to get: | 934 | * Figure out how much we want to get: |
936 | * Try to get the remaining amount. | 935 | * Try to get the remaining amount, |
937 | * But don't get more than the buffer size. | 936 | * but not more than the buffer size. |
938 | * And don't try to go past the end of the file. | ||
939 | * If we're not at a page boundary, | ||
940 | * don't go past the next page. | ||
941 | * If this means getting 0, then we were asked | ||
942 | * to write past the end of file. | ||
943 | * Finally, round down to a block boundary. | ||
944 | */ | 937 | */ |
945 | amount = min(amount_left_to_req, FSG_BUFLEN); | 938 | amount = min(amount_left_to_req, FSG_BUFLEN); |
946 | amount = min((loff_t)amount, | 939 | |
947 | curlun->file_length - usb_offset); | 940 | /* Beyond the end of the backing file? */ |
948 | partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); | 941 | if (usb_offset >= curlun->file_length) { |
949 | if (partial_page > 0) | ||
950 | amount = min(amount, | ||
951 | (unsigned int)PAGE_CACHE_SIZE - partial_page); | ||
952 | |||
953 | if (amount == 0) { | ||
954 | get_some_more = 0; | 942 | get_some_more = 0; |
955 | curlun->sense_data = | 943 | curlun->sense_data = |
956 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 944 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
957 | curlun->sense_data_info = usb_offset >> 9; | 945 | curlun->sense_data_info = |
946 | usb_offset >> curlun->blkbits; | ||
958 | curlun->info_valid = 1; | 947 | curlun->info_valid = 1; |
959 | continue; | 948 | continue; |
960 | } | 949 | } |
961 | amount -= amount & 511; | ||
962 | if (amount == 0) { | ||
963 | |||
964 | /* | ||
965 | * Why were we were asked to transfer a | ||
966 | * partial block? | ||
967 | */ | ||
968 | get_some_more = 0; | ||
969 | continue; | ||
970 | } | ||
971 | 950 | ||
972 | /* Get the next buffer */ | 951 | /* Get the next buffer */ |
973 | usb_offset += amount; | 952 | usb_offset += amount; |
@@ -977,12 +956,11 @@ static int do_write(struct fsg_common *common) | |||
977 | get_some_more = 0; | 956 | get_some_more = 0; |
978 | 957 | ||
979 | /* | 958 | /* |
980 | * amount is always divisible by 512, hence by | 959 | * Except at the end of the transfer, amount will be |
981 | * the bulk-out maxpacket size | 960 | * equal to the buffer size, which is divisible by |
961 | * the bulk-out maxpacket size. | ||
982 | */ | 962 | */ |
983 | bh->outreq->length = amount; | 963 | set_bulk_out_req_length(common, bh, amount); |
984 | bh->bulk_out_intended_length = amount; | ||
985 | bh->outreq->short_not_ok = 1; | ||
986 | if (!start_out_transfer(common, bh)) | 964 | if (!start_out_transfer(common, bh)) |
987 | /* Dunno what to do if common->fsg is NULL */ | 965 | /* Dunno what to do if common->fsg is NULL */ |
988 | return -EIO; | 966 | return -EIO; |
@@ -1002,7 +980,8 @@ static int do_write(struct fsg_common *common) | |||
1002 | /* Did something go wrong with the transfer? */ | 980 | /* Did something go wrong with the transfer? */ |
1003 | if (bh->outreq->status != 0) { | 981 | if (bh->outreq->status != 0) { |
1004 | curlun->sense_data = SS_COMMUNICATION_FAILURE; | 982 | curlun->sense_data = SS_COMMUNICATION_FAILURE; |
1005 | curlun->sense_data_info = file_offset >> 9; | 983 | curlun->sense_data_info = |
984 | file_offset >> curlun->blkbits; | ||
1006 | curlun->info_valid = 1; | 985 | curlun->info_valid = 1; |
1007 | break; | 986 | break; |
1008 | } | 987 | } |
@@ -1016,6 +995,16 @@ static int do_write(struct fsg_common *common) | |||
1016 | amount = curlun->file_length - file_offset; | 995 | amount = curlun->file_length - file_offset; |
1017 | } | 996 | } |
1018 | 997 | ||
998 | /* Don't accept excess data. The spec doesn't say | ||
999 | * what to do in this case. We'll ignore the error. | ||
1000 | */ | ||
1001 | amount = min(amount, bh->bulk_out_intended_length); | ||
1002 | |||
1003 | /* Don't write a partial block */ | ||
1004 | amount = round_down(amount, curlun->blksize); | ||
1005 | if (amount == 0) | ||
1006 | goto empty_write; | ||
1007 | |||
1019 | /* Perform the write */ | 1008 | /* Perform the write */ |
1020 | file_offset_tmp = file_offset; | 1009 | file_offset_tmp = file_offset; |
1021 | nwritten = vfs_write(curlun->filp, | 1010 | nwritten = vfs_write(curlun->filp, |
@@ -1033,8 +1022,7 @@ static int do_write(struct fsg_common *common) | |||
1033 | } else if (nwritten < amount) { | 1022 | } else if (nwritten < amount) { |
1034 | LDBG(curlun, "partial file write: %d/%u\n", | 1023 | LDBG(curlun, "partial file write: %d/%u\n", |
1035 | (int)nwritten, amount); | 1024 | (int)nwritten, amount); |
1036 | nwritten -= (nwritten & 511); | 1025 | nwritten = round_down(nwritten, curlun->blksize); |
1037 | /* Round down to a block */ | ||
1038 | } | 1026 | } |
1039 | file_offset += nwritten; | 1027 | file_offset += nwritten; |
1040 | amount_left_to_write -= nwritten; | 1028 | amount_left_to_write -= nwritten; |
@@ -1043,13 +1031,15 @@ static int do_write(struct fsg_common *common) | |||
1043 | /* If an error occurred, report it and its position */ | 1031 | /* If an error occurred, report it and its position */ |
1044 | if (nwritten < amount) { | 1032 | if (nwritten < amount) { |
1045 | curlun->sense_data = SS_WRITE_ERROR; | 1033 | curlun->sense_data = SS_WRITE_ERROR; |
1046 | curlun->sense_data_info = file_offset >> 9; | 1034 | curlun->sense_data_info = |
1035 | file_offset >> curlun->blkbits; | ||
1047 | curlun->info_valid = 1; | 1036 | curlun->info_valid = 1; |
1048 | break; | 1037 | break; |
1049 | } | 1038 | } |
1050 | 1039 | ||
1040 | empty_write: | ||
1051 | /* Did the host decide to stop early? */ | 1041 | /* Did the host decide to stop early? */ |
1052 | if (bh->outreq->actual != bh->outreq->length) { | 1042 | if (bh->outreq->actual < bh->bulk_out_intended_length) { |
1053 | common->short_packet_received = 1; | 1043 | common->short_packet_received = 1; |
1054 | break; | 1044 | break; |
1055 | } | 1045 | } |
@@ -1129,8 +1119,8 @@ static int do_verify(struct fsg_common *common) | |||
1129 | return -EIO; /* No default reply */ | 1119 | return -EIO; /* No default reply */ |
1130 | 1120 | ||
1131 | /* Prepare to carry out the file verify */ | 1121 | /* Prepare to carry out the file verify */ |
1132 | amount_left = verification_length << 9; | 1122 | amount_left = verification_length << curlun->blkbits; |
1133 | file_offset = ((loff_t) lba) << 9; | 1123 | file_offset = ((loff_t) lba) << curlun->blkbits; |
1134 | 1124 | ||
1135 | /* Write out all the dirty buffers before invalidating them */ | 1125 | /* Write out all the dirty buffers before invalidating them */ |
1136 | fsg_lun_fsync_sub(curlun); | 1126 | fsg_lun_fsync_sub(curlun); |
@@ -1148,8 +1138,6 @@ static int do_verify(struct fsg_common *common) | |||
1148 | * Try to read the remaining amount, but not more than | 1138 | * Try to read the remaining amount, but not more than |
1149 | * the buffer size. | 1139 | * the buffer size. |
1150 | * And don't try to read past the end of the file. | 1140 | * And don't try to read past the end of the file. |
1151 | * If this means reading 0 then we were asked to read | ||
1152 | * past the end of file. | ||
1153 | */ | 1141 | */ |
1154 | amount = min(amount_left, FSG_BUFLEN); | 1142 | amount = min(amount_left, FSG_BUFLEN); |
1155 | amount = min((loff_t)amount, | 1143 | amount = min((loff_t)amount, |
@@ -1157,7 +1145,8 @@ static int do_verify(struct fsg_common *common) | |||
1157 | if (amount == 0) { | 1145 | if (amount == 0) { |
1158 | curlun->sense_data = | 1146 | curlun->sense_data = |
1159 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1147 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
1160 | curlun->sense_data_info = file_offset >> 9; | 1148 | curlun->sense_data_info = |
1149 | file_offset >> curlun->blkbits; | ||
1161 | curlun->info_valid = 1; | 1150 | curlun->info_valid = 1; |
1162 | break; | 1151 | break; |
1163 | } | 1152 | } |
@@ -1179,11 +1168,12 @@ static int do_verify(struct fsg_common *common) | |||
1179 | } else if (nread < amount) { | 1168 | } else if (nread < amount) { |
1180 | LDBG(curlun, "partial file verify: %d/%u\n", | 1169 | LDBG(curlun, "partial file verify: %d/%u\n", |
1181 | (int)nread, amount); | 1170 | (int)nread, amount); |
1182 | nread -= nread & 511; /* Round down to a sector */ | 1171 | nread = round_down(nread, curlun->blksize); |
1183 | } | 1172 | } |
1184 | if (nread == 0) { | 1173 | if (nread == 0) { |
1185 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 1174 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
1186 | curlun->sense_data_info = file_offset >> 9; | 1175 | curlun->sense_data_info = |
1176 | file_offset >> curlun->blkbits; | ||
1187 | curlun->info_valid = 1; | 1177 | curlun->info_valid = 1; |
1188 | break; | 1178 | break; |
1189 | } | 1179 | } |
@@ -1289,7 +1279,7 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh) | |||
1289 | 1279 | ||
1290 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); | 1280 | put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); |
1291 | /* Max logical block */ | 1281 | /* Max logical block */ |
1292 | put_unaligned_be32(512, &buf[4]); /* Block length */ | 1282 | put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */ |
1293 | return 8; | 1283 | return 8; |
1294 | } | 1284 | } |
1295 | 1285 | ||
@@ -1527,7 +1517,7 @@ static int do_read_format_capacities(struct fsg_common *common, | |||
1527 | 1517 | ||
1528 | put_unaligned_be32(curlun->num_sectors, &buf[0]); | 1518 | put_unaligned_be32(curlun->num_sectors, &buf[0]); |
1529 | /* Number of blocks */ | 1519 | /* Number of blocks */ |
1530 | put_unaligned_be32(512, &buf[4]); /* Block length */ | 1520 | put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */ |
1531 | buf[4] = 0x02; /* Current capacity */ | 1521 | buf[4] = 0x02; /* Current capacity */ |
1532 | return 12; | 1522 | return 12; |
1533 | } | 1523 | } |
@@ -1607,7 +1597,7 @@ static int throw_away_data(struct fsg_common *common) | |||
1607 | common->next_buffhd_to_drain = bh->next; | 1597 | common->next_buffhd_to_drain = bh->next; |
1608 | 1598 | ||
1609 | /* A short packet or an error ends everything */ | 1599 | /* A short packet or an error ends everything */ |
1610 | if (bh->outreq->actual != bh->outreq->length || | 1600 | if (bh->outreq->actual < bh->bulk_out_intended_length || |
1611 | bh->outreq->status != 0) { | 1601 | bh->outreq->status != 0) { |
1612 | raise_exception(common, | 1602 | raise_exception(common, |
1613 | FSG_STATE_ABORT_BULK_OUT); | 1603 | FSG_STATE_ABORT_BULK_OUT); |
@@ -1623,12 +1613,11 @@ static int throw_away_data(struct fsg_common *common) | |||
1623 | amount = min(common->usb_amount_left, FSG_BUFLEN); | 1613 | amount = min(common->usb_amount_left, FSG_BUFLEN); |
1624 | 1614 | ||
1625 | /* | 1615 | /* |
1626 | * amount is always divisible by 512, hence by | 1616 | * Except at the end of the transfer, amount will be |
1617 | * equal to the buffer size, which is divisible by | ||
1627 | * the bulk-out maxpacket size. | 1618 | * the bulk-out maxpacket size. |
1628 | */ | 1619 | */ |
1629 | bh->outreq->length = amount; | 1620 | set_bulk_out_req_length(common, bh, amount); |
1630 | bh->bulk_out_intended_length = amount; | ||
1631 | bh->outreq->short_not_ok = 1; | ||
1632 | if (!start_out_transfer(common, bh)) | 1621 | if (!start_out_transfer(common, bh)) |
1633 | /* Dunno what to do if common->fsg is NULL */ | 1622 | /* Dunno what to do if common->fsg is NULL */ |
1634 | return -EIO; | 1623 | return -EIO; |
@@ -2022,7 +2011,8 @@ static int do_scsi_command(struct fsg_common *common) | |||
2022 | 2011 | ||
2023 | case READ_6: | 2012 | case READ_6: |
2024 | i = common->cmnd[4]; | 2013 | i = common->cmnd[4]; |
2025 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | 2014 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << |
2015 | common->curlun->blkbits; | ||
2026 | reply = check_command(common, 6, DATA_DIR_TO_HOST, | 2016 | reply = check_command(common, 6, DATA_DIR_TO_HOST, |
2027 | (7<<1) | (1<<4), 1, | 2017 | (7<<1) | (1<<4), 1, |
2028 | "READ(6)"); | 2018 | "READ(6)"); |
@@ -2032,7 +2022,8 @@ static int do_scsi_command(struct fsg_common *common) | |||
2032 | 2022 | ||
2033 | case READ_10: | 2023 | case READ_10: |
2034 | common->data_size_from_cmnd = | 2024 | common->data_size_from_cmnd = |
2035 | get_unaligned_be16(&common->cmnd[7]) << 9; | 2025 | get_unaligned_be16(&common->cmnd[7]) << |
2026 | common->curlun->blkbits; | ||
2036 | reply = check_command(common, 10, DATA_DIR_TO_HOST, | 2027 | reply = check_command(common, 10, DATA_DIR_TO_HOST, |
2037 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2028 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2038 | "READ(10)"); | 2029 | "READ(10)"); |
@@ -2042,7 +2033,8 @@ static int do_scsi_command(struct fsg_common *common) | |||
2042 | 2033 | ||
2043 | case READ_12: | 2034 | case READ_12: |
2044 | common->data_size_from_cmnd = | 2035 | common->data_size_from_cmnd = |
2045 | get_unaligned_be32(&common->cmnd[6]) << 9; | 2036 | get_unaligned_be32(&common->cmnd[6]) << |
2037 | common->curlun->blkbits; | ||
2046 | reply = check_command(common, 12, DATA_DIR_TO_HOST, | 2038 | reply = check_command(common, 12, DATA_DIR_TO_HOST, |
2047 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2039 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2048 | "READ(12)"); | 2040 | "READ(12)"); |
@@ -2142,7 +2134,8 @@ static int do_scsi_command(struct fsg_common *common) | |||
2142 | 2134 | ||
2143 | case WRITE_6: | 2135 | case WRITE_6: |
2144 | i = common->cmnd[4]; | 2136 | i = common->cmnd[4]; |
2145 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; | 2137 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << |
2138 | common->curlun->blkbits; | ||
2146 | reply = check_command(common, 6, DATA_DIR_FROM_HOST, | 2139 | reply = check_command(common, 6, DATA_DIR_FROM_HOST, |
2147 | (7<<1) | (1<<4), 1, | 2140 | (7<<1) | (1<<4), 1, |
2148 | "WRITE(6)"); | 2141 | "WRITE(6)"); |
@@ -2152,7 +2145,8 @@ static int do_scsi_command(struct fsg_common *common) | |||
2152 | 2145 | ||
2153 | case WRITE_10: | 2146 | case WRITE_10: |
2154 | common->data_size_from_cmnd = | 2147 | common->data_size_from_cmnd = |
2155 | get_unaligned_be16(&common->cmnd[7]) << 9; | 2148 | get_unaligned_be16(&common->cmnd[7]) << |
2149 | common->curlun->blkbits; | ||
2156 | reply = check_command(common, 10, DATA_DIR_FROM_HOST, | 2150 | reply = check_command(common, 10, DATA_DIR_FROM_HOST, |
2157 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2151 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2158 | "WRITE(10)"); | 2152 | "WRITE(10)"); |
@@ -2162,7 +2156,8 @@ static int do_scsi_command(struct fsg_common *common) | |||
2162 | 2156 | ||
2163 | case WRITE_12: | 2157 | case WRITE_12: |
2164 | common->data_size_from_cmnd = | 2158 | common->data_size_from_cmnd = |
2165 | get_unaligned_be32(&common->cmnd[6]) << 9; | 2159 | get_unaligned_be32(&common->cmnd[6]) << |
2160 | common->curlun->blkbits; | ||
2166 | reply = check_command(common, 12, DATA_DIR_FROM_HOST, | 2161 | reply = check_command(common, 12, DATA_DIR_FROM_HOST, |
2167 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2162 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2168 | "WRITE(12)"); | 2163 | "WRITE(12)"); |
@@ -2297,7 +2292,6 @@ static int get_next_command(struct fsg_common *common) | |||
2297 | 2292 | ||
2298 | /* Queue a request to read a Bulk-only CBW */ | 2293 | /* Queue a request to read a Bulk-only CBW */ |
2299 | set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); | 2294 | set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); |
2300 | bh->outreq->short_not_ok = 1; | ||
2301 | if (!start_out_transfer(common, bh)) | 2295 | if (!start_out_transfer(common, bh)) |
2302 | /* Don't know what to do if common->fsg is NULL */ | 2296 | /* Don't know what to do if common->fsg is NULL */ |
2303 | return -EIO; | 2297 | return -EIO; |
@@ -2348,7 +2342,7 @@ reset: | |||
2348 | if (common->fsg) { | 2342 | if (common->fsg) { |
2349 | fsg = common->fsg; | 2343 | fsg = common->fsg; |
2350 | 2344 | ||
2351 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2345 | for (i = 0; i < fsg_num_buffers; ++i) { |
2352 | struct fsg_buffhd *bh = &common->buffhds[i]; | 2346 | struct fsg_buffhd *bh = &common->buffhds[i]; |
2353 | 2347 | ||
2354 | if (bh->inreq) { | 2348 | if (bh->inreq) { |
@@ -2401,12 +2395,11 @@ reset: | |||
2401 | goto reset; | 2395 | goto reset; |
2402 | fsg->bulk_out->driver_data = common; | 2396 | fsg->bulk_out->driver_data = common; |
2403 | fsg->bulk_out_enabled = 1; | 2397 | fsg->bulk_out_enabled = 1; |
2404 | common->bulk_out_maxpacket = | 2398 | common->bulk_out_maxpacket = usb_endpoint_maxp(fsg->bulk_out->desc); |
2405 | le16_to_cpu(fsg->bulk_out->desc->wMaxPacketSize); | ||
2406 | clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); | 2399 | clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); |
2407 | 2400 | ||
2408 | /* Allocate the requests */ | 2401 | /* Allocate the requests */ |
2409 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2402 | for (i = 0; i < fsg_num_buffers; ++i) { |
2410 | struct fsg_buffhd *bh = &common->buffhds[i]; | 2403 | struct fsg_buffhd *bh = &common->buffhds[i]; |
2411 | 2404 | ||
2412 | rc = alloc_request(common, fsg->bulk_in, &bh->inreq); | 2405 | rc = alloc_request(common, fsg->bulk_in, &bh->inreq); |
@@ -2475,7 +2468,7 @@ static void handle_exception(struct fsg_common *common) | |||
2475 | 2468 | ||
2476 | /* Cancel all the pending transfers */ | 2469 | /* Cancel all the pending transfers */ |
2477 | if (likely(common->fsg)) { | 2470 | if (likely(common->fsg)) { |
2478 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2471 | for (i = 0; i < fsg_num_buffers; ++i) { |
2479 | bh = &common->buffhds[i]; | 2472 | bh = &common->buffhds[i]; |
2480 | if (bh->inreq_busy) | 2473 | if (bh->inreq_busy) |
2481 | usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); | 2474 | usb_ep_dequeue(common->fsg->bulk_in, bh->inreq); |
@@ -2487,7 +2480,7 @@ static void handle_exception(struct fsg_common *common) | |||
2487 | /* Wait until everything is idle */ | 2480 | /* Wait until everything is idle */ |
2488 | for (;;) { | 2481 | for (;;) { |
2489 | int num_active = 0; | 2482 | int num_active = 0; |
2490 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2483 | for (i = 0; i < fsg_num_buffers; ++i) { |
2491 | bh = &common->buffhds[i]; | 2484 | bh = &common->buffhds[i]; |
2492 | num_active += bh->inreq_busy + bh->outreq_busy; | 2485 | num_active += bh->inreq_busy + bh->outreq_busy; |
2493 | } | 2486 | } |
@@ -2510,7 +2503,7 @@ static void handle_exception(struct fsg_common *common) | |||
2510 | */ | 2503 | */ |
2511 | spin_lock_irq(&common->lock); | 2504 | spin_lock_irq(&common->lock); |
2512 | 2505 | ||
2513 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2506 | for (i = 0; i < fsg_num_buffers; ++i) { |
2514 | bh = &common->buffhds[i]; | 2507 | bh = &common->buffhds[i]; |
2515 | bh->state = BUF_STATE_EMPTY; | 2508 | bh->state = BUF_STATE_EMPTY; |
2516 | } | 2509 | } |
@@ -2719,6 +2712,10 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2719 | int nluns, i, rc; | 2712 | int nluns, i, rc; |
2720 | char *pathbuf; | 2713 | char *pathbuf; |
2721 | 2714 | ||
2715 | rc = fsg_num_buffers_validate(); | ||
2716 | if (rc != 0) | ||
2717 | return ERR_PTR(rc); | ||
2718 | |||
2722 | /* Find out how many LUNs there should be */ | 2719 | /* Find out how many LUNs there should be */ |
2723 | nluns = cfg->nluns; | 2720 | nluns = cfg->nluns; |
2724 | if (nluns < 1 || nluns > FSG_MAX_LUNS) { | 2721 | if (nluns < 1 || nluns > FSG_MAX_LUNS) { |
@@ -2737,6 +2734,14 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2737 | common->free_storage_on_release = 0; | 2734 | common->free_storage_on_release = 0; |
2738 | } | 2735 | } |
2739 | 2736 | ||
2737 | common->buffhds = kcalloc(fsg_num_buffers, | ||
2738 | sizeof *(common->buffhds), GFP_KERNEL); | ||
2739 | if (!common->buffhds) { | ||
2740 | if (common->free_storage_on_release) | ||
2741 | kfree(common); | ||
2742 | return ERR_PTR(-ENOMEM); | ||
2743 | } | ||
2744 | |||
2740 | common->ops = cfg->ops; | 2745 | common->ops = cfg->ops; |
2741 | common->private_data = cfg->private_data; | 2746 | common->private_data = cfg->private_data; |
2742 | 2747 | ||
@@ -2814,7 +2819,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2814 | 2819 | ||
2815 | /* Data buffers cyclic list */ | 2820 | /* Data buffers cyclic list */ |
2816 | bh = common->buffhds; | 2821 | bh = common->buffhds; |
2817 | i = FSG_NUM_BUFFERS; | 2822 | i = fsg_num_buffers; |
2818 | goto buffhds_first_it; | 2823 | goto buffhds_first_it; |
2819 | do { | 2824 | do { |
2820 | bh->next = bh + 1; | 2825 | bh->next = bh + 1; |
@@ -2940,12 +2945,13 @@ static void fsg_common_release(struct kref *ref) | |||
2940 | 2945 | ||
2941 | { | 2946 | { |
2942 | struct fsg_buffhd *bh = common->buffhds; | 2947 | struct fsg_buffhd *bh = common->buffhds; |
2943 | unsigned i = FSG_NUM_BUFFERS; | 2948 | unsigned i = fsg_num_buffers; |
2944 | do { | 2949 | do { |
2945 | kfree(bh->buf); | 2950 | kfree(bh->buf); |
2946 | } while (++bh, --i); | 2951 | } while (++bh, --i); |
2947 | } | 2952 | } |
2948 | 2953 | ||
2954 | kfree(common->buffhds); | ||
2949 | if (common->free_storage_on_release) | 2955 | if (common->free_storage_on_release) |
2950 | kfree(common); | 2956 | kfree(common); |
2951 | } | 2957 | } |
@@ -3019,6 +3025,28 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | |||
3019 | } | 3025 | } |
3020 | } | 3026 | } |
3021 | 3027 | ||
3028 | if (gadget_is_superspeed(gadget)) { | ||
3029 | unsigned max_burst; | ||
3030 | |||
3031 | /* Calculate bMaxBurst, we know packet size is 1024 */ | ||
3032 | max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15); | ||
3033 | |||
3034 | fsg_ss_bulk_in_desc.bEndpointAddress = | ||
3035 | fsg_fs_bulk_in_desc.bEndpointAddress; | ||
3036 | fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; | ||
3037 | |||
3038 | fsg_ss_bulk_out_desc.bEndpointAddress = | ||
3039 | fsg_fs_bulk_out_desc.bEndpointAddress; | ||
3040 | fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; | ||
3041 | |||
3042 | f->ss_descriptors = usb_copy_descriptors(fsg_ss_function); | ||
3043 | if (unlikely(!f->ss_descriptors)) { | ||
3044 | usb_free_descriptors(f->hs_descriptors); | ||
3045 | usb_free_descriptors(f->descriptors); | ||
3046 | return -ENOMEM; | ||
3047 | } | ||
3048 | } | ||
3049 | |||
3022 | return 0; | 3050 | return 0; |
3023 | 3051 | ||
3024 | autoconf_fail: | 3052 | autoconf_fail: |