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  
fsg_lun_close(struct fsg_lun * curlun)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  
fsg_lun_open(struct fsg_lun * curlun,const char * filename)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   */
fsg_lun_fsync_sub(struct fsg_lun * curlun)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  
store_cdrom_address(u8 * dest,int msf,u32 addr)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  
fsg_show_ro(struct fsg_lun * curlun,char * buf)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  
fsg_show_nofua(struct fsg_lun * curlun,char * buf)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  
fsg_show_file(struct fsg_lun * curlun,struct rw_semaphore * filesem,char * buf)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  
fsg_show_cdrom(struct fsg_lun * curlun,char * buf)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  
fsg_show_removable(struct fsg_lun * curlun,char * buf)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  
fsg_show_inquiry_string(struct fsg_lun * curlun,char * buf)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   */
_fsg_store_ro(struct fsg_lun * curlun,bool ro)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  
fsg_store_ro(struct fsg_lun * curlun,struct rw_semaphore * filesem,const char * buf,size_t count)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  
fsg_store_nofua(struct fsg_lun * curlun,const char * buf,size_t count)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  
fsg_store_file(struct fsg_lun * curlun,struct rw_semaphore * filesem,const char * buf,size_t count)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  
fsg_store_cdrom(struct fsg_lun * curlun,struct rw_semaphore * filesem,const char * buf,size_t count)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  
fsg_store_removable(struct fsg_lun * curlun,const char * buf,size_t count)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  
fsg_store_inquiry_string(struct fsg_lun * curlun,const char * buf,size_t count)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  
fsg_store_forced_eject(struct fsg_lun * curlun,struct rw_semaphore * filesem,const char * buf,size_t count)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_DESCRIPTION("Common definitions for mass storage functionality");
541  MODULE_LICENSE("GPL");
542