All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] usb: gadget: mass_storage: Add GET_EVENT_STATUS_NOTIFICATION
@ 2018-07-27  0:22 Benjamin Herrenschmidt
  0 siblings, 0 replies; only message in thread
From: Benjamin Herrenschmidt @ 2018-07-27  0:22 UTC (permalink / raw)
  To: linux-usb, Felipe Balbi

This is just RFC at this stage, I was getting annoyed at the once-per-second
debug message about unsupported command when using f_mass_storage as a CDROM,
so I quickly hacked that up.

I'm not clearing the events per-se, I'm just sending events based on the
state of pending unit attentions, which seems to be enough to please Linux
on the other side, but definitely needs more testing or expert opinions.

If I find some spare cycle in the next few weeks I might add a few more
of the basic MMC commands so we at least support everything Linux throws
at us for a normal read-only CDROM.

Comments ?

Not-Yet-Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 drivers/usb/gadget/function/f_mass_storage.c | 49 +++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)




--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index 7b13928077c9..d8c83359f470 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -1390,6 +1390,42 @@ static int do_mode_select(struct fsg_common *common, struct fsg_buffhd *bh)
 	return -EINVAL;
 }
 
+static int do_get_event_status_notification(struct fsg_common *common,
+					    struct fsg_buffhd *bh)
+{
+	struct fsg_lun	*curlun = common->curlun;
+	u8		*buf = (u8 *) bh->buf;
+	bool		media_class;
+	u8		event;
+	int		size;
+
+	/* We only support media class */
+	media_class = (common->cmnd[4] & 0x10) != 0;
+
+	/* We just mirror the unit attentions */
+	if (curlun->unit_attention_data == SS_NOT_READY_TO_READY_TRANSITION)
+		event = 2; /* New media */
+	else if (curlun->unit_attention_data == SS_MEDIUM_NOT_PRESENT)
+		event = 3;
+	else
+		event = 0;
+
+	/* Fill common header */
+	size = 4;
+	buf[3] = 0x10; /* Support classes: media */
+	if (media_class) {
+		buf[2] = 4; /* Return media event */
+		if (event == 0)
+			buf[2] |= 0x80; /* No Event Available */
+		size += 8;
+		buf[4] = event;
+		buf[5] = 1; /* Active */
+		buf[6] = buf[7] = 0;
+	} else {
+		buf[2] = 0; /* None of the req. classes supported */
+	}
+	return size;
+}
 
 /*-------------------------------------------------------------------------*/
 
@@ -1753,7 +1789,8 @@ static int check_command(struct fsg_common *common, int cmnd_size,
 	 */
 	if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
 	    common->cmnd[0] != INQUIRY &&
-	    common->cmnd[0] != REQUEST_SENSE) {
+	    common->cmnd[0] != REQUEST_SENSE &&
+	    common->cmnd[0] != GET_EVENT_STATUS_NOTIFICATION) {
 		curlun->sense_data = curlun->unit_attention_data;
 		curlun->unit_attention_data = SS_NO_SENSE;
 		return -EINVAL;
@@ -2025,6 +2062,16 @@ static int do_scsi_command(struct fsg_common *common)
 			reply = do_write(common);
 		break;
 
+	case GET_EVENT_STATUS_NOTIFICATION:
+		common->data_size_from_cmnd =
+			get_unaligned_be16(&common->cmnd[7]);
+		reply = check_command(common, 10, DATA_DIR_TO_HOST,
+				      (1 << 1) | (1 << 4) | (3 << 7) | (1 << 9),
+				      0, "GET_EVENT_STATUS_NOTIFICATION");
+		if (reply == 0)
+			reply = do_get_event_status_notification(common, bh);
+		break;
+
 	/*
 	 * Some mandatory commands that we recognize but don't implement.
 	 * They don't mean much in this setting.  It's left as an exercise

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2018-07-27  0:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-27  0:22 [RFC] usb: gadget: mass_storage: Add GET_EVENT_STATUS_NOTIFICATION Benjamin Herrenschmidt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.