Hi, Benjamin Herrenschmidt <b...@kernel.crashing.org> writes: > This is just RFC at this stage, I was getting annoyed at the > once-per-seconddebug 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 thestate > of pending unit attentions, which seems to be enough to please Linuxon 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 moreof the > basic MMC commands so we at least support everything Linux throwsat us for a > normal read-only CDROM. > Comments ? > Not-Yet-Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org>--- > drivers/usb/gadget/function/f_mass_storage.c | 49 +++++++++++++++++++- 1 file > changed, 48 insertions(+), 1 deletion(-) > diff --git a/drivers/usb/gadget/function/f_mass_storage.c > b/drivers/usb/gadget/function/f_mass_storage.cindex > 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
html + plain text? C'mon Ben :) -- balbi
signature.asc
Description: PGP signature