summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile47
-rw-r--r--block-migration.c2
-rw-r--r--docs/libcacard.txt20
-rw-r--r--docs/qapi-code-gen.txt2
-rw-r--r--hw/ide/atapi.c20
-rw-r--r--hw/mips_mipssim.c2
-rw-r--r--hw/scsi-bus.c128
-rw-r--r--hw/scsi-defs.h10
-rw-r--r--hw/scsi-disk.c37
-rw-r--r--hw/scsi.h2
-rw-r--r--monitor.c4
-rw-r--r--qapi/qmp-output-visitor.c2
-rw-r--r--qemu-doc.texi60
-rw-r--r--target-i386/kvm.c2
14 files changed, 253 insertions, 85 deletions
diff --git a/Makefile b/Makefile
index 168093c6cf..7c93739604 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ ifeq ($(TRACE_BACKEND),dtrace)
 GENERATED_HEADERS += trace-dtrace.h
 endif
 GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h
+GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c
 
 ifneq ($(wildcard config-host.mak),)
 # Put the all: rule here so that config-host.mak can contain dependencies.
@@ -171,34 +172,34 @@ qapi-dir := qapi-generated
 test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
 qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
 
-$(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h
-$(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
+$(qapi-dir)/test-qapi-types.c $(qapi-dir)/test-qapi-types.h :\
+$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "test-" < $<, "  GEN   $@")
-$(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h
-$(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
+$(qapi-dir)/test-qapi-visit.c $(qapi-dir)/test-qapi-visit.h :\
+$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "test-" < $<, "  GEN   $@")
-$(qapi-dir)/test-qmp-commands.h: $(qapi-dir)/test-qmp-marshal.c
-$(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
+$(qapi-dir)/test-qmp-commands.h $(qapi-dir)/test-qmp-marshal.c :\
+$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
 	    $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "test-" < $<, "  GEN   $@")
 
-$(qapi-dir)/qga-qapi-types.c: $(qapi-dir)/qga-qapi-types.h
-$(qapi-dir)/qga-qapi-types.h: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-types.py
+$(qapi-dir)/qga-qapi-types.c $(qapi-dir)/qga-qapi-types.h :\
+$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-types.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
-$(qapi-dir)/qga-qapi-visit.c: $(qapi-dir)/qga-qapi-visit.h
-$(qapi-dir)/qga-qapi-visit.h: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-visit.py
+$(qapi-dir)/qga-qapi-visit.c $(qapi-dir)/qga-qapi-visit.h :\
+$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-visit.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
-$(qapi-dir)/qga-qmp-commands.h: $(qapi-dir)/qga-qmp-marshal.c
-$(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-commands.py
+$(qapi-dir)/qga-qmp-commands.h $(qapi-dir)/qga-qmp-marshal.c :\
+$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-commands.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
 
-qapi-types.c: qapi-types.h
-qapi-types.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py
+qapi-types.c qapi-types.h :\
+$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "." < $<, "  GEN   $@")
-qapi-visit.c: qapi-visit.h
-qapi-visit.h: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py
+qapi-visit.c qapi-visit.h :\
+$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "."  < $<, "  GEN   $@")
-qmp-commands.h: qmp-marshal.c
-qmp-marshal.c: $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py
+qmp-commands.h qmp-marshal.c :\
+$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -m -o "." < $<, "  GEN   $@")
 
 test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
@@ -207,11 +208,12 @@ test-visitor: test-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qap
 test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y)
 test-qmp-commands: test-qmp-commands.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
 
-QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.c qga-qapi-types.h qga-qapi-visit.c qga-qmp-marshal.c)
-$(QGALIB_GEN): $(GENERATED_HEADERS)
-$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
+QGALIB_OBJ=$(addprefix $(qapi-dir)/, qga-qapi-types.o qga-qapi-visit.o qga-qmp-marshal.o)
+QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
+$(QGALIB_OBJ): $(QGALIB_GEN) $(GENERATED_HEADERS)
+$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) $(GENERATED_HEADERS)
 
-qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qobject-obj-y) $(version-obj-y) $(addprefix $(qapi-dir)/, qga-qapi-visit.o qga-qapi-types.o qga-qmp-marshal.o)
+qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qobject-obj-y) $(version-obj-y) $(QGALIB_OBJ)
 
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
@@ -227,6 +229,7 @@ clean:
 	rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
 	rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
 	rm -f trace-dtrace.h trace-dtrace.h-timestamp
+	rm -f $(GENERATED_SOURCES)
 	rm -rf $(qapi-dir)
 	$(MAKE) -C tests clean
 	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
diff --git a/block-migration.c b/block-migration.c
index 0bff07538b..5f10486416 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -521,7 +521,7 @@ static int is_stage2_completed(void)
 
         if ((remaining_dirty / bwidth) <=
             migrate_max_downtime()) {
-            /* finish stage2 because we think that we can finish remaing work
+            /* finish stage2 because we think that we can finish remaining work
                below max_downtime */
 
             return 1;
diff --git a/docs/libcacard.txt b/docs/libcacard.txt
index 5dee6fa479..f7d7519f3a 100644
--- a/docs/libcacard.txt
+++ b/docs/libcacard.txt
@@ -170,7 +170,7 @@ public entry point:
                                int cert_count);
 
   The parameters for this are:
-  card       - the virtual card structure which will prepresent this card.
+  card       - the virtual card structure which will represent this card.
   flags      - option flags that may be specific to this card type.
   cert       - array of binary certificates.
   cert_len   - array of lengths of each of the certificates specified in cert.
@@ -179,7 +179,7 @@ public entry point:
   cert_count - number of entries in cert, cert_len, and key arrays.
 
   Any cert, cert_len, or key with the same index are matching sets. That is
-  cert[0] is cert_len[0] long and has the corresponsing private key of key[0].
+  cert[0] is cert_len[0] long and has the corresponding private key of key[0].
 
 The card type emulator is expected to own the VCardKeys, but it should copy
 any raw cert data it wants to save. It can create new applets and add them to
@@ -261,7 +261,7 @@ Prior to processing calling the card type emulator's VCardProcessAPDU function,
    apdu->a_Le   - The expected length of any returned data.
    apdu->a_cla  - The raw apdu class.
    apdu->a_channel - The channel (decoded from the class).
-   apdu->a_secure_messaging_type - The decoded secure messagin type
+   apdu->a_secure_messaging_type - The decoded secure messaging type
                                    (from class).
    apdu->a_type - The decode class type.
    apdu->a_gen_type - the generic class type (7816, PROPRIETARY, RFU, PTS).
@@ -273,7 +273,7 @@ Creating a Response --
 
 The expected result of any APDU call is a response. The card type emulator must
 set *response with an appropriate VCardResponse value if it returns VCARD_DONE.
-Reponses could be as simple as returning a 2 byte status word response, to as
+Responses could be as simple as returning a 2 byte status word response, to as
 complex as returning a block of data along with a 2 byte response. Which is
 returned will depend on the semantics of the APDU. The following functions will
 create card responses.
@@ -281,13 +281,13 @@ create card responses.
         VCardResponse *vcard_make_response(VCard7816Status status);
 
     This is the most basic function to get a response. This function will
-    return a response the consists soley one 2 byte status code. If that status
-    code is defined in card_7816t.h, then this function is guarrenteed to
+    return a response the consists solely one 2 byte status code. If that status
+    code is defined in card_7816t.h, then this function is guaranteed to
     return a response with that status. If a cart type specific status code
     is passed and vcard_make_response fails to allocate the appropriate memory
     for that response, then vcard_make_response will return a VCardResponse
     of VCARD7816_STATUS_EXC_ERROR_MEMORY. In any case, this function is
-    guarrenteed to return a valid VCardResponse.
+    guaranteed to return a valid VCardResponse.
 
         VCardResponse *vcard_response_new(unsigned char *buf, int len,
                                           VCard7816Status status);
@@ -327,7 +327,7 @@ and applet.
 
         int vcard_emul_get_login_count(VCard *card);
 
-    This function returns the the number of remaing login attempts for this
+    This function returns the the number of remaining login attempts for this
     card. If the card emulator does not know, or the card does not have a
     way of giving this information, this function returns -1.
 
@@ -373,7 +373,7 @@ functions:
 
   The options structure is built by another function in the virtual card
   interface where a string of virtual card emulator specific strings are
-  mapped to the options. The actual structure is defined by the virutal card
+  mapped to the options. The actual structure is defined by the virtual card
   emulator and is used to determine the configuration of soft cards, or to
   determine which physical cards to present to the guest.
 
@@ -399,7 +399,7 @@ functions:
       This function will automatically generate the appropriate new reader
       events and add the reader to the list.
 
-  To create a new card, the virtual card emulator will call a similiar
+  To create a new card, the virtual card emulator will call a similar
   function.
 
            VCard *vcard_new(VCardEmul *card_emul,
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index c0a9325db8..5831e371ea 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -14,7 +14,7 @@ To map QMP-defined interfaces to the native C QAPI implementations,
 a JSON-based schema is used to define types and function
 signatures, and a set of scripts is used to generate types/signatures,
 and marshaling/dispatch code. The QEMU Guest Agent also uses these
-scripts, paired with a seperate schema, to generate
+scripts, paired with a separate schema, to generate
 marshaling/dispatch code for the guest agent server running in the
 guest.
 
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 1fed359ab1..8af1cfdd7e 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -695,12 +695,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
     int action, code;
     int max_len;
 
-    if (buf[0] == GPCMD_MODE_SENSE_10) {
-        max_len = ube16_to_cpu(buf + 7);
-    } else {
-        max_len = buf[4];
-    }
-
+    max_len = ube16_to_cpu(buf + 7);
     action = buf[2] >> 6;
     code = buf[2] & 0x3f;
 
@@ -708,7 +703,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
     case 0: /* current values */
         switch(code) {
         case MODE_PAGE_R_W_ERROR: /* error recovery */
-            cpu_to_ube16(&buf[0], 16 + 6);
+            cpu_to_ube16(&buf[0], 16 - 2);
             buf[2] = 0x70;
             buf[3] = 0;
             buf[4] = 0;
@@ -727,7 +722,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
             ide_atapi_cmd_reply(s, 16, max_len);
             break;
         case MODE_PAGE_AUDIO_CTL:
-            cpu_to_ube16(&buf[0], 24 + 6);
+            cpu_to_ube16(&buf[0], 24 - 2);
             buf[2] = 0x70;
             buf[3] = 0;
             buf[4] = 0;
@@ -746,7 +741,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
             ide_atapi_cmd_reply(s, 24, max_len);
             break;
         case MODE_PAGE_CAPABILITIES:
-            cpu_to_ube16(&buf[0], 28 + 6);
+            cpu_to_ube16(&buf[0], 30 - 2);
             buf[2] = 0x70;
             buf[3] = 0;
             buf[4] = 0;
@@ -755,7 +750,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
             buf[7] = 0;
 
             buf[8] = MODE_PAGE_CAPABILITIES;
-            buf[9] = 28 - 10;
+            buf[9] = 30 - 10;
             buf[10] = 0x3b; /* read CDR/CDRW/DVDROM/DVDR/DVDRAM */
             buf[11] = 0x00;
 
@@ -777,7 +772,9 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
             buf[25] = 0;
             buf[26] = 0;
             buf[27] = 0;
-            ide_atapi_cmd_reply(s, 28, max_len);
+            buf[28] = 0;
+            buf[29] = 0;
+            ide_atapi_cmd_reply(s, 30, max_len);
             break;
         default:
             goto error_cmd;
@@ -1043,7 +1040,6 @@ static const struct {
     [ 0x00 ] = { cmd_test_unit_ready,               CHECK_READY },
     [ 0x03 ] = { cmd_request_sense,                 ALLOW_UA },
     [ 0x12 ] = { cmd_inquiry,                       ALLOW_UA },
-    [ 0x1a ] = { cmd_mode_sense, /* (6) */          0 },
     [ 0x1b ] = { cmd_start_stop_unit,               0 }, /* [1] */
     [ 0x1e ] = { cmd_prevent_allow_medium_removal,  0 },
     [ 0x25 ] = { cmd_read_cdvd_capacity,            CHECK_READY },
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index 740715854b..b56cba619e 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -1,7 +1,7 @@
 /*
  * QEMU/mipssim emulation
  *
- * Emulates a very simple machine model similiar to the one use by the
+ * Emulates a very simple machine model similar to the one used by the
  * proprietary MIPS emulator.
  * 
  * Copyright (c) 2007 Thiemo Seufer
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index e6ebbd594e..3a2a7bb72c 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -9,8 +9,6 @@
 static char *scsibus_get_fw_dev_path(DeviceState *dev);
 static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
 static void scsi_req_dequeue(SCSIRequest *req);
-static int scsi_build_sense(uint8_t *in_buf, int in_len,
-                            uint8_t *buf, int len, bool fixed);
 
 static struct BusInfo scsi_bus_info = {
     .name  = "SCSI",
@@ -502,7 +500,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
                                  hba_private);
         } else if (lun != d->lun ||
             buf[0] == REPORT_LUNS ||
-            buf[0] == REQUEST_SENSE) {
+            (buf[0] == REQUEST_SENSE && (d->sense_len || cmd.xfer < 4))) {
             req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
                                  hba_private);
         } else {
@@ -649,6 +647,31 @@ static void scsi_req_dequeue(SCSIRequest *req)
     }
 }
 
+static int scsi_get_performance_length(int num_desc, int type, int data_type)
+{
+    /* MMC-6, paragraph 6.7.  */
+    switch (type) {
+    case 0:
+        if ((data_type & 3) == 0) {
+            /* Each descriptor is as in Table 295 - Nominal performance.  */
+            return 16 * num_desc + 8;
+        } else {
+            /* Each descriptor is as in Table 296 - Exceptions.  */
+            return 6 * num_desc + 8;
+        }
+    case 1:
+    case 4:
+    case 5:
+        return 8 * num_desc + 8;
+    case 2:
+        return 2048 * num_desc + 8;
+    case 3:
+        return 16 * num_desc + 8;
+    default:
+        return 8;
+    }
+}
+
 static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
 {
     switch (buf[0] >> 5) {
@@ -666,11 +689,11 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
         cmd->len = 10;
         break;
     case 4:
-        cmd->xfer = ldl_be_p(&buf[10]);
+        cmd->xfer = ldl_be_p(&buf[10]) & 0xffffffffULL;
         cmd->len = 16;
         break;
     case 5:
-        cmd->xfer = ldl_be_p(&buf[6]);
+        cmd->xfer = ldl_be_p(&buf[6]) & 0xffffffffULL;
         cmd->len = 12;
         break;
     default:
@@ -681,8 +704,9 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case TEST_UNIT_READY:
     case REWIND:
     case START_STOP:
-    case SEEK_6:
+    case SET_CAPACITY:
     case WRITE_FILEMARKS:
+    case WRITE_FILEMARKS_16:
     case SPACE:
     case RESERVE:
     case RELEASE:
@@ -691,6 +715,8 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case VERIFY_10:
     case SEEK_10:
     case SYNCHRONIZE_CACHE:
+    case SYNCHRONIZE_CACHE_16:
+    case LOCATE_16:
     case LOCK_UNLOCK_CACHE:
     case LOAD_UNLOAD:
     case SET_CD_SPEED:
@@ -698,6 +724,11 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case WRITE_LONG_10:
     case MOVE_MEDIUM:
     case UPDATE_BLOCK:
+    case RESERVE_TRACK:
+    case SET_READ_AHEAD:
+    case PRE_FETCH:
+    case PRE_FETCH_16:
+    case ALLOW_OVERWRITE:
         cmd->xfer = 0;
         break;
     case MODE_SENSE:
@@ -711,14 +742,13 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case READ_BLOCK_LIMITS:
         cmd->xfer = 6;
         break;
-    case READ_POSITION:
-        cmd->xfer = 20;
-        break;
     case SEND_VOLUME_TAG:
-        cmd->xfer *= 40;
-        break;
-    case MEDIUM_SCAN:
-        cmd->xfer *= 8;
+        /* GPCMD_SET_STREAMING from multimedia commands.  */
+        if (dev->type == TYPE_ROM) {
+            cmd->xfer = buf[10] | (buf[9] << 8);
+        } else {
+            cmd->xfer = buf[9] | (buf[8] << 8);
+        }
         break;
     case WRITE_10:
     case WRITE_VERIFY_10:
@@ -737,9 +767,39 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case READ_16:
         cmd->xfer *= dev->blocksize;
         break;
+    case FORMAT_UNIT:
+        /* MMC mandates the parameter list to be 12-bytes long.  Parameters
+         * for block devices are restricted to the header right now.  */
+        if (dev->type == TYPE_ROM && (buf[1] & 16)) {
+            cmd->xfer = 12;
+        } else {
+            cmd->xfer = (buf[1] & 16) == 0 ? 0 : (buf[1] & 32 ? 8 : 4);
+        }
+        break;
     case INQUIRY:
+    case RECEIVE_DIAGNOSTIC:
+    case SEND_DIAGNOSTIC:
         cmd->xfer = buf[4] | (buf[3] << 8);
         break;
+    case READ_CD:
+    case READ_BUFFER:
+    case WRITE_BUFFER:
+    case SEND_CUE_SHEET:
+        cmd->xfer = buf[8] | (buf[7] << 8) | (buf[6] << 16);
+        break;
+    case PERSISTENT_RESERVE_OUT:
+        cmd->xfer = ldl_be_p(&buf[5]) & 0xffffffffULL;
+        break;
+    case ERASE_12:
+        if (dev->type == TYPE_ROM) {
+            /* MMC command GET PERFORMANCE.  */
+            cmd->xfer = scsi_get_performance_length(buf[9] | (buf[8] << 8),
+                                                    buf[10], buf[1] & 0x1f);
+        }
+        break;
+    case MECHANISM_STATUS:
+    case READ_DVD_STRUCTURE:
+    case SEND_DVD_STRUCTURE:
     case MAINTENANCE_OUT:
     case MAINTENANCE_IN:
         if (dev->type == TYPE_ROM) {
@@ -755,6 +815,10 @@ static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *bu
 {
     switch (buf[0]) {
     /* stream commands */
+    case ERASE_12:
+    case ERASE_16:
+        cmd->xfer = 0;
+        break;
     case READ_6:
     case READ_REVERSE:
     case RECOVER_BUFFERED_DATA:
@@ -770,6 +834,15 @@ static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *bu
         cmd->len = 6;
         cmd->xfer = 0;
         break;
+    case SPACE_16:
+        cmd->xfer = buf[13] | (buf[12] << 8);
+        break;
+    case READ_POSITION:
+        cmd->xfer = buf[8] | (buf[7] << 8);
+        break;
+    case FORMAT_UNIT:
+        cmd->xfer = buf[4] | (buf[3] << 8);
+        break;
     /* generic commands */
     default:
         return scsi_req_length(cmd, dev, buf);
@@ -809,6 +882,8 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
     case SEARCH_LOW_12:
     case MEDIUM_SCAN:
     case SEND_VOLUME_TAG:
+    case SEND_CUE_SHEET:
+    case SEND_DVD_STRUCTURE:
     case PERSISTENT_RESERVE_OUT:
     case MAINTENANCE_OUT:
         cmd->mode = SCSI_XFER_TO_DEV;
@@ -835,7 +910,7 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
     case 1:
     case 2:
     case 5:
-        lba = ldl_be_p(&buf[2]);
+        lba = ldl_be_p(&buf[2]) & 0xffffffffULL;
         break;
     case 4:
         lba = ldq_be_p(&buf[2]);
@@ -1036,7 +1111,7 @@ static const char *scsi_command_name(uint8_t cmd)
         [ REASSIGN_BLOCKS          ] = "REASSIGN_BLOCKS",
         [ READ_6                   ] = "READ_6",
         [ WRITE_6                  ] = "WRITE_6",
-        [ SEEK_6                   ] = "SEEK_6",
+        [ SET_CAPACITY             ] = "SET_CAPACITY",
         [ READ_REVERSE             ] = "READ_REVERSE",
         [ WRITE_FILEMARKS          ] = "WRITE_FILEMARKS",
         [ SPACE                    ] = "SPACE",
@@ -1064,7 +1139,7 @@ static const char *scsi_command_name(uint8_t cmd)
         [ SEARCH_EQUAL             ] = "SEARCH_EQUAL",
         [ SEARCH_LOW               ] = "SEARCH_LOW",
         [ SET_LIMITS               ] = "SET_LIMITS",
-        [ PRE_FETCH                ] = "PRE_FETCH",
+        [ PRE_FETCH                ] = "PRE_FETCH/READ_POSITION",
         /* READ_POSITION and PRE_FETCH use the same operation code */
         [ SYNCHRONIZE_CACHE        ] = "SYNCHRONIZE_CACHE",
         [ LOCK_UNLOCK_CACHE        ] = "LOCK_UNLOCK_CACHE",
@@ -1101,9 +1176,11 @@ static const char *scsi_command_name(uint8_t cmd)
         [ WRITE_16                 ] = "WRITE_16",
         [ WRITE_VERIFY_16          ] = "WRITE_VERIFY_16",
         [ VERIFY_16                ] = "VERIFY_16",
-        [ SYNCHRONIZE_CACHE_16     ] = "SYNCHRONIZE_CACHE_16",
+        [ PRE_FETCH_16             ] = "PRE_FETCH_16",
+        [ SYNCHRONIZE_CACHE_16     ] = "SPACE_16/SYNCHRONIZE_CACHE_16",
+        /* SPACE_16 and SYNCHRONIZE_CACHE_16 use the same operation code */
         [ LOCATE_16                ] = "LOCATE_16",
-        [ WRITE_SAME_16            ] = "WRITE_SAME_16",
+        [ WRITE_SAME_16            ] = "ERASE_16/WRITE_SAME_16",
         /* ERASE_16 and WRITE_SAME_16 use the same operation code */
         [ SERVICE_ACTION_IN_16     ] = "SERVICE_ACTION_IN_16",
         [ WRITE_LONG_16            ] = "WRITE_LONG_16",
@@ -1113,6 +1190,8 @@ static const char *scsi_command_name(uint8_t cmd)
         [ LOAD_UNLOAD              ] = "LOAD_UNLOAD",
         [ READ_12                  ] = "READ_12",
         [ WRITE_12                 ] = "WRITE_12",
+        [ ERASE_12                 ] = "ERASE_12/GET_PERFORMANCE",
+        /* ERASE_12 and GET_PERFORMANCE use the same operation code */
         [ SERVICE_ACTION_IN_12     ] = "SERVICE_ACTION_IN_12",
         [ WRITE_VERIFY_12          ] = "WRITE_VERIFY_12",
         [ VERIFY_12                ] = "VERIFY_12",
@@ -1120,9 +1199,18 @@ static const char *scsi_command_name(uint8_t cmd)
         [ SEARCH_EQUAL_12          ] = "SEARCH_EQUAL_12",
         [ SEARCH_LOW_12            ] = "SEARCH_LOW_12",
         [ READ_ELEMENT_STATUS      ] = "READ_ELEMENT_STATUS",
-        [ SEND_VOLUME_TAG          ] = "SEND_VOLUME_TAG",
+        [ SEND_VOLUME_TAG          ] = "SEND_VOLUME_TAG/SET_STREAMING",
+        /* SEND_VOLUME_TAG and SET_STREAMING use the same operation code */
+        [ READ_CD                  ] = "READ_CD",
         [ READ_DEFECT_DATA_12      ] = "READ_DEFECT_DATA_12",
+        [ READ_DVD_STRUCTURE       ] = "READ_DVD_STRUCTURE",
+        [ RESERVE_TRACK            ] = "RESERVE_TRACK",
+        [ SEND_CUE_SHEET           ] = "SEND_CUE_SHEET",
+        [ SEND_DVD_STRUCTURE       ] = "SEND_DVD_STRUCTURE",
         [ SET_CD_SPEED             ] = "SET_CD_SPEED",
+        [ SET_READ_AHEAD           ] = "SET_READ_AHEAD",
+        [ ALLOW_OVERWRITE          ] = "ALLOW_OVERWRITE",
+        [ MECHANISM_STATUS         ] = "MECHANISM_STATUS",
     };
 
     if (cmd >= ARRAY_SIZE(names) || names[cmd] == NULL)
@@ -1279,7 +1367,7 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
     SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
     char path[100];
 
-    snprintf(path, sizeof(path), "%s@%d:%d:%d", qdev_fw_name(dev),
+    snprintf(path, sizeof(path), "%s@%d,%d,%d", qdev_fw_name(dev),
              d->channel, d->id, d->lun);
 
     return strdup(path);
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index d0a467aab7..354ed7b55b 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -32,7 +32,7 @@
 #define REASSIGN_BLOCKS       0x07
 #define READ_6                0x08
 #define WRITE_6               0x0a
-#define SEEK_6                0x0b
+#define SET_CAPACITY          0x0b
 #define READ_REVERSE          0x0f
 #define WRITE_FILEMARKS       0x10
 #define SPACE                 0x11
@@ -81,14 +81,17 @@
 #define GET_EVENT_STATUS_NOTIFICATION 0x4a
 #define LOG_SELECT            0x4c
 #define LOG_SENSE             0x4d
+#define RESERVE_TRACK         0x53
 #define MODE_SELECT_10        0x55
 #define RESERVE_10            0x56
 #define RELEASE_10            0x57
 #define MODE_SENSE_10         0x5a
+#define SEND_CUE_SHEET        0x5d
 #define PERSISTENT_RESERVE_IN 0x5e
 #define PERSISTENT_RESERVE_OUT 0x5f
 #define VARLENGTH_CDB         0x7f
 #define WRITE_FILEMARKS_16    0x80
+#define ALLOW_OVERWRITE       0x82
 #define EXTENDED_COPY         0x83
 #define ATA_PASSTHROUGH       0x85
 #define ACCESS_CONTROL_IN     0x86
@@ -98,6 +101,8 @@
 #define WRITE_16              0x8a
 #define WRITE_VERIFY_16       0x8e
 #define VERIFY_16             0x8f
+#define PRE_FETCH_16          0x90
+#define SPACE_16              0x91
 #define SYNCHRONIZE_CACHE_16  0x91
 #define LOCATE_16             0x92
 #define WRITE_SAME_16         0x93
@@ -110,9 +115,11 @@
 #define MAINTENANCE_OUT       0xa4
 #define MOVE_MEDIUM           0xa5
 #define LOAD_UNLOAD           0xa6
+#define SET_READ_AHEAD        0xa7
 #define READ_12               0xa8
 #define WRITE_12              0xaa
 #define SERVICE_ACTION_IN_12  0xab
+#define ERASE_12              0xac
 #define READ_DVD_STRUCTURE    0xad
 #define WRITE_VERIFY_12       0xae
 #define VERIFY_12             0xaf
@@ -125,6 +132,7 @@
 #define SET_CD_SPEED          0xbb
 #define MECHANISM_STATUS      0xbd
 #define READ_CD               0xbe
+#define SEND_DVD_STRUCTURE    0xbf
 
 /*
  * SERVICE ACTION IN subcodes
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 62f538f4f8..673948c51f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -797,7 +797,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
             break;
         }
         /* if a geometry hint is available, use it */
-        bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
+        bdrv_guess_geometry(bdrv, &cylinders, &heads, &secs);
         p[2] = (cylinders >> 16) & 0xff;
         p[3] = (cylinders >> 8) & 0xff;
         p[4] = cylinders & 0xff;
@@ -831,7 +831,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
         p[2] = 5000 >> 8;
         p[3] = 5000 & 0xff;
         /* if a geometry hint is available, use it */
-        bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
+        bdrv_guess_geometry(bdrv, &cylinders, &heads, &secs);
         p[4] = heads & 0xff;
         p[5] = secs & 0xff;
         p[6] = s->qdev.blocksize >> 8;
@@ -956,8 +956,9 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
         p += 8;
     }
 
+    /* MMC prescribes that CD/DVD drives have no block descriptors.  */
     bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
-    if (!dbd && nb_sectors) {
+    if (!dbd && s->qdev.type == TYPE_DISK && nb_sectors) {
         if (r->req.cmd.buf[0] == MODE_SENSE) {
             outbuf[3] = 8; /* Block descriptor length  */
         } else { /* MODE_SENSE_10 */
@@ -1178,6 +1179,11 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
         outbuf[7] = 0;
         buflen = 8;
         break;
+    case REQUEST_SENSE:
+        /* Just return "NO SENSE".  */
+        buflen = scsi_build_sense(NULL, 0, outbuf, r->buflen,
+                                  (req->cmd.buf[1] & 1) == 0);
+        break;
     case MECHANISM_STATUS:
         buflen = scsi_emulate_mechanism_status(s, outbuf);
         if (buflen < 0) {
@@ -1312,6 +1318,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     case GET_EVENT_STATUS_NOTIFICATION:
     case MECHANISM_STATUS:
     case SERVICE_ACTION_IN_16:
+    case REQUEST_SENSE:
     case VERIFY_10:
         rc = scsi_disk_emulate_command(r);
         if (rc < 0) {
@@ -1374,10 +1381,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
             goto fail;
         }
         break;
-    case SEEK_6:
     case SEEK_10:
-        DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
-                r->req.cmd.lba);
+        DPRINTF("Seek(10) (sector %" PRId64 ")\n", r->req.cmd.lba);
         if (r->req.cmd.lba > s->qdev.max_lba) {
             goto illegal_lba;
         }
@@ -1408,8 +1413,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         }
 
         break;
-    case REQUEST_SENSE:
-        abort();
     default:
         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
         scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
@@ -1553,7 +1556,7 @@ static int scsi_initfn(SCSIDevice *dev)
     bdrv_set_buffer_alignment(s->qdev.conf.bs, s->qdev.blocksize);
 
     bdrv_iostatus_enable(s->qdev.conf.bs);
-    add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
+    add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL);
     return 0;
 }
 
@@ -1700,8 +1703,20 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
     case WRITE_VERIFY_10:
     case WRITE_VERIFY_12:
     case WRITE_VERIFY_16:
-        return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun,
-                              hba_private);
+        /* MMC writing cannot be done via pread/pwrite, because it sometimes
+         * involves writing beyond the maximum LBA or to negative LBA (lead-in).
+         * And once you do these writes, reading from the block device is
+         * unreliable, too.  It is even possible that reads deliver random data
+         * from the host page cache (this is probably a Linux bug).
+         *
+         * We might use scsi_disk_reqops as long as no writing commands are
+         * seen, but performance usually isn't paramount on optical media.  So,
+         * just make scsi-block operate the same as scsi-generic for them.
+         */
+        if (s->qdev.type != TYPE_ROM) {
+            return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun,
+                                  hba_private);
+        }
     }
 
     return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
diff --git a/hw/scsi.h b/hw/scsi.h
index ff8fdd0962..61c64d5c72 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -179,6 +179,8 @@ extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
 #define SENSE_CODE(x) sense_code_ ## x
 
 int scsi_sense_valid(SCSISense sense);
+int scsi_build_sense(uint8_t *in_buf, int in_len,
+                     uint8_t *buf, int len, bool fixed);
 
 SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
                             uint32_t tag, uint32_t lun, void *hba_private);
diff --git a/monitor.c b/monitor.c
index 5ea35de849..1be222ee18 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4207,9 +4207,9 @@ static void file_completion(const char *input)
             /* stat the file to find out if it's a directory.
              * In that case add a slash to speed up typing long paths
              */
-            stat(file, &sb);
-            if(S_ISDIR(sb.st_mode))
+            if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) {
                 pstrcat(file, sizeof(file), "/");
+            }
             readline_add_completion(cur_mon->rs, file);
         }
     }
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index d67724ea4b..f76d0159cd 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -190,7 +190,7 @@ static void qmp_output_type_enum(Visitor *v, int *obj, const char *strings[],
 
     assert(strings);
     while (strings[i++] != NULL);
-    if (value >= i - 1) {
+    if (value < 0 || value >= i - 1) {
         error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");
         return;
     }
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 149e9bd28b..9c3cb62ee3 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -421,6 +421,7 @@ snapshots.
 * disk_images_fat_images::    Virtual FAT disk images
 * disk_images_nbd::           NBD access
 * disk_images_sheepdog::      Sheepdog disk images
+* disk_images_iscsi::         iSCSI LUNs
 @end menu
 
 @node disk_images_quickstart
@@ -695,6 +696,61 @@ qemu-img create sheepdog:@var{hostname}:@var{port}:@var{image} @var{size}
 qemu sheepdog:@var{hostname}:@var{port}:@var{image}
 @end example
 
+@node disk_images_iscsi
+@subsection iSCSI LUNs
+
+iSCSI is a popular protocol used to access SCSI devices across a computer
+network.
+
+There are two different ways iSCSI devices can be used by QEMU.
+
+The first method is to mount the iSCSI LUN on the host, and make it appear as
+any other ordinary SCSI device on the host and then to access this device as a
+/dev/sd device from QEMU. How to do this differs between host OSes.
+
+The second method involves using the iSCSI initiator that is built into
+QEMU. This provides a mechanism that works the same way regardless of which
+host OS you are running QEMU on. This section will describe this second method
+of using iSCSI together with QEMU.
+
+In QEMU, iSCSI devices are described using special iSCSI URLs
+
+@example
+URL syntax:
+iscsi://[<username>[%<password>]@@]<host>[:<port>]/<target-iqn-name>/<lun>
+@end example
+
+Username and password are optional and only used if your target is set up
+using CHAP authentication for access control.
+Alternatively the username and password can also be set via environment
+variables to have these not show up in the process list
+
+@example
+export LIBISCSI_CHAP_USERNAME=<username>
+export LIBISCSI_CHAP_PASSWORD=<password>
+iscsi://<host>/<target-iqn-name>/<lun>
+@end example
+
+Howto set up a simple iSCSI target on loopback and accessing it via QEMU:
+@example
+This example shows how to set up an iSCSI target with one CDROM and one DISK
+using the Linux STGT software target. This target is available on Red Hat based
+systems as the package 'scsi-target-utils'.
+
+tgtd --iscsi portal=127.0.0.1:3260
+tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
+tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \
+    -b /IMAGES/disk.img --device-type=disk
+tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
+    -b /IMAGES/cd.iso --device-type=cd
+tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
+
+qemu-system-i386 -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
+    -cdrom iscsi://127.0.0.1/iqn.qemu.test/2
+@end example
+
+
+
 @node pcsys_network
 @section Network emulation
 
@@ -1749,7 +1805,7 @@ PC Keyboard
 IDE controller
 @end itemize
 
-The mipssim pseudo board emulation provides an environment similiar
+The mipssim pseudo board emulation provides an environment similar
 to what the proprietary MIPS emulator uses for running Linux.
 It supports:
 
@@ -2141,7 +2197,7 @@ Xtensa emulator pseudo board "sim"
 Avnet LX60/LX110/LX200 board
 @end itemize
 
-The sim pseudo board emulation provides an environment similiar
+The sim pseudo board emulation provides an environment similar
 to one provided by the proprietary Tensilica ISS.
 It supports:
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ddd115c53c..5bfc21fc53 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1845,7 +1845,7 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
                 code);
         if (host_supports_vmx() && code == VMX_INVALID_GUEST_STATE) {
             fprintf(stderr,
-                    "\nIf you're runnning a guest on an Intel machine without "
+                    "\nIf you're running a guest on an Intel machine without "
                         "unrestricted mode\n"
                     "support, the failure can be most likely due to the guest "
                         "entering an invalid\n"