PCI and IRQ rework, pci.c rewritten from ground up, fixes numerous issues such as the bridge being added when the number of normal PCI devices equals the number of normal PCI slots, Windows 95 PCI operation on Intel 430NX, sharing of PCI IRQ's with non-PCI level-triggered devices, having both configuration mechanisms operating at the same time (ALi M1435), etc., and makes the code much more readable.
This commit is contained in:
@@ -42,9 +42,12 @@ typedef struct cmd640_t {
|
||||
uint8_t id;
|
||||
uint8_t in_cfg;
|
||||
uint8_t channels;
|
||||
uint8_t pci, regs[256];
|
||||
uint8_t pci;
|
||||
uint8_t irq_state;
|
||||
uint8_t pci_slot;
|
||||
uint8_t pad0;
|
||||
uint8_t regs[256];
|
||||
uint32_t local;
|
||||
int slot;
|
||||
int irq_mode[2];
|
||||
int irq_pin;
|
||||
int irq_line;
|
||||
@@ -95,12 +98,12 @@ cmd640_set_irq(int channel, void *priv)
|
||||
|
||||
if (irq) {
|
||||
if (dev->irq_mode[channel] == 1)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
|
||||
else
|
||||
picint(1 << (14 + channel));
|
||||
} else {
|
||||
if (dev->irq_mode[channel] == 1)
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
|
||||
else
|
||||
picintc(1 << (14 + channel));
|
||||
}
|
||||
@@ -500,7 +503,10 @@ cmd640_init(const device_t *info)
|
||||
if (info->flags & DEVICE_PCI) {
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
|
||||
if (info->local & 0x80000)
|
||||
pci_add_card(PCI_ADD_NORMAL, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot);
|
||||
else
|
||||
pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
if (dev->channels & 0x01)
|
||||
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
|
||||
|
||||
@@ -41,11 +41,16 @@ typedef struct cmd646_t {
|
||||
uint8_t vlb_idx;
|
||||
uint8_t single_channel;
|
||||
uint8_t in_cfg;
|
||||
uint8_t pci_slot;
|
||||
|
||||
uint8_t regs[256];
|
||||
|
||||
uint32_t local;
|
||||
int slot;
|
||||
int irq_mode[2];
|
||||
|
||||
int irq_pin;
|
||||
|
||||
int irq_mode[2];
|
||||
|
||||
sff8038i_t *bm[2];
|
||||
} cmd646_t;
|
||||
|
||||
@@ -102,6 +107,9 @@ cmd646_ide_handlers(cmd646_t *dev)
|
||||
uint16_t side;
|
||||
int irq_mode[2] = { 0, 0 };
|
||||
|
||||
sff_set_slot(dev->bm[0], dev->pci_slot);
|
||||
sff_set_slot(dev->bm[1], dev->pci_slot);
|
||||
|
||||
ide_pri_disable();
|
||||
|
||||
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
|
||||
@@ -382,7 +390,10 @@ cmd646_init(const device_t *info)
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->slot = pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev);
|
||||
if (info->local & 0x80000)
|
||||
pci_add_card(PCI_ADD_NORMAL, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot);
|
||||
else
|
||||
pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
dev->single_channel = !!(info->local & 0x20000);
|
||||
|
||||
|
||||
@@ -409,31 +409,31 @@ sff_bus_master_set_irq(int channel, void *priv)
|
||||
case 1:
|
||||
/* Native PCI IRQ mode with interrupt pin. */
|
||||
if (irq)
|
||||
pci_set_irq(dev->slot, dev->irq_pin);
|
||||
pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->slot, dev->irq_pin);
|
||||
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
/* MIRQ 0 or 1. */
|
||||
if (irq)
|
||||
pci_set_mirq(dev->irq_mode[channel] & 1, 0);
|
||||
pci_set_mirq(dev->irq_mode[channel] & 1, 0, &dev->irq_state);
|
||||
else
|
||||
pci_clear_mirq(dev->irq_mode[channel] & 1, 0);
|
||||
pci_clear_mirq(dev->irq_mode[channel] & 1, 0, &dev->irq_state);
|
||||
break;
|
||||
case 3:
|
||||
/* Native PCI IRQ mode with specified interrupt line. */
|
||||
if (irq)
|
||||
picintlevel(1 << dev->irq_line);
|
||||
picintlevel(1 << dev->irq_line, &dev->irq_state);
|
||||
else
|
||||
picintc(1 << dev->irq_line);
|
||||
picintclevel(1 << dev->irq_line, &dev->irq_state);
|
||||
break;
|
||||
case 4:
|
||||
/* ALi Aladdin Native PCI INTAJ mode. */
|
||||
if (irq)
|
||||
pci_set_mirq(channel + 2, dev->irq_level[channel]);
|
||||
pci_set_mirq(channel + 2, dev->irq_level[channel], &dev->irq_state);
|
||||
else
|
||||
pci_clear_mirq(channel + 2, dev->irq_level[channel]);
|
||||
pci_clear_mirq(channel + 2, dev->irq_level[channel], &dev->irq_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -456,6 +456,7 @@ sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base)
|
||||
dev->addr = 0x00000000;
|
||||
dev->ptr0 = 0x00;
|
||||
dev->count = dev->eot = 0x00000000;
|
||||
dev->irq_state = 0;
|
||||
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
@@ -570,6 +571,7 @@ sff_init(UNUSED(const device_t *info))
|
||||
dev->irq_pin = PCI_INTA;
|
||||
dev->irq_line = 14;
|
||||
dev->irq_level[0] = dev->irq_level[1] = 0;
|
||||
dev->irq_state = 0;
|
||||
|
||||
next_id++;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user