aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/f_mass_storage.c17
-rw-r--r--drivers/usb/gadget/storage_common.c9
2 files changed, 16 insertions, 10 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index efa8469..a6b21cb 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -771,12 +771,17 @@ static int do_read(struct fsg_common *common)
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
return -EINVAL;
}
- file_offset = ((loff_t) lba) << 9;
+ if (curlun->cdrom)
+ file_offset = ((loff_t) lba) << 11;
+ else
+ file_offset = ((loff_t) lba) << 9;
/* Carry out the file reads */
amount_left = common->data_size_from_cmnd;
if (unlikely(amount_left == 0))
return -EIO; /* No default reply */
+ if (curlun->cdrom)
+ amount_left <<= 2;
for (;;) {
/*
@@ -1291,7 +1296,7 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh)
put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
/* Max logical block */
- put_unaligned_be32(512, &buf[4]); /* Block length */
+ put_unaligned_be32(curlun->cdrom ? 2048 : 512, &buf[4]); /* Block length */
return 8;
}
@@ -1529,7 +1534,7 @@ static int do_read_format_capacities(struct fsg_common *common,
put_unaligned_be32(curlun->num_sectors, &buf[0]);
/* Number of blocks */
- put_unaligned_be32(512, &buf[4]); /* Block length */
+ put_unaligned_be32(curlun->cdrom ? 2048 : 512, &buf[4]); /* Block length */
buf[4] = 0x02; /* Current capacity */
return 12;
}
@@ -1922,7 +1927,9 @@ static int check_command(struct fsg_common *common, int cmnd_size,
return -EINVAL;
}
- /* Check that only command bytes listed in the mask are non-zero */
+ /* Check that only command bytes listed in the mask are non-zero
+ * Some BIOSes put some non-zero values in READ_TOC requests in
+ * the last two bytes */
common->cmnd[1] &= 0x1f; /* Mask away the LUN */
for (i = 1; i < cmnd_size; ++i) {
if (common->cmnd[i] && !(mask & (1 << i))) {
@@ -2079,7 +2086,7 @@ static int do_scsi_command(struct fsg_common *common)
common->data_size_from_cmnd =
get_unaligned_be16(&common->cmnd[7]);
reply = check_command(common, 10, DATA_DIR_TO_HOST,
- (7<<6) | (1<<1), 1,
+ (0xf<<6) | (1<<1), 1,
"READ TOC");
if (reply == 0)
reply = do_read_toc(common, bh);
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 4e64b08..4dfede4 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -583,10 +583,10 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
num_sectors = size >> 9; /* File size in 512-byte blocks */
min_sectors = 1;
if (curlun->cdrom) {
- num_sectors &= ~3; /* Reduce to a multiple of 2048 */
- min_sectors = 300*4; /* Smallest track is 300 frames */
- if (num_sectors >= 256*60*75*4) {
- num_sectors = (256*60*75 - 1) * 4;
+ num_sectors >>= 2; /* Reduce to a multiple of 2048 */
+ min_sectors = 300; /* Smallest track is 300 frames */
+ if (num_sectors >= 256*60*75) {
+ num_sectors = (256*60*75 - 1);
LINFO(curlun, "file too big: %s\n", filename);
LINFO(curlun, "using only first %d blocks\n",
(int) num_sectors);
@@ -641,7 +641,6 @@ static void store_cdrom_address(u8 *dest, int msf, u32 addr)
{
if (msf) {
/* Convert to Minutes-Seconds-Frames */
- addr >>= 2; /* Convert to 2048-byte frames */
addr += 2*75; /* Lead-in occupies 2 seconds */
dest[3] = addr % 75; /* Frames */
addr /= 75;