.. | .. |
---|
47 | 47 | * |
---|
48 | 48 | * For more information about MSF and in particular its module |
---|
49 | 49 | * parameters and sysfs interface read the |
---|
50 | | - * <Documentation/usb/mass-storage.txt> file. |
---|
| 50 | + * <Documentation/usb/mass-storage.rst> file. |
---|
51 | 51 | */ |
---|
52 | 52 | |
---|
53 | 53 | /* |
---|
.. | .. |
---|
216 | 216 | #include <linux/freezer.h> |
---|
217 | 217 | #include <linux/module.h> |
---|
218 | 218 | #include <linux/uaccess.h> |
---|
| 219 | +#include <asm/unaligned.h> |
---|
219 | 220 | |
---|
220 | 221 | #include <linux/usb/ch9.h> |
---|
221 | 222 | #include <linux/usb/gadget.h> |
---|
.. | .. |
---|
408 | 409 | common->state = new_state; |
---|
409 | 410 | common->exception_arg = arg; |
---|
410 | 411 | if (common->thread_task) |
---|
411 | | - send_sig_info(SIGUSR1, SEND_SIG_FORCED, |
---|
| 412 | + send_sig_info(SIGUSR1, SEND_SIG_PRIV, |
---|
412 | 413 | common->thread_task); |
---|
413 | 414 | } |
---|
414 | 415 | spin_unlock_irqrestore(&common->lock, flags); |
---|
.. | .. |
---|
950 | 951 | { |
---|
951 | 952 | struct file *filp = curlun->filp; |
---|
952 | 953 | struct inode *inode = file_inode(filp); |
---|
953 | | - unsigned long rc; |
---|
| 954 | + unsigned long __maybe_unused rc; |
---|
954 | 955 | |
---|
955 | 956 | rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); |
---|
956 | 957 | VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); |
---|
.. | .. |
---|
1187 | 1188 | int msf = common->cmnd[1] & 0x02; |
---|
1188 | 1189 | int start_track = common->cmnd[6]; |
---|
1189 | 1190 | u8 *buf = (u8 *)bh->buf; |
---|
| 1191 | + u8 format; |
---|
| 1192 | + int i, len; |
---|
| 1193 | + |
---|
| 1194 | + format = common->cmnd[2] & 0xf; |
---|
1190 | 1195 | |
---|
1191 | 1196 | if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ |
---|
1192 | | - start_track > 1) { |
---|
| 1197 | + (start_track > 1 && format != 0x1)) { |
---|
1193 | 1198 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
---|
1194 | 1199 | return -EINVAL; |
---|
1195 | 1200 | } |
---|
1196 | 1201 | |
---|
1197 | | - memset(buf, 0, 20); |
---|
1198 | | - buf[1] = (20-2); /* TOC data length */ |
---|
1199 | | - buf[2] = 1; /* First track number */ |
---|
1200 | | - buf[3] = 1; /* Last track number */ |
---|
1201 | | - buf[5] = 0x16; /* Data track, copying allowed */ |
---|
1202 | | - buf[6] = 0x01; /* Only track is number 1 */ |
---|
1203 | | - store_cdrom_address(&buf[8], msf, 0); |
---|
| 1202 | + /* |
---|
| 1203 | + * Check if CDB is old style SFF-8020i |
---|
| 1204 | + * i.e. format is in 2 MSBs of byte 9 |
---|
| 1205 | + * Mac OS-X host sends us this. |
---|
| 1206 | + */ |
---|
| 1207 | + if (format == 0) |
---|
| 1208 | + format = (common->cmnd[9] >> 6) & 0x3; |
---|
1204 | 1209 | |
---|
1205 | | - buf[13] = 0x16; /* Lead-out track is data */ |
---|
1206 | | - buf[14] = 0xAA; /* Lead-out track number */ |
---|
1207 | | - store_cdrom_address(&buf[16], msf, curlun->num_sectors); |
---|
1208 | | - return 20; |
---|
| 1210 | + switch (format) { |
---|
| 1211 | + case 0: /* Formatted TOC */ |
---|
| 1212 | + case 1: /* Multi-session info */ |
---|
| 1213 | + len = 4 + 2*8; /* 4 byte header + 2 descriptors */ |
---|
| 1214 | + memset(buf, 0, len); |
---|
| 1215 | + buf[1] = len - 2; /* TOC Length excludes length field */ |
---|
| 1216 | + buf[2] = 1; /* First track number */ |
---|
| 1217 | + buf[3] = 1; /* Last track number */ |
---|
| 1218 | + buf[5] = 0x16; /* Data track, copying allowed */ |
---|
| 1219 | + buf[6] = 0x01; /* Only track is number 1 */ |
---|
| 1220 | + store_cdrom_address(&buf[8], msf, 0); |
---|
| 1221 | + |
---|
| 1222 | + buf[13] = 0x16; /* Lead-out track is data */ |
---|
| 1223 | + buf[14] = 0xAA; /* Lead-out track number */ |
---|
| 1224 | + store_cdrom_address(&buf[16], msf, curlun->num_sectors); |
---|
| 1225 | + return len; |
---|
| 1226 | + |
---|
| 1227 | + case 2: |
---|
| 1228 | + /* Raw TOC */ |
---|
| 1229 | + len = 4 + 3*11; /* 4 byte header + 3 descriptors */ |
---|
| 1230 | + memset(buf, 0, len); /* Header + A0, A1 & A2 descriptors */ |
---|
| 1231 | + buf[1] = len - 2; /* TOC Length excludes length field */ |
---|
| 1232 | + buf[2] = 1; /* First complete session */ |
---|
| 1233 | + buf[3] = 1; /* Last complete session */ |
---|
| 1234 | + |
---|
| 1235 | + buf += 4; |
---|
| 1236 | + /* fill in A0, A1 and A2 points */ |
---|
| 1237 | + for (i = 0; i < 3; i++) { |
---|
| 1238 | + buf[0] = 1; /* Session number */ |
---|
| 1239 | + buf[1] = 0x16; /* Data track, copying allowed */ |
---|
| 1240 | + /* 2 - Track number 0 -> TOC */ |
---|
| 1241 | + buf[3] = 0xA0 + i; /* A0, A1, A2 point */ |
---|
| 1242 | + /* 4, 5, 6 - Min, sec, frame is zero */ |
---|
| 1243 | + buf[8] = 1; /* Pmin: last track number */ |
---|
| 1244 | + buf += 11; /* go to next track descriptor */ |
---|
| 1245 | + } |
---|
| 1246 | + buf -= 11; /* go back to A2 descriptor */ |
---|
| 1247 | + |
---|
| 1248 | + /* For A2, 7, 8, 9, 10 - zero, Pmin, Psec, Pframe of Lead out */ |
---|
| 1249 | + store_cdrom_address(&buf[7], msf, curlun->num_sectors); |
---|
| 1250 | + return len; |
---|
| 1251 | + |
---|
| 1252 | + default: |
---|
| 1253 | + /* PMA, ATIP, CD-TEXT not supported/required */ |
---|
| 1254 | + curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
---|
| 1255 | + return -EINVAL; |
---|
| 1256 | + } |
---|
1209 | 1257 | } |
---|
1210 | 1258 | |
---|
1211 | 1259 | static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) |
---|
.. | .. |
---|
1932 | 1980 | common->data_size_from_cmnd = |
---|
1933 | 1981 | get_unaligned_be16(&common->cmnd[7]); |
---|
1934 | 1982 | reply = check_command(common, 10, DATA_DIR_TO_HOST, |
---|
1935 | | - (7<<6) | (1<<1), 1, |
---|
| 1983 | + (0xf<<6) | (3<<1), 1, |
---|
1936 | 1984 | "READ TOC"); |
---|
1937 | 1985 | if (reply == 0) |
---|
1938 | 1986 | reply = do_read_toc(common, bh); |
---|
.. | .. |
---|
2038 | 2086 | case RELEASE: |
---|
2039 | 2087 | case RESERVE: |
---|
2040 | 2088 | case SEND_DIAGNOSTIC: |
---|
2041 | | - /* Fall through */ |
---|
2042 | 2089 | |
---|
2043 | 2090 | default: |
---|
2044 | 2091 | unknown_cmnd: |
---|
.. | .. |
---|
2301 | 2348 | { |
---|
2302 | 2349 | struct fsg_dev *fsg = fsg_from_func(f); |
---|
2303 | 2350 | |
---|
| 2351 | + /* Disable the endpoints */ |
---|
| 2352 | + if (fsg->bulk_in_enabled) { |
---|
| 2353 | + usb_ep_disable(fsg->bulk_in); |
---|
| 2354 | + fsg->bulk_in_enabled = 0; |
---|
| 2355 | + } |
---|
| 2356 | + if (fsg->bulk_out_enabled) { |
---|
| 2357 | + usb_ep_disable(fsg->bulk_out); |
---|
| 2358 | + fsg->bulk_out_enabled = 0; |
---|
| 2359 | + } |
---|
| 2360 | + |
---|
2304 | 2361 | __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); |
---|
2305 | 2362 | } |
---|
2306 | 2363 | |
---|
.. | .. |
---|
2321 | 2378 | * into a high-priority EXIT exception. |
---|
2322 | 2379 | */ |
---|
2323 | 2380 | for (;;) { |
---|
2324 | | - int sig = kernel_dequeue_signal(NULL); |
---|
| 2381 | + int sig = kernel_dequeue_signal(); |
---|
2325 | 2382 | if (!sig) |
---|
2326 | 2383 | break; |
---|
2327 | 2384 | if (sig != SIGUSR1) { |
---|
.. | .. |
---|
3436 | 3493 | |
---|
3437 | 3494 | DECLARE_USB_FUNCTION_INIT(mass_storage, fsg_alloc_inst, fsg_alloc); |
---|
3438 | 3495 | MODULE_LICENSE("GPL"); |
---|
| 3496 | +MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); |
---|
3439 | 3497 | MODULE_AUTHOR("Michal Nazarewicz"); |
---|
3440 | 3498 | |
---|
3441 | 3499 | /************************* Module parameters *************************/ |
---|