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

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

unix.superglobalmegacorp.com

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