Revision 66c6ef76 hw/ide.c

b/hw/ide.c
943 943
    memset(buf, 0, 288);
944 944
}
945 945

  
946
static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
946
static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
947 947
                           int sector_size)
948 948
{
949
    int ret;
950

  
949 951
    switch(sector_size) {
950 952
    case 2048:
951
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
953
        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
952 954
        break;
953 955
    case 2352:
954
        bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
956
        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
957
        if (ret < 0)
958
            return ret;
955 959
        cd_data_to_raw(buf, lba);
956 960
        break;
957 961
    default:
962
        ret = -EIO;
958 963
        break;
959 964
    }
965
    return ret;
966
}
967

  
968
static void ide_atapi_io_error(IDEState *s, int ret)
969
{
970
    /* XXX: handle more errors */
971
    if (ret == -ENOMEDIUM) {
972
        ide_atapi_cmd_error(s, SENSE_NOT_READY, 
973
                            ASC_MEDIUM_NOT_PRESENT);
974
    } else {
975
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
976
                            ASC_LOGICAL_BLOCK_OOR);
977
    }
960 978
}
961 979

  
962 980
/* The whole ATAPI transfer logic is handled in this function */
963 981
static void ide_atapi_cmd_reply_end(IDEState *s)
964 982
{
965
    int byte_count_limit, size;
983
    int byte_count_limit, size, ret;
966 984
#ifdef DEBUG_IDE_ATAPI
967 985
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", 
968 986
           s->packet_transfer_size,
......
981 999
    } else {
982 1000
        /* see if a new sector must be read */
983 1001
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
984
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
1002
            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
1003
            if (ret < 0) {
1004
                ide_transfer_stop(s);
1005
                ide_atapi_io_error(s, ret);
1006
                return;
1007
            }
985 1008
            s->lba++;
986 1009
            s->io_buffer_index = 0;
987 1010
        }
......
1070 1093
    IDEState *s = bm->ide_if;
1071 1094
    int data_offset, n;
1072 1095

  
1096
    if (ret < 0) {
1097
        ide_atapi_io_error(s, ret);
1098
        goto eot;
1099
    }
1100

  
1073 1101
    if (s->io_buffer_size > 0) {
1074 1102
        if (s->cd_sector_size == 2352) {
1075 1103
            n = 1;
......
1114 1142
    bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2, 
1115 1143
                              s->io_buffer + data_offset, n * 4, 
1116 1144
                              ide_atapi_cmd_read_dma_cb, bm);
1145
    if (!bm->aiocb) {
1146
        /* Note: media not present is the most likely case */
1147
        ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1148
                            ASC_MEDIUM_NOT_PRESENT);
1149
        goto eot;
1150
    }
1117 1151
}
1118 1152

  
1119 1153
/* start a CD-CDROM read command with DMA */
......
1270 1304
        {
1271 1305
            int nb_sectors, lba;
1272 1306

  
1273
            if (!bdrv_is_inserted(s->bs)) {
1274
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1275
                                    ASC_MEDIUM_NOT_PRESENT);
1276
                break;
1277
            }
1278 1307
            if (packet[0] == GPCMD_READ_10)
1279 1308
                nb_sectors = ube16_to_cpu(packet + 7);
1280 1309
            else
......
1284 1313
                ide_atapi_cmd_ok(s);
1285 1314
                break;
1286 1315
            }
1287
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1288
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1289
                                    ASC_LOGICAL_BLOCK_OOR);
1290
                break;
1291
            }
1292 1316
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1293 1317
        }
1294 1318
        break;
......
1296 1320
        {
1297 1321
            int nb_sectors, lba, transfer_request;
1298 1322

  
1299
            if (!bdrv_is_inserted(s->bs)) {
1300
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1301
                                    ASC_MEDIUM_NOT_PRESENT);
1302
                break;
1303
            }
1304 1323
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1305 1324
            lba = ube32_to_cpu(packet + 2);
1306 1325
            if (nb_sectors == 0) {
1307 1326
                ide_atapi_cmd_ok(s);
1308 1327
                break;
1309 1328
            }
1310
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1311
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1312
                                    ASC_LOGICAL_BLOCK_OOR);
1313
                break;
1314
            }
1315 1329
            transfer_request = packet[9];
1316 1330
            switch(transfer_request & 0xf8) {
1317 1331
            case 0x00:
......
1336 1350
    case GPCMD_SEEK:
1337 1351
        {
1338 1352
            int lba;
1339
            if (!bdrv_is_inserted(s->bs)) {
1353
            int64_t total_sectors;
1354

  
1355
            bdrv_get_geometry(s->bs, &total_sectors);
1356
            total_sectors >>= 2;
1357
            if (total_sectors <= 0) {
1340 1358
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1341 1359
                                    ASC_MEDIUM_NOT_PRESENT);
1342 1360
                break;
1343 1361
            }
1344 1362
            lba = ube32_to_cpu(packet + 2);
1345
            if (((int64_t)lba << 2) > s->nb_sectors) {
1363
            if (lba >= total_sectors) {
1346 1364
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1347 1365
                                    ASC_LOGICAL_BLOCK_OOR);
1348 1366
                break;
......
1358 1376
            
1359 1377
            if (eject && !start) {
1360 1378
                /* eject the disk */
1361
                bdrv_close(s->bs);
1379
                bdrv_eject(s->bs, 1);
1380
            } else if (eject && start) {
1381
                /* close the tray */
1382
                bdrv_eject(s->bs, 0);
1362 1383
            }
1363 1384
            ide_atapi_cmd_ok(s);
1364 1385
        }
......
1379 1400
    case GPCMD_READ_TOC_PMA_ATIP:
1380 1401
        {
1381 1402
            int format, msf, start_track, len;
1403
            int64_t total_sectors;
1382 1404

  
1383
            if (!bdrv_is_inserted(s->bs)) {
1405
            bdrv_get_geometry(s->bs, &total_sectors);
1406
            total_sectors >>= 2;
1407
            if (total_sectors <= 0) {
1384 1408
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1385 1409
                                    ASC_MEDIUM_NOT_PRESENT);
1386 1410
                break;
......
1391 1415
            start_track = packet[6];
1392 1416
            switch(format) {
1393 1417
            case 0:
1394
                len = cdrom_read_toc(s->nb_sectors >> 2, buf, msf, start_track);
1418
                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
1395 1419
                if (len < 0)
1396 1420
                    goto error_cmd;
1397 1421
                ide_atapi_cmd_reply(s, len, max_len);
......
1405 1429
                ide_atapi_cmd_reply(s, 12, max_len);
1406 1430
                break;
1407 1431
            case 2:
1408
                len = cdrom_read_toc_raw(s->nb_sectors >> 2, buf, msf, start_track);
1432
                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
1409 1433
                if (len < 0)
1410 1434
                    goto error_cmd;
1411 1435
                ide_atapi_cmd_reply(s, len, max_len);
......
1419 1443
        }
1420 1444
        break;
1421 1445
    case GPCMD_READ_CDVD_CAPACITY:
1422
        if (!bdrv_is_inserted(s->bs)) {
1423
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1424
                                ASC_MEDIUM_NOT_PRESENT);
1425
            break;
1446
        {
1447
            int64_t total_sectors;
1448

  
1449
            bdrv_get_geometry(s->bs, &total_sectors);
1450
            total_sectors >>= 2;
1451
            if (total_sectors <= 0) {
1452
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1453
                                    ASC_MEDIUM_NOT_PRESENT);
1454
                break;
1455
            }
1456
            /* NOTE: it is really the number of sectors minus 1 */
1457
            cpu_to_ube32(buf, total_sectors - 1);
1458
            cpu_to_ube32(buf + 4, 2048);
1459
            ide_atapi_cmd_reply(s, 8, 8);
1426 1460
        }
1427
        /* NOTE: it is really the number of sectors minus 1 */
1428
        cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
1429
        cpu_to_ube32(buf + 4, 2048);
1430
        ide_atapi_cmd_reply(s, 8, 8);
1431 1461
        break;
1432 1462
    case GPCMD_INQUIRY:
1433 1463
        max_len = packet[4];
......
1451 1481
    }
1452 1482
}
1453 1483

  
1454
/* called when the inserted state of the media has changed */
1455
static void cdrom_change_cb(void *opaque)
1456
{
1457
    IDEState *s = opaque;
1458
    int64_t nb_sectors;
1459

  
1460
    /* XXX: send interrupt too */
1461
    bdrv_get_geometry(s->bs, &nb_sectors);
1462
    s->nb_sectors = nb_sectors;
1463
}
1464

  
1465 1484
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1466 1485
{
1467 1486
    s->lba48 = lba48;
......
2092 2111
            }
2093 2112
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
2094 2113
                s->is_cdrom = 1;
2095
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
2096 2114
            }
2097 2115
        }
2098 2116
        s->drive_serial = drive_serial++;

Also available in: Unified diff