Commit 5457c8ceebafae8d3ff929d22bb32d1edb2250dd
1 parent
0aa6a4a2
added CMD646 PCI IDE controller support - better IRQ handling - added IDE flush …
…cache command - added work around for Darwin/PPC to select IDE drive git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1449 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
165 additions
and
70 deletions
hw/ide.c
... | ... | @@ -296,8 +296,9 @@ typedef struct IDEState { |
296 | 296 | int cylinders, heads, sectors; |
297 | 297 | int64_t nb_sectors; |
298 | 298 | int mult_sectors; |
299 | + SetIRQFunc *set_irq; | |
300 | + void *irq_opaque; | |
299 | 301 | int irq; |
300 | - openpic_t *openpic; | |
301 | 302 | PCIDevice *pci_dev; |
302 | 303 | struct BMDMAState *bmdma; |
303 | 304 | int drive_serial; |
... | ... | @@ -342,6 +343,18 @@ typedef struct IDEState { |
342 | 343 | #define BM_CMD_START 0x01 |
343 | 344 | #define BM_CMD_READ 0x08 |
344 | 345 | |
346 | +#define IDE_TYPE_PIIX3 0 | |
347 | +#define IDE_TYPE_CMD646 1 | |
348 | + | |
349 | +/* CMD646 specific */ | |
350 | +#define MRDMODE 0x71 | |
351 | +#define MRDMODE_INTR_CH0 0x04 | |
352 | +#define MRDMODE_INTR_CH1 0x08 | |
353 | +#define MRDMODE_BLK_CH0 0x10 | |
354 | +#define MRDMODE_BLK_CH1 0x20 | |
355 | +#define UDIDETCR0 0x73 | |
356 | +#define UDIDETCR1 0x7B | |
357 | + | |
345 | 358 | typedef int IDEDMAFunc(IDEState *s, |
346 | 359 | target_phys_addr_t phys_addr, |
347 | 360 | int transfer_size1); |
... | ... | @@ -350,6 +363,8 @@ typedef struct BMDMAState { |
350 | 363 | uint8_t cmd; |
351 | 364 | uint8_t status; |
352 | 365 | uint32_t addr; |
366 | + | |
367 | + struct PCIIDEState *pci_dev; | |
353 | 368 | /* current transfer state */ |
354 | 369 | IDEState *ide_if; |
355 | 370 | IDEDMAFunc *dma_cb; |
... | ... | @@ -359,6 +374,7 @@ typedef struct PCIIDEState { |
359 | 374 | PCIDevice dev; |
360 | 375 | IDEState ide_if[4]; |
361 | 376 | BMDMAState bmdma[2]; |
377 | + int type; /* see IDE_TYPE_xxx */ | |
362 | 378 | } PCIIDEState; |
363 | 379 | |
364 | 380 | static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); |
... | ... | @@ -502,17 +518,10 @@ static inline void ide_set_irq(IDEState *s) |
502 | 518 | { |
503 | 519 | BMDMAState *bm = s->bmdma; |
504 | 520 | if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) { |
505 | - if (bm) | |
521 | + if (bm) { | |
506 | 522 | bm->status |= BM_STATUS_INT; |
507 | -#ifdef TARGET_PPC | |
508 | - if (s->openpic) | |
509 | - openpic_set_irq(s->openpic, s->irq, 1); | |
510 | - else | |
511 | -#endif | |
512 | - if (s->irq == 16) | |
513 | - pci_set_irq(s->pci_dev, 0, 1); | |
514 | - else | |
515 | - pic_set_irq(s->irq, 1); | |
523 | + } | |
524 | + s->set_irq(s->irq_opaque, s->irq, 1); | |
516 | 525 | } |
517 | 526 | } |
518 | 527 | |
... | ... | @@ -814,7 +823,8 @@ static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, |
814 | 823 | case 2352: |
815 | 824 | /* sync bytes */ |
816 | 825 | buf[0] = 0x00; |
817 | - memset(buf + 1, 0xff, 11); | |
826 | + memset(buf + 1, 0xff, 10); | |
827 | + buf[11] = 0x00; | |
818 | 828 | buf += 12; |
819 | 829 | /* MSF */ |
820 | 830 | lba_to_msf(buf, lba); |
... | ... | @@ -942,6 +952,9 @@ static int ide_atapi_cmd_read_dma_cb(IDEState *s, |
942 | 952 | |
943 | 953 | transfer_size = transfer_size1; |
944 | 954 | while (transfer_size > 0) { |
955 | +#ifdef DEBUG_IDE_ATAPI | |
956 | + printf("transfer_size: %d phys_addr=%08x\n", transfer_size, phys_addr); | |
957 | +#endif | |
945 | 958 | if (s->packet_transfer_size <= 0) |
946 | 959 | break; |
947 | 960 | len = s->cd_sector_size - s->io_buffer_index; |
... | ... | @@ -1019,9 +1032,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track) |
1019 | 1032 | *q++ = 0; /* reserved */ |
1020 | 1033 | if (msf) { |
1021 | 1034 | *q++ = 0; /* reserved */ |
1022 | - *q++ = 0; /* minute */ | |
1023 | - *q++ = 2; /* second */ | |
1024 | - *q++ = 0; /* frame */ | |
1035 | + lba_to_msf(q, 0); | |
1036 | + q += 3; | |
1025 | 1037 | } else { |
1026 | 1038 | /* sector 0 */ |
1027 | 1039 | cpu_to_ube32(q, 0); |
... | ... | @@ -1476,6 +1488,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
1476 | 1488 | unit = (val >> 4) & 1; |
1477 | 1489 | s = ide_if + unit; |
1478 | 1490 | ide_if->cur_drive = s; |
1491 | +#ifdef TARGET_PPC | |
1492 | + /* XXX: currently a workaround for Darwin/PPC. Need to check | |
1493 | + the IDE spec to see if it is correct */ | |
1494 | + ide_set_signature(s); | |
1495 | +#endif | |
1479 | 1496 | break; |
1480 | 1497 | default: |
1481 | 1498 | case 7: |
... | ... | @@ -1596,6 +1613,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
1596 | 1613 | break; |
1597 | 1614 | case WIN_STANDBYNOW1: |
1598 | 1615 | case WIN_IDLEIMMEDIATE: |
1616 | + case WIN_FLUSH_CACHE: | |
1599 | 1617 | s->status = READY_STAT; |
1600 | 1618 | ide_set_irq(s); |
1601 | 1619 | break; |
... | ... | @@ -1697,15 +1715,7 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1) |
1697 | 1715 | ret = 0; |
1698 | 1716 | else |
1699 | 1717 | ret = s->status; |
1700 | -#ifdef TARGET_PPC | |
1701 | - if (s->openpic) | |
1702 | - openpic_set_irq(s->openpic, s->irq, 0); | |
1703 | - else | |
1704 | -#endif | |
1705 | - if (s->irq == 16) | |
1706 | - pci_set_irq(s->pci_dev, 0, 0); | |
1707 | - else | |
1708 | - pic_set_irq(s->irq, 0); | |
1718 | + s->set_irq(s->irq_opaque, s->irq, 0); | |
1709 | 1719 | break; |
1710 | 1720 | } |
1711 | 1721 | #ifdef DEBUG_IDE |
... | ... | @@ -1898,8 +1908,9 @@ static int guess_disk_lchs(IDEState *s, |
1898 | 1908 | return -1; |
1899 | 1909 | } |
1900 | 1910 | |
1901 | -static void ide_init2(IDEState *ide_state, int irq, | |
1902 | - BlockDriverState *hd0, BlockDriverState *hd1) | |
1911 | +static void ide_init2(IDEState *ide_state, | |
1912 | + BlockDriverState *hd0, BlockDriverState *hd1, | |
1913 | + SetIRQFunc *set_irq, void *irq_opaque, int irq) | |
1903 | 1914 | { |
1904 | 1915 | IDEState *s; |
1905 | 1916 | static int drive_serial = 1; |
... | ... | @@ -1960,6 +1971,8 @@ static void ide_init2(IDEState *ide_state, int irq, |
1960 | 1971 | } |
1961 | 1972 | } |
1962 | 1973 | s->drive_serial = drive_serial++; |
1974 | + s->set_irq = set_irq; | |
1975 | + s->irq_opaque = irq_opaque; | |
1963 | 1976 | s->irq = irq; |
1964 | 1977 | s->sector_write_timer = qemu_new_timer(vm_clock, |
1965 | 1978 | ide_sector_write_timer_cb, s); |
... | ... | @@ -1995,13 +2008,15 @@ void isa_ide_init(int iobase, int iobase2, int irq, |
1995 | 2008 | if (!ide_state) |
1996 | 2009 | return; |
1997 | 2010 | |
1998 | - ide_init2(ide_state, irq, hd0, hd1); | |
2011 | + ide_init2(ide_state, hd0, hd1, pic_set_irq_new, NULL, irq); | |
1999 | 2012 | ide_init_ioport(ide_state, iobase, iobase2); |
2000 | 2013 | } |
2001 | 2014 | |
2002 | 2015 | /***********************************************************/ |
2003 | 2016 | /* PCI IDE definitions */ |
2004 | 2017 | |
2018 | +static void cmd646_update_irq(PCIIDEState *d); | |
2019 | + | |
2005 | 2020 | static void ide_map(PCIDevice *pci_dev, int region_num, |
2006 | 2021 | uint32_t addr, uint32_t size, int type) |
2007 | 2022 | { |
... | ... | @@ -2082,17 +2097,6 @@ static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb) |
2082 | 2097 | } |
2083 | 2098 | } |
2084 | 2099 | |
2085 | -static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr) | |
2086 | -{ | |
2087 | - BMDMAState *bm = opaque; | |
2088 | - uint32_t val; | |
2089 | - val = bm->cmd; | |
2090 | -#ifdef DEBUG_IDE | |
2091 | - printf("%s: 0x%08x\n", __func__, val); | |
2092 | -#endif | |
2093 | - return val; | |
2094 | -} | |
2095 | - | |
2096 | 2100 | static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) |
2097 | 2101 | { |
2098 | 2102 | BMDMAState *bm = opaque; |
... | ... | @@ -2112,24 +2116,77 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) |
2112 | 2116 | } |
2113 | 2117 | } |
2114 | 2118 | |
2115 | -static uint32_t bmdma_status_readb(void *opaque, uint32_t addr) | |
2119 | +static uint32_t bmdma_readb(void *opaque, uint32_t addr) | |
2116 | 2120 | { |
2117 | 2121 | BMDMAState *bm = opaque; |
2122 | + PCIIDEState *pci_dev; | |
2118 | 2123 | uint32_t val; |
2119 | - val = bm->status; | |
2124 | + | |
2125 | + switch(addr & 3) { | |
2126 | + case 0: | |
2127 | + val = bm->cmd; | |
2128 | + break; | |
2129 | + case 1: | |
2130 | + pci_dev = bm->pci_dev; | |
2131 | + if (pci_dev->type == IDE_TYPE_CMD646) { | |
2132 | + val = pci_dev->dev.config[MRDMODE]; | |
2133 | + } else { | |
2134 | + val = 0xff; | |
2135 | + } | |
2136 | + break; | |
2137 | + case 2: | |
2138 | + val = bm->status; | |
2139 | + break; | |
2140 | + case 3: | |
2141 | + pci_dev = bm->pci_dev; | |
2142 | + if (pci_dev->type == IDE_TYPE_CMD646) { | |
2143 | + if (bm == &pci_dev->bmdma[0]) | |
2144 | + val = pci_dev->dev.config[UDIDETCR0]; | |
2145 | + else | |
2146 | + val = pci_dev->dev.config[UDIDETCR1]; | |
2147 | + } else { | |
2148 | + val = 0xff; | |
2149 | + } | |
2150 | + break; | |
2151 | + default: | |
2152 | + val = 0xff; | |
2153 | + break; | |
2154 | + } | |
2120 | 2155 | #ifdef DEBUG_IDE |
2121 | - printf("%s: 0x%08x\n", __func__, val); | |
2156 | + printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); | |
2122 | 2157 | #endif |
2123 | 2158 | return val; |
2124 | 2159 | } |
2125 | 2160 | |
2126 | -static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val) | |
2161 | +static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) | |
2127 | 2162 | { |
2128 | 2163 | BMDMAState *bm = opaque; |
2164 | + PCIIDEState *pci_dev; | |
2129 | 2165 | #ifdef DEBUG_IDE |
2130 | - printf("%s: 0x%08x\n", __func__, val); | |
2166 | + printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); | |
2131 | 2167 | #endif |
2132 | - bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); | |
2168 | + switch(addr & 3) { | |
2169 | + case 1: | |
2170 | + pci_dev = bm->pci_dev; | |
2171 | + if (pci_dev->type == IDE_TYPE_CMD646) { | |
2172 | + pci_dev->dev.config[MRDMODE] = | |
2173 | + (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30); | |
2174 | + cmd646_update_irq(pci_dev); | |
2175 | + } | |
2176 | + break; | |
2177 | + case 2: | |
2178 | + bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); | |
2179 | + break; | |
2180 | + case 3: | |
2181 | + pci_dev = bm->pci_dev; | |
2182 | + if (pci_dev->type == IDE_TYPE_CMD646) { | |
2183 | + if (bm == &pci_dev->bmdma[0]) | |
2184 | + pci_dev->dev.config[UDIDETCR0] = val; | |
2185 | + else | |
2186 | + pci_dev->dev.config[UDIDETCR1] = val; | |
2187 | + } | |
2188 | + break; | |
2189 | + } | |
2133 | 2190 | } |
2134 | 2191 | |
2135 | 2192 | static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr) |
... | ... | @@ -2162,12 +2219,12 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, |
2162 | 2219 | BMDMAState *bm = &d->bmdma[i]; |
2163 | 2220 | d->ide_if[2 * i].bmdma = bm; |
2164 | 2221 | d->ide_if[2 * i + 1].bmdma = bm; |
2165 | - | |
2222 | + bm->pci_dev = (PCIIDEState *)pci_dev; | |
2223 | + | |
2166 | 2224 | register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); |
2167 | - register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm); | |
2168 | 2225 | |
2169 | - register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm); | |
2170 | - register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm); | |
2226 | + register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); | |
2227 | + register_ioport_read(addr, 4, 1, bmdma_readb, bm); | |
2171 | 2228 | |
2172 | 2229 | register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); |
2173 | 2230 | register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); |
... | ... | @@ -2175,29 +2232,62 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, |
2175 | 2232 | } |
2176 | 2233 | } |
2177 | 2234 | |
2178 | -/* hd_table must contain 4 block drivers */ | |
2179 | -void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) | |
2235 | +/* XXX: call it also when the MRDMODE is changed from the PCI config | |
2236 | + registers */ | |
2237 | +static void cmd646_update_irq(PCIIDEState *d) | |
2238 | +{ | |
2239 | + int pci_level; | |
2240 | + pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) && | |
2241 | + !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) || | |
2242 | + ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) && | |
2243 | + !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1)); | |
2244 | + pci_set_irq((PCIDevice *)d, 0, pci_level); | |
2245 | +} | |
2246 | + | |
2247 | +/* the PCI irq level is the logical OR of the two channels */ | |
2248 | +static void cmd646_set_irq(void *opaque, int channel, int level) | |
2249 | +{ | |
2250 | + PCIIDEState *d = opaque; | |
2251 | + int irq_mask; | |
2252 | + | |
2253 | + irq_mask = MRDMODE_INTR_CH0 << channel; | |
2254 | + if (level) | |
2255 | + d->dev.config[MRDMODE] |= irq_mask; | |
2256 | + else | |
2257 | + d->dev.config[MRDMODE] &= ~irq_mask; | |
2258 | + cmd646_update_irq(d); | |
2259 | +} | |
2260 | + | |
2261 | +/* CMD646 PCI IDE controller */ | |
2262 | +void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table, | |
2263 | + int secondary_ide_enabled) | |
2180 | 2264 | { |
2181 | 2265 | PCIIDEState *d; |
2182 | 2266 | uint8_t *pci_conf; |
2183 | 2267 | int i; |
2184 | 2268 | |
2185 | - d = (PCIIDEState *)pci_register_device(bus, "IDE", sizeof(PCIIDEState), | |
2269 | + d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", | |
2270 | + sizeof(PCIIDEState), | |
2186 | 2271 | -1, |
2187 | 2272 | NULL, NULL); |
2273 | + d->type = IDE_TYPE_CMD646; | |
2188 | 2274 | pci_conf = d->dev.config; |
2189 | - pci_conf[0x00] = 0x86; // Intel | |
2190 | - pci_conf[0x01] = 0x80; | |
2191 | - pci_conf[0x02] = 0x00; // fake | |
2192 | - pci_conf[0x03] = 0x01; // fake | |
2275 | + pci_conf[0x00] = 0x95; // CMD646 | |
2276 | + pci_conf[0x01] = 0x10; | |
2277 | + pci_conf[0x02] = 0x46; | |
2278 | + pci_conf[0x03] = 0x06; | |
2279 | + | |
2280 | + pci_conf[0x08] = 0x07; // IDE controller revision | |
2281 | + pci_conf[0x09] = 0x8f; | |
2282 | + | |
2193 | 2283 | pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE |
2194 | 2284 | pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage |
2195 | - pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic | |
2196 | - | |
2197 | - pci_conf[0x2c] = 0x86; // subsys vendor | |
2198 | - pci_conf[0x2d] = 0x80; // subsys vendor | |
2199 | - pci_conf[0x2e] = 0x00; // fake | |
2200 | - pci_conf[0x2f] = 0x01; // fake | |
2285 | + pci_conf[0x0e] = 0x00; // header_type | |
2286 | + | |
2287 | + if (secondary_ide_enabled) { | |
2288 | + /* XXX: if not enabled, really disable the seconday IDE controller */ | |
2289 | + pci_conf[0x51] = 0x80; /* enable IDE1 */ | |
2290 | + } | |
2201 | 2291 | |
2202 | 2292 | pci_register_io_region((PCIDevice *)d, 0, 0x8, |
2203 | 2293 | PCI_ADDRESS_SPACE_IO, ide_map); |
... | ... | @@ -2211,11 +2301,13 @@ void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) |
2211 | 2301 | PCI_ADDRESS_SPACE_IO, bmdma_map); |
2212 | 2302 | |
2213 | 2303 | pci_conf[0x3d] = 0x01; // interrupt on pin 1 |
2214 | - | |
2304 | + | |
2215 | 2305 | for(i = 0; i < 4; i++) |
2216 | 2306 | d->ide_if[i].pci_dev = (PCIDevice *)d; |
2217 | - ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]); | |
2218 | - ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]); | |
2307 | + ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], | |
2308 | + cmd646_set_irq, d, 0); | |
2309 | + ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], | |
2310 | + cmd646_set_irq, d, 1); | |
2219 | 2311 | } |
2220 | 2312 | |
2221 | 2313 | /* hd_table must contain 4 block drivers */ |
... | ... | @@ -2230,6 +2322,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) |
2230 | 2322 | sizeof(PCIIDEState), |
2231 | 2323 | ((PCIDevice *)piix3_state)->devfn + 1, |
2232 | 2324 | NULL, NULL); |
2325 | + d->type = IDE_TYPE_PIIX3; | |
2326 | + | |
2233 | 2327 | pci_conf = d->dev.config; |
2234 | 2328 | pci_conf[0x00] = 0x86; // Intel |
2235 | 2329 | pci_conf[0x01] = 0x80; |
... | ... | @@ -2242,8 +2336,10 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) |
2242 | 2336 | pci_register_io_region((PCIDevice *)d, 4, 0x10, |
2243 | 2337 | PCI_ADDRESS_SPACE_IO, bmdma_map); |
2244 | 2338 | |
2245 | - ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); | |
2246 | - ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); | |
2339 | + ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], | |
2340 | + pic_set_irq_new, NULL, 14); | |
2341 | + ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], | |
2342 | + pic_set_irq_new, NULL, 15); | |
2247 | 2343 | ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); |
2248 | 2344 | ide_init_ioport(&d->ide_if[2], 0x170, 0x376); |
2249 | 2345 | } |
... | ... | @@ -2361,15 +2457,14 @@ static CPUReadMemoryFunc *pmac_ide_read[] = { |
2361 | 2457 | /* PowerMac uses memory mapped registers, not I/O. Return the memory |
2362 | 2458 | I/O index to access the ide. */ |
2363 | 2459 | int pmac_ide_init (BlockDriverState **hd_table, |
2364 | - openpic_t *openpic, int irq) | |
2460 | + SetIRQFunc *set_irq, void *irq_opaque, int irq) | |
2365 | 2461 | { |
2366 | 2462 | IDEState *ide_if; |
2367 | 2463 | int pmac_ide_memory; |
2368 | 2464 | |
2369 | 2465 | ide_if = qemu_mallocz(sizeof(IDEState) * 2); |
2370 | - ide_init2(&ide_if[0], irq, hd_table[0], hd_table[1]); | |
2371 | - ide_if[0].openpic = openpic; | |
2372 | - ide_if[1].openpic = openpic; | |
2466 | + ide_init2(&ide_if[0], hd_table[0], hd_table[1], | |
2467 | + set_irq, irq_opaque, irq); | |
2373 | 2468 | |
2374 | 2469 | pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, |
2375 | 2470 | pmac_ide_write, &ide_if[0]); | ... | ... |