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

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

unix.superglobalmegacorp.com

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