| .. | .. |
|---|
| 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 *************************/ |
|---|