diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-05-25 21:59:01 +1000 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-05-28 14:04:14 +0200 |
commit | dbfff6d776670cca751b904063c9173a23ae8c75 (patch) | |
tree | 04edbf1f81909ce8bb52d861cc90354d18ec32cf /block | |
parent | c7b4a95202032bf1a9e13dd9695389c0ed246eec (diff) |
ISCSI: get device type at connection time
This is needed to avoid READ CAPACITY(16) for MMC devices.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/iscsi.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/block/iscsi.c b/block/iscsi.c index 9cd258ff6f..91cca83c5b 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -29,6 +29,7 @@ #include "qemu-error.h" #include "block_int.h" #include "trace.h" +#include "hw/scsi-defs.h" #include <iscsi/iscsi.h> #include <iscsi/scsi-lowlevel.h> @@ -37,6 +38,7 @@ typedef struct IscsiLun { struct iscsi_context *iscsi; int lun; + enum scsi_inquiry_peripheral_device_type type; int block_size; uint64_t num_blocks; int events; @@ -508,18 +510,33 @@ iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status, } static void -iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data, +iscsi_inquiry_cb(struct iscsi_context *iscsi, int status, void *command_data, void *opaque) { struct IscsiTask *itask = opaque; - struct scsi_task *task; + struct scsi_task *task = command_data; + struct scsi_inquiry_standard *inq; if (status != 0) { itask->status = 1; itask->complete = 1; + scsi_free_scsi_task(task); return; } + inq = scsi_datain_unmarshall(task); + if (inq == NULL) { + error_report("iSCSI: Failed to unmarshall inquiry data."); + itask->status = 1; + itask->complete = 1; + scsi_free_scsi_task(task); + return; + } + + itask->iscsilun->type = inq->periperal_device_type; + + scsi_free_scsi_task(task); + task = iscsi_readcapacity16_task(iscsi, itask->iscsilun->lun, iscsi_readcapacity16_cb, opaque); if (task == NULL) { @@ -530,6 +547,30 @@ iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data, } } +static void +iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data, + void *opaque) +{ + struct IscsiTask *itask = opaque; + struct scsi_task *task; + + if (status != 0) { + itask->status = 1; + itask->complete = 1; + return; + } + + task = iscsi_inquiry_task(iscsi, itask->iscsilun->lun, + 0, 0, 36, + iscsi_inquiry_cb, opaque); + if (task == NULL) { + error_report("iSCSI: failed to send inquiry command."); + itask->status = 1; + itask->complete = 1; + return; + } +} + static int parse_chap(struct iscsi_context *iscsi, const char *target) { QemuOptsList *list; |