From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:60157) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QRh72-0008QV-Ff for qemu-devel@nongnu.org; Wed, 01 Jun 2011 04:49:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QRh70-0002Hu-Ay for qemu-devel@nongnu.org; Wed, 01 Jun 2011 04:49:12 -0400 Received: from mx1.redhat.com ([209.132.183.28]:10810) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QRh6z-0002HQ-EF for qemu-devel@nongnu.org; Wed, 01 Jun 2011 04:49:09 -0400 Date: Wed, 1 Jun 2011 11:49:22 +0300 From: "Michael S. Tsirkin" Message-ID: <20110601084922.GA5863@redhat.com> References: <4DD6246F.4080802@gnu.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4DD6246F.4080802@gnu.org> Subject: Re: [Qemu-devel] virtio scsi host draft specification, v2 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: qemu-devel , Stefan Hajnoczi On Fri, May 20, 2011 at 10:21:03AM +0200, Paolo Bonzini wrote: > Hi all, > > here is the second version of the spec. In the end I took the > advice of merging all requestq's into one. The reason for this is > that I took a look at the vSCSI device and liked its approach of > using SAM 8-byte LUNs directly. While it _is_ complex (and not yet > done right by QEMU---will send a patch for that), the scheme is > actually quite natural to implement and use, and supporting generic > bus/target/LUN topologies is good to have for passthrough, as well. > > I also added a few more features from SAM to avoid redefining the > structs in the future. > > Of course it may be that I'm completely wrong. :) Please comment on > the spec! > > Paolo > Virtio SCSI Host Device Spec > ============================ > > The virtio SCSI host device groups together one or more simple virtual > devices (ie. disk), and allows communicating to these devices using the > SCSI protocol. An instance of the device represents a SCSI host with > possibly many buses, targets and LUN attached. > > The virtio SCSI device services two kinds of requests: > > - command requests for a logical unit; > > - task management functions related to a logical unit, target or > command. > > The device is also able to send out notifications about added > and removed logical units. > > v4: > First public version > > v5: > Merged all virtqueues into one, removed separate TARGET fields Document still seems to refer to multiple VQs - maybe I misunderstand? > Configuration > ------------- > > Subsystem Device ID > TBD > > Virtqueues > 0:control transmitq > 1:control receiveq > 2:requestq > > Feature bits > VIRTIO_SCSI_F_INOUT - Whether a single request can include both > read-only and write-only data buffers. > > Device configuration layout > struct virtio_scsi_config { > } > > (Still empty) > > Device initialization > --------------------- > > The initialization routine should first of all discover the device's > control virtqueues. > > The driver should then place at least a buffer in the control receiveq. Size of the buffer? > Buffers returned by the device on the control receiveq may be referred > to as "events" in the rest of the document. > > The driver can immediately issue requests (for example, INQUIRY or > REPORT LUNS) or task management functions (for example, I_T RESET). > > Device operation: request queue > ------------------------------- > > The driver queues requests to the virtqueue, and they are used by the device > (not necessarily in order). > > Requests have the following format: > > struct virtio_scsi_req_cmd { > u8 lun[8]; > u64 id; > u8 task_attr; > u8 prio; > u8 crn; > u32 num_dataout, num_datain; > char cdb[]; > char data[][num_dataout+num_datain]; > u8 sense[]; > u32 sense_len; > u32 residual; > u16 status_qualifier; > u8 status; > u8 response; > }; > > /* command-specific response values */ > #define VIRTIO_SCSI_S_OK 0 > #define VIRTIO_SCSI_S_UNDERRUN 1 > #define VIRTIO_SCSI_S_ABORTED 2 > #define VIRTIO_SCSI_S_FAILURE 3 > > The lun field addresses a bus, target and logical unit in the SCSI > host. The id field is the command identifier as defined in SAM. > > The task_attr, prio field should always be zero, as task > attributes other than SIMPLE, as well as command priority, are > explicitly not supported by this version of the device. > CRN is also as defined in SAM; while it is generally expected to > be 0, clients can provide it. The maximum CRN value defined by > the protocol is 255, since CRN is stored in an 8-bit integer. > > All of these fields are always read-only. > > The cdb, data and sense fields must reside in separate buffers. > The cdb field is always read-only. The data buffers may be either > read-only or write-only, depending on the request, with the read-only > buffers coming first. The sense buffer is always write-only. > > The request shall have num_dataout read-only data buffers and > num_datain write-only data buffers. One of these two values must be > zero if the VIRTIO_SCSI_F_INOUT has not been negotiated. Why do num_datain/num_dataout need to be there? We can just look at the number of io/out bufs in virtio descriptors, no? Also, from experience, it's better not to have any layout assumptions - let the guest stick everything in a single in + single out buffer if it desires. > Remaining fields are filled in by the device. The sense_len field > indicates the number of bytes actually written to the sense buffer, > while the residual field indicates the residual size, calculated as > data_length - number_of_transferred_bytes. Again virtio gives you total number of written bytes in the used len field. So just one of these fields will be enough. > The status byte is written by the device to be the SCSI status code. > > The response byte is written by the device to be one of the following: > > - VIRTIO_SCSI_S_OK when the request was completed and the status byte > is filled with a SCSI status code (not necessarily "GOOD"). > > - VIRTIO_SCSI_S_UNDERRUN if the content of the CDB requires transferring > more data than is available in the data buffers. > > - VIRTIO_SCSI_S_ABORTED if the request was cancelled due to a reset > or another task management function. > > - VIRTIO_SCSI_S_FAILURE for other host or guest error. > > Device operation: control transmitq > ----------------------------------- > > The control transmitq is used for other SCSI transport operations. > These are not placed on the requestq so that they can be sent out-of-band, > even when the requestq is full. This is particularly important for task > management functions. > > Requests have the following format: > > struct virtio_scsi_ctrl > { > u32 type; > ... > u8 response; > } > > The type identifies the remaining fields. > > The following commands are defined: > > - Task management function > > #define VIRTIO_SCSI_T_TMF 0 > > #define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 > #define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 > #define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 > #define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 > #define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 > #define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 > #define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 > #define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 > > struct virtio_scsi_ctrl_tmf > { > u32 type; > u32 subtype; > u8 lun[8]; > u64 id; > u8 additional[]; > u8 response; > } > > /* command-specific response values */ > #define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0 > #define VIRTIO_SCSI_S_FAILURE 3 > #define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 4 > #define VIRTIO_SCSI_S_FUNCTION_REJECTED 5 > #define VIRTIO_SCSI_S_INCORRECT_LUN 6 > > The type is VIRTIO_SCSI_T_TMF. All fields but the last one are > filled by the driver, the response field is filled in by the device. > The id command must match the id in a SCSI command. Irrelevant fields > for the requested TMF are ignored. > > Note that since ACA is not supported by this version of the spec, > VIRTIO_SCSI_T_TMF_CLEAR_ACA is always a no-operation. > > The outcome of the task management function is written by the device > in the response field. Return values map 1-to-1 with those defined > in SAM. > > - Asynchronous notification query > > #define VIRTIO_SCSI_T_AN_QUERY 1 > > struct virtio_scsi_ctrl_an { > u32 type; > u8 lun[8]; > u32 event_requested; > u32 event_actual; > u8 response; > } > > #define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16 > > By sending this command, the driver asks the device which events > the given LUN can report, as described in Annex A of the SCSI MMC > specification. The driver writes the events it is interested in > into the event_requested; the device responds by writing the events > that it supports into event_actual. > > The type is VIRTIO_SCSI_T_AN_QUERY. The lun and event_requested > fields are written by the driver. The event_actual and response > fields are written by the device. > > Valid values of the response byte are VIRTIO_SCSI_S_OK or > VIRTIO_SCSI_S_FAILURE (with the same meaning as above). > > - Asynchronous notification subscription > > #define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 > > struct virtio_scsi_ctrl_an { > u32 type; > u8 lun[8]; > u32 event_requested; > u32 event_actual; > u8 response; > } > > #define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16 > > By sending this command, the driver asks the specified LUN to report > events for its physical interface, as described in Annex A of the SCSI > MMC specification. The driver writes the events it is interested in > into the event_requested; the device responds by writing the events > that it supports into event_actual. > > The type is VIRTIO_SCSI_T_AN_SUBSCRIBE. The lun and event_requested > fields are written by the driver. The event_actual and response > fields are written by the device. > > Valid values of the response byte are VIRTIO_SCSI_S_OK, > VIRTIO_SCSI_S_FAILURE (with the same meaning as above). > > Device operation: control receiveq > ---------------------------------- > > The control receiveq is used by the device to report information on > logical units that are attached to it. The driver should always > leave a few (?) buffers ready in the control receiveq. The device may > end up dropping events if it finds no buffer ready. Is this safe? It looks like there's a finite number of possible events. Can't the device queue them until there's a buffer? If this mechanism is unreliable, how is it useful? > Buffers are placed in the control receiveq and filled by the device when > interesting events occur. Events have the following format: > > #define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 > > struct virtio_scsi_ctrl_recv { > u32 event; > ... > } > > If bit 31 is set in the event, the device failed to report an event due > to missing buffers. In this case, the driver should poll the logical > units for unit attention conditions, and/or do whatever form of bus scan > is appropriate for the guest operating system. > > The following events are defined: > > - Transport reset > > #define VIRTIO_SCSI_T_TRANSPORT_RESET 0 > > struct virtio_scsi_reset { > u32 event; > u8 lun[8]; > u32 reason; > } > > #define VIRTIO_SCSI_EVT_RESET_HARD 0 > #define VIRTIO_SCSI_EVT_RESET_RESCAN 1 > #define VIRTIO_SCSI_EVT_RESET_SHUTDOWN 2 > #define VIRTIO_SCSI_EVT_RESET_REMOVED 3 > > By sending this event, the device signals that a logical unit > on a target has been reset, including the case of a new device > appearing or disappearing on the bus. > > The device fills in all fields. The event field is set to > VIRTIO_SCSI_T_TRANSPORT_RESET. The following format is used > to represent an event that affects all LUNs enumerated by > a target: > > - for logical units at the top level ("bus 0"), the LUN should be > (255,255,0,0,0,0,0,0), whose meaning is "logical unit not specified"; > > - otherwise it should identify a bus and target indication in > peripheral device addressing format, followed by the six bytes > (255,255,0,0,0,0), whose meaning is also "logical unit not > specified". > > The reason value is one of the four #define values appearing above. > VIRTIO_SCSI_EVT_RESET_REMOVED is used if the target or logical unit > is no longer able to receive commands. VIRTIO_SCSI_EVT_RESET_HARD > is used if the logical unit has been reset, but is still present. > VIRTIO_SCSI_EVT_RESET_RESCAN is used if a target or logical unit has > just appeared on the device. VIRTIO_SCSI_EVT_RESET_SHUTDOWN > is used when the host wants to initiate a graceful shutdown of a > logical unit. > > Events should also be reported via sense codes or response codes > (this obviously does not apply to newly appeared buses or targets, > since the application has never discovered them): > > - VIRTIO_SCSI_EVT_RESET_HARD > sense UNIT ATTENTION > asc POWER ON, RESET OR BUS DEVICE RESET OCCURRED > > - VIRTIO_SCSI_EVT_RESET_RESCAN > sense UNIT ATTENTION > asc REPORTED LUNS DATA HAS CHANGED > > - VIRTIO_SCSI_EVT_RESET_SHUTDOWN > sense UNIT ATTENTION > asc TARGET OPERATING CONDITIONS HAVE CHANGED > ascq 0x80 (vendor specific) > > - VIRTIO_SCSI_EVT_RESET_REMOVED > sense ILLEGAL REQUEST > asc LOGICAL UNIT NOT SUPPORTED > > However, in general events should be more easily handled by the > driver than sense codes. > > - Asynchronous notification > > #define VIRTIO_SCSI_T_ASYNC_NOTIFY 1 > > struct virtio_scsi_an_event { > u8 lun[8]; > u32 event; > } > > #define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16 > > By sending this event, the device signals that an event was > fired from a physical interface. The device only sends events > that the driver has subscribed to via the "Asynchronous notification > subscription" command. > > All fields are written by the device. The event field is set to > VIRTIO_SCSI_T_ASYNC_NOTIFY. We'll have to define events, right?