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

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

unix.superglobalmegacorp.com

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