(linenum→info "unix/slp.c:2238")

qemu/0.9.1/hw/cdrom.c

    1: /*
    2:  * QEMU ATAPI CD-ROM Emulator
    3:  *
    4:  * Copyright (c) 2006 Fabrice Bellard
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    7:  * of this software and associated documentation files (the "Software"), to deal
    8:  * in the Software without restriction, including without limitation the rights
    9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   10:  * copies of the Software, and to permit persons to whom the Software is
   11:  * furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included in
   14:  * all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22:  * THE SOFTWARE.
   23:  */
   24: 
   25: /* ??? Most of the ATAPI emulation is still in ide.c.  It should be moved
   26:    here.  */
   27: 
   28: #include "qemu-common.h"
   29: #include "scsi-disk.h"
   30: 
   31: static void lba_to_msf(uint8_t *buf, int lba)
   32: {
   33:     lba += 150;
   34:     buf[0] = (lba / 75) / 60;
   35:     buf[1] = (lba / 75) % 60;
   36:     buf[2] = lba % 75;
   37: }
   38: 
   39: /* same toc as bochs. Return -1 if error or the toc length */
   40: /* XXX: check this */
   41: int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
   42: {
   43:     uint8_t *q;
   44:     int len;
   45: 
   46:     if (start_track > 1 && start_track != 0xaa)
   47:         return -1;
   48:     q = buf + 2;
   49:     *q++ = 1; /* first session */
   50:     *q++ = 1; /* last session */
   51:     if (start_track <= 1) {
   52:         *q++ = 0; /* reserved */
   53:         *q++ = 0x14; /* ADR, control */
   54:         *q++ = 1;    /* track number */
   55:         *q++ = 0; /* reserved */
   56:         if (msf) {
   57:             *q++ = 0; /* reserved */
   58:             lba_to_msf(q, 0);
   59:             q += 3;
   60:         } else {
   61:             /* sector 0 */
   62:             cpu_to_be32wu((uint32_t *)q, 0);
   63:             q += 4;
   64:         }
   65:     }
   66:     /* lead out track */
   67:     *q++ = 0; /* reserved */
   68:     *q++ = 0x16; /* ADR, control */
   69:     *q++ = 0xaa; /* track number */
   70:     *q++ = 0; /* reserved */
   71:     if (msf) {
   72:         *q++ = 0; /* reserved */
   73:         lba_to_msf(q, nb_sectors);
   74:         q += 3;
   75:     } else {
   76:         cpu_to_be32wu((uint32_t *)q, nb_sectors);
   77:         q += 4;
   78:     }
   79:     len = q - buf;
   80:     cpu_to_be16wu((uint16_t *)buf, len - 2);
   81:     return len;
   82: }
   83: 
   84: /* mostly same info as PearPc */
   85: int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
   86: {
   87:     uint8_t *q;
   88:     int len;
   89: 
   90:     q = buf + 2;
   91:     *q++ = 1; /* first session */
   92:     *q++ = 1; /* last session */
   93: 
   94:     *q++ = 1; /* session number */
   95:     *q++ = 0x14; /* data track */
   96:     *q++ = 0; /* track number */
   97:     *q++ = 0xa0; /* lead-in */
   98:     *q++ = 0; /* min */
   99:     *q++ = 0; /* sec */
  100:     *q++ = 0; /* frame */
  101:     *q++ = 0;
  102:     *q++ = 1; /* first track */
  103:     *q++ = 0x00; /* disk type */
  104:     *q++ = 0x00;
  105: 
  106:     *q++ = 1; /* session number */
  107:     *q++ = 0x14; /* data track */
  108:     *q++ = 0; /* track number */
  109:     *q++ = 0xa1;
  110:     *q++ = 0; /* min */
  111:     *q++ = 0; /* sec */
  112:     *q++ = 0; /* frame */
  113:     *q++ = 0;
  114:     *q++ = 1; /* last track */
  115:     *q++ = 0x00;
  116:     *q++ = 0x00;
  117: 
  118:     *q++ = 1; /* session number */
  119:     *q++ = 0x14; /* data track */
  120:     *q++ = 0; /* track number */
  121:     *q++ = 0xa2; /* lead-out */
  122:     *q++ = 0; /* min */
  123:     *q++ = 0; /* sec */
  124:     *q++ = 0; /* frame */
  125:     if (msf) {
  126:         *q++ = 0; /* reserved */
  127:         lba_to_msf(q, nb_sectors);
  128:         q += 3;
  129:     } else {
  130:         cpu_to_be32wu((uint32_t *)q, nb_sectors);
  131:         q += 4;
  132:     }
  133: 
  134:     *q++ = 1; /* session number */
  135:     *q++ = 0x14; /* ADR, control */
  136:     *q++ = 0;    /* track number */
  137:     *q++ = 1;    /* point */
  138:     *q++ = 0; /* min */
  139:     *q++ = 0; /* sec */
  140:     *q++ = 0; /* frame */
  141:     if (msf) {
  142:         *q++ = 0;
  143:         lba_to_msf(q, 0);
  144:         q += 3;
  145:     } else {
  146:         *q++ = 0;
  147:         *q++ = 0;
  148:         *q++ = 0;
  149:         *q++ = 0;
  150:     }
  151: 
  152:     len = q - buf;
  153:     cpu_to_be16wu((uint16_t *)buf, len - 2);
  154:     return len;
  155: }
  156: 
  157: 
Syntax (Markdown)