diff mbox series

[v4] usb: gadget: f_mass_storage: Make CD-ROM emulation work with Mac OS-X

Message ID 20220124160150.19499-1-quic_jackp@quicinc.com
State New
Headers show
Series [v4] usb: gadget: f_mass_storage: Make CD-ROM emulation work with Mac OS-X | expand

Commit Message

Jack Pham Jan. 24, 2022, 4:01 p.m. UTC
From: Roger Quadros <roger.quadros@nokia.com>

Mac OS-X expects CD-ROM TOC in raw format (i.e. format:2). It also
sends the READ_TOC CDB in old style SFF8020i format. i.e. 2 format bits
are encoded in MSBs of CDB byte 9.

This patch will enable CD-ROM emulation to work with Mac OS-X. Tested on
Mac OS X v10.6.3.

Signed-off-by: Roger Quadros <roger.quadros@nokia.com>
Signed-off-by: Jack Pham <quic_jackp@quicinc.com>
---
v4: Updated return length as I had inadvertently applied an earlier version of
    Roger's patch which had the same mistake [2]
v3: Updated command mask to allow for non-zero byte 2
v2: Removed Change-Id
v1: Resurrected original change [1] and consolidated into single patch

[1] https://lore.kernel.org/lkml/1302015569-9668-1-git-send-email-roger.quadros@nokia.com/T/#u
[2] https://lore.kernel.org/lkml/4D876ECA.4010503@nokia.com/

 drivers/usb/gadget/function/f_mass_storage.c | 70 ++++++++++++++++----
 1 file changed, 58 insertions(+), 12 deletions(-)

Comments

Jack Pham Jan. 26, 2022, 1:21 a.m. UTC | #1
On Mon, Jan 24, 2022 at 08:01:50AM -0800, Jack Pham wrote:
> From: Roger Quadros <roger.quadros@nokia.com>
> 
> Mac OS-X expects CD-ROM TOC in raw format (i.e. format:2). It also
> sends the READ_TOC CDB in old style SFF8020i format. i.e. 2 format bits
> are encoded in MSBs of CDB byte 9.
> 
> This patch will enable CD-ROM emulation to work with Mac OS-X. Tested on
> Mac OS X v10.6.3.
> 
> Signed-off-by: Roger Quadros <roger.quadros@nokia.com>
> Signed-off-by: Jack Pham <quic_jackp@quicinc.com>
> ---
> v4: Updated return length as I had inadvertently applied an earlier version of
>     Roger's patch which had the same mistake [2]

Hi Alan, if this looks fine to you would you please mind providing your
Acked-by again?

Also, if there are no objections, I think this patch can qualify as a
bugfix and I can send a v5 Cc'ed to stable with a Fixes tag of commit
d5e2b67aae79 ("USB: g_mass_storage: template f_mass_storage.c file
created") -- basically this has been around for as long as
f_mass_storage.c itself (if not even before when CD-ROM emulation was
first introduced to the former file_storage gadget).

Thanks,
Jack
Alan Stern Jan. 26, 2022, 1:51 a.m. UTC | #2
On Tue, Jan 25, 2022 at 05:21:54PM -0800, Jack Pham wrote:
> On Mon, Jan 24, 2022 at 08:01:50AM -0800, Jack Pham wrote:
> > From: Roger Quadros <roger.quadros@nokia.com>
> > 
> > Mac OS-X expects CD-ROM TOC in raw format (i.e. format:2). It also
> > sends the READ_TOC CDB in old style SFF8020i format. i.e. 2 format bits
> > are encoded in MSBs of CDB byte 9.
> > 
> > This patch will enable CD-ROM emulation to work with Mac OS-X. Tested on
> > Mac OS X v10.6.3.
> > 
> > Signed-off-by: Roger Quadros <roger.quadros@nokia.com>
> > Signed-off-by: Jack Pham <quic_jackp@quicinc.com>
> > ---
> > v4: Updated return length as I had inadvertently applied an earlier version of
> >     Roger's patch which had the same mistake [2]
> 
> Hi Alan, if this looks fine to you would you please mind providing your
> Acked-by again?

Sure, this is good, a simple fix to the earlier version of the patch.  
In fact, I should have noticed the wrong length value while reading it.

Acked-by: Alan Stern <stern@rowland.harvard.edu>


> Also, if there are no objections, I think this patch can qualify as a
> bugfix and I can send a v5 Cc'ed to stable with a Fixes tag of commit
> d5e2b67aae79 ("USB: g_mass_storage: template f_mass_storage.c file
> created") -- basically this has been around for as long as
> f_mass_storage.c itself (if not even before when CD-ROM emulation was
> first introduced to the former file_storage gadget).

Whether to call it a bug fix is questionable, because this interface 
never worked with Mac OSX.  But if you want it to be merged into the 
-stable kernels, I have no objection.  Greg KH may not agree...

Alan Stern
Greg KH Jan. 26, 2022, 12:37 p.m. UTC | #3
On Tue, Jan 25, 2022 at 05:21:54PM -0800, Jack Pham wrote:
> On Mon, Jan 24, 2022 at 08:01:50AM -0800, Jack Pham wrote:
> > From: Roger Quadros <roger.quadros@nokia.com>
> > 
> > Mac OS-X expects CD-ROM TOC in raw format (i.e. format:2). It also
> > sends the READ_TOC CDB in old style SFF8020i format. i.e. 2 format bits
> > are encoded in MSBs of CDB byte 9.
> > 
> > This patch will enable CD-ROM emulation to work with Mac OS-X. Tested on
> > Mac OS X v10.6.3.
> > 
> > Signed-off-by: Roger Quadros <roger.quadros@nokia.com>
> > Signed-off-by: Jack Pham <quic_jackp@quicinc.com>
> > ---
> > v4: Updated return length as I had inadvertently applied an earlier version of
> >     Roger's patch which had the same mistake [2]
> 
> Hi Alan, if this looks fine to you would you please mind providing your
> Acked-by again?
> 
> Also, if there are no objections, I think this patch can qualify as a
> bugfix and I can send a v5 Cc'ed to stable with a Fixes tag of commit
> d5e2b67aae79 ("USB: g_mass_storage: template f_mass_storage.c file
> created") -- basically this has been around for as long as
> f_mass_storage.c itself (if not even before when CD-ROM emulation was
> first introduced to the former file_storage gadget).

It's a new feature, not a bugfix :)
diff mbox series

Patch

diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index 752439690fda..988cbc8cec7a 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -1188,6 +1188,8 @@  static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
 	int		msf = common->cmnd[1] & 0x02;
 	int		start_track = common->cmnd[6];
 	u8		*buf = (u8 *)bh->buf;
+	u8		format;
+	int		i, len;
 
 	if ((common->cmnd[1] & ~0x02) != 0 ||	/* Mask away MSF */
 			start_track > 1) {
@@ -1195,18 +1197,62 @@  static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
 		return -EINVAL;
 	}
 
-	memset(buf, 0, 20);
-	buf[1] = (20-2);		/* TOC data length */
-	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);
+	format = common->cmnd[2] & 0xf;
+	/*
+	 * Check if CDB is old style SFF-8020i
+	 * i.e. format is in 2 MSBs of byte 9
+	 * Mac OS-X host sends us this.
+	 */
+	if (format == 0)
+		format = (common->cmnd[9] >> 6) & 0x3;
+
+	switch (format) {
+	case 0:
+		/* Formatted TOC */
+		len = 4 + 2*8;		/* 4 byte header + 2 descriptors */
+		memset(buf, 0, len);
+		buf[1] = len - 2;	/* TOC Length excludes length field */
+		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 len;
+
+	case 2:
+		/* Raw TOC */
+		len = 4 + 3*11;		/* 4 byte header + 3 descriptors */
+		memset(buf, 0, len);	/* Header + A0, A1 & A2 descriptors */
+		buf[1] = len - 2;	/* TOC Length excludes length field */
+		buf[2] = 1;		/* First complete session */
+		buf[3] = 1;		/* Last complete session */
+
+		buf += 4;
+		/* fill in A0, A1 and A2 points */
+		for (i = 0; i < 3; i++) {
+			buf[0] = 1;	/* Session number */
+			buf[1] = 0x16;	/* Data track, copying allowed */
+			/* 2 - Track number 0 ->  TOC */
+			buf[3] = 0xA0 + i; /* A0, A1, A2 point */
+			/* 4, 5, 6 - Min, sec, frame is zero */
+			buf[8] = 1;	/* Pmin: last track number */
+			buf += 11;	/* go to next track descriptor */
+		}
+		buf -= 11;		/* go back to A2 descriptor */
 
-	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;
+		/* For A2, 7, 8, 9, 10 - zero, Pmin, Psec, Pframe of Lead out */
+		store_cdrom_address(&buf[7], msf, curlun->num_sectors);
+		return len;
+
+	default:
+		/* Multi-session, PMA, ATIP, CD-TEXT not supported/required */
+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+		return -EINVAL;
+	}
 }
 
 static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
@@ -1944,7 +1990,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) | (3<<1), 1,
 				      "READ TOC");
 		if (reply == 0)
 			reply = do_read_toc(common, bh);