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