Annotation of hatari/src/ide.c, revision 1.1.1.11

1.1       root        1: /*
                      2:   Hatari - ide.c
                      3: 
1.1.1.7   root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
                      7:   This is where we intercept read/writes to/from the IDE controller hardware.
                      8: */
1.1.1.2   root        9: 
                     10: #include <SDL_endian.h>
                     11: #include <errno.h>
                     12: 
                     13: #include <sys/types.h>
                     14: #include <sys/stat.h>
                     15: #include <unistd.h>
1.1       root       16: 
                     17: #include "main.h"
                     18: #include "configuration.h"
1.1.1.2   root       19: #include "file.h"
1.1       root       20: #include "ide.h"
1.1.1.9   root       21: #include "hdc.h" /* for partition counting */
1.1       root       22: #include "m68000.h"
1.1.1.2   root       23: #include "mfp.h"
1.1       root       24: #include "stMemory.h"
1.1.1.9   root       25: #include "str.h"
1.1       root       26: #include "sysdeps.h"
                     27: 
1.1.1.2   root       28: #if HAVE_MALLOC_H
                     29: # include <malloc.h>
                     30: #endif
                     31: 
1.1.1.9   root       32: int nIDEPartitions = 0;
1.1.1.2   root       33: struct IDEState;
                     34: 
1.1       root       35: 
1.1.1.2   root       36: static struct IDEState *opaque_ide_if;
                     37: 
                     38: static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val);
                     39: static uint32_t ide_ioport_read(void *opaque, uint32_t addr1);
                     40: static uint32_t ide_status_read(void *opaque, uint32_t addr);
                     41: static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val);
                     42: static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val);
                     43: static uint32_t ide_data_readw(void *opaque, uint32_t addr);
                     44: static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
                     45: static uint32_t ide_data_readl(void *opaque, uint32_t addr);
                     46: 
                     47: 
                     48: /**
                     49:  * Convert Falcon IDE registers to "normal" IDE register numbers.
                     50:  * (taken from Aranym - cheers!)
                     51:  */
                     52: static uint32_t fcha2io(uint32_t address)
                     53: {
                     54:        switch (address)
                     55:        {
                     56:        case 0xf00000:
                     57:                return 0x00;
                     58:        case 0xf00005:
                     59:                return 0x01;
                     60:        case 0xf00009:
                     61:                return 0x02;
                     62:        case 0xf0000d:
                     63:                return 0x03;
                     64:        case 0xf00011:
                     65:                return 0x04;
                     66:        case 0xf00015:
                     67:                return 0x05;
                     68:        case 0xf00019:
                     69:                return 0x06;
                     70:        case 0xf0001d:
                     71:                return 0x07;
                     72:        case 0xf00039:
                     73:                return 0x16;
                     74:        default:
                     75:                return 0xffffffff;
                     76:        }
                     77: }
                     78: 
1.1       root       79: 
                     80: /**
                     81:  * Handle byte read access from IDE IO memory.
                     82:  */
1.1.1.10  root       83: uae_u32 REGPARAM3 Ide_Mem_bget(uaecptr addr)
1.1       root       84: {
1.1.1.2   root       85:        int ideport;
                     86:        uint8_t retval;
1.1.1.11! root       87:        uaecptr addr_in = addr;
1.1.1.2   root       88: 
1.1       root       89:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
                     90: 
1.1.1.4   root       91:        if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1       root       92:        {
                     93:                /* invalid memory addressing --> bus error */
1.1.1.11! root       94:                M68000_BusError(addr_in, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1       root       95:                return -1;
                     96:        }
                     97: 
1.1.1.2   root       98:        ideport = fcha2io(addr);
                     99: 
1.1.1.3   root      100:        if (ideport >= 1 && ideport <= 7)
1.1.1.2   root      101:        {
                    102:                retval = ide_ioport_read(opaque_ide_if, ideport);
1.1.1.3   root      103:        }
                    104:        else if (ideport == 8 || ideport == 22)
                    105:        {
1.1.1.2   root      106:                retval = ide_status_read(opaque_ide_if, 0);
1.1.1.3   root      107:        }
                    108:        else
                    109:        {
1.1.1.2   root      110:                retval = 0xFF;
                    111:        }
                    112: 
1.1.1.9   root      113:        LOG_TRACE(TRACE_IDE, "IDE: bget($%x) = $%02x\n", addr, retval);
1.1.1.2   root      114:        return retval;
1.1       root      115: }
                    116: 
                    117: 
                    118: /**
                    119:  * Handle word read access from IDE IO memory.
                    120:  */
1.1.1.10  root      121: uae_u32 REGPARAM3 Ide_Mem_wget(uaecptr addr)
1.1       root      122: {
1.1.1.2   root      123:        uint16_t retval;
1.1.1.11! root      124:        uaecptr addr_in = addr;
1.1       root      125: 
                    126:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
                    127: 
1.1.1.4   root      128:        if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1       root      129:        {
                    130:                /* invalid memory addressing --> bus error */
1.1.1.11! root      131:                M68000_BusError(addr_in, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1       root      132:                return -1;
                    133:        }
                    134: 
1.1.1.10  root      135:        if (addr == 0xf00000 || addr == 0xf00002)
1.1.1.2   root      136:        {
                    137:                retval = ide_data_readw(opaque_ide_if, 0);
                    138:        }
                    139:        else
                    140:        {
                    141:                retval = 0xFFFF;
                    142:        }
                    143: 
1.1.1.9   root      144:        LOG_TRACE(TRACE_IDE, "IDE: wget($%x) = $%04x\n", addr, retval);
1.1.1.2   root      145:        return retval;
1.1       root      146: }
                    147: 
                    148: 
                    149: /**
                    150:  * Handle long-word read access from IDE IO memory.
                    151:  */
1.1.1.10  root      152: uae_u32 REGPARAM3 Ide_Mem_lget(uaecptr addr)
1.1       root      153: {
1.1.1.2   root      154:        uint32_t retval;
1.1.1.11! root      155:        uaecptr addr_in = addr;
1.1       root      156: 
                    157:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
                    158: 
1.1.1.4   root      159:        if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1       root      160:        {
                    161:                /* invalid memory addressing --> bus error */
1.1.1.11! root      162:                M68000_BusError(addr_in, BUS_ERROR_READ, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1       root      163:                return -1;
                    164:        }
                    165: 
1.1.1.2   root      166:        if (addr == 0xf00000)
                    167:        {
                    168:                retval = ide_data_readl(opaque_ide_if, 0);
                    169:        }
                    170:        else
                    171:        {
                    172:                retval = 0xFFFFFFFF;
                    173:        }
                    174: 
                    175:        /* word swap for long access to data register */
                    176:        retval = ((retval >> 16) & 0x0000ffff) | ((retval & 0x0000ffff) << 16);
                    177: 
1.1.1.9   root      178:        LOG_TRACE(TRACE_IDE, "IDE: lget($%x) = $%08x\n", addr, retval);
1.1.1.2   root      179:        return retval;
1.1       root      180: }
                    181: 
                    182: 
                    183: /**
                    184:  * Handle byte write access to IDE IO memory.
                    185:  */
1.1.1.10  root      186: void REGPARAM3 Ide_Mem_bput(uaecptr addr, uae_u32 val)
1.1       root      187: {
1.1.1.2   root      188:        int ideport;
1.1.1.11! root      189:        uaecptr addr_in = addr;
1.1       root      190: 
                    191:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
1.1.1.2   root      192:        val &= 0x0ff;
                    193: 
1.1.1.9   root      194:        LOG_TRACE(TRACE_IDE, "IDE: bput($%x, $%x)\n", addr, val);
1.1       root      195: 
1.1.1.4   root      196:        if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1       root      197:        {
                    198:                /* invalid memory addressing --> bus error */
1.1.1.11! root      199:                M68000_BusError(addr_in, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1       root      200:                return;
                    201:        }
                    202: 
1.1.1.2   root      203:        ideport = fcha2io(addr);
                    204: 
1.1.1.3   root      205:        if (ideport >= 1 && ideport <= 7)
1.1.1.2   root      206:        {
                    207:                ide_ioport_write(opaque_ide_if, ideport, val);
1.1.1.3   root      208:        }
                    209:        else if (ideport == 8 || ideport == 22)
                    210:        {
1.1.1.2   root      211:                ide_cmd_write(opaque_ide_if, 0, val);
                    212:        }
1.1       root      213: }
                    214: 
                    215: 
                    216: /**
                    217:  * Handle word write access to IDE IO memory.
                    218:  */
1.1.1.10  root      219: void REGPARAM3 Ide_Mem_wput(uaecptr addr, uae_u32 val)
1.1       root      220: {
1.1.1.11! root      221:        uaecptr addr_in = addr;
        !           222: 
1.1       root      223:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
1.1.1.2   root      224:        val &= 0x0ffff;
                    225: 
1.1.1.9   root      226:        LOG_TRACE(TRACE_IDE, "IDE: wput($%x, $%x)\n", addr, val);
1.1       root      227: 
1.1.1.4   root      228:        if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1       root      229:        {
                    230:                /* invalid memory addressing --> bus error */
1.1.1.11! root      231:                M68000_BusError(addr_in, BUS_ERROR_WRITE, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1       root      232:                return;
                    233:        }
                    234: 
1.1.1.10  root      235:        if (addr == 0xf00000 || addr == 0xf00002)
1.1.1.2   root      236:        {
                    237:                ide_data_writew(opaque_ide_if, 0, val);
                    238:        }
1.1       root      239: }
                    240: 
                    241: 
                    242: /**
                    243:  * Handle long-word write access to IDE IO memory.
                    244:  */
1.1.1.10  root      245: void REGPARAM3 Ide_Mem_lput(uaecptr addr, uae_u32 val)
1.1       root      246: {
1.1.1.11! root      247:        uaecptr addr_in = addr;
        !           248: 
1.1       root      249:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
                    250: 
1.1.1.9   root      251:        LOG_TRACE(TRACE_IDE, "IDE: lput($%x, $%x)\n", addr, val);
1.1.1.2   root      252: 
1.1.1.4   root      253:        if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1       root      254:        {
                    255:                /* invalid memory addressing --> bus error */
1.1.1.11! root      256:                M68000_BusError(addr_in, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1       root      257:                return;
                    258:        }
                    259: 
1.1.1.2   root      260:        /* word swap for long access to data register */
                    261:        val = ((val >> 16) & 0x0000ffff) | ((val & 0x0000ffff) << 16);
                    262: 
                    263:        if (addr == 0xf00000)
                    264:        {
                    265:                ide_data_writel(opaque_ide_if, 0, val);
                    266:        }
                    267: }
                    268: 
                    269: 
                    270: /*----------------------------------------------------------------------------*/
                    271: 
                    272: 
                    273: /*
                    274:  * QEMU IDE disk and CD-ROM Emulator
                    275:  *
                    276:  * Copyright (c) 2003 Fabrice Bellard
                    277:  * Copyright (c) 2006 Openedhand Ltd.
                    278:  *
                    279:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                    280:  * of this software and associated documentation files (the "Software"), to deal
                    281:  * in the Software without restriction, including without limitation the rights
                    282:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                    283:  * copies of the Software, and to permit persons to whom the Software is
                    284:  * furnished to do so, subject to the following conditions:
                    285:  *
                    286:  * The above copyright notice and this permission notice shall be included in
                    287:  * all copies or substantial portions of the Software.
                    288:  *
                    289:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                    290:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                    291:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                    292:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                    293:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                    294:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                    295:  * THE SOFTWARE.
                    296:  */
                    297: 
                    298: #define FW_VERSION "1.0"
                    299: 
                    300: 
                    301: #define BDRV_TYPE_HD     0
                    302: #define BDRV_TYPE_CDROM  1
                    303: #define BDRV_TYPE_FLOPPY 2
                    304: #define BIOS_ATA_TRANSLATION_AUTO   0
                    305: #define BIOS_ATA_TRANSLATION_NONE   1
                    306: #define BIOS_ATA_TRANSLATION_LBA    2
                    307: #define BIOS_ATA_TRANSLATION_LARGE  3
                    308: #define BIOS_ATA_TRANSLATION_RECHS  4
                    309: 
1.1.1.11! root      310: #ifndef ENOMEDIUM           // It's not defined on macOS for example
1.1.1.2   root      311: #define ENOMEDIUM ENODEV
                    312: #endif
                    313: 
                    314: 
                    315: typedef struct BlockDriverState BlockDriverState;
                    316: 
                    317: struct BlockDriverState {
                    318:     int64_t total_sectors; /* if we are reading a disk image, give its
                    319:                               size in sectors */
                    320:     int read_only; /* if true, the media is read only */
                    321:     int removable; /* if true, the media can be removed */
                    322:     int locked;    /* if true, the media cannot temporarily be ejected */
                    323:     int sg;        /* if true, the device is a /dev/sg* */
                    324:     /* event callback when inserting/removing */
                    325:     void (*change_cb)(void *opaque);
                    326:     void *change_opaque;
                    327: 
                    328:     FILE *fhndl;
                    329:     void *opaque;
1.1.1.10  root      330:     off_t file_size;
1.1.1.2   root      331:     int media_changed;
                    332: 
                    333:     /* I/O stats (display with "info blockstats"). */
                    334:     uint64_t rd_bytes;
                    335:     uint64_t wr_bytes;
                    336:     uint64_t rd_ops;
                    337:     uint64_t wr_ops;
                    338: 
                    339:     /* NOTE: the following infos are only hints for real hardware
                    340:        drivers. They are not used by the block driver */
                    341:     int cyls, heads, secs, translation;
                    342:     int type;
                    343: };
                    344: 
                    345: 
                    346: static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
                    347: {
                    348:        uint8_t *p1 = (uint8_t *)p;
                    349: 
                    350:        p1[0] = v >> 8;
                    351:        p1[1] = v;
                    352: }
                    353: 
                    354: 
                    355: #define le32_to_cpu SDL_SwapLE32
                    356: #define le16_to_cpu SDL_SwapLE16
                    357: #define cpu_to_le32 SDL_SwapLE32
                    358: #define cpu_to_le16 SDL_SwapLE16
                    359: 
                    360: 
                    361: #define MIN(a, b) (((a) < (b)) ? (a) : (b))
                    362: 
                    363: #define SECTOR_BITS 9
                    364: #define SECTOR_SIZE (1 << SECTOR_BITS)
                    365: 
                    366: 
                    367: /**
                    368:  * return 0 as number of sectors if no device present or error
                    369:  */
                    370: static void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
                    371: {
1.1.1.10  root      372:        off_t length = bs->file_size;
1.1.1.2   root      373: 
                    374:        if (length < 0)
                    375:                length = 0;
                    376:        else
                    377:                length = length >> SECTOR_BITS;
                    378:        *nb_sectors_ptr = length;
                    379: }
                    380: 
                    381: static void bdrv_get_geometry_hint(BlockDriverState *bs,
                    382:                             int *pcyls, int *pheads, int *psecs)
                    383: {
                    384:        *pcyls = bs->cyls;
                    385:        *pheads = bs->heads;
                    386:        *psecs = bs->secs;
                    387: }
                    388: 
                    389: static void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
                    390: {
                    391:        bs->translation = translation;
                    392: }
                    393: 
                    394: static void bdrv_set_geometry_hint(BlockDriverState *bs,
                    395:                             int cyls, int heads, int secs)
                    396: {
                    397:        bs->cyls = cyls;
                    398:        bs->heads = heads;
                    399:        bs->secs = secs;
                    400: }
                    401: 
                    402: static int bdrv_get_type_hint(BlockDriverState *bs)
                    403: {
                    404:        return bs->type;
                    405: }
                    406: 
                    407: static int bdrv_get_translation_hint(BlockDriverState *bs)
                    408: {
                    409:        return bs->translation;
                    410: }
                    411: 
                    412: /* XXX: no longer used */
                    413: static void bdrv_set_change_cb(BlockDriverState *bs,
                    414:                         void (*change_cb)(void *opaque), void *opaque)
                    415: {
                    416:        bs->change_cb = change_cb;
                    417:        bs->change_opaque = opaque;
                    418: }
                    419: 
                    420: 
                    421: /**
                    422:  * Return TRUE if the media is present
                    423:  */
                    424: static int bdrv_is_inserted(BlockDriverState *bs)
                    425: {
                    426:        return (bs->fhndl != NULL);
                    427: }
                    428: 
                    429: 
                    430: static int bdrv_is_locked(BlockDriverState *bs)
                    431: {
                    432:        return bs->locked;
                    433: }
                    434: 
                    435: /**
                    436:  * Lock or unlock the media (if it is locked, the user won't be able
                    437:  * to eject it manually).
                    438:  */
                    439: static void bdrv_set_locked(BlockDriverState *bs, int locked)
                    440: {
                    441:        bs->locked = locked;
                    442: }
                    443: 
                    444: 
                    445: /* return < 0 if error. See bdrv_write() for the return codes */
                    446: static int bdrv_read(BlockDriverState *bs, int64_t sector_num,
                    447:                      uint8_t *buf, int nb_sectors)
                    448: {
1.1.1.3   root      449:        int ret, len;
                    450: 
1.1.1.2   root      451:        if (!bs->fhndl)
                    452:                return -ENOMEDIUM;
                    453: 
1.1.1.10  root      454:        len = nb_sectors * SECTOR_SIZE;
1.1.1.2   root      455: 
1.1.1.10  root      456:        if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
1.1.1.9   root      457:        {
                    458:                perror("bdrv_read");
                    459:                return -errno;
                    460:        }
1.1.1.2   root      461:        ret = fread(buf, 1, len, bs->fhndl);
                    462:        if (ret != len)
                    463:        {
1.1.1.9   root      464:                fprintf(stderr,"IDE: bdrv_read error (%d != %d length) at sector %lu!\n", ret, len, (unsigned long)sector_num);
1.1.1.2   root      465:                return -EINVAL;
                    466:        }
                    467:        else
                    468:        {
                    469:                bs->rd_bytes += (unsigned) len;
                    470:                bs->rd_ops ++;
                    471:                return 0;
                    472:        }
                    473: }
                    474: 
                    475: 
                    476: /* Return < 0 if error. Important errors are:
                    477:   -EIO         generic I/O error (may happen for all errors)
                    478:   -ENOMEDIUM   No media inserted.
                    479:   -EINVAL      Invalid sector number or nb_sectors
                    480:   -EACCES      Trying to write a read-only device
                    481: */
                    482: static int bdrv_write(BlockDriverState *bs, int64_t sector_num,
                    483:                       const uint8_t *buf, int nb_sectors)
                    484: {
1.1.1.3   root      485:        int ret, len;
                    486: 
1.1.1.2   root      487:        if (!bs->fhndl)
                    488:                return -ENOMEDIUM;
                    489:        if (bs->read_only)
                    490:                return -EACCES;
                    491: 
1.1.1.10  root      492:        len = nb_sectors * SECTOR_SIZE;
1.1.1.2   root      493: 
1.1.1.10  root      494:        if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
1.1.1.9   root      495:        {
                    496:                perror("bdrv_write");
                    497:                return -errno;
                    498:        }
1.1.1.2   root      499:        ret = fwrite(buf, 1, len, bs->fhndl);
                    500:        if (ret != len)
                    501:        {
1.1.1.9   root      502:                fprintf(stderr,"IDE: bdrv_write error (%d != %d length) at sector %lu!\n", ret, len,  (unsigned long)sector_num);
1.1.1.2   root      503:                return -EIO;
                    504:        }
                    505:        else
                    506:        {
                    507:                bs->wr_bytes += (unsigned) len;
                    508:                bs->wr_ops ++;
                    509:                return 0;
                    510:        }
                    511: }
                    512: 
                    513: 
                    514: static int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
                    515: {
1.1.1.9   root      516:        Log_Printf(LOG_INFO, "Mounting IDE hard drive image %s\n", filename);
1.1.1.2   root      517: 
                    518:        bs->read_only = 0;
1.1.1.10  root      519:        bs->file_size = HDC_CheckAndGetSize(filename);
                    520:        if (bs->file_size <= 0)
                    521:                return -1;
                    522:        if (bs->file_size < 2 * 16 * 63 * SECTOR_SIZE)
                    523:        {
                    524:                Log_AlertDlg(LOG_ERROR, "IDE disk image size (%"PRId64" bytes) is "
                    525:                                        "too small for an IDE disk image "
                    526:                                        "(min. 1032192 byte)", bs->file_size);
                    527:                return -1;
                    528:        }
1.1.1.2   root      529: 
                    530:        bs->fhndl = fopen(filename, "rb+");
                    531:        if (!bs->fhndl) {
                    532:                /* Maybe the file is read-only? */
                    533:                bs->fhndl = fopen(filename, "rb");
                    534:                if (!bs->fhndl)
                    535:                        perror("bdrv_open");
                    536:                bs->read_only = 1;
                    537:        }
1.1.1.9   root      538:        else if (!File_Lock(bs->fhndl))
                    539:        {
                    540:                Log_Printf(LOG_ERROR, "ERROR: cannot lock HD file for writing!\n");
                    541:                fclose(bs->fhndl);
                    542:                bs->fhndl = NULL;
                    543:        }
1.1.1.2   root      544: 
                    545:        /* call the change callback */
                    546:        bs->media_changed = 1;
                    547:        if (bs->change_cb)
                    548:                bs->change_cb(bs->change_opaque);
                    549: 
                    550:        return 0;
                    551: }
                    552: 
                    553: static void bdrv_flush(BlockDriverState *bs)
                    554: {
                    555:        fflush(bs->fhndl);
                    556: }
                    557: 
                    558: static void bdrv_close(BlockDriverState *bs)
                    559: {
1.1.1.9   root      560:        File_UnLock(bs->fhndl);
1.1.1.2   root      561:        fclose(bs->fhndl);
                    562:        bs->fhndl = NULL;
                    563: }
                    564: 
                    565: /**
                    566:  * If eject_flag is TRUE, eject the media. Otherwise, close the tray
                    567:  */
                    568: static void bdrv_eject(BlockDriverState *bs, int eject_flag)
                    569: {
                    570:        if (eject_flag)
                    571:                bdrv_close(bs);
                    572: }
                    573: 
                    574: 
                    575: // #define USE_DMA_CDROM
                    576: 
                    577: /* Bits of HD_STATUS */
                    578: #define ERR_STAT               0x01
                    579: #define INDEX_STAT             0x02
                    580: #define ECC_STAT               0x04    /* Corrected error */
                    581: #define DRQ_STAT               0x08
                    582: #define SEEK_STAT              0x10
                    583: #define SRV_STAT               0x10
                    584: #define WRERR_STAT             0x20
                    585: #define READY_STAT             0x40
                    586: #define BUSY_STAT              0x80
                    587: 
                    588: /* Bits for HD_ERROR */
                    589: #define MARK_ERR               0x01    /* Bad address mark */
                    590: #define TRK0_ERR               0x02    /* couldn't find track 0 */
                    591: #define ABRT_ERR               0x04    /* Command aborted */
                    592: #define MCR_ERR                        0x08    /* media change request */
                    593: #define ID_ERR                 0x10    /* ID field not found */
                    594: #define MC_ERR                 0x20    /* media changed */
                    595: #define ECC_ERR                        0x40    /* Uncorrectable ECC error */
                    596: #define BBD_ERR                        0x80    /* pre-EIDE meaning:  block marked bad */
                    597: #define ICRC_ERR               0x80    /* new meaning:  CRC error during transfer */
                    598: 
                    599: /* Bits of HD_NSECTOR */
                    600: #define CD                     0x01
                    601: #define IO                     0x02
                    602: #define REL                    0x04
                    603: #define TAG_MASK               0xf8
                    604: 
                    605: #define IDE_CMD_RESET           0x04
                    606: #define IDE_CMD_DISABLE_IRQ     0x02
                    607: 
                    608: /* ATA/ATAPI Commands pre T13 Spec */
                    609: #define WIN_NOP                                0x00
                    610: /*
                    611:  *     0x01->0x02 Reserved
                    612:  */
                    613: #define CFA_REQ_EXT_ERROR_CODE         0x03 /* CFA Request Extended Error Code */
                    614: /*
                    615:  *     0x04->0x07 Reserved
                    616:  */
                    617: #define WIN_SRST                       0x08 /* ATAPI soft reset command */
                    618: #define WIN_DEVICE_RESET               0x08
                    619: /*
                    620:  *     0x09->0x0F Reserved
                    621:  */
                    622: #define WIN_RECAL                      0x10
                    623: #define WIN_RESTORE                    WIN_RECAL
                    624: /*
                    625:  *     0x10->0x1F Reserved
                    626:  */
                    627: #define WIN_READ                       0x20 /* 28-Bit */
                    628: #define WIN_READ_ONCE                  0x21 /* 28-Bit without retries */
                    629: #define WIN_READ_LONG                  0x22 /* 28-Bit */
                    630: #define WIN_READ_LONG_ONCE             0x23 /* 28-Bit without retries */
                    631: #define WIN_READ_EXT                   0x24 /* 48-Bit */
                    632: #define WIN_READDMA_EXT                        0x25 /* 48-Bit */
                    633: #define WIN_READDMA_QUEUED_EXT         0x26 /* 48-Bit */
                    634: #define WIN_READ_NATIVE_MAX_EXT                0x27 /* 48-Bit */
                    635: /*
                    636:  *     0x28
                    637:  */
                    638: #define WIN_MULTREAD_EXT               0x29 /* 48-Bit */
                    639: /*
                    640:  *     0x2A->0x2F Reserved
                    641:  */
                    642: #define WIN_WRITE                      0x30 /* 28-Bit */
                    643: #define WIN_WRITE_ONCE                 0x31 /* 28-Bit without retries */
                    644: #define WIN_WRITE_LONG                 0x32 /* 28-Bit */
                    645: #define WIN_WRITE_LONG_ONCE            0x33 /* 28-Bit without retries */
                    646: #define WIN_WRITE_EXT                  0x34 /* 48-Bit */
                    647: #define WIN_WRITEDMA_EXT               0x35 /* 48-Bit */
                    648: #define WIN_WRITEDMA_QUEUED_EXT                0x36 /* 48-Bit */
                    649: #define WIN_SET_MAX_EXT                        0x37 /* 48-Bit */
                    650: #define CFA_WRITE_SECT_WO_ERASE                0x38 /* CFA Write Sectors without erase */
                    651: #define WIN_MULTWRITE_EXT              0x39 /* 48-Bit */
                    652: /*
                    653:  *     0x3A->0x3B Reserved
                    654:  */
                    655: #define WIN_WRITE_VERIFY               0x3C /* 28-Bit */
                    656: /*
                    657:  *     0x3D->0x3F Reserved
                    658:  */
                    659: #define WIN_VERIFY                     0x40 /* 28-Bit - Read Verify Sectors */
                    660: #define WIN_VERIFY_ONCE                        0x41 /* 28-Bit - without retries */
                    661: #define WIN_VERIFY_EXT                 0x42 /* 48-Bit */
                    662: /*
                    663:  *     0x43->0x4F Reserved
                    664:  */
                    665: #define WIN_FORMAT                     0x50
                    666: /*
                    667:  *     0x51->0x5F Reserved
                    668:  */
                    669: #define WIN_INIT                       0x60
                    670: /*
                    671:  *     0x61->0x5F Reserved
                    672:  */
                    673: #define WIN_SEEK                       0x70 /* 0x70-0x7F Reserved */
                    674: #define CFA_TRANSLATE_SECTOR           0x87 /* CFA Translate Sector */
                    675: #define WIN_DIAGNOSE                   0x90
                    676: #define WIN_SPECIFY                    0x91 /* set drive geometry translation */
                    677: #define WIN_DOWNLOAD_MICROCODE         0x92
                    678: #define WIN_STANDBYNOW2                        0x94
                    679: #define CFA_IDLEIMMEDIATE              0x95 /* force drive to become "ready" */
                    680: #define WIN_STANDBY2                   0x96
                    681: #define WIN_SETIDLE2                   0x97
                    682: #define WIN_CHECKPOWERMODE2            0x98
                    683: #define WIN_SLEEPNOW2                  0x99
                    684: /*
                    685:  *     0x9A VENDOR
                    686:  */
                    687: #define WIN_PACKETCMD                  0xA0 /* Send a packet command. */
                    688: #define WIN_PIDENTIFY                  0xA1 /* identify ATAPI device   */
                    689: #define WIN_QUEUED_SERVICE             0xA2
                    690: #define WIN_SMART                      0xB0 /* self-monitoring and reporting */
                    691: #define CFA_ACCESS_METADATA_STORAGE    0xB8
                    692: #define CFA_ERASE_SECTORS              0xC0 /* microdrives implement as NOP */
                    693: #define WIN_MULTREAD                   0xC4 /* read sectors using multiple mode*/
                    694: #define WIN_MULTWRITE                  0xC5 /* write sectors using multiple mode */
                    695: #define WIN_SETMULT                    0xC6 /* enable/disable multiple mode */
                    696: #define WIN_READDMA_QUEUED             0xC7 /* read sectors using Queued DMA transfers */
                    697: #define WIN_READDMA                    0xC8 /* read sectors using DMA transfers */
                    698: #define WIN_READDMA_ONCE               0xC9 /* 28-Bit - without retries */
                    699: #define WIN_WRITEDMA                   0xCA /* write sectors using DMA transfers */
                    700: #define WIN_WRITEDMA_ONCE              0xCB /* 28-Bit - without retries */
                    701: #define WIN_WRITEDMA_QUEUED            0xCC /* write sectors using Queued DMA transfers */
                    702: #define CFA_WRITE_MULTI_WO_ERASE       0xCD /* CFA Write multiple without erase */
                    703: #define WIN_GETMEDIASTATUS             0xDA
                    704: #define WIN_ACKMEDIACHANGE             0xDB /* ATA-1, ATA-2 vendor */
                    705: #define WIN_POSTBOOT                   0xDC
                    706: #define WIN_PREBOOT                    0xDD
                    707: #define WIN_DOORLOCK                   0xDE /* lock door on removable drives */
                    708: #define WIN_DOORUNLOCK                 0xDF /* unlock door on removable drives */
                    709: #define WIN_STANDBYNOW1                        0xE0
                    710: #define WIN_IDLEIMMEDIATE              0xE1 /* force drive to become "ready" */
                    711: #define WIN_STANDBY                    0xE2 /* Set device in Standby Mode */
                    712: #define WIN_SETIDLE1                   0xE3
                    713: #define WIN_READ_BUFFER                        0xE4 /* force read only 1 sector */
                    714: #define WIN_CHECKPOWERMODE1            0xE5
                    715: #define WIN_SLEEPNOW1                  0xE6
                    716: #define WIN_FLUSH_CACHE                        0xE7
                    717: #define WIN_WRITE_BUFFER               0xE8 /* force write only 1 sector */
                    718: #define WIN_WRITE_SAME                 0xE9 /* read ata-2 to use */
                    719: /* SET_FEATURES 0x22 or 0xDD */
                    720: #define WIN_FLUSH_CACHE_EXT            0xEA /* 48-Bit */
                    721: #define WIN_IDENTIFY                   0xEC /* ask drive to identify itself    */
                    722: #define WIN_MEDIAEJECT                 0xED
                    723: #define WIN_IDENTIFY_DMA               0xEE /* same as WIN_IDENTIFY, but DMA */
                    724: #define WIN_SETFEATURES                        0xEF /* set special drive features */
                    725: #define EXABYTE_ENABLE_NEST            0xF0
                    726: #define IBM_SENSE_CONDITION            0xF0 /* measure disk temperature */
                    727: #define WIN_SECURITY_SET_PASS          0xF1
                    728: #define WIN_SECURITY_UNLOCK            0xF2
                    729: #define WIN_SECURITY_ERASE_PREPARE     0xF3
                    730: #define WIN_SECURITY_ERASE_UNIT                0xF4
                    731: #define WIN_SECURITY_FREEZE_LOCK       0xF5
                    732: #define CFA_WEAR_LEVEL                 0xF5 /* microdrives implement as NOP */
                    733: #define WIN_SECURITY_DISABLE           0xF6
                    734: #define WIN_READ_NATIVE_MAX            0xF8 /* return the native maximum address */
                    735: #define WIN_SET_MAX                    0xF9
                    736: #define DISABLE_SEAGATE                        0xFB
                    737: 
                    738: /* set to 1 set disable mult support */
                    739: #define MAX_MULT_SECTORS 16
                    740: 
                    741: /* ATAPI defines */
                    742: 
                    743: #define ATAPI_PACKET_SIZE 12
                    744: 
                    745: /* The generic packet command opcodes for CD/DVD Logical Units,
                    746:  * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
                    747: #define GPCMD_BLANK                        0xa1
                    748: #define GPCMD_CLOSE_TRACK                  0x5b
                    749: #define GPCMD_FLUSH_CACHE                  0x35
                    750: #define GPCMD_FORMAT_UNIT                  0x04
                    751: #define GPCMD_GET_CONFIGURATION                    0x46
                    752: #define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
                    753: #define GPCMD_GET_PERFORMANCE              0xac
                    754: #define GPCMD_INQUIRY                      0x12
                    755: #define GPCMD_LOAD_UNLOAD                  0xa6
                    756: #define GPCMD_MECHANISM_STATUS             0xbd
                    757: #define GPCMD_MODE_SELECT_10               0x55
                    758: #define GPCMD_MODE_SENSE_10                0x5a
                    759: #define GPCMD_PAUSE_RESUME                 0x4b
                    760: #define GPCMD_PLAY_AUDIO_10                0x45
                    761: #define GPCMD_PLAY_AUDIO_MSF               0x47
                    762: #define GPCMD_PLAY_AUDIO_TI                0x48
                    763: #define GPCMD_PLAY_CD                      0xbc
                    764: #define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
                    765: #define GPCMD_READ_10                      0x28
                    766: #define GPCMD_READ_12                      0xa8
                    767: #define GPCMD_READ_CDVD_CAPACITY           0x25
                    768: #define GPCMD_READ_CD                      0xbe
                    769: #define GPCMD_READ_CD_MSF                  0xb9
                    770: #define GPCMD_READ_DISC_INFO               0x51
                    771: #define GPCMD_READ_DVD_STRUCTURE           0xad
                    772: #define GPCMD_READ_FORMAT_CAPACITIES       0x23
                    773: #define GPCMD_READ_HEADER                  0x44
                    774: #define GPCMD_READ_TRACK_RZONE_INFO        0x52
                    775: #define GPCMD_READ_SUBCHANNEL              0x42
                    776: #define GPCMD_READ_TOC_PMA_ATIP                    0x43
                    777: #define GPCMD_REPAIR_RZONE_TRACK           0x58
                    778: #define GPCMD_REPORT_KEY                   0xa4
                    779: #define GPCMD_REQUEST_SENSE                0x03
                    780: #define GPCMD_RESERVE_RZONE_TRACK          0x53
                    781: #define GPCMD_SCAN                         0xba
                    782: #define GPCMD_SEEK                         0x2b
                    783: #define GPCMD_SEND_DVD_STRUCTURE           0xad
                    784: #define GPCMD_SEND_EVENT                   0xa2
                    785: #define GPCMD_SEND_KEY                     0xa3
                    786: #define GPCMD_SEND_OPC                     0x54
                    787: #define GPCMD_SET_READ_AHEAD               0xa7
                    788: #define GPCMD_SET_STREAMING                0xb6
                    789: #define GPCMD_START_STOP_UNIT              0x1b
                    790: #define GPCMD_STOP_PLAY_SCAN               0x4e
                    791: #define GPCMD_TEST_UNIT_READY              0x00
                    792: #define GPCMD_VERIFY_10                            0x2f
                    793: #define GPCMD_WRITE_10                     0x2a
                    794: #define GPCMD_WRITE_AND_VERIFY_10          0x2e
                    795: /* This is listed as optional in ATAPI 2.6, but is (curiously)
                    796:  * missing from Mt. Fuji, Table 57.  It _is_ mentioned in Mt. Fuji
                    797:  * Table 377 as an MMC command for SCSi devices though...  Most ATAPI
                    798:  * drives support it. */
                    799: #define GPCMD_SET_SPEED                            0xbb
                    800: /* This seems to be a SCSI specific CD-ROM opcode
                    801:  * to play data at track/index */
                    802: #define GPCMD_PLAYAUDIO_TI                 0x48
                    803: /*
                    804:  * From MS Media Status Notification Support Specification. For
                    805:  * older drives only.
                    806:  */
                    807: #define GPCMD_GET_MEDIA_STATUS             0xda
                    808: #define GPCMD_MODE_SENSE_6                 0x1a
                    809: 
                    810: /* Mode page codes for mode sense/set */
                    811: #define GPMODE_R_W_ERROR_PAGE          0x01
                    812: #define GPMODE_WRITE_PARMS_PAGE                0x05
                    813: #define GPMODE_AUDIO_CTL_PAGE          0x0e
                    814: #define GPMODE_POWER_PAGE              0x1a
                    815: #define GPMODE_FAULT_FAIL_PAGE         0x1c
                    816: #define GPMODE_TO_PROTECT_PAGE         0x1d
                    817: #define GPMODE_CAPABILITIES_PAGE       0x2a
                    818: #define GPMODE_ALL_PAGES               0x3f
                    819: /* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
                    820:  * of MODE_SENSE_POWER_PAGE */
                    821: #define GPMODE_CDROM_PAGE              0x0d
                    822: 
                    823: #define ATAPI_INT_REASON_CD             0x01 /* 0 = data transfer */
                    824: #define ATAPI_INT_REASON_IO             0x02 /* 1 = transfer to the host */
                    825: #define ATAPI_INT_REASON_REL            0x04
                    826: #define ATAPI_INT_REASON_TAG            0xf8
                    827: 
                    828: /* same constants as bochs */
                    829: #define ASC_ILLEGAL_OPCODE                   0x20
                    830: #define ASC_LOGICAL_BLOCK_OOR                0x21
                    831: #define ASC_INV_FIELD_IN_CMD_PACKET          0x24
                    832: #define ASC_MEDIUM_NOT_PRESENT               0x3a
                    833: #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
                    834: 
                    835: #define SENSE_NONE            0
                    836: #define SENSE_NOT_READY       2
                    837: #define SENSE_ILLEGAL_REQUEST 5
                    838: #define SENSE_UNIT_ATTENTION  6
                    839: 
                    840: typedef void EndTransferFunc(struct IDEState *);
                    841: 
                    842: /* NOTE: IDEState represents in fact one drive */
                    843: typedef struct IDEState
                    844: {
                    845:        /* ide config */
                    846:        int is_cdrom;
                    847:        int cylinders, heads, sectors;
                    848:        int64_t nb_sectors;
                    849:        int mult_sectors;
                    850:        int identify_set;
                    851:        uint16_t identify_data[256];
                    852:        int drive_serial;
                    853:        /* ide regs */
                    854:        uint8_t feature;
                    855:        uint8_t error;
                    856:        uint32_t nsector;
                    857:        uint8_t sector;
                    858:        uint8_t lcyl;
                    859:        uint8_t hcyl;
                    860:        /* other part of tf for lba48 support */
                    861:        uint8_t hob_feature;
                    862:        uint8_t hob_nsector;
                    863:        uint8_t hob_sector;
                    864:        uint8_t hob_lcyl;
                    865:        uint8_t hob_hcyl;
                    866: 
                    867:        uint8_t select;
                    868:        uint8_t status;
                    869: 
                    870:        /* 0x3f6 command, only meaningful for drive 0 */
                    871:        uint8_t cmd;
                    872:        /* set for lba48 access */
                    873:        uint8_t lba48;
                    874:        /* depends on bit 4 in select, only meaningful for drive 0 */
                    875:        struct IDEState *cur_drive;
                    876:        BlockDriverState *bs;
                    877:        /* ATAPI specific */
                    878:        uint8_t sense_key;
                    879:        uint8_t asc;
                    880:        int packet_transfer_size;
                    881:        int elementary_transfer_size;
                    882:        int io_buffer_index;
                    883:        int lba;
                    884:        int cd_sector_size;
                    885:        /* ATA DMA state */
                    886:        int io_buffer_size;
                    887:        /* PIO transfer handling */
                    888:        int req_nb_sectors; /* number of sectors per interrupt */
                    889:        EndTransferFunc *end_transfer_func;
                    890:        uint8_t *data_ptr;
                    891:        uint8_t *data_end;
                    892:        uint8_t *io_buffer;
                    893:        int media_changed;
                    894: } IDEState;
                    895: 
                    896: 
                    897: static void padstr(char *str, const char *src, int len)
                    898: {
                    899:        int i, v;
                    900:        for (i = 0; i < len; i++)
                    901:        {
                    902:                if (*src)
                    903:                        v = *src++;
                    904:                else
                    905:                        v = ' ';
                    906:                str[i^1] = v;
                    907:        }
                    908: }
                    909: 
                    910: static void padstr8(uint8_t *buf, int buf_size, const char *src)
                    911: {
                    912:        int i;
                    913:        for (i = 0; i < buf_size; i++)
                    914:        {
                    915:                if (*src)
                    916:                        buf[i] = *src++;
                    917:                else
                    918:                        buf[i] = ' ';
                    919:        }
                    920: }
                    921: 
                    922: static void put_le16(uint16_t *p, unsigned int v)
                    923: {
                    924:        *p = SDL_SwapLE16(v);
                    925: }
                    926: 
                    927: static void ide_identify(IDEState *s)
                    928: {
                    929:        uint16_t *p;
                    930:        unsigned int oldsize;
                    931:        char buf[20];
                    932: 
                    933:        if (s->identify_set)
                    934:        {
                    935:                memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
                    936:                return;
                    937:        }
                    938: 
                    939:        memset(s->io_buffer, 0, 512);
                    940:        p = (uint16_t *)s->io_buffer;
                    941:        put_le16(p + 0, 0x0040);
                    942:        put_le16(p + 1, s->cylinders);
                    943:        put_le16(p + 3, s->heads);
                    944:        put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
                    945:        put_le16(p + 5, 512); /* XXX: retired, remove ? */
                    946:        put_le16(p + 6, s->sectors);
                    947:        snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
                    948:        padstr((char *)(p + 10), buf, 20); /* serial number */
                    949:        put_le16(p + 20, 3); /* XXX: retired, remove ? */
                    950:        put_le16(p + 21, 512); /* cache size in sectors */
                    951:        put_le16(p + 22, 4); /* ecc bytes */
                    952:        padstr((char *)(p + 23), FW_VERSION, 8); /* firmware version */
1.1.1.4   root      953:        if(s == opaque_ide_if) /* model */
                    954:        {
                    955:                padstr((char *)(p + 27), "Hatari IDE master disk", 40);
                    956:        }
                    957:        else
                    958:        {
                    959:                padstr((char *)(p + 27), "Hatari IDE slave disk", 40);
                    960:        }
1.1.1.2   root      961: #if MAX_MULT_SECTORS > 1
                    962:        put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
                    963: #endif
                    964:        put_le16(p + 48, 1); /* dword I/O */
                    965:        put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
                    966:        put_le16(p + 51, 0x200); /* PIO transfer cycle */
                    967:        put_le16(p + 52, 0x200); /* DMA transfer cycle */
                    968:        put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
                    969:        put_le16(p + 54, s->cylinders);
                    970:        put_le16(p + 55, s->heads);
                    971:        put_le16(p + 56, s->sectors);
                    972:        oldsize = s->cylinders * s->heads * s->sectors;
                    973:        put_le16(p + 57, oldsize);
                    974:        put_le16(p + 58, oldsize >> 16);
                    975:        if (s->mult_sectors)
                    976:                put_le16(p + 59, 0x100 | s->mult_sectors);
                    977:        put_le16(p + 60, s->nb_sectors);
                    978:        put_le16(p + 61, s->nb_sectors >> 16);
                    979:        put_le16(p + 63, 0x07); /* mdma0-2 supported */
                    980:        put_le16(p + 65, 120);
                    981:        put_le16(p + 66, 120);
                    982:        put_le16(p + 67, 120);
                    983:        put_le16(p + 68, 120);
                    984:        put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
                    985:        put_le16(p + 81, 0x16); /* conforms to ata5 */
                    986:        put_le16(p + 82, (1 << 14));
                    987:        /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
                    988:        put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
                    989:        put_le16(p + 84, (1 << 14));
                    990:        put_le16(p + 85, (1 << 14));
                    991:        /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
                    992:        put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
                    993:        put_le16(p + 87, (1 << 14));
                    994:        put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
                    995:        put_le16(p + 93, 1 | (1 << 14) | 0x2000);
                    996:        put_le16(p + 100, s->nb_sectors);
                    997:        put_le16(p + 101, s->nb_sectors >> 16);
                    998:        put_le16(p + 102, s->nb_sectors >> 32);
                    999:        put_le16(p + 103, s->nb_sectors >> 48);
                   1000: 
                   1001:        memcpy(s->identify_data, p, sizeof(s->identify_data));
                   1002:        s->identify_set = 1;
                   1003: }
                   1004: 
                   1005: static void ide_atapi_identify(IDEState *s)
                   1006: {
                   1007:        uint16_t *p;
                   1008:        char buf[20];
                   1009: 
                   1010:        if (s->identify_set)
                   1011:        {
                   1012:                memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
                   1013:                return;
                   1014:        }
                   1015: 
                   1016:        memset(s->io_buffer, 0, 512);
                   1017:        p = (uint16_t *)s->io_buffer;
                   1018:        /* Removable CDROM, 50us response, 12 byte packets */
                   1019:        put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
                   1020:        snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
                   1021:        padstr((char *)(p + 10), buf, 20); /* serial number */
                   1022:        put_le16(p + 20, 3); /* buffer type */
                   1023:        put_le16(p + 21, 512); /* cache size in sectors */
                   1024:        put_le16(p + 22, 4); /* ecc bytes */
                   1025:        padstr((char *)(p + 23), FW_VERSION, 8); /* firmware version */
                   1026:        padstr((char *)(p + 27), "Hatari CD-ROM", 40); /* model */
                   1027:        put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
                   1028: #ifdef USE_DMA_CDROM
                   1029:        put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
                   1030:        put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
                   1031:        put_le16(p + 63, 7);  /* mdma0-2 supported */
                   1032:        put_le16(p + 64, 0x3f); /* PIO modes supported */
                   1033: #else
                   1034:        put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
                   1035:        put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
                   1036:        put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
                   1037:        put_le16(p + 64, 1); /* PIO modes */
                   1038: #endif
                   1039:        put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
                   1040:        put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
                   1041:        put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
                   1042:        put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
                   1043: 
                   1044:        put_le16(p + 71, 30); /* in ns */
                   1045:        put_le16(p + 72, 30); /* in ns */
                   1046: 
                   1047:        put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
                   1048: #ifdef USE_DMA_CDROM
                   1049:        put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
                   1050: #endif
                   1051:        memcpy(s->identify_data, p, sizeof(s->identify_data));
                   1052:        s->identify_set = 1;
                   1053: }
                   1054: 
                   1055: 
                   1056: static void ide_set_signature(IDEState *s)
                   1057: {
                   1058:        s->select &= 0xf0; /* clear head */
                   1059:        /* put signature */
                   1060:        s->nsector = 1;
                   1061:        s->sector = 1;
                   1062:        if (s->is_cdrom)
                   1063:        {
                   1064:                s->lcyl = 0x14;
                   1065:                s->hcyl = 0xeb;
                   1066:        }
                   1067:        else if (s->bs)
                   1068:        {
                   1069:                s->lcyl = 0;
                   1070:                s->hcyl = 0;
                   1071:        }
                   1072:        else
                   1073:        {
                   1074:                s->lcyl = 0xff;
                   1075:                s->hcyl = 0xff;
                   1076:        }
                   1077: }
                   1078: 
                   1079: static inline void ide_abort_command(IDEState *s)
                   1080: {
                   1081:        s->status = READY_STAT | ERR_STAT;
                   1082:        s->error = ABRT_ERR;
                   1083: }
                   1084: 
                   1085: static inline void ide_set_irq(IDEState *s)
                   1086: {
                   1087:        if (!(s->cmd & IDE_CMD_DISABLE_IRQ))
                   1088:        {
1.1.1.9   root     1089:                /* Set IRQ (set line to low) */
                   1090:                MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_FDC_HDC , MFP_GPIP_STATE_LOW );
1.1.1.2   root     1091:        }
                   1092: }
                   1093: 
                   1094: /* prepare data transfer and tell what to do after */
                   1095: static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
                   1096:                                EndTransferFunc *end_transfer_func)
                   1097: {
                   1098:        s->end_transfer_func = end_transfer_func;
                   1099:        s->data_ptr = buf;
                   1100:        s->data_end = buf + size;
                   1101:        if (!(s->status & ERR_STAT))
                   1102:                s->status |= DRQ_STAT;
                   1103: }
                   1104: 
                   1105: static void ide_transfer_stop(IDEState *s)
                   1106: {
                   1107:        s->end_transfer_func = ide_transfer_stop;
                   1108:        s->data_ptr = s->io_buffer;
                   1109:        s->data_end = s->io_buffer;
                   1110:        s->status &= ~DRQ_STAT;
                   1111: }
                   1112: 
                   1113: static int64_t ide_get_sector(IDEState *s)
                   1114: {
                   1115:        int64_t sector_num;
                   1116:        if (s->select & 0x40)
                   1117:        {
                   1118:                /* lba */
                   1119:                if (!s->lba48)
                   1120:                {
                   1121:                        sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
                   1122:                                     (s->lcyl << 8) | s->sector;
                   1123:                }
                   1124:                else
                   1125:                {
                   1126:                        sector_num = ((int64_t)s->hob_hcyl << 40) |
                   1127:                                     ((int64_t) s->hob_lcyl << 32) |
                   1128:                                     ((int64_t) s->hob_sector << 24) |
                   1129:                                     ((int64_t) s->hcyl << 16) |
                   1130:                                     ((int64_t) s->lcyl << 8) | s->sector;
                   1131:                }
                   1132:        }
                   1133:        else
                   1134:        {
                   1135:                sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
                   1136:                             (s->select & 0x0f) * s->sectors + (s->sector - 1);
                   1137:        }
                   1138:        return sector_num;
                   1139: }
                   1140: 
                   1141: static void ide_set_sector(IDEState *s, int64_t sector_num)
                   1142: {
                   1143:        unsigned int cyl, r;
                   1144:        if (s->select & 0x40)
                   1145:        {
                   1146:                if (!s->lba48)
                   1147:                {
                   1148:                        s->select = (s->select & 0xf0) | (sector_num >> 24);
                   1149:                        s->hcyl = (sector_num >> 16);
                   1150:                        s->lcyl = (sector_num >> 8);
                   1151:                        s->sector = (sector_num);
                   1152:                }
                   1153:                else
                   1154:                {
                   1155:                        s->sector = sector_num;
                   1156:                        s->lcyl = sector_num >> 8;
                   1157:                        s->hcyl = sector_num >> 16;
                   1158:                        s->hob_sector = sector_num >> 24;
                   1159:                        s->hob_lcyl = sector_num >> 32;
                   1160:                        s->hob_hcyl = sector_num >> 40;
                   1161:                }
                   1162:        }
                   1163:        else
                   1164:        {
                   1165:                cyl = sector_num / (s->heads * s->sectors);
                   1166:                r = sector_num % (s->heads * s->sectors);
                   1167:                s->hcyl = cyl >> 8;
                   1168:                s->lcyl = cyl;
                   1169:                s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
                   1170:                s->sector = (r % s->sectors) + 1;
                   1171:        }
                   1172: }
                   1173: 
                   1174: static void ide_sector_read(IDEState *s)
                   1175: {
                   1176:        int64_t sector_num;
                   1177:        int ret, n;
                   1178: 
                   1179:        s->status = READY_STAT | SEEK_STAT;
                   1180:        s->error = 0; /* not needed by IDE spec, but needed by Windows */
                   1181:        sector_num = ide_get_sector(s);
                   1182:        n = s->nsector;
                   1183:        if (n == 0)
                   1184:        {
                   1185:                /* no more sector to read from disk */
                   1186:                ide_transfer_stop(s);
                   1187:        }
                   1188:        else
                   1189:        {
1.1.1.9   root     1190:                LOG_TRACE(TRACE_IDE, "IDE: read sector=%"PRId64"\n", sector_num);
                   1191: 
1.1.1.2   root     1192:                if (n > s->req_nb_sectors)
                   1193:                        n = s->req_nb_sectors;
                   1194:                ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
1.1.1.4   root     1195:                if (ret != 0)
                   1196:                {
                   1197:                        ide_abort_command(s);
                   1198:                        ide_set_irq(s);
                   1199:                        return;
                   1200:                }
1.1.1.2   root     1201:                ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
                   1202:                ide_set_irq(s);
                   1203:                ide_set_sector(s, sector_num + n);
                   1204:                s->nsector -= n;
                   1205:        }
                   1206: }
                   1207: 
                   1208: 
                   1209: static void ide_sector_write(IDEState *s)
                   1210: {
                   1211:        int64_t sector_num;
                   1212:        int ret, n, n1;
                   1213: 
                   1214:        s->status = READY_STAT | SEEK_STAT;
                   1215:        sector_num = ide_get_sector(s);
1.1.1.9   root     1216:        LOG_TRACE(TRACE_IDE, "IDE: write sector=%"PRId64"\n", sector_num);
                   1217: 
1.1.1.2   root     1218:        n = s->nsector;
                   1219:        if (n > s->req_nb_sectors)
                   1220:                n = s->req_nb_sectors;
                   1221:        ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
1.1.1.4   root     1222:        if (ret != 0)
                   1223:        {
                   1224:                ide_abort_command(s);
                   1225:                ide_set_irq(s);
                   1226:                return;
                   1227:        }
1.1.1.2   root     1228:        s->nsector -= n;
                   1229:        if (s->nsector == 0)
                   1230:        {
                   1231:                /* no more sectors to write */
                   1232:                ide_transfer_stop(s);
                   1233:        }
                   1234:        else
                   1235:        {
                   1236:                n1 = s->nsector;
                   1237:                if (n1 > s->req_nb_sectors)
                   1238:                        n1 = s->req_nb_sectors;
                   1239:                ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
                   1240:        }
                   1241:        ide_set_sector(s, sector_num + n);
                   1242: 
                   1243:        ide_set_irq(s);
                   1244: }
                   1245: 
                   1246: 
                   1247: static void ide_atapi_cmd_ok(IDEState *s)
                   1248: {
                   1249:        s->error = 0;
                   1250:        s->status = READY_STAT;
                   1251:        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
                   1252:        ide_set_irq(s);
                   1253: }
                   1254: 
                   1255: static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
                   1256: {
1.1.1.9   root     1257:        LOG_TRACE(TRACE_IDE, "IDE: ATAPI cmd error sense=0x%x asc=0x%x\n", sense_key, asc);
                   1258: 
1.1.1.2   root     1259:        s->error = sense_key << 4;
                   1260:        s->status = READY_STAT | ERR_STAT;
                   1261:        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
                   1262:        s->sense_key = sense_key;
                   1263:        s->asc = asc;
                   1264:        ide_set_irq(s);
                   1265: }
                   1266: 
                   1267: static inline void cpu_to_ube16(uint8_t *buf, int val)
                   1268: {
                   1269:        buf[0] = val >> 8;
                   1270:        buf[1] = val;
                   1271: }
                   1272: 
                   1273: static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
                   1274: {
                   1275:        buf[0] = val >> 24;
                   1276:        buf[1] = val >> 16;
                   1277:        buf[2] = val >> 8;
                   1278:        buf[3] = val;
                   1279: }
                   1280: 
                   1281: static inline int ube16_to_cpu(const uint8_t *buf)
                   1282: {
                   1283:        return (buf[0] << 8) | buf[1];
                   1284: }
                   1285: 
                   1286: static inline int ube32_to_cpu(const uint8_t *buf)
                   1287: {
                   1288:        return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
                   1289: }
                   1290: 
                   1291: static void lba_to_msf(uint8_t *buf, int lba)
                   1292: {
                   1293:        lba += 150;
                   1294:        buf[0] = (lba / 75) / 60;
                   1295:        buf[1] = (lba / 75) % 60;
                   1296:        buf[2] = lba % 75;
                   1297: }
                   1298: 
                   1299: static void cd_data_to_raw(uint8_t *buf, int lba)
                   1300: {
                   1301:        /* sync bytes */
                   1302:        buf[0] = 0x00;
                   1303:        memset(buf + 1, 0xff, 10);
                   1304:        buf[11] = 0x00;
                   1305:        buf += 12;
                   1306:        /* MSF */
                   1307:        lba_to_msf(buf, lba);
                   1308:        buf[3] = 0x01; /* mode 1 data */
                   1309:        buf += 4;
                   1310:        /* data */
                   1311:        buf += 2048;
                   1312:        /* XXX: ECC not computed */
                   1313:        memset(buf, 0, 288);
                   1314: }
                   1315: 
                   1316: static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
                   1317:                           int sector_size)
                   1318: {
                   1319:        int ret;
                   1320: 
                   1321:        switch (sector_size)
                   1322:        {
                   1323:        case 2048:
                   1324:                ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
                   1325:                break;
                   1326:        case 2352:
                   1327:                ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
                   1328:                if (ret < 0)
                   1329:                        return ret;
                   1330:                cd_data_to_raw(buf, lba);
                   1331:                break;
                   1332:        default:
                   1333:                ret = -EIO;
                   1334:                break;
                   1335:        }
                   1336:        return ret;
                   1337: }
                   1338: 
                   1339: static void ide_atapi_io_error(IDEState *s, int ret)
                   1340: {
                   1341:        /* XXX: handle more errors */
                   1342:        if (ret == -ENOMEDIUM)
                   1343:        {
                   1344:                ide_atapi_cmd_error(s, SENSE_NOT_READY,
                   1345:                                    ASC_MEDIUM_NOT_PRESENT);
                   1346:        }
                   1347:        else
                   1348:        {
                   1349:                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1350:                                    ASC_LOGICAL_BLOCK_OOR);
                   1351:        }
                   1352: }
                   1353: 
                   1354: /* The whole ATAPI transfer logic is handled in this function */
                   1355: static void ide_atapi_cmd_reply_end(IDEState *s)
                   1356: {
                   1357:        int byte_count_limit, size, ret;
1.1.1.9   root     1358: 
                   1359:        LOG_TRACE(TRACE_IDE, "IDE: ATAPI reply tx_size=%d elem_tx_size=%d index=%d\n",
1.1.1.2   root     1360:               s->packet_transfer_size,
                   1361:               s->elementary_transfer_size,
                   1362:               s->io_buffer_index);
1.1.1.9   root     1363: 
1.1.1.2   root     1364:        if (s->packet_transfer_size <= 0)
                   1365:        {
                   1366:                /* end of transfer */
                   1367:                ide_transfer_stop(s);
                   1368:                s->status = READY_STAT;
                   1369:                s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
                   1370:                ide_set_irq(s);
1.1.1.9   root     1371:                LOG_TRACE(TRACE_IDE, "IDE: ATAPI status=0x%x\n", s->status);
1.1.1.2   root     1372:        }
                   1373:        else
                   1374:        {
                   1375:                /* see if a new sector must be read */
                   1376:                if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size)
                   1377:                {
                   1378:                        ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
                   1379:                        if (ret < 0)
                   1380:                        {
                   1381:                                ide_transfer_stop(s);
                   1382:                                ide_atapi_io_error(s, ret);
                   1383:                                return;
                   1384:                        }
                   1385:                        s->lba++;
                   1386:                        s->io_buffer_index = 0;
                   1387:                }
                   1388:                if (s->elementary_transfer_size > 0)
                   1389:                {
                   1390:                        /* there are some data left to transmit in this elementary
                   1391:                           transfer */
                   1392:                        size = s->cd_sector_size - s->io_buffer_index;
                   1393:                        if (size > s->elementary_transfer_size)
                   1394:                                size = s->elementary_transfer_size;
                   1395:                        ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
                   1396:                                           size, ide_atapi_cmd_reply_end);
                   1397:                        s->packet_transfer_size -= size;
                   1398:                        s->elementary_transfer_size -= size;
                   1399:                        s->io_buffer_index += size;
                   1400:                }
                   1401:                else
                   1402:                {
                   1403:                        /* a new transfer is needed */
                   1404:                        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
                   1405:                        byte_count_limit = s->lcyl | (s->hcyl << 8);
1.1.1.9   root     1406:                        LOG_TRACE(TRACE_IDE, "IDE: ATAPI byte_count_limit=%d\n", byte_count_limit);
                   1407: 
1.1.1.2   root     1408:                        if (byte_count_limit == 0xffff)
                   1409:                                byte_count_limit--;
                   1410:                        size = s->packet_transfer_size;
                   1411:                        if (size > byte_count_limit)
                   1412:                        {
                   1413:                                /* byte count limit must be even if this case */
                   1414:                                if (byte_count_limit & 1)
                   1415:                                        byte_count_limit--;
                   1416:                                size = byte_count_limit;
                   1417:                        }
                   1418:                        s->lcyl = size;
                   1419:                        s->hcyl = size >> 8;
                   1420:                        s->elementary_transfer_size = size;
                   1421:                        /* we cannot transmit more than one sector at a time */
                   1422:                        if (s->lba != -1)
                   1423:                        {
                   1424:                                if (size > (s->cd_sector_size - s->io_buffer_index))
                   1425:                                        size = (s->cd_sector_size - s->io_buffer_index);
                   1426:                        }
                   1427:                        ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
                   1428:                                           size, ide_atapi_cmd_reply_end);
                   1429:                        s->packet_transfer_size -= size;
                   1430:                        s->elementary_transfer_size -= size;
                   1431:                        s->io_buffer_index += size;
                   1432:                        ide_set_irq(s);
1.1.1.9   root     1433: 
                   1434:                        LOG_TRACE(TRACE_IDE, "IDE: ATAPI status=0x%x\n", s->status);
1.1.1.2   root     1435:                }
                   1436:        }
                   1437: }
                   1438: 
                   1439: /* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
                   1440: static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
                   1441: {
                   1442:        if (size > max_size)
                   1443:                size = max_size;
                   1444:        s->lba = -1; /* no sector read */
                   1445:        s->packet_transfer_size = size;
                   1446:        s->io_buffer_size = size;    /* dma: send the reply data as one chunk */
                   1447:        s->elementary_transfer_size = 0;
                   1448:        s->io_buffer_index = 0;
                   1449: 
                   1450:        s->status = READY_STAT;
                   1451:        ide_atapi_cmd_reply_end(s);
                   1452: }
                   1453: 
                   1454: /* start a CD-CDROM read command */
                   1455: static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
                   1456:                                int sector_size)
                   1457: {
1.1.1.9   root     1458:        LOG_TRACE(TRACE_IDE, "IDE: ATAPI read pio LBA=%d nb_sectors=%d\n", lba, nb_sectors);
                   1459: 
1.1.1.2   root     1460:        s->lba = lba;
                   1461:        s->packet_transfer_size = nb_sectors * sector_size;
                   1462:        s->elementary_transfer_size = 0;
                   1463:        s->io_buffer_index = sector_size;
                   1464:        s->cd_sector_size = sector_size;
                   1465: 
                   1466:        s->status = READY_STAT;
                   1467:        ide_atapi_cmd_reply_end(s);
                   1468: }
                   1469: 
                   1470: 
                   1471: static void ide_atapi_cmd(IDEState *s)
                   1472: {
                   1473:        const uint8_t *packet;
                   1474:        uint8_t *buf;
                   1475:        int max_len;
                   1476: 
                   1477:        packet = s->io_buffer;
                   1478:        buf = s->io_buffer;
1.1.1.9   root     1479:        if (LOG_TRACE_LEVEL(TRACE_IDE))
1.1.1.2   root     1480:        {
                   1481:                int i;
1.1.1.9   root     1482:                LOG_TRACE_PRINT("IDE: ATAPI limit=0x%x packet", s->lcyl | (s->hcyl << 8));
1.1.1.2   root     1483:                for (i = 0; i < ATAPI_PACKET_SIZE; i++)
                   1484:                {
                   1485:                        printf(" %02x", packet[i]);
                   1486:                }
                   1487:                printf("\n");
                   1488:        }
1.1.1.9   root     1489: 
1.1.1.2   root     1490:        switch (s->io_buffer[0])
                   1491:        {
                   1492:        case GPCMD_TEST_UNIT_READY:
                   1493:                if (bdrv_is_inserted(s->bs))
                   1494:                {
                   1495:                        ide_atapi_cmd_ok(s);
                   1496:                }
                   1497:                else
                   1498:                {
                   1499:                        ide_atapi_cmd_error(s, SENSE_NOT_READY,
                   1500:                                            ASC_MEDIUM_NOT_PRESENT);
                   1501:                }
                   1502:                break;
                   1503:        case GPCMD_MODE_SENSE_6:
                   1504:        case GPCMD_MODE_SENSE_10:
                   1505:        {
                   1506:                int action, code;
                   1507:                if (packet[0] == GPCMD_MODE_SENSE_10)
                   1508:                        max_len = ube16_to_cpu(packet + 7);
                   1509:                else
                   1510:                        max_len = packet[4];
                   1511:                action = packet[2] >> 6;
                   1512:                code = packet[2] & 0x3f;
                   1513:                switch (action)
                   1514:                {
                   1515:                case 0: /* current values */
                   1516:                        switch (code)
                   1517:                        {
                   1518:                        case 0x01: /* error recovery */
                   1519:                                cpu_to_ube16(&buf[0], 16 + 6);
                   1520:                                buf[2] = 0x70;
                   1521:                                buf[3] = 0;
                   1522:                                buf[4] = 0;
                   1523:                                buf[5] = 0;
                   1524:                                buf[6] = 0;
                   1525:                                buf[7] = 0;
                   1526: 
                   1527:                                buf[8] = 0x01;
                   1528:                                buf[9] = 0x06;
                   1529:                                buf[10] = 0x00;
                   1530:                                buf[11] = 0x05;
                   1531:                                buf[12] = 0x00;
                   1532:                                buf[13] = 0x00;
                   1533:                                buf[14] = 0x00;
                   1534:                                buf[15] = 0x00;
                   1535:                                ide_atapi_cmd_reply(s, 16, max_len);
                   1536:                                break;
                   1537:                        case 0x2a:
                   1538:                                cpu_to_ube16(&buf[0], 28 + 6);
                   1539:                                buf[2] = 0x70;
                   1540:                                buf[3] = 0;
                   1541:                                buf[4] = 0;
                   1542:                                buf[5] = 0;
                   1543:                                buf[6] = 0;
                   1544:                                buf[7] = 0;
                   1545: 
                   1546:                                buf[8] = 0x2a;
                   1547:                                buf[9] = 0x12;
                   1548:                                buf[10] = 0x00;
                   1549:                                buf[11] = 0x00;
                   1550: 
                   1551:                                buf[12] = 0x70;
                   1552:                                buf[13] = 3 << 5;
                   1553:                                buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
                   1554:                                if (bdrv_is_locked(s->bs))
                   1555:                                        buf[6] |= 1 << 1;
                   1556:                                buf[15] = 0x00;
                   1557:                                cpu_to_ube16(&buf[16], 706);
                   1558:                                buf[18] = 0;
                   1559:                                buf[19] = 2;
                   1560:                                cpu_to_ube16(&buf[20], 512);
                   1561:                                cpu_to_ube16(&buf[22], 706);
                   1562:                                buf[24] = 0;
                   1563:                                buf[25] = 0;
                   1564:                                buf[26] = 0;
                   1565:                                buf[27] = 0;
                   1566:                                ide_atapi_cmd_reply(s, 28, max_len);
                   1567:                                break;
                   1568:                        default:
                   1569:                                goto error_cmd;
                   1570:                        }
                   1571:                        break;
                   1572:                case 1: /* changeable values */
                   1573:                        goto error_cmd;
                   1574:                case 2: /* default values */
                   1575:                        goto error_cmd;
                   1576:                default:
                   1577:                case 3: /* saved values */
                   1578:                        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1579:                                            ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
                   1580:                        break;
                   1581:                }
                   1582:        }
                   1583:        break;
                   1584:        case GPCMD_REQUEST_SENSE:
                   1585:                max_len = packet[4];
                   1586:                memset(buf, 0, 18);
                   1587:                buf[0] = 0x70 | (1 << 7);
                   1588:                buf[2] = s->sense_key;
                   1589:                buf[7] = 10;
                   1590:                buf[12] = s->asc;
                   1591:                ide_atapi_cmd_reply(s, 18, max_len);
                   1592:                break;
                   1593:        case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
                   1594:                if (bdrv_is_inserted(s->bs))
                   1595:                {
                   1596:                        bdrv_set_locked(s->bs, packet[4] & 1);
                   1597:                        ide_atapi_cmd_ok(s);
                   1598:                }
                   1599:                else
                   1600:                {
                   1601:                        ide_atapi_cmd_error(s, SENSE_NOT_READY,
                   1602:                                            ASC_MEDIUM_NOT_PRESENT);
                   1603:                }
                   1604:                break;
                   1605:        case GPCMD_READ_10:
                   1606:        case GPCMD_READ_12:
                   1607:        {
                   1608:                int nb_sectors, lba;
                   1609: 
                   1610:                if (packet[0] == GPCMD_READ_10)
                   1611:                        nb_sectors = ube16_to_cpu(packet + 7);
                   1612:                else
                   1613:                        nb_sectors = ube32_to_cpu(packet + 6);
                   1614:                lba = ube32_to_cpu(packet + 2);
                   1615:                if (nb_sectors == 0)
                   1616:                {
                   1617:                        ide_atapi_cmd_ok(s);
                   1618:                        break;
                   1619:                }
                   1620:                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
                   1621:        }
                   1622:        break;
                   1623:        case GPCMD_READ_CD:
                   1624:        {
                   1625:                int nb_sectors, lba, transfer_request;
                   1626: 
                   1627:                nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
                   1628:                lba = ube32_to_cpu(packet + 2);
                   1629:                if (nb_sectors == 0)
                   1630:                {
                   1631:                        ide_atapi_cmd_ok(s);
                   1632:                        break;
                   1633:                }
                   1634:                transfer_request = packet[9];
                   1635:                switch (transfer_request & 0xf8)
                   1636:                {
                   1637:                case 0x00:
                   1638:                        /* nothing */
                   1639:                        ide_atapi_cmd_ok(s);
                   1640:                        break;
                   1641:                case 0x10:
                   1642:                        /* normal read */
                   1643:                        ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
                   1644:                        break;
                   1645:                case 0xf8:
                   1646:                        /* read all data */
                   1647:                        ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
                   1648:                        break;
                   1649:                default:
                   1650:                        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1651:                                            ASC_INV_FIELD_IN_CMD_PACKET);
                   1652:                        break;
                   1653:                }
                   1654:        }
                   1655:        break;
                   1656:        case GPCMD_SEEK:
                   1657:        {
                   1658:                unsigned int lba;
                   1659:                uint64_t total_sectors;
                   1660: 
                   1661:                bdrv_get_geometry(s->bs, &total_sectors);
                   1662:                total_sectors >>= 2;
                   1663:                if (total_sectors == 0)
                   1664:                {
                   1665:                        ide_atapi_cmd_error(s, SENSE_NOT_READY,
                   1666:                                            ASC_MEDIUM_NOT_PRESENT);
                   1667:                        break;
                   1668:                }
                   1669:                lba = ube32_to_cpu(packet + 2);
                   1670:                if (lba >= total_sectors)
                   1671:                {
                   1672:                        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1673:                                            ASC_LOGICAL_BLOCK_OOR);
                   1674:                        break;
                   1675:                }
                   1676:                ide_atapi_cmd_ok(s);
                   1677:        }
                   1678:        break;
                   1679:        case GPCMD_START_STOP_UNIT:
                   1680:        {
                   1681:                int start, eject;
                   1682:                start = packet[4] & 1;
                   1683:                eject = (packet[4] >> 1) & 1;
                   1684: 
                   1685:                if (eject && !start)
                   1686:                {
                   1687:                        /* eject the disk */
                   1688:                        bdrv_eject(s->bs, 1);
                   1689:                }
                   1690:                else if (eject && start)
                   1691:                {
                   1692:                        /* close the tray */
                   1693:                        bdrv_eject(s->bs, 0);
                   1694:                }
                   1695:                ide_atapi_cmd_ok(s);
                   1696:        }
                   1697:        break;
                   1698:        case GPCMD_MECHANISM_STATUS:
                   1699:        {
                   1700:                max_len = ube16_to_cpu(packet + 8);
                   1701:                cpu_to_ube16(buf, 0);
                   1702:                /* no current LBA */
                   1703:                buf[2] = 0;
                   1704:                buf[3] = 0;
                   1705:                buf[4] = 0;
                   1706:                buf[5] = 1;
                   1707:                cpu_to_ube16(buf + 6, 0);
                   1708:                ide_atapi_cmd_reply(s, 8, max_len);
                   1709:        }
                   1710:        break;
                   1711:        case GPCMD_READ_TOC_PMA_ATIP:
                   1712:        {
1.1.1.6   root     1713:                int format, len;
                   1714:                // int msf, start_track;
1.1.1.2   root     1715:                uint64_t total_sectors;
                   1716: 
                   1717:                bdrv_get_geometry(s->bs, &total_sectors);
                   1718:                total_sectors >>= 2;
                   1719:                if (total_sectors == 0)
                   1720:                {
                   1721:                        ide_atapi_cmd_error(s, SENSE_NOT_READY,
                   1722:                                            ASC_MEDIUM_NOT_PRESENT);
                   1723:                        break;
                   1724:                }
                   1725:                max_len = ube16_to_cpu(packet + 7);
                   1726:                format = packet[9] >> 6;
1.1.1.6   root     1727:                // msf = (packet[1] >> 1) & 1;
                   1728:                // start_track = packet[6];
1.1.1.2   root     1729:                switch (format)
                   1730:                {
                   1731:                case 0:
1.1.1.4   root     1732:                        fprintf(stderr,"IDE FIXME: cdrom_read_toc");
1.1.1.2   root     1733:                        len=-1;
                   1734:                        //len = cdrom_read_toc(total_sectors, buf, msf, start_track);
                   1735:                        if (len < 0)
                   1736:                                goto error_cmd;
                   1737:                        ide_atapi_cmd_reply(s, len, max_len);
                   1738:                        break;
                   1739:                case 1:
                   1740:                        /* multi session : only a single session defined */
                   1741:                        memset(buf, 0, 12);
                   1742:                        buf[1] = 0x0a;
                   1743:                        buf[2] = 0x01;
                   1744:                        buf[3] = 0x01;
                   1745:                        ide_atapi_cmd_reply(s, 12, max_len);
                   1746:                        break;
                   1747:                case 2:
1.1.1.4   root     1748:                        fprintf(stderr,"IDE FIXME: cdrom_read_toc_raw");
1.1.1.2   root     1749:                        len=-1;
                   1750:                        //len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
                   1751:                        if (len < 0)
                   1752:                                goto error_cmd;
                   1753:                        ide_atapi_cmd_reply(s, len, max_len);
                   1754:                        break;
                   1755:                default:
                   1756: error_cmd:
                   1757:                        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1758:                                            ASC_INV_FIELD_IN_CMD_PACKET);
                   1759:                        break;
                   1760:                }
                   1761:        }
                   1762:        break;
                   1763:        case GPCMD_READ_CDVD_CAPACITY:
                   1764:        {
                   1765:                uint64_t total_sectors;
                   1766: 
                   1767:                bdrv_get_geometry(s->bs, &total_sectors);
                   1768:                total_sectors >>= 2;
                   1769:                if (total_sectors == 0)
                   1770:                {
                   1771:                        ide_atapi_cmd_error(s, SENSE_NOT_READY,
                   1772:                                            ASC_MEDIUM_NOT_PRESENT);
                   1773:                        break;
                   1774:                }
                   1775:                /* NOTE: it is really the number of sectors minus 1 */
                   1776:                cpu_to_ube32(buf, total_sectors - 1);
                   1777:                cpu_to_ube32(buf + 4, 2048);
                   1778:                ide_atapi_cmd_reply(s, 8, 8);
                   1779:        }
                   1780:        break;
                   1781:        case GPCMD_READ_DVD_STRUCTURE:
                   1782:        {
                   1783:                int media = packet[1];
                   1784:                int layer = packet[6];
                   1785:                int format = packet[2];
                   1786:                uint64_t total_sectors;
                   1787: 
                   1788:                if (media != 0 || layer != 0)
                   1789:                {
                   1790:                        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1791:                                            ASC_INV_FIELD_IN_CMD_PACKET);
                   1792:                }
                   1793: 
                   1794:                switch (format)
                   1795:                {
                   1796:                case 0:
                   1797:                        bdrv_get_geometry(s->bs, &total_sectors);
                   1798:                        total_sectors >>= 2;
                   1799:                        if (total_sectors == 0)
                   1800:                        {
                   1801:                                ide_atapi_cmd_error(s, SENSE_NOT_READY,
                   1802:                                                    ASC_MEDIUM_NOT_PRESENT);
                   1803:                                break;
                   1804:                        }
                   1805: 
                   1806:                        memset(buf, 0, 2052);
                   1807: 
                   1808:                        buf[4] = 1;   // DVD-ROM, part version 1
                   1809:                        buf[5] = 0xf; // 120mm disc, maximum rate unspecified
                   1810:                        buf[6] = 0;   // one layer, embossed data
                   1811:                        buf[7] = 0;
                   1812: 
                   1813:                        cpu_to_ube32(buf + 8, 0);
                   1814:                        cpu_to_ube32(buf + 12, total_sectors - 1);
                   1815:                        cpu_to_ube32(buf + 16, total_sectors - 1);
                   1816: 
                   1817:                        cpu_to_be16wu((uint16_t *)buf, 2048 + 4);
                   1818: 
                   1819:                        ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4);
                   1820:                        break;
                   1821: 
                   1822:                default:
                   1823:                        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1824:                                            ASC_INV_FIELD_IN_CMD_PACKET);
                   1825:                        break;
                   1826:                }
                   1827:        }
                   1828:        break;
                   1829:        case GPCMD_SET_SPEED:
                   1830:                ide_atapi_cmd_ok(s);
                   1831:                break;
                   1832:        case GPCMD_INQUIRY:
                   1833:                max_len = packet[4];
                   1834:                buf[0] = 0x05; /* CD-ROM */
                   1835:                buf[1] = 0x80; /* removable */
                   1836:                buf[2] = 0x00; /* ISO */
                   1837:                buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
                   1838:                buf[4] = 31; /* additional length */
                   1839:                buf[5] = 0; /* reserved */
                   1840:                buf[6] = 0; /* reserved */
                   1841:                buf[7] = 0; /* reserved */
                   1842:                padstr8(buf + 8, 8, "QEMU");
                   1843:                padstr8(buf + 16, 16, "QEMU CD-ROM");
                   1844:                padstr8(buf + 32, 4, FW_VERSION);
                   1845:                ide_atapi_cmd_reply(s, 36, max_len);
                   1846:                break;
                   1847:        case GPCMD_GET_CONFIGURATION:
                   1848:        {
                   1849:                uint64_t total_sectors;
                   1850: 
                   1851:                /* only feature 0 is supported */
                   1852:                if (packet[2] != 0 || packet[3] != 0)
                   1853:                {
                   1854:                        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1855:                                            ASC_INV_FIELD_IN_CMD_PACKET);
                   1856:                        break;
                   1857:                }
                   1858:                memset(buf, 0, 32);
                   1859:                bdrv_get_geometry(s->bs, &total_sectors);
                   1860:                buf[3] = 16;
                   1861:                buf[7] = total_sectors <= 1433600 ? 0x08 : 0x10; /* current profile */
                   1862:                buf[10] = 0x10 | 0x1;
                   1863:                buf[11] = 0x08; /* size of profile list */
                   1864:                buf[13] = 0x10; /* DVD-ROM profile */
                   1865:                buf[14] = buf[7] == 0x10; /* (in)active */
                   1866:                buf[17] = 0x08; /* CD-ROM profile */
                   1867:                buf[18] = buf[7] == 0x08; /* (in)active */
                   1868:                ide_atapi_cmd_reply(s, 32, 32);
                   1869:                break;
                   1870:        }
                   1871:        default:
                   1872:                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
                   1873:                                    ASC_ILLEGAL_OPCODE);
                   1874:                break;
                   1875:        }
                   1876: }
                   1877: 
                   1878: 
                   1879: /* called when the inserted state of the media has changed */
                   1880: static void cdrom_change_cb(void *opaque)
                   1881: {
                   1882:        IDEState *s = opaque;
                   1883:        uint64_t nb_sectors;
                   1884: 
                   1885:        /* XXX: send interrupt too */
                   1886:        bdrv_get_geometry(s->bs, &nb_sectors);
                   1887:        s->nb_sectors = nb_sectors;
                   1888: }
                   1889: 
                   1890: static void ide_cmd_lba48_transform(IDEState *s, int lba48)
                   1891: {
                   1892:        s->lba48 = lba48;
                   1893: 
                   1894:        /* handle the 'magic' 0 nsector count conversion here. to avoid
                   1895:         * fiddling with the rest of the read logic, we just store the
                   1896:         * full sector count in ->nsector and ignore ->hob_nsector from now
                   1897:         */
                   1898:        if (!s->lba48)
                   1899:        {
                   1900:                if (!s->nsector)
                   1901:                        s->nsector = 256;
                   1902:        }
                   1903:        else
                   1904:        {
                   1905:                if (!s->nsector && !s->hob_nsector)
                   1906:                        s->nsector = 65536;
                   1907:                else
                   1908:                {
                   1909:                        int lo = s->nsector;
                   1910:                        int hi = s->hob_nsector;
                   1911: 
                   1912:                        s->nsector = (hi << 8) | lo;
                   1913:                }
                   1914:        }
                   1915: }
                   1916: 
                   1917: static void ide_clear_hob(IDEState *ide_if)
                   1918: {
                   1919:        /* any write clears HOB high bit of device control register */
                   1920:        ide_if[0].select &= ~(1 << 7);
                   1921:        ide_if[1].select &= ~(1 << 7);
                   1922: }
                   1923: 
                   1924: static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
                   1925: {
                   1926:        IDEState *ide_if = opaque;
                   1927:        IDEState *s;
                   1928:        int unit, n;
                   1929:        int lba48 = 0;
                   1930: 
1.1.1.9   root     1931:        LOG_TRACE(TRACE_IDE, "IDE: write addr=0x%x val=0x%02x\n", addr, val);
1.1.1.2   root     1932: 
                   1933:        addr &= 7;
                   1934:        switch (addr)
                   1935:        {
                   1936:        case 0:
                   1937:                break;
                   1938:        case 1:
                   1939:                ide_clear_hob(ide_if);
                   1940:                /* NOTE: data is written to the two drives */
                   1941:                ide_if[0].hob_feature = ide_if[0].feature;
                   1942:                ide_if[1].hob_feature = ide_if[1].feature;
                   1943:                ide_if[0].feature = val;
                   1944:                ide_if[1].feature = val;
                   1945:                break;
                   1946:        case 2:
                   1947:                ide_clear_hob(ide_if);
                   1948:                ide_if[0].hob_nsector = ide_if[0].nsector;
                   1949:                ide_if[1].hob_nsector = ide_if[1].nsector;
                   1950:                ide_if[0].nsector = val;
                   1951:                ide_if[1].nsector = val;
                   1952:                break;
                   1953:        case 3:
                   1954:                ide_clear_hob(ide_if);
                   1955:                ide_if[0].hob_sector = ide_if[0].sector;
                   1956:                ide_if[1].hob_sector = ide_if[1].sector;
                   1957:                ide_if[0].sector = val;
                   1958:                ide_if[1].sector = val;
                   1959:                break;
                   1960:        case 4:
                   1961:                ide_clear_hob(ide_if);
                   1962:                ide_if[0].hob_lcyl = ide_if[0].lcyl;
                   1963:                ide_if[1].hob_lcyl = ide_if[1].lcyl;
                   1964:                ide_if[0].lcyl = val;
                   1965:                ide_if[1].lcyl = val;
                   1966:                break;
                   1967:        case 5:
                   1968:                ide_clear_hob(ide_if);
                   1969:                ide_if[0].hob_hcyl = ide_if[0].hcyl;
                   1970:                ide_if[1].hob_hcyl = ide_if[1].hcyl;
                   1971:                ide_if[0].hcyl = val;
                   1972:                ide_if[1].hcyl = val;
                   1973:                break;
                   1974:        case 6:
                   1975:                /* FIXME: HOB readback uses bit 7 */
                   1976:                ide_if[0].select = (val & ~0x10) | 0xa0;
                   1977:                ide_if[1].select = (val | 0x10) | 0xa0;
                   1978:                /* select drive */
                   1979:                unit = (val >> 4) & 1;
                   1980:                s = ide_if + unit;
                   1981:                ide_if->cur_drive = s;
                   1982:                break;
                   1983:        default:
                   1984:        case 7:
                   1985:                /* command */
1.1.1.9   root     1986:                LOG_TRACE(TRACE_IDE, "IDE: CMD=%02x\n", val);
                   1987: 
1.1.1.2   root     1988:                s = ide_if->cur_drive;
1.1.1.7   root     1989:                /* ignore commands to non existent slave */
1.1.1.2   root     1990:                if (s != ide_if && !s->bs)
                   1991:                {
1.1.1.4   root     1992:                        fprintf(stderr,"IDE: CMD to non-existant slave!\n");
1.1.1.2   root     1993:                        break;
                   1994:                }
                   1995: 
                   1996:                switch (val)
                   1997:                {
                   1998:                case WIN_IDENTIFY:
                   1999:                        if (s->bs && !s->is_cdrom)
                   2000:                        {
                   2001:                                ide_identify(s);
                   2002:                                s->status = READY_STAT | SEEK_STAT;
                   2003:                                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
                   2004:                        }
                   2005:                        else
                   2006:                        {
                   2007:                                if (s->is_cdrom)
                   2008:                                {
                   2009:                                        ide_set_signature(s);
                   2010:                                }
                   2011:                                ide_abort_command(s);
                   2012:                        }
                   2013:                        ide_set_irq(s);
                   2014:                        break;
                   2015:                case WIN_SPECIFY:
                   2016:                case WIN_RECAL:
                   2017:                        s->error = 0;
                   2018:                        s->status = READY_STAT | SEEK_STAT;
                   2019:                        ide_set_irq(s);
                   2020:                        break;
                   2021:                case WIN_SETMULT:
                   2022:                        if ((s->nsector & 0xff) != 0 &&
                   2023:                            ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
                   2024:                             (s->nsector & (s->nsector - 1)) != 0))
                   2025:                        {
                   2026:                                ide_abort_command(s);
                   2027:                        }
                   2028:                        else
                   2029:                        {
                   2030:                                s->mult_sectors = s->nsector & 0xff;
                   2031:                                s->status = READY_STAT;
                   2032:                        }
                   2033:                        ide_set_irq(s);
                   2034:                        break;
                   2035:                case WIN_VERIFY_EXT:
                   2036:                        lba48 = 1;
                   2037:                case WIN_VERIFY:
                   2038:                case WIN_VERIFY_ONCE:
                   2039:                        /* do sector number check ? */
                   2040:                        ide_cmd_lba48_transform(s, lba48);
                   2041:                        s->status = READY_STAT;
                   2042:                        ide_set_irq(s);
                   2043:                        break;
1.1.1.4   root     2044:                case WIN_FORMAT:
                   2045:                        ide_cmd_lba48_transform(s, lba48);
                   2046:                        s->error = 0;
                   2047:                        s->status = READY_STAT | SEEK_STAT;
                   2048:                        s->req_nb_sectors = s->mult_sectors;
                   2049:                        n = s->nsector;
                   2050:                        if (n > s->req_nb_sectors)
                   2051:                                n = s->req_nb_sectors;
                   2052:                        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
                   2053:                        s->media_changed = 1;
                   2054:                        break;
1.1.1.2   root     2055:                case WIN_READ_EXT:
                   2056:                        lba48 = 1;
                   2057:                case WIN_READ:
                   2058:                case WIN_READ_ONCE:
                   2059:                        if (!s->bs)
                   2060:                                goto abort_cmd;
                   2061:                        ide_cmd_lba48_transform(s, lba48);
                   2062:                        s->req_nb_sectors = 1;
                   2063:                        ide_sector_read(s);
                   2064:                        break;
                   2065:                case WIN_WRITE_EXT:
                   2066:                        lba48 = 1;
                   2067:                case WIN_WRITE:
                   2068:                case WIN_WRITE_ONCE:
                   2069:                case CFA_WRITE_SECT_WO_ERASE:
                   2070:                case WIN_WRITE_VERIFY:
                   2071:                        ide_cmd_lba48_transform(s, lba48);
                   2072:                        s->error = 0;
                   2073:                        s->status = SEEK_STAT | READY_STAT;
                   2074:                        s->req_nb_sectors = 1;
                   2075:                        ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
                   2076:                        s->media_changed = 1;
                   2077:                        break;
                   2078:                case WIN_MULTREAD_EXT:
                   2079:                        lba48 = 1;
                   2080:                case WIN_MULTREAD:
                   2081:                        if (!s->mult_sectors)
                   2082:                                goto abort_cmd;
                   2083:                        ide_cmd_lba48_transform(s, lba48);
                   2084:                        s->req_nb_sectors = s->mult_sectors;
                   2085:                        ide_sector_read(s);
                   2086:                        break;
                   2087:                case WIN_MULTWRITE_EXT:
                   2088:                        lba48 = 1;
                   2089:                case WIN_MULTWRITE:
                   2090:                case CFA_WRITE_MULTI_WO_ERASE:
                   2091:                        if (!s->mult_sectors)
                   2092:                                goto abort_cmd;
                   2093:                        ide_cmd_lba48_transform(s, lba48);
                   2094:                        s->error = 0;
                   2095:                        s->status = SEEK_STAT | READY_STAT;
                   2096:                        s->req_nb_sectors = s->mult_sectors;
                   2097:                        n = s->nsector;
                   2098:                        if (n > s->req_nb_sectors)
                   2099:                                n = s->req_nb_sectors;
                   2100:                        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
                   2101:                        s->media_changed = 1;
                   2102:                        break;
                   2103:                case WIN_READDMA_EXT:
                   2104:                        lba48 = 1;
                   2105:                case WIN_READDMA:
                   2106:                case WIN_READDMA_ONCE:
                   2107:                        if (!s->bs)
                   2108:                                goto abort_cmd;
                   2109:                        ide_cmd_lba48_transform(s, lba48);
                   2110:                        // ide_sector_read_dma(s);
                   2111:                        fprintf(stderr, "IDE: DMA read not supported!\n");
                   2112:                        break;
                   2113:                case WIN_WRITEDMA_EXT:
                   2114:                        lba48 = 1;
                   2115:                case WIN_WRITEDMA:
                   2116:                case WIN_WRITEDMA_ONCE:
                   2117:                        if (!s->bs)
                   2118:                                goto abort_cmd;
                   2119:                        ide_cmd_lba48_transform(s, lba48);
                   2120:                        // ide_sector_write_dma(s);
                   2121:                        fprintf(stderr, "IDE: DMA write not supported!\n");
                   2122:                        s->media_changed = 1;
                   2123:                        break;
                   2124:                case WIN_READ_NATIVE_MAX_EXT:
                   2125:                        lba48 = 1;
                   2126:                case WIN_READ_NATIVE_MAX:
                   2127:                        ide_cmd_lba48_transform(s, lba48);
                   2128:                        ide_set_sector(s, s->nb_sectors - 1);
                   2129:                        s->status = READY_STAT;
                   2130:                        ide_set_irq(s);
                   2131:                        break;
                   2132:                case WIN_CHECKPOWERMODE1:
                   2133:                case WIN_CHECKPOWERMODE2:
                   2134:                        s->nsector = 0xff; /* device active or idle */
                   2135:                        s->status = READY_STAT;
                   2136:                        ide_set_irq(s);
                   2137:                        break;
                   2138:                case WIN_SETFEATURES:
                   2139:                        if (!s->bs)
                   2140:                                goto abort_cmd;
                   2141:                        /* XXX: valid for CDROM ? */
                   2142:                        switch (s->feature)
                   2143:                        {
                   2144:                        case 0xcc: /* reverting to power-on defaults enable */
                   2145:                        case 0x66: /* reverting to power-on defaults disable */
                   2146:                        case 0x02: /* write cache enable */
                   2147:                        case 0x82: /* write cache disable */
                   2148:                        case 0xaa: /* read look-ahead enable */
                   2149:                        case 0x55: /* read look-ahead disable */
                   2150:                        case 0x05: /* set advanced power management mode */
                   2151:                        case 0x85: /* disable advanced power management mode */
                   2152:                        case 0x69: /* NOP */
                   2153:                        case 0x67: /* NOP */
                   2154:                        case 0x96: /* NOP */
                   2155:                        case 0x9a: /* NOP */
                   2156:                        case 0x42: /* enable Automatic Acoustic Mode */
                   2157:                        case 0xc2: /* disable Automatic Acoustic Mode */
                   2158:                                s->status = READY_STAT | SEEK_STAT;
                   2159:                                ide_set_irq(s);
                   2160:                                break;
                   2161:                        case 0x03:   /* set transfer mode */
                   2162:                        {
1.1.1.10  root     2163:                                uint8_t mval = s->nsector & 0x07;
1.1.1.2   root     2164: 
                   2165:                                switch (s->nsector >> 3)
                   2166:                                {
                   2167:                                case 0x00: /* pio default */
                   2168:                                case 0x01: /* pio mode */
                   2169:                                        put_le16(s->identify_data + 63,0x07);
                   2170:                                        put_le16(s->identify_data + 88,0x3f);
                   2171:                                        break;
                   2172:                                case 0x04: /* mdma mode */
1.1.1.10  root     2173:                                        put_le16(s->identify_data + 63,0x07 | (1 << (mval + 8)));
1.1.1.2   root     2174:                                        put_le16(s->identify_data + 88,0x3f);
                   2175:                                        break;
                   2176:                                case 0x08: /* udma mode */
                   2177:                                        put_le16(s->identify_data + 63,0x07);
1.1.1.10  root     2178:                                        put_le16(s->identify_data + 88,0x3f | (1 << (mval + 8)));
1.1.1.2   root     2179:                                        break;
                   2180:                                default:
                   2181:                                        goto abort_cmd;
                   2182:                                }
                   2183:                                s->status = READY_STAT | SEEK_STAT;
                   2184:                                ide_set_irq(s);
                   2185:                                break;
                   2186:                        }
                   2187:                        default:
                   2188:                                goto abort_cmd;
                   2189:                        }
                   2190:                        break;
                   2191:                case WIN_FLUSH_CACHE:
                   2192:                case WIN_FLUSH_CACHE_EXT:
                   2193:                        if (s->bs)
                   2194:                                bdrv_flush(s->bs);
                   2195:                        s->status = READY_STAT;
                   2196:                        ide_set_irq(s);
                   2197:                        break;
                   2198:                case WIN_STANDBY:
                   2199:                case WIN_STANDBY2:
                   2200:                case WIN_STANDBYNOW1:
                   2201:                case WIN_STANDBYNOW2:
                   2202:                case WIN_IDLEIMMEDIATE:
                   2203:                case CFA_IDLEIMMEDIATE:
                   2204:                case WIN_SETIDLE1:
                   2205:                case WIN_SETIDLE2:
                   2206:                case WIN_SLEEPNOW1:
                   2207:                case WIN_SLEEPNOW2:
                   2208:                        s->status = READY_STAT;
                   2209:                        ide_set_irq(s);
                   2210:                        break;
                   2211:                        /* ATAPI commands */
                   2212:                case WIN_PIDENTIFY:
                   2213:                        if (s->is_cdrom)
                   2214:                        {
                   2215:                                ide_atapi_identify(s);
                   2216:                                s->status = READY_STAT | SEEK_STAT;
                   2217:                                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
                   2218:                        }
                   2219:                        else
                   2220:                        {
                   2221:                                ide_abort_command(s);
                   2222:                        }
                   2223:                        ide_set_irq(s);
                   2224:                        break;
                   2225:                case WIN_DIAGNOSE:
                   2226:                        ide_set_signature(s);
                   2227:                        s->status = 0x00; /* NOTE: READY is _not_ set */
                   2228:                        s->error = 0x01;
                   2229:                        ide_set_irq(s);
                   2230:                        break;
                   2231:                case WIN_SRST:
                   2232:                        if (!s->is_cdrom)
                   2233:                                goto abort_cmd;
                   2234:                        ide_set_signature(s);
                   2235:                        s->status = 0x00; /* NOTE: READY is _not_ set */
                   2236:                        s->error = 0x01;
                   2237:                        break;
                   2238:                case WIN_PACKETCMD:
                   2239:                        if (!s->is_cdrom)
                   2240:                                goto abort_cmd;
                   2241:                        /* overlapping commands not supported */
                   2242:                        if (s->feature & 0x02)
                   2243:                                goto abort_cmd;
                   2244:                        s->status = READY_STAT;
                   2245:                        // s->atapi_dma = s->feature & 1;
                   2246:                        s->nsector = 1;
                   2247:                        ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
                   2248:                                           ide_atapi_cmd);
                   2249:                        break;
                   2250:                default:
                   2251:                abort_cmd:
                   2252:                        ide_abort_command(s);
                   2253:                        ide_set_irq(s);
                   2254:                        break;
                   2255:                }
                   2256:        }
                   2257: }
                   2258: 
                   2259: static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
                   2260: {
                   2261:        IDEState *ide_if = opaque;
                   2262:        IDEState *s = ide_if->cur_drive;
                   2263:        uint32_t addr;
1.1.1.9   root     2264:        int ret;
1.1.1.2   root     2265: 
                   2266:        /* FIXME: HOB readback uses bit 7, but it's always set right now */
1.1.1.9   root     2267:        //int hob = s->select & (1 << 7);
                   2268:        const int hob = 0;
                   2269: 
                   2270:        addr = addr1 & 7;
1.1.1.2   root     2271:        switch (addr)
                   2272:        {
                   2273:        case 0:
                   2274:                ret = 0xff;
                   2275:                break;
                   2276:        case 1:
                   2277:                if (!ide_if[0].bs && !ide_if[1].bs)
                   2278:                        ret = 0;
                   2279:                else if (!hob)
                   2280:                        ret = s->error;
                   2281:                else
                   2282:                        ret = s->hob_feature;
                   2283:                break;
                   2284:        case 2:
                   2285:                if (!ide_if[0].bs && !ide_if[1].bs)
                   2286:                        ret = 0;
                   2287:                else if (!hob)
                   2288:                        ret = s->nsector & 0xff;
                   2289:                else
                   2290:                        ret = s->hob_nsector;
                   2291:                break;
                   2292:        case 3:
                   2293:                if (!ide_if[0].bs && !ide_if[1].bs)
                   2294:                        ret = 0;
                   2295:                else if (!hob)
                   2296:                        ret = s->sector;
                   2297:                else
                   2298:                        ret = s->hob_sector;
                   2299:                break;
                   2300:        case 4:
                   2301:                if (!ide_if[0].bs && !ide_if[1].bs)
                   2302:                        ret = 0;
                   2303:                else if (!hob)
                   2304:                        ret = s->lcyl;
                   2305:                else
                   2306:                        ret = s->hob_lcyl;
                   2307:                break;
                   2308:        case 5:
                   2309:                if (!ide_if[0].bs && !ide_if[1].bs)
                   2310:                        ret = 0;
                   2311:                else if (!hob)
                   2312:                        ret = s->hcyl;
                   2313:                else
                   2314:                        ret = s->hob_hcyl;
                   2315:                break;
                   2316:        case 6:
                   2317:                if (!ide_if[0].bs && !ide_if[1].bs)
                   2318:                        ret = 0;
                   2319:                else
                   2320:                        ret = s->select;
                   2321:                break;
                   2322:        default:
                   2323:        case 7:
                   2324:                if ((!ide_if[0].bs && !ide_if[1].bs) ||
                   2325:                        (s != ide_if && !s->bs))
                   2326:                        ret = 0;
                   2327:                else
                   2328:                        ret = s->status;
1.1.1.9   root     2329: 
                   2330:                /* Clear IRQ (set line to high) */
                   2331:                MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_FDC_HDC , MFP_GPIP_STATE_HIGH );
1.1.1.2   root     2332:                break;
                   2333:        }
1.1.1.9   root     2334:        LOG_TRACE(TRACE_IDE, "IDE: read addr=0x%x val=%02x\n", addr1, ret);
1.1.1.2   root     2335:        return ret;
                   2336: }
                   2337: 
                   2338: static uint32_t ide_status_read(void *opaque, uint32_t addr)
                   2339: {
                   2340:        IDEState *ide_if = opaque;
                   2341:        IDEState *s = ide_if->cur_drive;
                   2342:        int ret;
                   2343: 
                   2344:        if ((!ide_if[0].bs && !ide_if[1].bs) ||
                   2345:                (s != ide_if && !s->bs))
                   2346:                ret = 0;
                   2347:        else
                   2348:                ret = s->status;
1.1.1.9   root     2349: 
                   2350:        LOG_TRACE(TRACE_IDE, "IDE: read status addr=0x%x val=%02x\n", addr, ret);
1.1.1.2   root     2351:        return ret;
                   2352: }
                   2353: 
                   2354: static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
                   2355: {
                   2356:        IDEState *ide_if = opaque;
                   2357:        IDEState *s;
                   2358:        int i;
                   2359: 
1.1.1.9   root     2360:        LOG_TRACE(TRACE_IDE, "IDE: write control addr=0x%x val=%02x\n", addr, val);
                   2361: 
1.1.1.2   root     2362:        /* common for both drives */
                   2363:        if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
                   2364:                (val & IDE_CMD_RESET))
                   2365:        {
                   2366:                /* reset low to high */
                   2367:                for (i = 0;i < 2; i++)
                   2368:                {
                   2369:                        s = &ide_if[i];
                   2370:                        s->status = BUSY_STAT | SEEK_STAT;
                   2371:                        s->error = 0x01;
                   2372:                }
                   2373:        }
                   2374:        else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
                   2375:                 !(val & IDE_CMD_RESET))
                   2376:        {
                   2377:                /* high to low */
                   2378:                for (i = 0;i < 2; i++)
                   2379:                {
                   2380:                        s = &ide_if[i];
                   2381:                        if (s->is_cdrom)
                   2382:                                s->status = 0x00; /* NOTE: READY is _not_ set */
                   2383:                        else
                   2384:                                s->status = READY_STAT | SEEK_STAT;
                   2385:                        ide_set_signature(s);
                   2386:                }
                   2387:        }
                   2388: 
                   2389:        ide_if[0].cmd = val;
                   2390:        ide_if[1].cmd = val;
                   2391: }
                   2392: 
                   2393: static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
                   2394: {
                   2395:        IDEState *s = ((IDEState *)opaque)->cur_drive;
                   2396:        uint8_t *p;
                   2397: 
                   2398:        p = s->data_ptr;
                   2399:        *(uint16_t *)p = le16_to_cpu(val);
                   2400:        p += 2;
                   2401:        s->data_ptr = p;
                   2402:        if (p >= s->data_end)
                   2403:                s->end_transfer_func(s);
                   2404: }
                   2405: 
                   2406: static uint32_t ide_data_readw(void *opaque, uint32_t addr)
                   2407: {
                   2408:        IDEState *s = ((IDEState *)opaque)->cur_drive;
                   2409:        uint8_t *p;
                   2410:        int ret;
                   2411:        p = s->data_ptr;
                   2412:        ret = cpu_to_le16(*(uint16_t *)p);
                   2413:        p += 2;
                   2414:        s->data_ptr = p;
                   2415:        if (p >= s->data_end)
                   2416:                s->end_transfer_func(s);
                   2417:        return ret;
                   2418: }
                   2419: 
                   2420: static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
                   2421: {
                   2422:        IDEState *s = ((IDEState *)opaque)->cur_drive;
                   2423:        uint8_t *p;
                   2424: 
                   2425:        p = s->data_ptr;
                   2426:        *(uint32_t *)p = le32_to_cpu(val);
                   2427:        p += 4;
                   2428:        s->data_ptr = p;
                   2429:        if (p >= s->data_end)
                   2430:                s->end_transfer_func(s);
                   2431: }
                   2432: 
                   2433: static uint32_t ide_data_readl(void *opaque, uint32_t addr)
                   2434: {
                   2435:        IDEState *s = ((IDEState *)opaque)->cur_drive;
                   2436:        uint8_t *p;
                   2437:        int ret;
                   2438: 
                   2439:        p = s->data_ptr;
                   2440:        ret = cpu_to_le32(*(uint32_t *)p);
                   2441:        p += 4;
                   2442:        s->data_ptr = p;
                   2443:        if (p >= s->data_end)
                   2444:                s->end_transfer_func(s);
                   2445:        return ret;
                   2446: }
                   2447: 
                   2448: static void ide_dummy_transfer_stop(IDEState *s)
                   2449: {
                   2450:        s->data_ptr = s->io_buffer;
                   2451:        s->data_end = s->io_buffer;
                   2452:        s->io_buffer[0] = 0xff;
                   2453:        s->io_buffer[1] = 0xff;
                   2454:        s->io_buffer[2] = 0xff;
                   2455:        s->io_buffer[3] = 0xff;
                   2456: }
                   2457: 
                   2458: static void ide_reset(IDEState *s)
                   2459: {
                   2460:        s->mult_sectors = MAX_MULT_SECTORS;
                   2461:        s->cur_drive = s;
                   2462:        s->select = 0xa0;
                   2463:        s->status = READY_STAT | SEEK_STAT;
                   2464: 
                   2465:        ide_set_signature(s);
                   2466:        /* init the transfer handler so that 0xffff is returned on data
                   2467:           accesses */
                   2468:        s->end_transfer_func = ide_dummy_transfer_stop;
                   2469:        ide_dummy_transfer_stop(s);
                   2470:        s->media_changed = 0;
                   2471: }
                   2472: 
                   2473: struct partition
                   2474: {
                   2475:        uint8_t boot_ind;               /* 0x80 - active */
                   2476:        uint8_t head;           /* starting head */
                   2477:        uint8_t sector;         /* starting sector */
                   2478:        uint8_t cyl;            /* starting cylinder */
                   2479:        uint8_t sys_ind;                /* What partition type */
                   2480:        uint8_t end_head;               /* end head */
                   2481:        uint8_t end_sector;     /* end sector */
                   2482:        uint8_t end_cyl;                /* end cylinder */
                   2483:        uint32_t start_sect;    /* starting sector counting from 0 */
                   2484:        uint32_t nr_sects;              /* nr of sectors in partition */
1.1.1.10  root     2485: };
1.1.1.2   root     2486: 
                   2487: /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
                   2488: static int guess_disk_lchs(IDEState *s,
                   2489:                            int *pcylinders, int *pheads, int *psectors)
                   2490: {
                   2491:        uint8_t *buf;
                   2492:        int ret, i, heads, sectors, cylinders;
                   2493:        struct partition *p;
                   2494:        uint32_t nr_sects;
                   2495: 
1.1.1.10  root     2496:        buf = malloc(SECTOR_SIZE);
1.1.1.2   root     2497:        if (buf == NULL)
                   2498:                return -1;
                   2499:        ret = bdrv_read(s->bs, 0, buf, 1);
                   2500:        if (ret < 0)
                   2501:        {
1.1.1.10  root     2502:                free(buf);
1.1.1.2   root     2503:                return -1;
                   2504:        }
                   2505:        /* test msdos magic */
                   2506:        if (buf[510] != 0x55 || buf[511] != 0xaa)
                   2507:        {
1.1.1.10  root     2508:                free(buf);
1.1.1.2   root     2509:                return -1;
                   2510:        }
                   2511:        for (i = 0; i < 4; i++)
                   2512:        {
                   2513:                p = ((struct partition *)(buf + 0x1be)) + i;
                   2514:                nr_sects = le32_to_cpu(p->nr_sects);
                   2515:                if (nr_sects && p->end_head)
                   2516:                {
                   2517:                        /* We make the assumption that the partition terminates on
                   2518:                           a cylinder boundary */
                   2519:                        heads = p->end_head + 1;
                   2520:                        sectors = p->end_sector & 63;
                   2521:                        if (sectors == 0)
                   2522:                                continue;
                   2523:                        cylinders = s->nb_sectors / (heads * sectors);
                   2524:                        if (cylinders < 1 || cylinders > 16383)
                   2525:                                continue;
                   2526:                        *pheads = heads;
                   2527:                        *psectors = sectors;
                   2528:                        *pcylinders = cylinders;
1.1.1.9   root     2529:                        LOG_TRACE(TRACE_IDE, "IDE: guessed geometry LCHS=%d %d %d\n",
1.1.1.2   root     2530:                               cylinders, heads, sectors);
1.1.1.10  root     2531:                        free(buf);
1.1.1.2   root     2532:                        return 0;
                   2533:                }
                   2534:        }
1.1.1.10  root     2535:        free(buf);
1.1.1.2   root     2536:        return -1;
                   2537: }
                   2538: 
                   2539: static void ide_init2(IDEState *ide_state, BlockDriverState *hd0,
                   2540:                       BlockDriverState *hd1)
                   2541: {
                   2542:        IDEState *s;
                   2543:        static int drive_serial = 1;
                   2544:        int i, cylinders, heads, secs, translation, lba_detected = 0;
                   2545:        uint64_t nb_sectors;
                   2546: 
                   2547:        for (i = 0; i < 2; i++)
                   2548:        {
                   2549:                s = ide_state + i;
1.1.1.10  root     2550:                s->io_buffer = malloc(MAX_MULT_SECTORS * 512 + 4);
1.1.1.4   root     2551:                assert(s->io_buffer);
1.1.1.2   root     2552:                if (i == 0)
                   2553:                        s->bs = hd0;
                   2554:                else
                   2555:                        s->bs = hd1;
                   2556:                if (s->bs)
                   2557:                {
                   2558:                        bdrv_get_geometry(s->bs, &nb_sectors);
                   2559:                        s->nb_sectors = nb_sectors;
                   2560:                        /* if a geometry hint is available, use it */
                   2561:                        bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
                   2562:                        translation = bdrv_get_translation_hint(s->bs);
                   2563:                        if (cylinders != 0)
                   2564:                        {
                   2565:                                s->cylinders = cylinders;
                   2566:                                s->heads = heads;
                   2567:                                s->sectors = secs;
                   2568:                        }
                   2569:                        else
                   2570:                        {
                   2571:                                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0)
                   2572:                                {
                   2573:                                        if (heads > 16)
                   2574:                                        {
                   2575:                                                /* if heads > 16, it means that a BIOS LBA
                   2576:                                                   translation was active, so the default
                   2577:                                                   hardware geometry is OK */
                   2578:                                                lba_detected = 1;
                   2579:                                                goto default_geometry;
                   2580:                                        }
                   2581:                                        else
                   2582:                                        {
                   2583:                                                s->cylinders = cylinders;
                   2584:                                                s->heads = heads;
                   2585:                                                s->sectors = secs;
                   2586:                                                /* disable any translation to be in sync with
                   2587:                                                   the logical geometry */
                   2588:                                                if (translation == BIOS_ATA_TRANSLATION_AUTO)
                   2589:                                                {
                   2590:                                                        bdrv_set_translation_hint(s->bs,
                   2591:                                                                                  BIOS_ATA_TRANSLATION_NONE);
                   2592:                                                }
                   2593:                                        }
                   2594:                                }
                   2595:                                else
                   2596:                                {
                   2597: default_geometry:
                   2598:                                        /* if no geometry, use a standard physical disk geometry */
                   2599:                                        cylinders = nb_sectors / (16 * 63);
                   2600:                                        if (cylinders > 16383)
                   2601:                                                cylinders = 16383;
                   2602:                                        else if (cylinders < 2)
                   2603:                                                cylinders = 2;
                   2604:                                        s->cylinders = cylinders;
                   2605:                                        s->heads = 16;
                   2606:                                        s->sectors = 63;
                   2607:                                        if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO))
                   2608:                                        {
                   2609:                                                if ((s->cylinders * s->heads) <= 131072)
                   2610:                                                {
                   2611:                                                        bdrv_set_translation_hint(s->bs,
                   2612:                                                                                  BIOS_ATA_TRANSLATION_LARGE);
                   2613:                                                }
                   2614:                                                else
                   2615:                                                {
                   2616:                                                        bdrv_set_translation_hint(s->bs,
                   2617:                                                                                  BIOS_ATA_TRANSLATION_LBA);
                   2618:                                                }
                   2619:                                        }
                   2620:                                }
                   2621:                                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
                   2622:                        }
                   2623:                        if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM)
                   2624:                        {
                   2625:                                s->is_cdrom = 1;
                   2626:                                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
                   2627:                        }
                   2628:                }
                   2629:                s->drive_serial = drive_serial++;
                   2630: 
                   2631:                ide_reset(s);
                   2632:        }
                   2633: }
                   2634: 
                   2635: 
                   2636: /*----------------------------------------------------------------------------*/
                   2637: 
                   2638: 
                   2639: static BlockDriverState *hd_table[2];
                   2640: 
                   2641: 
                   2642: /**
                   2643:  * Initialize the IDE subsystem
                   2644:  */
                   2645: void Ide_Init(void)
                   2646: {
1.1.1.4   root     2647:        if (!ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1.1.2   root     2648:                return;
                   2649: 
1.1.1.10  root     2650:        opaque_ide_if = calloc(2, sizeof(IDEState));
1.1.1.2   root     2651:        hd_table[0] = malloc(sizeof(BlockDriverState));
                   2652:        hd_table[1] = malloc(sizeof(BlockDriverState));
                   2653: 
1.1.1.4   root     2654:        assert(opaque_ide_if && hd_table[0] && hd_table[1]);
1.1.1.2   root     2655: 
                   2656:        memset(hd_table[0], 0, sizeof(BlockDriverState));
                   2657:        memset(hd_table[1], 0, sizeof(BlockDriverState));
                   2658: 
1.1.1.4   root     2659:        bdrv_open(hd_table[0], ConfigureParams.HardDisk.szIdeMasterHardDiskImage, 0);
1.1.1.9   root     2660:        nIDEPartitions += HDC_PartitionCount(hd_table[0]->fhndl, TRACE_IDE);
1.1.1.2   root     2661: 
1.1.1.4   root     2662:        if (ConfigureParams.HardDisk.bUseIdeSlaveHardDiskImage)
                   2663:        {
                   2664:                bdrv_open(hd_table[1], ConfigureParams.HardDisk.szIdeSlaveHardDiskImage, 0);
1.1.1.9   root     2665:                nIDEPartitions += HDC_PartitionCount(hd_table[1]->fhndl, TRACE_IDE);
1.1.1.4   root     2666: 
                   2667:                ide_init2(&opaque_ide_if[0], hd_table[0], hd_table[1]);
                   2668:        }
                   2669:        else
                   2670:        {
                   2671:                ide_init2(&opaque_ide_if[0], hd_table[0], NULL);
                   2672:        }
1.1.1.2   root     2673: }
                   2674: 
                   2675: 
                   2676: /**
                   2677:  * Free resources from the IDE subsystem
                   2678:  */
                   2679: void Ide_UnInit(void)
                   2680: {
                   2681:        int i;
                   2682: 
                   2683:        for (i = 0; i < 2; i++)
                   2684:        {
                   2685:                if (hd_table[i])
                   2686:                {
                   2687:                        if (bdrv_is_inserted(hd_table[i]))
                   2688:                        {
                   2689:                                bdrv_close(hd_table[i]);
                   2690:                        }
                   2691:                        free(hd_table[i]);
                   2692:                        hd_table[i] = NULL;
                   2693:                }
                   2694:        }
                   2695: 
                   2696:        if (opaque_ide_if)
1.1.1.4   root     2697:        {
                   2698:                for (i = 0; i < 2; i++)
                   2699:                {
                   2700:                        if (opaque_ide_if[i].io_buffer)
                   2701:                        {
                   2702:                                free(opaque_ide_if[i].io_buffer);
                   2703:                                opaque_ide_if[i].io_buffer = NULL;
                   2704:                        }
                   2705:                }
1.1.1.2   root     2706:                free(opaque_ide_if);
1.1.1.4   root     2707:                opaque_ide_if = NULL;
                   2708:        }
1.1.1.9   root     2709: 
                   2710:        nIDEPartitions = 0;
1.1       root     2711: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.