diff options
-rw-r--r-- | drivers/usb/gadget/f_mass_storage.c | 17 | ||||
-rw-r--r-- | drivers/usb/gadget/storage_common.c | 9 |
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; |