From patchwork Fri Jul 27 00:22:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 10546537 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6DB7014E2 for ; Fri, 27 Jul 2018 00:22:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57A262BA4F for ; Fri, 27 Jul 2018 00:22:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4BCB22BA5A; Fri, 27 Jul 2018 00:22:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DAD9B2BA4F for ; Fri, 27 Jul 2018 00:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731813AbeG0BmF (ORCPT ); Thu, 26 Jul 2018 21:42:05 -0400 Received: from gate.crashing.org ([63.228.1.57]:37310 "EHLO gate.crashing.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731796AbeG0BmF (ORCPT ); Thu, 26 Jul 2018 21:42:05 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id w6R0MmO7007724; Thu, 26 Jul 2018 19:22:49 -0500 Message-ID: <3af4cd764ba00439e1204be66fd45e5a546ffa66.camel@kernel.crashing.org> Subject: [RFC PATCH] usb: gadget: mass_storage: Add GET_EVENT_STATUS_NOTIFICATION From: Benjamin Herrenschmidt To: linux-usb@vger.kernel.org, Felipe Balbi Date: Fri, 27 Jul 2018 10:22:47 +1000 X-Mailer: Evolution 3.28.4 (3.28.4-1.fc28) Mime-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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