1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * storage_common.c -- Common definitions for mass storage functionality 4 * 5 * Copyright (C) 2003-2008 Alan Stern 6 * Copyeight (C) 2009 Samsung Electronics 7 * Author: Michal Nazarewicz (mina86@mina86.com) 8 */ 9 10 /* 11 * This file requires the following identifiers used in USB strings to 12 * be defined (each of type pointer to char): 13 * - fsg_string_interface -- name of the interface 14 */ 15 16 /* 17 * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers 18 * sets the number of pipeline buffers (length of the fsg_buffhd array). 19 * The valid range of num_buffers is: num >= 2 && num <= 4. 20 */ 21 22 #include <linux/module.h> 23 #include <linux/blkdev.h> 24 #include <linux/file.h> 25 #include <linux/fs.h> 26 #include <linux/kstrtox.h> 27 #include <linux/usb/composite.h> 28 29 #include "storage_common.h" 30 31 /* There is only one interface. */ 32 33 struct usb_interface_descriptor fsg_intf_desc = { 34 .bLength = sizeof fsg_intf_desc, 35 .bDescriptorType = USB_DT_INTERFACE, 36 37 .bNumEndpoints = 2, /* Adjusted during fsg_bind() */ 38 .bInterfaceClass = USB_CLASS_MASS_STORAGE, 39 .bInterfaceSubClass = USB_SC_SCSI, /* Adjusted during fsg_bind() */ 40 .bInterfaceProtocol = USB_PR_BULK, /* Adjusted during fsg_bind() */ 41 .iInterface = FSG_STRING_INTERFACE, 42 }; 43 EXPORT_SYMBOL_GPL(fsg_intf_desc); 44 45 /* 46 * Three full-speed endpoint descriptors: bulk-in, bulk-out, and 47 * interrupt-in. 48 */ 49 50 struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = { 51 .bLength = USB_DT_ENDPOINT_SIZE, 52 .bDescriptorType = USB_DT_ENDPOINT, 53 54 .bEndpointAddress = USB_DIR_IN, 55 .bmAttributes = USB_ENDPOINT_XFER_BULK, 56 /* wMaxPacketSize set by autoconfiguration */ 57 }; 58 EXPORT_SYMBOL_GPL(fsg_fs_bulk_in_desc); 59 60 struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = { 61 .bLength = USB_DT_ENDPOINT_SIZE, 62 .bDescriptorType = USB_DT_ENDPOINT, 63 64 .bEndpointAddress = USB_DIR_OUT, 65 .bmAttributes = USB_ENDPOINT_XFER_BULK, 66 /* wMaxPacketSize set by autoconfiguration */ 67 }; 68 EXPORT_SYMBOL_GPL(fsg_fs_bulk_out_desc); 69 70 struct usb_descriptor_header *fsg_fs_function[] = { 71 (struct usb_descriptor_header *) &fsg_intf_desc, 72 (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc, 73 (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, 74 NULL, 75 }; 76 EXPORT_SYMBOL_GPL(fsg_fs_function); 77 78 79 /* 80 * USB 2.0 devices need to expose both high speed and full speed 81 * descriptors, unless they only run at full speed. 82 * 83 * That means alternate endpoint descriptors (bigger packets). 84 */ 85 struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = { 86 .bLength = USB_DT_ENDPOINT_SIZE, 87 .bDescriptorType = USB_DT_ENDPOINT, 88 89 /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ 90 .bmAttributes = USB_ENDPOINT_XFER_BULK, 91 .wMaxPacketSize = cpu_to_le16(512), 92 }; 93 EXPORT_SYMBOL_GPL(fsg_hs_bulk_in_desc); 94 95 struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = { 96 .bLength = USB_DT_ENDPOINT_SIZE, 97 .bDescriptorType = USB_DT_ENDPOINT, 98 99 /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ 100 .bmAttributes = USB_ENDPOINT_XFER_BULK, 101 .wMaxPacketSize = cpu_to_le16(512), 102 .bInterval = 1, /* NAK every 1 uframe */ 103 }; 104 EXPORT_SYMBOL_GPL(fsg_hs_bulk_out_desc); 105 106 107 struct usb_descriptor_header *fsg_hs_function[] = { 108 (struct usb_descriptor_header *) &fsg_intf_desc, 109 (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc, 110 (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, 111 NULL, 112 }; 113 EXPORT_SYMBOL_GPL(fsg_hs_function); 114 115 struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = { 116 .bLength = USB_DT_ENDPOINT_SIZE, 117 .bDescriptorType = USB_DT_ENDPOINT, 118 119 /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ 120 .bmAttributes = USB_ENDPOINT_XFER_BULK, 121 .wMaxPacketSize = cpu_to_le16(1024), 122 }; 123 EXPORT_SYMBOL_GPL(fsg_ss_bulk_in_desc); 124 125 struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = { 126 .bLength = sizeof(fsg_ss_bulk_in_comp_desc), 127 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 128 129 /*.bMaxBurst = DYNAMIC, */ 130 }; 131 EXPORT_SYMBOL_GPL(fsg_ss_bulk_in_comp_desc); 132 133 struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = { 134 .bLength = USB_DT_ENDPOINT_SIZE, 135 .bDescriptorType = USB_DT_ENDPOINT, 136 137 /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ 138 .bmAttributes = USB_ENDPOINT_XFER_BULK, 139 .wMaxPacketSize = cpu_to_le16(1024), 140 }; 141 EXPORT_SYMBOL_GPL(fsg_ss_bulk_out_desc); 142 143 struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { 144 .bLength = sizeof(fsg_ss_bulk_in_comp_desc), 145 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 146 147 /*.bMaxBurst = DYNAMIC, */ 148 }; 149 EXPORT_SYMBOL_GPL(fsg_ss_bulk_out_comp_desc); 150 151 struct usb_descriptor_header *fsg_ss_function[] = { 152 (struct usb_descriptor_header *) &fsg_intf_desc, 153 (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc, 154 (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc, 155 (struct usb_descriptor_header *) &fsg_ss_bulk_out_desc, 156 (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, 157 NULL, 158 }; 159 EXPORT_SYMBOL_GPL(fsg_ss_function); 160 161 162 /*-------------------------------------------------------------------------*/ 163 164 /* 165 * If the next two routines are called while the gadget is registered, 166 * the caller must own fsg->filesem for writing. 167 */ 168 169 void fsg_lun_close(struct fsg_lun *curlun) 170 { 171 if (curlun->filp) { 172 LDBG(curlun, "close backing file\n"); 173 fput(curlun->filp); 174 curlun->filp = NULL; 175 } 176 } 177 EXPORT_SYMBOL_GPL(fsg_lun_close); 178 179 int fsg_lun_open(struct fsg_lun *curlun, const char *filename) 180 { 181 int ro; 182 struct file *filp = NULL; 183 int rc = -EINVAL; 184 struct inode *inode = NULL; 185 loff_t size; 186 loff_t num_sectors; 187 loff_t min_sectors; 188 unsigned int blkbits; 189 unsigned int blksize; 190 191 /* R/W if we can, R/O if we must */ 192 ro = curlun->initially_ro; 193 if (!ro) { 194 filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); 195 if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES) 196 ro = 1; 197 } 198 if (ro) 199 filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0); 200 if (IS_ERR(filp)) { 201 LINFO(curlun, "unable to open backing file: %s\n", filename); 202 return PTR_ERR(filp); 203 } 204 205 if (!(filp->f_mode & FMODE_WRITE)) 206 ro = 1; 207 208 inode = filp->f_mapping->host; 209 if ((!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) { 210 LINFO(curlun, "invalid file type: %s\n", filename); 211 goto out; 212 } 213 214 /* 215 * If we can't read the file, it's no good. 216 * If we can't write the file, use it read-only. 217 */ 218 if (!(filp->f_mode & FMODE_CAN_READ)) { 219 LINFO(curlun, "file not readable: %s\n", filename); 220 goto out; 221 } 222 if (!(filp->f_mode & FMODE_CAN_WRITE)) 223 ro = 1; 224 225 size = i_size_read(inode); 226 if (size < 0) { 227 LINFO(curlun, "unable to find file size: %s\n", filename); 228 rc = (int) size; 229 goto out; 230 } 231 232 if (curlun->cdrom) { 233 blksize = 2048; 234 blkbits = 11; 235 } else if (S_ISBLK(inode->i_mode)) { 236 blksize = bdev_logical_block_size(I_BDEV(inode)); 237 blkbits = blksize_bits(blksize); 238 } else { 239 blksize = 512; 240 blkbits = 9; 241 } 242 243 num_sectors = size >> blkbits; /* File size in logic-block-size blocks */ 244 min_sectors = 1; 245 if (curlun->cdrom) { 246 min_sectors = 300; /* Smallest track is 300 frames */ 247 if (num_sectors >= 256*60*75) { 248 num_sectors = 256*60*75 - 1; 249 LINFO(curlun, "file too big: %s\n", filename); 250 LINFO(curlun, "using only first %d blocks\n", 251 (int) num_sectors); 252 } 253 } 254 if (num_sectors < min_sectors) { 255 LINFO(curlun, "file too small: %s\n", filename); 256 rc = -ETOOSMALL; 257 goto out; 258 } 259 260 if (fsg_lun_is_open(curlun)) 261 fsg_lun_close(curlun); 262 263 curlun->blksize = blksize; 264 curlun->blkbits = blkbits; 265 curlun->ro = ro; 266 curlun->filp = filp; 267 curlun->file_length = size; 268 curlun->num_sectors = num_sectors; 269 LDBG(curlun, "open backing file: %s\n", filename); 270 return 0; 271 272 out: 273 fput(filp); 274 return rc; 275 } 276 EXPORT_SYMBOL_GPL(fsg_lun_open); 277 278 279 /*-------------------------------------------------------------------------*/ 280 281 /* 282 * Sync the file data, don't bother with the metadata. 283 * This code was copied from fs/buffer.c:sys_fdatasync(). 284 */ 285 int fsg_lun_fsync_sub(struct fsg_lun *curlun) 286 { 287 struct file *filp = curlun->filp; 288 289 if (curlun->ro || !filp) 290 return 0; 291 return vfs_fsync(filp, 1); 292 } 293 EXPORT_SYMBOL_GPL(fsg_lun_fsync_sub); 294 295 void store_cdrom_address(u8 *dest, int msf, u32 addr) 296 { 297 if (msf) { 298 /* 299 * Convert to Minutes-Seconds-Frames. 300 * Sector size is already set to 2048 bytes. 301 */ 302 addr += 2*75; /* Lead-in occupies 2 seconds */ 303 dest[3] = addr % 75; /* Frames */ 304 addr /= 75; 305 dest[2] = addr % 60; /* Seconds */ 306 addr /= 60; 307 dest[1] = addr; /* Minutes */ 308 dest[0] = 0; /* Reserved */ 309 } else { 310 /* Absolute sector */ 311 put_unaligned_be32(addr, dest); 312 } 313 } 314 EXPORT_SYMBOL_GPL(store_cdrom_address); 315 316 /*-------------------------------------------------------------------------*/ 317 318 319 ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf) 320 { 321 return sprintf(buf, "%d\n", fsg_lun_is_open(curlun) 322 ? curlun->ro 323 : curlun->initially_ro); 324 } 325 EXPORT_SYMBOL_GPL(fsg_show_ro); 326 327 ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf) 328 { 329 return sprintf(buf, "%u\n", curlun->nofua); 330 } 331 EXPORT_SYMBOL_GPL(fsg_show_nofua); 332 333 ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, 334 char *buf) 335 { 336 char *p; 337 ssize_t rc; 338 339 down_read(filesem); 340 if (fsg_lun_is_open(curlun)) { /* Get the complete pathname */ 341 p = file_path(curlun->filp, buf, PAGE_SIZE - 1); 342 if (IS_ERR(p)) 343 rc = PTR_ERR(p); 344 else { 345 rc = strlen(p); 346 memmove(buf, p, rc); 347 buf[rc] = '\n'; /* Add a newline */ 348 buf[++rc] = 0; 349 } 350 } else { /* No file, return 0 bytes */ 351 *buf = 0; 352 rc = 0; 353 } 354 up_read(filesem); 355 return rc; 356 } 357 EXPORT_SYMBOL_GPL(fsg_show_file); 358 359 ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf) 360 { 361 return sprintf(buf, "%u\n", curlun->cdrom); 362 } 363 EXPORT_SYMBOL_GPL(fsg_show_cdrom); 364 365 ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf) 366 { 367 return sprintf(buf, "%u\n", curlun->removable); 368 } 369 EXPORT_SYMBOL_GPL(fsg_show_removable); 370 371 ssize_t fsg_show_inquiry_string(struct fsg_lun *curlun, char *buf) 372 { 373 return sprintf(buf, "%s\n", curlun->inquiry_string); 374 } 375 EXPORT_SYMBOL_GPL(fsg_show_inquiry_string); 376 377 /* 378 * The caller must hold fsg->filesem for reading when calling this function. 379 */ 380 static ssize_t _fsg_store_ro(struct fsg_lun *curlun, bool ro) 381 { 382 if (fsg_lun_is_open(curlun)) { 383 LDBG(curlun, "read-only status change prevented\n"); 384 return -EBUSY; 385 } 386 387 curlun->ro = ro; 388 curlun->initially_ro = ro; 389 LDBG(curlun, "read-only status set to %d\n", curlun->ro); 390 391 return 0; 392 } 393 394 ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem, 395 const char *buf, size_t count) 396 { 397 ssize_t rc; 398 bool ro; 399 400 rc = kstrtobool(buf, &ro); 401 if (rc) 402 return rc; 403 404 /* 405 * Allow the write-enable status to change only while the 406 * backing file is closed. 407 */ 408 down_read(filesem); 409 rc = _fsg_store_ro(curlun, ro); 410 if (!rc) 411 rc = count; 412 up_read(filesem); 413 414 return rc; 415 } 416 EXPORT_SYMBOL_GPL(fsg_store_ro); 417 418 ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count) 419 { 420 bool nofua; 421 int ret; 422 423 ret = kstrtobool(buf, &nofua); 424 if (ret) 425 return ret; 426 427 /* Sync data when switching from async mode to sync */ 428 if (!nofua && curlun->nofua) 429 fsg_lun_fsync_sub(curlun); 430 431 curlun->nofua = nofua; 432 433 return count; 434 } 435 EXPORT_SYMBOL_GPL(fsg_store_nofua); 436 437 ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem, 438 const char *buf, size_t count) 439 { 440 int rc = 0; 441 442 if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) { 443 LDBG(curlun, "eject attempt prevented\n"); 444 return -EBUSY; /* "Door is locked" */ 445 } 446 447 /* Remove a trailing newline */ 448 if (count > 0 && buf[count-1] == '\n') 449 ((char *) buf)[count-1] = 0; /* Ugh! */ 450 451 /* Load new medium */ 452 down_write(filesem); 453 if (count > 0 && buf[0]) { 454 /* fsg_lun_open() will close existing file if any. */ 455 rc = fsg_lun_open(curlun, buf); 456 if (rc == 0) 457 curlun->unit_attention_data = 458 SS_NOT_READY_TO_READY_TRANSITION; 459 } else if (fsg_lun_is_open(curlun)) { 460 fsg_lun_close(curlun); 461 curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; 462 } 463 up_write(filesem); 464 return (rc < 0 ? rc : count); 465 } 466 EXPORT_SYMBOL_GPL(fsg_store_file); 467 468 ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem, 469 const char *buf, size_t count) 470 { 471 bool cdrom; 472 int ret; 473 474 ret = kstrtobool(buf, &cdrom); 475 if (ret) 476 return ret; 477 478 down_read(filesem); 479 ret = cdrom ? _fsg_store_ro(curlun, true) : 0; 480 481 if (!ret) { 482 curlun->cdrom = cdrom; 483 ret = count; 484 } 485 up_read(filesem); 486 487 return ret; 488 } 489 EXPORT_SYMBOL_GPL(fsg_store_cdrom); 490 491 ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf, 492 size_t count) 493 { 494 bool removable; 495 int ret; 496 497 ret = kstrtobool(buf, &removable); 498 if (ret) 499 return ret; 500 501 curlun->removable = removable; 502 503 return count; 504 } 505 EXPORT_SYMBOL_GPL(fsg_store_removable); 506 507 ssize_t fsg_store_inquiry_string(struct fsg_lun *curlun, const char *buf, 508 size_t count) 509 { 510 const size_t len = min(count, sizeof(curlun->inquiry_string)); 511 512 if (len == 0 || buf[0] == '\n') { 513 curlun->inquiry_string[0] = 0; 514 } else { 515 snprintf(curlun->inquiry_string, 516 sizeof(curlun->inquiry_string), "%-28s", buf); 517 if (curlun->inquiry_string[len-1] == '\n') 518 curlun->inquiry_string[len-1] = ' '; 519 } 520 521 return count; 522 } 523 EXPORT_SYMBOL_GPL(fsg_store_inquiry_string); 524 525 ssize_t fsg_store_forced_eject(struct fsg_lun *curlun, struct rw_semaphore *filesem, 526 const char *buf, size_t count) 527 { 528 int ret; 529 530 /* 531 * Forcibly detach the backing file from the LUN 532 * regardless of whether the host has allowed it. 533 */ 534 curlun->prevent_medium_removal = 0; 535 ret = fsg_store_file(curlun, filesem, "", 0); 536 return ret < 0 ? ret : count; 537 } 538 EXPORT_SYMBOL_GPL(fsg_store_forced_eject); 539 540 MODULE_LICENSE("GPL"); 541