usb: gadget: storage: Support READ_TOC for MacOS

Modify READ_TOC handling to add support for both Windows and MacOS
host environments.

Change-Id: I4bf3c6a8fbec95387608869efbacb6f0537c7bbf
Signed-off-by: Ravi Vembu <raviv@motorola.com>
Moto-CRs-fixed: (CR)
Reviewed-on: http://gerrit.mot.com/864910
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver <sltawvr@motorola.com>
Tested-by: Jira Key <jirakey@motorola.com>
Submit-Approved: Jira Key <jirakey@motorola.com>
Signed-off-by: Rav(CR) Vembu <raviv@motorola.com>
Reviewed-on: https://gerrit.mot.com/944111
Reviewed-on: https://gerrit.mot.com/1167320
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Lu Chai <chailu1@motorola.com>
Reviewed-by: Jianqi Yang <yangj@motorola.com>
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1262841
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Reviewed-on: https://gerrit.mot.com/1338861
Reviewed-on: https://gerrit.mot.com/1449077
Reviewed-on: https://gerrit.mot.com/1511637
Reviewed-by: Zonghua Liu <a17671@motorola.com>
Reviewed-by: Wang Wang <wangwang1@lenovo.com>
This commit is contained in:
Ravi Vembu authored and Gilberto Gambugge committed 2023-06-01 00:47:06 -03:00
1 parent 63fb41f31c
commit bcf6a699d1
1 file changed
+101 -14
+101 -14
View File
@@ -1192,12 +1192,105 @@ static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh)
return 8; return 8;
} }
struct toc_header {
u8 data_len_msb;
u8 data_len_lsb;
u8 first_track_number;
u8 last_track_number;
};
struct toc_descriptor {
u8 ctrl;
u8 adr;
u8 tno;
u8 point;
u8 min;
u8 sec;
u8 frame;
u8 zero;
u8 pmin;
u8 psec;
u8 pframe;
};
static int build_toc_response_buf(u8 *dest)
{
struct toc_header *pheader = (struct toc_header *)dest;
struct toc_descriptor *pdesc;
/* build header */
pheader->data_len_msb = 0x00;
pheader->data_len_lsb = 0x2E; /* TOC data length */
pheader->first_track_number = 0x01;
pheader->last_track_number = 0x01;
/* toc descriptor 1 */
pdesc = (struct toc_descriptor *)&dest[4];
pdesc->ctrl = 0x01;
pdesc->adr = 0x16;
pdesc->tno = 0x00;
pdesc->point = 0xA0;
pdesc->min = 0x00;
pdesc->sec = 0x00;
pdesc->frame = 0x00;
pdesc->zero = 0x00;
pdesc->pmin = 0x01; /* first track number */
pdesc->psec = 0x00;
pdesc->pframe = 0x00;
/* toc descriptor 2 */
pdesc = pdesc + 1;
pdesc->ctrl = 0x01;
pdesc->adr = 0x16;
pdesc->tno = 0x00;
pdesc->point = 0xA1;
pdesc->min = 0x00;
pdesc->sec = 0x00;
pdesc->frame = 0x00;
pdesc->zero = 0x00;
pdesc->pmin = 0x01; /* last track number */
pdesc->psec = 0x00;
pdesc->pframe = 0x00;
/* toc descriptor 3 */
pdesc = pdesc + 1;
pdesc->ctrl = 0x01;
pdesc->adr = 0x16;
pdesc->tno = 0x00;
pdesc->point = 0xA2;
pdesc->min = 0x00;
pdesc->sec = 0x00;
pdesc->frame = 0x00;
pdesc->zero = 0x00;
pdesc->pmin = 0x4F; /* pmin, psec, pframe represents */
pdesc->psec = 0x21; /* start position of lead-out */
pdesc->pframe = 0x029;
/* toc descriptor 4 */
pdesc = pdesc + 1;
pdesc->ctrl = 0x01;
pdesc->adr = 0x14;
pdesc->tno = 0x00;
pdesc->point = 0x01;
pdesc->min = 0x00;
pdesc->sec = 0x00;
pdesc->frame = 0x00;
pdesc->zero = 0x00;
pdesc->pmin = 0x00; /* pmin, psec, pframe represents */
pdesc->psec = 0x02; /* start position of track */
pdesc->pframe = 0x00;
/* return total packet length */
return (sizeof(struct toc_descriptor)*4) + sizeof(struct toc_header);
}
static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
{ {
struct fsg_lun *curlun = common->curlun; struct fsg_lun *curlun = common->curlun;
int msf = common->cmnd[1] & 0x02;
int start_track = common->cmnd[6]; int start_track = common->cmnd[6];
u8 *buf = (u8 *)bh->buf; u8 *buf = (u8 *)bh->buf;
int toc_buf_len = 0;
if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */
start_track > 1) { start_track > 1) {
@@ -1205,18 +1298,8 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
return -EINVAL; return -EINVAL;
} }
memset(buf, 0, 20); toc_buf_len = build_toc_response_buf(buf);
buf[1] = (20-2); /* TOC data length */ return toc_buf_len;
buf[2] = 1; /* First track number */
buf[3] = 1; /* Last track number */
buf[5] = 0x16; /* Data track, copying allowed */
buf[6] = 0x01; /* Only track is number 1 */
store_cdrom_address(&buf[8], msf, 0);
buf[13] = 0x16; /* Lead-out track is data */
buf[14] = 0xAA; /* Lead-out track number */
store_cdrom_address(&buf[16], msf, curlun->num_sectors);
return 20;
} }
static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
@@ -1942,8 +2025,12 @@ static int do_scsi_command(struct fsg_common *common)
goto unknown_cmnd; goto unknown_cmnd;
common->data_size_from_cmnd = common->data_size_from_cmnd =
get_unaligned_be16(&common->cmnd[7]); get_unaligned_be16(&common->cmnd[7]);
/* Set bit 9 to 1 in the mask because Mac Sends a value in byte
* 9 of the READ_TOC . Windows does not set it, but changing
* the mask covers both host envs.
*/
reply = check_command(common, 10, DATA_DIR_TO_HOST, reply = check_command(common, 10, DATA_DIR_TO_HOST,
(7<<6) | (1<<1), 1, (0xf<<6) | (1<<1), 1,
"READ TOC"); "READ TOC");
if (reply == 0) if (reply == 0)
reply = do_read_toc(common, bh); reply = do_read_toc(common, bh);