296 |
int cylinders, heads, sectors; |
int cylinders, heads, sectors; |
297 |
int64_t nb_sectors; |
int64_t nb_sectors; |
298 |
int mult_sectors; |
int mult_sectors; |
299 |
|
SetIRQFunc *set_irq; |
300 |
|
void *irq_opaque; |
301 |
int irq; |
int irq; |
|
openpic_t *openpic; |
|
302 |
PCIDevice *pci_dev; |
PCIDevice *pci_dev; |
303 |
struct BMDMAState *bmdma; |
struct BMDMAState *bmdma; |
304 |
int drive_serial; |
int drive_serial; |
343 |
#define BM_CMD_START 0x01 |
#define BM_CMD_START 0x01 |
344 |
#define BM_CMD_READ 0x08 |
#define BM_CMD_READ 0x08 |
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 |
|
|
358 |
typedef int IDEDMAFunc(IDEState *s, |
typedef int IDEDMAFunc(IDEState *s, |
359 |
target_phys_addr_t phys_addr, |
target_phys_addr_t phys_addr, |
360 |
int transfer_size1); |
int transfer_size1); |
363 |
uint8_t cmd; |
uint8_t cmd; |
364 |
uint8_t status; |
uint8_t status; |
365 |
uint32_t addr; |
uint32_t addr; |
366 |
|
|
367 |
|
struct PCIIDEState *pci_dev; |
368 |
/* current transfer state */ |
/* current transfer state */ |
369 |
IDEState *ide_if; |
IDEState *ide_if; |
370 |
IDEDMAFunc *dma_cb; |
IDEDMAFunc *dma_cb; |
374 |
PCIDevice dev; |
PCIDevice dev; |
375 |
IDEState ide_if[4]; |
IDEState ide_if[4]; |
376 |
BMDMAState bmdma[2]; |
BMDMAState bmdma[2]; |
377 |
|
int type; /* see IDE_TYPE_xxx */ |
378 |
} PCIIDEState; |
} PCIIDEState; |
379 |
|
|
380 |
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); |
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); |
518 |
{ |
{ |
519 |
BMDMAState *bm = s->bmdma; |
BMDMAState *bm = s->bmdma; |
520 |
if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) { |
if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) { |
521 |
if (bm) |
if (bm) { |
522 |
bm->status |= BM_STATUS_INT; |
bm->status |= BM_STATUS_INT; |
523 |
#ifdef TARGET_PPC |
} |
524 |
if (s->openpic) |
s->set_irq(s->irq_opaque, s->irq, 1); |
|
openpic_set_irq(s->openpic, s->irq, 1); |
|
|
else |
|
|
#endif |
|
|
if (s->irq == 16) |
|
|
pci_set_irq(s->pci_dev, 0, 1); |
|
|
else |
|
|
pic_set_irq(s->irq, 1); |
|
525 |
} |
} |
526 |
} |
} |
527 |
|
|
823 |
case 2352: |
case 2352: |
824 |
/* sync bytes */ |
/* sync bytes */ |
825 |
buf[0] = 0x00; |
buf[0] = 0x00; |
826 |
memset(buf + 1, 0xff, 11); |
memset(buf + 1, 0xff, 10); |
827 |
|
buf[11] = 0x00; |
828 |
buf += 12; |
buf += 12; |
829 |
/* MSF */ |
/* MSF */ |
830 |
lba_to_msf(buf, lba); |
lba_to_msf(buf, lba); |
952 |
|
|
953 |
transfer_size = transfer_size1; |
transfer_size = transfer_size1; |
954 |
while (transfer_size > 0) { |
while (transfer_size > 0) { |
955 |
|
#ifdef DEBUG_IDE_ATAPI |
956 |
|
printf("transfer_size: %d phys_addr=%08x\n", transfer_size, phys_addr); |
957 |
|
#endif |
958 |
if (s->packet_transfer_size <= 0) |
if (s->packet_transfer_size <= 0) |
959 |
break; |
break; |
960 |
len = s->cd_sector_size - s->io_buffer_index; |
len = s->cd_sector_size - s->io_buffer_index; |
1032 |
*q++ = 0; /* reserved */ |
*q++ = 0; /* reserved */ |
1033 |
if (msf) { |
if (msf) { |
1034 |
*q++ = 0; /* reserved */ |
*q++ = 0; /* reserved */ |
1035 |
*q++ = 0; /* minute */ |
lba_to_msf(q, 0); |
1036 |
*q++ = 2; /* second */ |
q += 3; |
|
*q++ = 0; /* frame */ |
|
1037 |
} else { |
} else { |
1038 |
/* sector 0 */ |
/* sector 0 */ |
1039 |
cpu_to_ube32(q, 0); |
cpu_to_ube32(q, 0); |
1488 |
unit = (val >> 4) & 1; |
unit = (val >> 4) & 1; |
1489 |
s = ide_if + unit; |
s = ide_if + unit; |
1490 |
ide_if->cur_drive = s; |
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 |
1496 |
break; |
break; |
1497 |
default: |
default: |
1498 |
case 7: |
case 7: |
1613 |
break; |
break; |
1614 |
case WIN_STANDBYNOW1: |
case WIN_STANDBYNOW1: |
1615 |
case WIN_IDLEIMMEDIATE: |
case WIN_IDLEIMMEDIATE: |
1616 |
|
case WIN_FLUSH_CACHE: |
1617 |
s->status = READY_STAT; |
s->status = READY_STAT; |
1618 |
ide_set_irq(s); |
ide_set_irq(s); |
1619 |
break; |
break; |
1715 |
ret = 0; |
ret = 0; |
1716 |
else |
else |
1717 |
ret = s->status; |
ret = s->status; |
1718 |
#ifdef TARGET_PPC |
s->set_irq(s->irq_opaque, s->irq, 0); |
|
if (s->openpic) |
|
|
openpic_set_irq(s->openpic, s->irq, 0); |
|
|
else |
|
|
#endif |
|
|
if (s->irq == 16) |
|
|
pci_set_irq(s->pci_dev, 0, 0); |
|
|
else |
|
|
pic_set_irq(s->irq, 0); |
|
1719 |
break; |
break; |
1720 |
} |
} |
1721 |
#ifdef DEBUG_IDE |
#ifdef DEBUG_IDE |
1908 |
return -1; |
return -1; |
1909 |
} |
} |
1910 |
|
|
1911 |
static void ide_init2(IDEState *ide_state, int irq, |
static void ide_init2(IDEState *ide_state, |
1912 |
BlockDriverState *hd0, BlockDriverState *hd1) |
BlockDriverState *hd0, BlockDriverState *hd1, |
1913 |
|
SetIRQFunc *set_irq, void *irq_opaque, int irq) |
1914 |
{ |
{ |
1915 |
IDEState *s; |
IDEState *s; |
1916 |
static int drive_serial = 1; |
static int drive_serial = 1; |
1971 |
} |
} |
1972 |
} |
} |
1973 |
s->drive_serial = drive_serial++; |
s->drive_serial = drive_serial++; |
1974 |
|
s->set_irq = set_irq; |
1975 |
|
s->irq_opaque = irq_opaque; |
1976 |
s->irq = irq; |
s->irq = irq; |
1977 |
s->sector_write_timer = qemu_new_timer(vm_clock, |
s->sector_write_timer = qemu_new_timer(vm_clock, |
1978 |
ide_sector_write_timer_cb, s); |
ide_sector_write_timer_cb, s); |
2008 |
if (!ide_state) |
if (!ide_state) |
2009 |
return; |
return; |
2010 |
|
|
2011 |
ide_init2(ide_state, irq, hd0, hd1); |
ide_init2(ide_state, hd0, hd1, pic_set_irq_new, NULL, irq); |
2012 |
ide_init_ioport(ide_state, iobase, iobase2); |
ide_init_ioport(ide_state, iobase, iobase2); |
2013 |
} |
} |
2014 |
|
|
2015 |
/***********************************************************/ |
/***********************************************************/ |
2016 |
/* PCI IDE definitions */ |
/* PCI IDE definitions */ |
2017 |
|
|
2018 |
|
static void cmd646_update_irq(PCIIDEState *d); |
2019 |
|
|
2020 |
static void ide_map(PCIDevice *pci_dev, int region_num, |
static void ide_map(PCIDevice *pci_dev, int region_num, |
2021 |
uint32_t addr, uint32_t size, int type) |
uint32_t addr, uint32_t size, int type) |
2022 |
{ |
{ |
2097 |
} |
} |
2098 |
} |
} |
2099 |
|
|
|
static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr) |
|
|
{ |
|
|
BMDMAState *bm = opaque; |
|
|
uint32_t val; |
|
|
val = bm->cmd; |
|
|
#ifdef DEBUG_IDE |
|
|
printf("%s: 0x%08x\n", __func__, val); |
|
|
#endif |
|
|
return val; |
|
|
} |
|
|
|
|
2100 |
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) |
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) |
2101 |
{ |
{ |
2102 |
BMDMAState *bm = opaque; |
BMDMAState *bm = opaque; |
2116 |
} |
} |
2117 |
} |
} |
2118 |
|
|
2119 |
static uint32_t bmdma_status_readb(void *opaque, uint32_t addr) |
static uint32_t bmdma_readb(void *opaque, uint32_t addr) |
2120 |
{ |
{ |
2121 |
BMDMAState *bm = opaque; |
BMDMAState *bm = opaque; |
2122 |
|
PCIIDEState *pci_dev; |
2123 |
uint32_t val; |
uint32_t val; |
2124 |
val = bm->status; |
|
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 |
|
} |
2155 |
#ifdef DEBUG_IDE |
#ifdef DEBUG_IDE |
2156 |
printf("%s: 0x%08x\n", __func__, val); |
printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); |
2157 |
#endif |
#endif |
2158 |
return val; |
return val; |
2159 |
} |
} |
2160 |
|
|
2161 |
static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val) |
static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) |
2162 |
{ |
{ |
2163 |
BMDMAState *bm = opaque; |
BMDMAState *bm = opaque; |
2164 |
|
PCIIDEState *pci_dev; |
2165 |
#ifdef DEBUG_IDE |
#ifdef DEBUG_IDE |
2166 |
printf("%s: 0x%08x\n", __func__, val); |
printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); |
2167 |
#endif |
#endif |
2168 |
bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); |
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 |
|
} |
2190 |
} |
} |
2191 |
|
|
2192 |
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr) |
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr) |
2219 |
BMDMAState *bm = &d->bmdma[i]; |
BMDMAState *bm = &d->bmdma[i]; |
2220 |
d->ide_if[2 * i].bmdma = bm; |
d->ide_if[2 * i].bmdma = bm; |
2221 |
d->ide_if[2 * i + 1].bmdma = bm; |
d->ide_if[2 * i + 1].bmdma = bm; |
2222 |
|
bm->pci_dev = (PCIIDEState *)pci_dev; |
2223 |
|
|
2224 |
register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); |
register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); |
|
register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm); |
|
2225 |
|
|
2226 |
register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm); |
register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); |
2227 |
register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm); |
register_ioport_read(addr, 4, 1, bmdma_readb, bm); |
2228 |
|
|
2229 |
register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); |
register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm); |
2230 |
register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); |
register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm); |
2232 |
} |
} |
2233 |
} |
} |
2234 |
|
|
2235 |
/* hd_table must contain 4 block drivers */ |
/* XXX: call it also when the MRDMODE is changed from the PCI config |
2236 |
void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) |
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) |
2264 |
{ |
{ |
2265 |
PCIIDEState *d; |
PCIIDEState *d; |
2266 |
uint8_t *pci_conf; |
uint8_t *pci_conf; |
2267 |
int i; |
int i; |
2268 |
|
|
2269 |
d = (PCIIDEState *)pci_register_device(bus, "IDE", sizeof(PCIIDEState), |
d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", |
2270 |
|
sizeof(PCIIDEState), |
2271 |
-1, |
-1, |
2272 |
NULL, NULL); |
NULL, NULL); |
2273 |
|
d->type = IDE_TYPE_CMD646; |
2274 |
pci_conf = d->dev.config; |
pci_conf = d->dev.config; |
2275 |
pci_conf[0x00] = 0x86; // Intel |
pci_conf[0x00] = 0x95; // CMD646 |
2276 |
pci_conf[0x01] = 0x80; |
pci_conf[0x01] = 0x10; |
2277 |
pci_conf[0x02] = 0x00; // fake |
pci_conf[0x02] = 0x46; |
2278 |
pci_conf[0x03] = 0x01; // fake |
pci_conf[0x03] = 0x06; |
2279 |
|
|
2280 |
|
pci_conf[0x08] = 0x07; // IDE controller revision |
2281 |
|
pci_conf[0x09] = 0x8f; |
2282 |
|
|
2283 |
pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE |
pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE |
2284 |
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage |
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage |
2285 |
pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic |
pci_conf[0x0e] = 0x00; // header_type |
2286 |
|
|
2287 |
pci_conf[0x2c] = 0x86; // subsys vendor |
if (secondary_ide_enabled) { |
2288 |
pci_conf[0x2d] = 0x80; // subsys vendor |
/* XXX: if not enabled, really disable the seconday IDE controller */ |
2289 |
pci_conf[0x2e] = 0x00; // fake |
pci_conf[0x51] = 0x80; /* enable IDE1 */ |
2290 |
pci_conf[0x2f] = 0x01; // fake |
} |
2291 |
|
|
2292 |
pci_register_io_region((PCIDevice *)d, 0, 0x8, |
pci_register_io_region((PCIDevice *)d, 0, 0x8, |
2293 |
PCI_ADDRESS_SPACE_IO, ide_map); |
PCI_ADDRESS_SPACE_IO, ide_map); |
2301 |
PCI_ADDRESS_SPACE_IO, bmdma_map); |
PCI_ADDRESS_SPACE_IO, bmdma_map); |
2302 |
|
|
2303 |
pci_conf[0x3d] = 0x01; // interrupt on pin 1 |
pci_conf[0x3d] = 0x01; // interrupt on pin 1 |
2304 |
|
|
2305 |
for(i = 0; i < 4; i++) |
for(i = 0; i < 4; i++) |
2306 |
d->ide_if[i].pci_dev = (PCIDevice *)d; |
d->ide_if[i].pci_dev = (PCIDevice *)d; |
2307 |
ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]); |
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], |
2308 |
ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]); |
cmd646_set_irq, d, 0); |
2309 |
|
ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], |
2310 |
|
cmd646_set_irq, d, 1); |
2311 |
} |
} |
2312 |
|
|
2313 |
/* hd_table must contain 4 block drivers */ |
/* hd_table must contain 4 block drivers */ |
2322 |
sizeof(PCIIDEState), |
sizeof(PCIIDEState), |
2323 |
((PCIDevice *)piix3_state)->devfn + 1, |
((PCIDevice *)piix3_state)->devfn + 1, |
2324 |
NULL, NULL); |
NULL, NULL); |
2325 |
|
d->type = IDE_TYPE_PIIX3; |
2326 |
|
|
2327 |
pci_conf = d->dev.config; |
pci_conf = d->dev.config; |
2328 |
pci_conf[0x00] = 0x86; // Intel |
pci_conf[0x00] = 0x86; // Intel |
2329 |
pci_conf[0x01] = 0x80; |
pci_conf[0x01] = 0x80; |
2336 |
pci_register_io_region((PCIDevice *)d, 4, 0x10, |
pci_register_io_region((PCIDevice *)d, 4, 0x10, |
2337 |
PCI_ADDRESS_SPACE_IO, bmdma_map); |
PCI_ADDRESS_SPACE_IO, bmdma_map); |
2338 |
|
|
2339 |
ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); |
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], |
2340 |
ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); |
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); |
2343 |
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); |
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); |
2344 |
ide_init_ioport(&d->ide_if[2], 0x170, 0x376); |
ide_init_ioport(&d->ide_if[2], 0x170, 0x376); |
2345 |
} |
} |
2457 |
/* PowerMac uses memory mapped registers, not I/O. Return the memory |
/* PowerMac uses memory mapped registers, not I/O. Return the memory |
2458 |
I/O index to access the ide. */ |
I/O index to access the ide. */ |
2459 |
int pmac_ide_init (BlockDriverState **hd_table, |
int pmac_ide_init (BlockDriverState **hd_table, |
2460 |
openpic_t *openpic, int irq) |
SetIRQFunc *set_irq, void *irq_opaque, int irq) |
2461 |
{ |
{ |
2462 |
IDEState *ide_if; |
IDEState *ide_if; |
2463 |
int pmac_ide_memory; |
int pmac_ide_memory; |
2464 |
|
|
2465 |
ide_if = qemu_mallocz(sizeof(IDEState) * 2); |
ide_if = qemu_mallocz(sizeof(IDEState) * 2); |
2466 |
ide_init2(&ide_if[0], irq, hd_table[0], hd_table[1]); |
ide_init2(&ide_if[0], hd_table[0], hd_table[1], |
2467 |
ide_if[0].openpic = openpic; |
set_irq, irq_opaque, irq); |
|
ide_if[1].openpic = openpic; |
|
2468 |
|
|
2469 |
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, |
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, |
2470 |
pmac_ide_write, &ide_if[0]); |
pmac_ide_write, &ide_if[0]); |