Skip to content

Commit

Permalink
Merge pull request #4 from drizzt/pureSTOCK-N7100-4.4.2
Browse files Browse the repository at this point in the history
Add "True CD-ROM emulation" support
  • Loading branch information
psndna88 committed Sep 12, 2014
2 parents e2eadbe + fc3dab0 commit 3b7adad
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 18 deletions.
29 changes: 16 additions & 13 deletions drivers/usb/gadget/f_mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,10 @@ 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;
Expand All @@ -1111,6 +1114,8 @@ static int do_read(struct fsg_common *common)
bh->inreq->length = 0;
return -EIO; /* No default reply */
}
if (curlun->cdrom)
amount_left <<= 2;

for (;;) {
/*
Expand Down Expand Up @@ -1685,7 +1690,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;
}

Expand Down Expand Up @@ -1961,7 +1966,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;
}
Expand Down Expand Up @@ -2354,7 +2359,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))) {
Expand Down Expand Up @@ -2511,16 +2518,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,
#if defined(CONFIG_USB_CDFS_SUPPORT)
#ifdef _SUPPORT_MAC_
(0xf<<6) | (1<<1), 1,
#else
(7<<6) | (1<<1), 1,
#endif
#else
(7<<6) | (1<<1), 1,
#endif

"READ TOC");
if (reply == 0)
reply = do_read_toc(common, bh);
Expand Down Expand Up @@ -3190,6 +3188,7 @@ static int fsg_main_thread(void *common_)
static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
static DEVICE_ATTR(cdrom, 0644, fsg_show_cdrom, fsg_store_cdrom);


/****************************** FSG COMMON ******************************/
Expand Down Expand Up @@ -3303,6 +3302,9 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
if (rc)
goto error_luns;
rc = device_create_file(&curlun->dev, &dev_attr_nofua);
if (rc)
goto error_luns;
rc = device_create_file(&curlun->dev, &dev_attr_cdrom);
if (rc)
goto error_luns;

Expand Down Expand Up @@ -3446,6 +3448,7 @@ static void fsg_common_release(struct kref *ref)
device_remove_file(&lun->dev, &dev_attr_nofua);
device_remove_file(&lun->dev, &dev_attr_ro);
device_remove_file(&lun->dev, &dev_attr_file);
device_remove_file(&lun->dev, &dev_attr_cdrom);
fsg_lun_close(lun);
device_unregister(&lun->dev);
}
Expand Down
46 changes: 41 additions & 5 deletions drivers/usb/gadget/storage_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,10 +701,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);
Expand Down Expand Up @@ -759,7 +759,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;
Expand Down Expand Up @@ -913,3 +912,40 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
up_write(filesem);
return (rc < 0 ? rc : count);
}

static ssize_t fsg_show_cdrom (struct device *dev, struct device_attribute *attr,
char *buf)
{
struct fsg_lun *curlun = fsg_lun_from_dev(dev);

return sprintf(buf, "%u\n", curlun->cdrom);
}

static ssize_t fsg_store_cdrom(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
ssize_t rc;
struct fsg_lun *curlun = fsg_lun_from_dev(dev);
struct rw_semaphore *filesem = dev_get_drvdata(dev);
unsigned cdrom;

rc = kstrtouint(buf, 2, &cdrom);
if (rc)
return rc;

/*
* Allow the cdrom status to change only while the
* backing file is closed.
*/
down_read(filesem);
if (fsg_lun_is_open(curlun)) {
LDBG(curlun, "cdrom status change prevented\n");
rc = -EBUSY;
} else {
curlun->cdrom = !!cdrom;
LDBG(curlun, "cdrom status set to %d\n", curlun->cdrom);
rc = count;
}
up_read(filesem);
return rc;
}

0 comments on commit 3b7adad

Please sign in to comment.