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

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

unix.superglobalmegacorp.com

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