Revision 24d3bd67

b/block/iscsi.c
1067 1067
};
1068 1068

  
1069 1069
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
1070
                                          int evpd, int pc, Error **errp)
1070
                                          int evpd, int pc, void **inq, Error **errp)
1071 1071
{
1072 1072
    int full_size;
1073 1073
    struct scsi_task *task = NULL;
......
1086 1086
        }
1087 1087
    }
1088 1088

  
1089
    *inq = scsi_datain_unmarshall(task);
1090
    if (*inq == NULL) {
1091
        error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
1092
        goto fail;
1093
    }
1094

  
1089 1095
    return task;
1090 1096

  
1091 1097
fail:
1092 1098
    error_setg(errp, "iSCSI: Inquiry command failed : %s",
1093 1099
               iscsi_get_error(iscsi));
1094
    if (task) {
1100
    if (task != NULL) {
1095 1101
        scsi_free_scsi_task(task);
1096
        return NULL;
1097 1102
    }
1098 1103
    return NULL;
1099 1104
}
......
1114 1119
    struct iscsi_url *iscsi_url = NULL;
1115 1120
    struct scsi_task *task = NULL;
1116 1121
    struct scsi_inquiry_standard *inq = NULL;
1122
    struct scsi_inquiry_supported_pages *inq_vpd;
1117 1123
    char *initiator_name = NULL;
1118 1124
    QemuOpts *opts;
1119 1125
    Error *local_err = NULL;
1120 1126
    const char *filename;
1121
    int ret;
1127
    int i, ret;
1122 1128

  
1123 1129
    if ((BDRV_SECTOR_SIZE % 512) != 0) {
1124 1130
        error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
......
1204 1210

  
1205 1211
    iscsilun->iscsi = iscsi;
1206 1212
    iscsilun->lun   = iscsi_url->lun;
1213
    iscsilun->has_write_same = true;
1207 1214

  
1208
    task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
1209

  
1210
    if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1211
        error_setg(errp, "iSCSI: failed to send inquiry command.");
1212
        ret = -EINVAL;
1213
        goto out;
1214
    }
1215

  
1216
    inq = scsi_datain_unmarshall(task);
1217
    if (inq == NULL) {
1218
        error_setg(errp, "iSCSI: Failed to unmarshall inquiry data.");
1215
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
1216
                            (void **) &inq, errp);
1217
    if (task == NULL) {
1219 1218
        ret = -EINVAL;
1220 1219
        goto out;
1221 1220
    }
1222

  
1223 1221
    iscsilun->type = inq->periperal_device_type;
1224
    iscsilun->has_write_same = true;
1222
    scsi_free_scsi_task(task);
1223
    task = NULL;
1225 1224

  
1226 1225
    iscsi_readcapacity_sync(iscsilun, &local_err);
1227 1226
    if (local_err != NULL) {
......
1240 1239
        bs->sg = 1;
1241 1240
    }
1242 1241

  
1243
    if (iscsilun->lbpme) {
1244
        struct scsi_inquiry_logical_block_provisioning *inq_lbp;
1245
        task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1246
                                SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
1247
                                errp);
1248
        if (task == NULL) {
1249
            ret = -EINVAL;
1250
            goto out;
1251
        }
1252
        inq_lbp = scsi_datain_unmarshall(task);
1253
        if (inq_lbp == NULL) {
1254
            error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
1255
            ret = -EINVAL;
1256
            goto out;
1257
        }
1258
        memcpy(&iscsilun->lbp, inq_lbp,
1259
               sizeof(struct scsi_inquiry_logical_block_provisioning));
1260
        scsi_free_scsi_task(task);
1261
        task = NULL;
1242
    task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1243
                            SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
1244
                            (void **) &inq_vpd, errp);
1245
    if (task == NULL) {
1246
        ret = -EINVAL;
1247
        goto out;
1262 1248
    }
1263

  
1264
    if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
1249
    for (i = 0; i < inq_vpd->num_pages; i++) {
1250
        struct scsi_task *inq_task;
1251
        struct scsi_inquiry_logical_block_provisioning *inq_lbp;
1265 1252
        struct scsi_inquiry_block_limits *inq_bl;
1266
        task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1267
                                SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, errp);
1268
        if (task == NULL) {
1269
            ret = -EINVAL;
1270
            goto out;
1271
        }
1272
        inq_bl = scsi_datain_unmarshall(task);
1273
        if (inq_bl == NULL) {
1274
            error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
1275
            ret = -EINVAL;
1276
            goto out;
1253
        switch (inq_vpd->pages[i]) {
1254
        case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
1255
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1256
                                        SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
1257
                                        (void **) &inq_lbp, errp);
1258
            if (inq_task == NULL) {
1259
                ret = -EINVAL;
1260
                goto out;
1261
            }
1262
            memcpy(&iscsilun->lbp, inq_lbp,
1263
                   sizeof(struct scsi_inquiry_logical_block_provisioning));
1264
            scsi_free_scsi_task(inq_task);
1265
            break;
1266
        case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
1267
            inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1268
                                    SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
1269
                                    (void **) &inq_bl, errp);
1270
            if (inq_task == NULL) {
1271
                ret = -EINVAL;
1272
                goto out;
1273
            }
1274
            memcpy(&iscsilun->bl, inq_bl,
1275
                   sizeof(struct scsi_inquiry_block_limits));
1276
            scsi_free_scsi_task(inq_task);
1277
            break;
1278
        default:
1279
            break;
1277 1280
        }
1278
        memcpy(&iscsilun->bl, inq_bl,
1279
               sizeof(struct scsi_inquiry_block_limits));
1280
        scsi_free_scsi_task(task);
1281
        task = NULL;
1282 1281
    }
1282
    scsi_free_scsi_task(task);
1283
    task = NULL;
1283 1284

  
1284 1285
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
1285 1286
    /* Set up a timer for sending out iSCSI NOPs */

Also available in: Unified diff