]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/usb/gadget/storage_common.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / usb / gadget / storage_common.c
1 /*
2  * storage_common.c -- Common definitions for mass storage functionality
3  *
4  * Copyright (C) 2003-2008 Alan Stern
5  * Copyeight (C) 2009 Samsung Electronics
6  * Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
7  *
8  * Ported to u-boot:
9  * Andrzej Pietrasiewicz <andrzej.p@samsung.com>
10  *
11  * Code refactoring & cleanup:
12  * Ćukasz Majewski <l.majewski@samsung.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  */
28
29
30 /*
31  * This file requires the following identifiers used in USB strings to
32  * be defined (each of type pointer to char):
33  *  - fsg_string_manufacturer -- name of the manufacturer
34  *  - fsg_string_product      -- name of the product
35  *  - fsg_string_serial       -- product's serial
36  *  - fsg_string_config       -- name of the configuration
37  *  - fsg_string_interface    -- name of the interface
38  * The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS
39  * macro is defined prior to including this file.
40  */
41
42 /*
43  * When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and
44  * fsg_hs_intr_in_desc objects as well as
45  * FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES
46  * macros are not defined.
47  *
48  * When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER,
49  * FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not
50  * defined (as well as corresponding entries in string tables are
51  * missing) and FSG_STRING_INTERFACE has value of zero.
52  *
53  * When FSG_NO_OTG is defined fsg_otg_desc won't be defined.
54  */
55
56 /*
57  * When FSG_BUFFHD_STATIC_BUFFER is defined when this file is included
58  * the fsg_buffhd structure's buf field will be an array of FSG_BUFLEN
59  * characters rather then a pointer to void.
60  */
61
62
63 /* #include <asm/unaligned.h> */
64
65
66 /*
67  * Thanks to NetChip Technologies for donating this product ID.
68  *
69  * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
70  * Instead:  allocate your own, using normal USB-IF procedures.
71  */
72 #define FSG_VENDOR_ID   0x0525  /* NetChip */
73 #define FSG_PRODUCT_ID  0xa4a5  /* Linux-USB File-backed Storage Gadget */
74
75 /*-------------------------------------------------------------------------*/
76
77 #ifndef DEBUG
78 #undef VERBOSE_DEBUG
79 #undef DUMP_MSGS
80 #endif /* !DEBUG */
81
82 #ifdef VERBOSE_DEBUG
83 #define VLDBG   LDBG
84 #else
85 #define VLDBG(lun, fmt, args...) do { } while (0)
86 #endif /* VERBOSE_DEBUG */
87
88 /*
89 #define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
90 #define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
91 #define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
92 #define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
93 */
94
95 #define LDBG(lun, fmt, args...) do { } while (0)
96 #define LERROR(lun, fmt, args...) do { } while (0)
97 #define LWARN(lun, fmt, args...) do { } while (0)
98 #define LINFO(lun, fmt, args...) do { } while (0)
99
100 /*
101  * Keep those macros in sync with those in
102  * include/linux/usb/composite.h or else GCC will complain.  If they
103  * are identical (the same names of arguments, white spaces in the
104  * same places) GCC will allow redefinition otherwise (even if some
105  * white space is removed or added) warning will be issued.
106  *
107  * Those macros are needed here because File Storage Gadget does not
108  * include the composite.h header.  For composite gadgets those macros
109  * are redundant since composite.h is included any way.
110  *
111  * One could check whether those macros are already defined (which
112  * would indicate composite.h had been included) or not (which would
113  * indicate we were in FSG) but this is not done because a warning is
114  * desired if definitions here differ from the ones in composite.h.
115  *
116  * We want the definitions to match and be the same in File Storage
117  * Gadget as well as Mass Storage Function (and so composite gadgets
118  * using MSF).  If someone changes them in composite.h it will produce
119  * a warning in this file when building MSF.
120  */
121
122 #define DBG(d, fmt, args...)     debug(fmt , ## args)
123 #define VDBG(d, fmt, args...)    debug(fmt , ## args)
124 /* #define ERROR(d, fmt, args...)   printf(fmt , ## args) */
125 /* #define WARNING(d, fmt, args...) printf(fmt , ## args) */
126 /* #define INFO(d, fmt, args...)    printf(fmt , ## args) */
127
128 /* #define DBG(d, fmt, args...)     do { } while (0) */
129 /* #define VDBG(d, fmt, args...)    do { } while (0) */
130 #define ERROR(d, fmt, args...)   do { } while (0)
131 #define WARNING(d, fmt, args...) do { } while (0)
132 #define INFO(d, fmt, args...)    do { } while (0)
133
134 #ifdef DUMP_MSGS
135
136 /* dump_msg(fsg, const char * label, const u8 * buf, unsigned length); */
137 # define dump_msg(fsg, label, buf, length) do {                         \
138         if (length < 512) {                                             \
139                 DBG(fsg, "%s, length %u:\n", label, length);            \
140                 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
141                                16, 1, buf, length, 0);                  \
142         }                                                               \
143 } while (0)
144
145 #  define dump_cdb(fsg) do { } while (0)
146
147 #else
148
149 #  define dump_msg(fsg, /* const char * */ label, \
150                    /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
151
152 #  ifdef VERBOSE_DEBUG
153
154 #    define dump_cdb(fsg)                                               \
155         print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
156                        16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
157
158 #  else
159
160 #    define dump_cdb(fsg) do { } while (0)
161
162 #  endif /* VERBOSE_DEBUG */
163
164 #endif /* DUMP_MSGS */
165
166 /*-------------------------------------------------------------------------*/
167
168 /* SCSI device types */
169 #define TYPE_DISK       0x00
170 #define TYPE_CDROM      0x05
171
172 /* USB protocol value = the transport method */
173 #define USB_PR_CBI      0x00            /* Control/Bulk/Interrupt */
174 #define USB_PR_CB       0x01            /* Control/Bulk w/o interrupt */
175 #define USB_PR_BULK     0x50            /* Bulk-only */
176
177 /* USB subclass value = the protocol encapsulation */
178 #define USB_SC_RBC      0x01            /* Reduced Block Commands (flash) */
179 #define USB_SC_8020     0x02            /* SFF-8020i, MMC-2, ATAPI (CD-ROM) */
180 #define USB_SC_QIC      0x03            /* QIC-157 (tape) */
181 #define USB_SC_UFI      0x04            /* UFI (floppy) */
182 #define USB_SC_8070     0x05            /* SFF-8070i (removable) */
183 #define USB_SC_SCSI     0x06            /* Transparent SCSI */
184
185 /* Bulk-only data structures */
186
187 /* Command Block Wrapper */
188 struct fsg_bulk_cb_wrap {
189         __le32  Signature;              /* Contains 'USBC' */
190         u32     Tag;                    /* Unique per command id */
191         __le32  DataTransferLength;     /* Size of the data */
192         u8      Flags;                  /* Direction in bit 7 */
193         u8      Lun;                    /* LUN (normally 0) */
194         u8      Length;                 /* Of the CDB, <= MAX_COMMAND_SIZE */
195         u8      CDB[16];                /* Command Data Block */
196 };
197
198 #define USB_BULK_CB_WRAP_LEN    31
199 #define USB_BULK_CB_SIG         0x43425355      /* Spells out USBC */
200 #define USB_BULK_IN_FLAG        0x80
201
202 /* Command Status Wrapper */
203 struct bulk_cs_wrap {
204         __le32  Signature;              /* Should = 'USBS' */
205         u32     Tag;                    /* Same as original command */
206         __le32  Residue;                /* Amount not transferred */
207         u8      Status;                 /* See below */
208 };
209
210 #define USB_BULK_CS_WRAP_LEN    13
211 #define USB_BULK_CS_SIG         0x53425355      /* Spells out 'USBS' */
212 #define USB_STATUS_PASS         0
213 #define USB_STATUS_FAIL         1
214 #define USB_STATUS_PHASE_ERROR  2
215
216 /* Bulk-only class specific requests */
217 #define USB_BULK_RESET_REQUEST          0xff
218 #define USB_BULK_GET_MAX_LUN_REQUEST    0xfe
219
220 /* CBI Interrupt data structure */
221 struct interrupt_data {
222         u8      bType;
223         u8      bValue;
224 };
225
226 #define CBI_INTERRUPT_DATA_LEN          2
227
228 /* CBI Accept Device-Specific Command request */
229 #define USB_CBI_ADSC_REQUEST            0x00
230
231 /* Length of a SCSI Command Data Block */
232 #define MAX_COMMAND_SIZE        16
233
234 /* SCSI commands that we recognize */
235 #define SC_FORMAT_UNIT                  0x04
236 #define SC_INQUIRY                      0x12
237 #define SC_MODE_SELECT_6                0x15
238 #define SC_MODE_SELECT_10               0x55
239 #define SC_MODE_SENSE_6                 0x1a
240 #define SC_MODE_SENSE_10                0x5a
241 #define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
242 #define SC_READ_6                       0x08
243 #define SC_READ_10                      0x28
244 #define SC_READ_12                      0xa8
245 #define SC_READ_CAPACITY                0x25
246 #define SC_READ_FORMAT_CAPACITIES       0x23
247 #define SC_READ_HEADER                  0x44
248 #define SC_READ_TOC                     0x43
249 #define SC_RELEASE                      0x17
250 #define SC_REQUEST_SENSE                0x03
251 #define SC_RESERVE                      0x16
252 #define SC_SEND_DIAGNOSTIC              0x1d
253 #define SC_START_STOP_UNIT              0x1b
254 #define SC_SYNCHRONIZE_CACHE            0x35
255 #define SC_TEST_UNIT_READY              0x00
256 #define SC_VERIFY                       0x2f
257 #define SC_WRITE_6                      0x0a
258 #define SC_WRITE_10                     0x2a
259 #define SC_WRITE_12                     0xaa
260
261 /* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
262 #define SS_NO_SENSE                             0
263 #define SS_COMMUNICATION_FAILURE                0x040800
264 #define SS_INVALID_COMMAND                      0x052000
265 #define SS_INVALID_FIELD_IN_CDB                 0x052400
266 #define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE   0x052100
267 #define SS_LOGICAL_UNIT_NOT_SUPPORTED           0x052500
268 #define SS_MEDIUM_NOT_PRESENT                   0x023a00
269 #define SS_MEDIUM_REMOVAL_PREVENTED             0x055302
270 #define SS_NOT_READY_TO_READY_TRANSITION        0x062800
271 #define SS_RESET_OCCURRED                       0x062900
272 #define SS_SAVING_PARAMETERS_NOT_SUPPORTED      0x053900
273 #define SS_UNRECOVERED_READ_ERROR               0x031100
274 #define SS_WRITE_ERROR                          0x030c02
275 #define SS_WRITE_PROTECTED                      0x072700
276
277 #define SK(x)           ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
278 #define ASC(x)          ((u8) ((x) >> 8))
279 #define ASCQ(x)         ((u8) (x))
280
281 struct device_attribute { int i; };
282 struct rw_semaphore { int i; };
283 #define down_write(...)                 do { } while (0)
284 #define up_write(...)                   do { } while (0)
285 #define down_read(...)                  do { } while (0)
286 #define up_read(...)                    do { } while (0)
287 #define ETOOSMALL       525
288
289 #include <usb_mass_storage.h>
290 extern struct ums_board_info            *ums_info;
291
292 /*-------------------------------------------------------------------------*/
293
294 struct fsg_lun {
295         loff_t          file_length;
296         loff_t          num_sectors;
297
298         unsigned int    initially_ro:1;
299         unsigned int    ro:1;
300         unsigned int    removable:1;
301         unsigned int    cdrom:1;
302         unsigned int    prevent_medium_removal:1;
303         unsigned int    registered:1;
304         unsigned int    info_valid:1;
305         unsigned int    nofua:1;
306
307         u32             sense_data;
308         u32             sense_data_info;
309         u32             unit_attention_data;
310
311         struct device   dev;
312 };
313
314 #define fsg_lun_is_open(curlun) ((curlun)->filp != NULL)
315 #if 0
316 static struct fsg_lun *fsg_lun_from_dev(struct device *dev)
317 {
318         return container_of(dev, struct fsg_lun, dev);
319 }
320 #endif
321
322 /* Big enough to hold our biggest descriptor */
323 #define EP0_BUFSIZE     256
324 #define DELAYED_STATUS  (EP0_BUFSIZE + 999)     /* An impossibly large value */
325
326 /* Number of buffers we will use.  2 is enough for double-buffering */
327 #define FSG_NUM_BUFFERS 2
328
329 /* Default size of buffer length. */
330 #define FSG_BUFLEN      ((u32)16384)
331
332 /* Maximal number of LUNs supported in mass storage function */
333 #define FSG_MAX_LUNS    8
334
335 enum fsg_buffer_state {
336         BUF_STATE_EMPTY = 0,
337         BUF_STATE_FULL,
338         BUF_STATE_BUSY
339 };
340
341 struct fsg_buffhd {
342 #ifdef FSG_BUFFHD_STATIC_BUFFER
343         char                            buf[FSG_BUFLEN];
344 #else
345         void                            *buf;
346 #endif
347         enum fsg_buffer_state           state;
348         struct fsg_buffhd               *next;
349
350         /*
351          * The NetChip 2280 is faster, and handles some protocol faults
352          * better, if we don't submit any short bulk-out read requests.
353          * So we will record the intended request length here.
354          */
355         unsigned int                    bulk_out_intended_length;
356
357         struct usb_request              *inreq;
358         int                             inreq_busy;
359         struct usb_request              *outreq;
360         int                             outreq_busy;
361 };
362
363 enum fsg_state {
364         /* This one isn't used anywhere */
365         FSG_STATE_COMMAND_PHASE = -10,
366         FSG_STATE_DATA_PHASE,
367         FSG_STATE_STATUS_PHASE,
368
369         FSG_STATE_IDLE = 0,
370         FSG_STATE_ABORT_BULK_OUT,
371         FSG_STATE_RESET,
372         FSG_STATE_INTERFACE_CHANGE,
373         FSG_STATE_CONFIG_CHANGE,
374         FSG_STATE_DISCONNECT,
375         FSG_STATE_EXIT,
376         FSG_STATE_TERMINATED
377 };
378
379 enum data_direction {
380         DATA_DIR_UNKNOWN = 0,
381         DATA_DIR_FROM_HOST,
382         DATA_DIR_TO_HOST,
383         DATA_DIR_NONE
384 };
385
386 /*-------------------------------------------------------------------------*/
387
388 static inline u32 get_unaligned_be24(u8 *buf)
389 {
390         return 0xffffff & (u32) get_unaligned_be32(buf - 1);
391 }
392
393 /*-------------------------------------------------------------------------*/
394
395 enum {
396 #ifndef FSG_NO_DEVICE_STRINGS
397         FSG_STRING_MANUFACTURER = 1,
398         FSG_STRING_PRODUCT,
399         FSG_STRING_SERIAL,
400         FSG_STRING_CONFIG,
401 #endif
402         FSG_STRING_INTERFACE
403 };
404
405 #ifndef FSG_NO_OTG
406 static struct usb_otg_descriptor
407 fsg_otg_desc = {
408         .bLength =              sizeof fsg_otg_desc,
409         .bDescriptorType =      USB_DT_OTG,
410
411         .bmAttributes =         USB_OTG_SRP,
412 };
413 #endif
414
415 /* There is only one interface. */
416
417 static struct usb_interface_descriptor
418 fsg_intf_desc = {
419         .bLength =              sizeof fsg_intf_desc,
420         .bDescriptorType =      USB_DT_INTERFACE,
421
422         .bNumEndpoints =        2,              /* Adjusted during fsg_bind() */
423         .bInterfaceClass =      USB_CLASS_MASS_STORAGE,
424         .bInterfaceSubClass =   USB_SC_SCSI,    /* Adjusted during fsg_bind() */
425         .bInterfaceProtocol =   USB_PR_BULK,    /* Adjusted during fsg_bind() */
426         .iInterface =           FSG_STRING_INTERFACE,
427 };
428
429 /*
430  * Three full-speed endpoint descriptors: bulk-in, bulk-out, and
431  * interrupt-in.
432  */
433
434 static struct usb_endpoint_descriptor
435 fsg_fs_bulk_in_desc = {
436         .bLength =              USB_DT_ENDPOINT_SIZE,
437         .bDescriptorType =      USB_DT_ENDPOINT,
438
439         .bEndpointAddress =     USB_DIR_IN,
440         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
441         /* wMaxPacketSize set by autoconfiguration */
442 };
443
444 static struct usb_endpoint_descriptor
445 fsg_fs_bulk_out_desc = {
446         .bLength =              USB_DT_ENDPOINT_SIZE,
447         .bDescriptorType =      USB_DT_ENDPOINT,
448
449         .bEndpointAddress =     USB_DIR_OUT,
450         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
451         /* wMaxPacketSize set by autoconfiguration */
452 };
453
454 #ifndef FSG_NO_INTR_EP
455
456 static struct usb_endpoint_descriptor
457 fsg_fs_intr_in_desc = {
458         .bLength =              USB_DT_ENDPOINT_SIZE,
459         .bDescriptorType =      USB_DT_ENDPOINT,
460
461         .bEndpointAddress =     USB_DIR_IN,
462         .bmAttributes =         USB_ENDPOINT_XFER_INT,
463         .wMaxPacketSize =       cpu_to_le16(2),
464         .bInterval =            32,     /* frames -> 32 ms */
465 };
466
467 #ifndef FSG_NO_OTG
468 #  define FSG_FS_FUNCTION_PRE_EP_ENTRIES        2
469 #else
470 #  define FSG_FS_FUNCTION_PRE_EP_ENTRIES        1
471 #endif
472
473 #endif
474
475 static struct usb_descriptor_header *fsg_fs_function[] = {
476 #ifndef FSG_NO_OTG
477         (struct usb_descriptor_header *) &fsg_otg_desc,
478 #endif
479         (struct usb_descriptor_header *) &fsg_intf_desc,
480         (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
481         (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
482 #ifndef FSG_NO_INTR_EP
483         (struct usb_descriptor_header *) &fsg_fs_intr_in_desc,
484 #endif
485         NULL,
486 };
487
488 /*
489  * USB 2.0 devices need to expose both high speed and full speed
490  * descriptors, unless they only run at full speed.
491  *
492  * That means alternate endpoint descriptors (bigger packets)
493  * and a "device qualifier" ... plus more construction options
494  * for the configuration descriptor.
495  */
496 static struct usb_endpoint_descriptor
497 fsg_hs_bulk_in_desc = {
498         .bLength =              USB_DT_ENDPOINT_SIZE,
499         .bDescriptorType =      USB_DT_ENDPOINT,
500
501         /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
502         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
503         .wMaxPacketSize =       cpu_to_le16(512),
504 };
505
506 static struct usb_endpoint_descriptor
507 fsg_hs_bulk_out_desc = {
508         .bLength =              USB_DT_ENDPOINT_SIZE,
509         .bDescriptorType =      USB_DT_ENDPOINT,
510
511         /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
512         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
513         .wMaxPacketSize =       cpu_to_le16(512),
514         .bInterval =            1,      /* NAK every 1 uframe */
515 };
516
517 #ifndef FSG_NO_INTR_EP
518
519 static struct usb_endpoint_descriptor
520 fsg_hs_intr_in_desc = {
521         .bLength =              USB_DT_ENDPOINT_SIZE,
522         .bDescriptorType =      USB_DT_ENDPOINT,
523
524         /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
525         .bmAttributes =         USB_ENDPOINT_XFER_INT,
526         .wMaxPacketSize =       cpu_to_le16(2),
527         .bInterval =            9,      /* 2**(9-1) = 256 uframes -> 32 ms */
528 };
529
530 #ifndef FSG_NO_OTG
531 #  define FSG_HS_FUNCTION_PRE_EP_ENTRIES        2
532 #else
533 #  define FSG_HS_FUNCTION_PRE_EP_ENTRIES        1
534 #endif
535
536 #endif
537
538 static struct usb_descriptor_header *fsg_hs_function[] = {
539 #ifndef FSG_NO_OTG
540         (struct usb_descriptor_header *) &fsg_otg_desc,
541 #endif
542         (struct usb_descriptor_header *) &fsg_intf_desc,
543         (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
544         (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
545 #ifndef FSG_NO_INTR_EP
546         (struct usb_descriptor_header *) &fsg_hs_intr_in_desc,
547 #endif
548         NULL,
549 };
550
551 /* Maxpacket and other transfer characteristics vary by speed. */
552 static struct usb_endpoint_descriptor *
553 fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
554                 struct usb_endpoint_descriptor *hs)
555 {
556         if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
557                 return hs;
558         return fs;
559 }
560
561 /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
562 static struct usb_string                fsg_strings[] = {
563 #ifndef FSG_NO_DEVICE_STRINGS
564         {FSG_STRING_MANUFACTURER,       fsg_string_manufacturer},
565         {FSG_STRING_PRODUCT,            fsg_string_product},
566         {FSG_STRING_SERIAL,             fsg_string_serial},
567         {FSG_STRING_CONFIG,             fsg_string_config},
568 #endif
569         {FSG_STRING_INTERFACE,          fsg_string_interface},
570         {}
571 };
572
573 static struct usb_gadget_strings        fsg_stringtab = {
574         .language       = 0x0409,               /* en-us */
575         .strings        = fsg_strings,
576 };
577
578 /*-------------------------------------------------------------------------*/
579
580 /*
581  * If the next two routines are called while the gadget is registered,
582  * the caller must own fsg->filesem for writing.
583  */
584
585 static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
586 {
587         int                             ro;
588         int                             rc = -EINVAL;
589         loff_t                          size;
590         loff_t                          num_sectors;
591         loff_t                          min_sectors;
592
593         /* R/W if we can, R/O if we must */
594         ro = curlun->initially_ro;
595
596         ums_info->get_capacity(&(ums_info->ums_dev), &size);
597         if (size < 0) {
598                 printf("unable to find file size: %s\n", filename);
599                 rc = (int) size;
600                 goto out;
601         }
602         num_sectors = size >> 9;        /* File size in 512-byte blocks */
603         min_sectors = 1;
604         if (num_sectors < min_sectors) {
605                 printf("file too small: %s\n", filename);
606                 rc = -ETOOSMALL;
607                 goto out;
608         }
609
610         curlun->ro = ro;
611         curlun->file_length = size;
612         curlun->num_sectors = num_sectors;
613         debug("open backing file: %s\n", filename);
614         rc = 0;
615
616 out:
617         return rc;
618 }
619
620 static void fsg_lun_close(struct fsg_lun *curlun)
621 {
622 }
623
624 /*-------------------------------------------------------------------------*/
625
626 /*
627  * Sync the file data, don't bother with the metadata.
628  * This code was copied from fs/buffer.c:sys_fdatasync().
629  */
630 static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
631 {
632         return 0;
633 }
634
635 static void store_cdrom_address(u8 *dest, int msf, u32 addr)
636 {
637         if (msf) {
638                 /* Convert to Minutes-Seconds-Frames */
639                 addr >>= 2;             /* Convert to 2048-byte frames */
640                 addr += 2*75;           /* Lead-in occupies 2 seconds */
641                 dest[3] = addr % 75;    /* Frames */
642                 addr /= 75;
643                 dest[2] = addr % 60;    /* Seconds */
644                 addr /= 60;
645                 dest[1] = addr;         /* Minutes */
646                 dest[0] = 0;            /* Reserved */
647         } else {
648                 /* Absolute sector */
649                 put_unaligned_be32(addr, dest);
650         }
651 }
652
653 /*-------------------------------------------------------------------------*/