CMD640 improvements.
This commit is contained in:
@@ -41,7 +41,7 @@ typedef struct cmd640_t {
|
|||||||
uint8_t vlb_idx;
|
uint8_t vlb_idx;
|
||||||
uint8_t id;
|
uint8_t id;
|
||||||
uint8_t in_cfg;
|
uint8_t in_cfg;
|
||||||
uint8_t single_channel;
|
uint8_t channels;
|
||||||
uint8_t pci, regs[256];
|
uint8_t pci, regs[256];
|
||||||
uint32_t local;
|
uint32_t local;
|
||||||
int slot;
|
int slot;
|
||||||
@@ -89,6 +89,10 @@ cmd640_set_irq(int channel, void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
channel &= 0x01;
|
channel &= 0x01;
|
||||||
|
|
||||||
|
if (!(dev->channels & (1 << channel)))
|
||||||
|
return;
|
||||||
|
|
||||||
if (irq) {
|
if (irq) {
|
||||||
if (dev->irq_mode[channel] == 1)
|
if (dev->irq_mode[channel] == 1)
|
||||||
pci_set_irq(dev->slot, dev->irq_pin);
|
pci_set_irq(dev->slot, dev->irq_pin);
|
||||||
@@ -108,40 +112,41 @@ cmd640_ide_handlers(cmd640_t *dev)
|
|||||||
uint16_t main;
|
uint16_t main;
|
||||||
uint16_t side;
|
uint16_t side;
|
||||||
|
|
||||||
ide_pri_disable();
|
if (dev->channels & 0x01) {
|
||||||
|
ide_pri_disable();
|
||||||
|
|
||||||
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
|
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
|
||||||
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
|
main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8);
|
||||||
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
|
side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2;
|
||||||
} else {
|
} else {
|
||||||
main = 0x1f0;
|
main = 0x1f0;
|
||||||
side = 0x3f6;
|
side = 0x3f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide_set_base(0, main);
|
||||||
|
ide_set_side(0, side);
|
||||||
|
|
||||||
|
if (dev->regs[0x04] & 0x01)
|
||||||
|
ide_pri_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
ide_set_base(0, main);
|
if (dev->channels & 0x02) {
|
||||||
ide_set_side(0, side);
|
ide_sec_disable();
|
||||||
|
|
||||||
if (dev->regs[0x04] & 0x01)
|
if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) {
|
||||||
ide_pri_enable();
|
main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
|
||||||
|
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
|
||||||
|
} else {
|
||||||
|
main = 0x170;
|
||||||
|
side = 0x376;
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->single_channel)
|
ide_set_base(1, main);
|
||||||
return;
|
ide_set_side(1, side);
|
||||||
|
|
||||||
ide_sec_disable();
|
if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
|
||||||
|
ide_sec_enable();
|
||||||
if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) {
|
|
||||||
main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8);
|
|
||||||
side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2;
|
|
||||||
} else {
|
|
||||||
main = 0x170;
|
|
||||||
side = 0x376;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ide_set_base(1, main);
|
|
||||||
ide_set_side(1, side);
|
|
||||||
|
|
||||||
if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08))
|
|
||||||
ide_sec_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -382,8 +387,11 @@ cmd640_reset(void *priv)
|
|||||||
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
mo_reset((scsi_common_t *) mo_drives[i].priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd640_set_irq(0x00, priv);
|
if (dev->channels & 0x01)
|
||||||
cmd640_set_irq(0x01, priv);
|
cmd640_set_irq(0x00, priv);
|
||||||
|
|
||||||
|
if (dev->channels & 0x02)
|
||||||
|
cmd640_set_irq(0x01, priv);
|
||||||
|
|
||||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||||
|
|
||||||
@@ -429,6 +437,8 @@ cmd640_reset(void *priv)
|
|||||||
dev->irq_pin = PCI_INTA;
|
dev->irq_pin = PCI_INTA;
|
||||||
dev->irq_line = 14;
|
dev->irq_line = 14;
|
||||||
} else {
|
} else {
|
||||||
|
dev->regs[0x04] = 0x01; /* To make sure the two channels get enabled. */
|
||||||
|
|
||||||
if ((dev->local & 0xffff) == 0x0078)
|
if ((dev->local & 0xffff) == 0x0078)
|
||||||
dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */
|
dev->regs[0x50] |= 0x20; /* 0 = 178h, 17Ch; 1 = 078h, 07Ch */
|
||||||
|
|
||||||
@@ -461,18 +471,26 @@ cmd640_init(const device_t *info)
|
|||||||
dev->pci = !!(info->flags & DEVICE_PCI);
|
dev->pci = !!(info->flags & DEVICE_PCI);
|
||||||
dev->local = info->local;
|
dev->local = info->local;
|
||||||
|
|
||||||
|
dev->channels = ((info->local & 0x60000) >> 17) & 0x03;
|
||||||
|
|
||||||
if (info->flags & DEVICE_PCI) {
|
if (info->flags & DEVICE_PCI) {
|
||||||
device_add(&ide_pci_2ch_device);
|
device_add(&ide_pci_2ch_device);
|
||||||
|
|
||||||
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
|
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
|
||||||
|
|
||||||
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
|
if (dev->channels & 0x01)
|
||||||
ide_set_bus_master(1, NULL, cmd640_set_irq, dev);
|
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);
|
||||||
|
|
||||||
|
if (dev->channels & 0x02)
|
||||||
|
ide_set_bus_master(1, NULL, cmd640_set_irq, dev);
|
||||||
|
|
||||||
/* The CMD PCI-0640B IDE controller has no DMA capability,
|
/* The CMD PCI-0640B IDE controller has no DMA capability,
|
||||||
so set our devices IDE devices to force ATA-3 (no DMA). */
|
so set our devices IDE devices to force ATA-3 (no DMA). */
|
||||||
ide_board_set_force_ata3(0, 1);
|
if (dev->channels & 0x01)
|
||||||
ide_board_set_force_ata3(1, 1);
|
ide_board_set_force_ata3(0, 1);
|
||||||
|
|
||||||
|
if (dev->channels & 0x02)
|
||||||
|
ide_board_set_force_ata3(1, 1);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ide_pri_disable();
|
ide_pri_disable();
|
||||||
@@ -486,8 +504,6 @@ cmd640_init(const device_t *info)
|
|||||||
dev);
|
dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->single_channel = !!(info->local & 0x20000);
|
|
||||||
|
|
||||||
next_id++;
|
next_id++;
|
||||||
|
|
||||||
cmd640_reset(dev);
|
cmd640_reset(dev);
|
||||||
@@ -499,7 +515,7 @@ const device_t ide_cmd640_vlb_device = {
|
|||||||
.name = "CMD PCI-0640B VLB",
|
.name = "CMD PCI-0640B VLB",
|
||||||
.internal_name = "ide_cmd640_vlb",
|
.internal_name = "ide_cmd640_vlb",
|
||||||
.flags = DEVICE_VLB,
|
.flags = DEVICE_VLB,
|
||||||
.local = 0x0078,
|
.local = 0x60078,
|
||||||
.init = cmd640_init,
|
.init = cmd640_init,
|
||||||
.close = cmd640_close,
|
.close = cmd640_close,
|
||||||
.reset = cmd640_reset,
|
.reset = cmd640_reset,
|
||||||
@@ -513,7 +529,63 @@ const device_t ide_cmd640_vlb_178_device = {
|
|||||||
.name = "CMD PCI-0640B VLB (Port 178h)",
|
.name = "CMD PCI-0640B VLB (Port 178h)",
|
||||||
.internal_name = "ide_cmd640_vlb_178",
|
.internal_name = "ide_cmd640_vlb_178",
|
||||||
.flags = DEVICE_VLB,
|
.flags = DEVICE_VLB,
|
||||||
.local = 0x0178,
|
.local = 0x60178,
|
||||||
|
.init = cmd640_init,
|
||||||
|
.close = cmd640_close,
|
||||||
|
.reset = cmd640_reset,
|
||||||
|
{ .available = NULL },
|
||||||
|
.speed_changed = NULL,
|
||||||
|
.force_redraw = NULL,
|
||||||
|
.config = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const device_t ide_cmd640_vlb_pri_device = {
|
||||||
|
.name = "CMD PCI-0640B VLB",
|
||||||
|
.internal_name = "ide_cmd640_vlb",
|
||||||
|
.flags = DEVICE_VLB,
|
||||||
|
.local = 0x20078,
|
||||||
|
.init = cmd640_init,
|
||||||
|
.close = cmd640_close,
|
||||||
|
.reset = cmd640_reset,
|
||||||
|
{ .available = NULL },
|
||||||
|
.speed_changed = NULL,
|
||||||
|
.force_redraw = NULL,
|
||||||
|
.config = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const device_t ide_cmd640_vlb_pri_178_device = {
|
||||||
|
.name = "CMD PCI-0640B VLB (Port 178h)",
|
||||||
|
.internal_name = "ide_cmd640_vlb_178",
|
||||||
|
.flags = DEVICE_VLB,
|
||||||
|
.local = 0x20178,
|
||||||
|
.init = cmd640_init,
|
||||||
|
.close = cmd640_close,
|
||||||
|
.reset = cmd640_reset,
|
||||||
|
{ .available = NULL },
|
||||||
|
.speed_changed = NULL,
|
||||||
|
.force_redraw = NULL,
|
||||||
|
.config = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const device_t ide_cmd640_vlb_sec_device = {
|
||||||
|
.name = "CMD PCI-0640B VLB",
|
||||||
|
.internal_name = "ide_cmd640_vlb",
|
||||||
|
.flags = DEVICE_VLB,
|
||||||
|
.local = 0x40078,
|
||||||
|
.init = cmd640_init,
|
||||||
|
.close = cmd640_close,
|
||||||
|
.reset = cmd640_reset,
|
||||||
|
{ .available = NULL },
|
||||||
|
.speed_changed = NULL,
|
||||||
|
.force_redraw = NULL,
|
||||||
|
.config = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const device_t ide_cmd640_vlb_sec_178_device = {
|
||||||
|
.name = "CMD PCI-0640B VLB (Port 178h)",
|
||||||
|
.internal_name = "ide_cmd640_vlb_178",
|
||||||
|
.flags = DEVICE_VLB,
|
||||||
|
.local = 0x40178,
|
||||||
.init = cmd640_init,
|
.init = cmd640_init,
|
||||||
.close = cmd640_close,
|
.close = cmd640_close,
|
||||||
.reset = cmd640_reset,
|
.reset = cmd640_reset,
|
||||||
@@ -527,7 +599,7 @@ const device_t ide_cmd640_pci_device = {
|
|||||||
.name = "CMD PCI-0640B PCI",
|
.name = "CMD PCI-0640B PCI",
|
||||||
.internal_name = "ide_cmd640_pci",
|
.internal_name = "ide_cmd640_pci",
|
||||||
.flags = DEVICE_PCI,
|
.flags = DEVICE_PCI,
|
||||||
.local = 0x0a,
|
.local = 0x6000a,
|
||||||
.init = cmd640_init,
|
.init = cmd640_init,
|
||||||
.close = cmd640_close,
|
.close = cmd640_close,
|
||||||
.reset = cmd640_reset,
|
.reset = cmd640_reset,
|
||||||
@@ -541,7 +613,7 @@ const device_t ide_cmd640_pci_legacy_only_device = {
|
|||||||
.name = "CMD PCI-0640B PCI (Legacy Mode Only)",
|
.name = "CMD PCI-0640B PCI (Legacy Mode Only)",
|
||||||
.internal_name = "ide_cmd640_pci_legacy_only",
|
.internal_name = "ide_cmd640_pci_legacy_only",
|
||||||
.flags = DEVICE_PCI,
|
.flags = DEVICE_PCI,
|
||||||
.local = 0x00,
|
.local = 0x60000,
|
||||||
.init = cmd640_init,
|
.init = cmd640_init,
|
||||||
.close = cmd640_close,
|
.close = cmd640_close,
|
||||||
.reset = cmd640_reset,
|
.reset = cmd640_reset,
|
||||||
|
@@ -62,6 +62,10 @@ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */
|
|||||||
|
|
||||||
extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */
|
extern const device_t ide_cmd640_vlb_device; /* CMD PCI-640B VLB */
|
||||||
extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */
|
extern const device_t ide_cmd640_vlb_178_device; /* CMD PCI-640B VLB (Port 178h) */
|
||||||
|
extern const device_t ide_cmd640_vlb_pri_device; /* CMD PCI-640B VLB (Only primary channel) */
|
||||||
|
extern const device_t ide_cmd640_vlb_pri_178_device; /* CMD PCI-640B VLB (Only primary channel) (Port 178h) */
|
||||||
|
extern const device_t ide_cmd640_vlb_sec_device; /* CMD PCI-640B VLB (Only secondary channel) */
|
||||||
|
extern const device_t ide_cmd640_vlb_sec_178_device; /* CMD PCI-640B VLB (Only secondary channel) (Port 178h) */
|
||||||
extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */
|
extern const device_t ide_cmd640_pci_device; /* CMD PCI-640B PCI */
|
||||||
extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */
|
extern const device_t ide_cmd640_pci_legacy_only_device; /* CMD PCI-640B PCI (Legacy Mode Only) */
|
||||||
extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */
|
extern const device_t ide_cmd640_pci_single_channel_device; /* CMD PCI-640B PCI (Only primary channel) */
|
||||||
|
Reference in New Issue
Block a user