18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU ATAPI CD-ROM Emulator 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2006 Fabrice Bellard 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions: 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software. 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE. 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ??? Most of the ATAPI emulation is still in ide.c. It should be moved 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project here. */ 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h" 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "scsi-disk.h" 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void lba_to_msf(uint8_t *buf, int lba) 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lba += 150; 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = (lba / 75) / 60; 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = (lba / 75) % 60; 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[2] = lba % 75; 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* same toc as bochs. Return -1 if error or the toc length */ 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: check this */ 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track) 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *q; 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (start_track > 1 && start_track != 0xaa) 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q = buf + 2; 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* first session */ 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* last session */ 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (start_track <= 1) { 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* reserved */ 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x14; /* ADR, control */ 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* track number */ 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* reserved */ 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (msf) { 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* reserved */ 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lba_to_msf(q, 0); 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q += 3; 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* sector 0 */ 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_to_be32wu((uint32_t *)q, 0); 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q += 4; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* lead out track */ 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* reserved */ 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x16; /* ADR, control */ 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0xaa; /* track number */ 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* reserved */ 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (msf) { 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* reserved */ 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lba_to_msf(q, nb_sectors); 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q += 3; 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_to_be32wu((uint32_t *)q, nb_sectors); 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q += 4; 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = q - buf; 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_to_be16wu((uint16_t *)buf, len - 2); 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return len; 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* mostly same info as PearPc */ 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num) 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *q; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q = buf + 2; 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* first session */ 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* last session */ 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* session number */ 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x14; /* data track */ 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* track number */ 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0xa0; /* lead-in */ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* min */ 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* sec */ 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* frame */ 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* first track */ 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x00; /* disk type */ 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x00; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* session number */ 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x14; /* data track */ 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* track number */ 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0xa1; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* min */ 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* sec */ 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* frame */ 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* last track */ 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x00; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x00; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* session number */ 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x14; /* data track */ 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* track number */ 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0xa2; /* lead-out */ 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* min */ 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* sec */ 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* frame */ 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (msf) { 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* reserved */ 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lba_to_msf(q, nb_sectors); 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q += 3; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_to_be32wu((uint32_t *)q, nb_sectors); 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q += 4; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* session number */ 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0x14; /* ADR, control */ 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* track number */ 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 1; /* point */ 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* min */ 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* sec */ 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; /* frame */ 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (msf) { 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lba_to_msf(q, 0); 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project q += 3; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *q++ = 0; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = q - buf; 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_to_be16wu((uint16_t *)buf, len - 2); 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return len; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 156