Assorted IDE fixes and the PCI IDE bus master now also resets ATAPI hard disks.
This commit is contained in:
@@ -1172,8 +1172,6 @@ piix_read(int func, int addr, void *priv)
|
|||||||
if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
|
if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
|
||||||
fregs = (uint8_t *) dev->regs[func];
|
fregs = (uint8_t *) dev->regs[func];
|
||||||
ret = fregs[addr];
|
ret = fregs[addr];
|
||||||
if ((func == 2) && (addr == 0xff))
|
|
||||||
ret |= 0xef;
|
|
||||||
|
|
||||||
piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr);
|
piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr);
|
||||||
}
|
}
|
||||||
|
@@ -336,7 +336,7 @@ ide_atapi_get_period(uint8_t channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_irq_update(ide_board_t *dev)
|
ide_irq_update(ide_board_t *dev, int log)
|
||||||
{
|
{
|
||||||
ide_t *ide;
|
ide_t *ide;
|
||||||
uint8_t set;
|
uint8_t set;
|
||||||
@@ -344,7 +344,10 @@ ide_irq_update(ide_board_t *dev)
|
|||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq);
|
#ifdef ENABLE_IDE_LOG
|
||||||
|
if (log)
|
||||||
|
ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq);
|
||||||
|
#endif
|
||||||
|
|
||||||
ide = ide_drives[dev->cur_dev];
|
ide = ide_drives[dev->cur_dev];
|
||||||
set = !(ide_boards[ide->board]->devctl & 2) && ide->irqstat;
|
set = !(ide_boards[ide->board]->devctl & 2) && ide->irqstat;
|
||||||
@@ -356,32 +359,22 @@ ide_irq_update(ide_board_t *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_irq_raise(ide_t *ide)
|
ide_irq(ide_t *ide, int set, int log)
|
||||||
{
|
{
|
||||||
if (!ide_boards[ide->board])
|
if (!ide_boards[ide->board])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ide_log("IDE %i: IRQ raise\n", ide->channel);
|
#ifdef IDE_MORE_SPECIFIC_LOGS
|
||||||
|
ide_log("IDE %i: IRQ %s\n", set ? "raise" : "lower");
|
||||||
|
#endif
|
||||||
|
|
||||||
ide->irqstat = 1;
|
ide->irqstat = set;
|
||||||
ide->service = 1;
|
|
||||||
|
if (set)
|
||||||
|
ide->service = 1;
|
||||||
|
|
||||||
if (ide->selected)
|
if (ide->selected)
|
||||||
ide_irq_update(ide_boards[ide->board]);
|
ide_irq_update(ide_boards[ide->board], log);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ide_irq_lower(ide_t *ide)
|
|
||||||
{
|
|
||||||
if (!ide_boards[ide->board])
|
|
||||||
return;
|
|
||||||
|
|
||||||
ide_log("IDE %i: IRQ lower\n", ide->channel);
|
|
||||||
|
|
||||||
ide->irqstat = 0;
|
|
||||||
|
|
||||||
if (ide->selected)
|
|
||||||
ide_irq_update(ide_boards[ide->board]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1214,7 +1207,9 @@ ide_writew(uint16_t addr, uint16_t val, void *priv)
|
|||||||
ch = dev->cur_dev;
|
ch = dev->cur_dev;
|
||||||
ide = ide_drives[ch];
|
ide = ide_drives[ch];
|
||||||
|
|
||||||
|
#ifdef IDE_MORE_SPECIFIC_LOGS
|
||||||
ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv);
|
ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv);
|
||||||
|
#endif
|
||||||
|
|
||||||
addr &= 0x7;
|
addr &= 0x7;
|
||||||
|
|
||||||
@@ -1246,7 +1241,9 @@ ide_writel(uint16_t addr, uint32_t val, void *priv)
|
|||||||
ch = dev->cur_dev;
|
ch = dev->cur_dev;
|
||||||
ide = ide_drives[ch];
|
ide = ide_drives[ch];
|
||||||
|
|
||||||
|
#ifdef IDE_MORE_SPECIFIC_LOGS
|
||||||
ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv);
|
ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv);
|
||||||
|
#endif
|
||||||
|
|
||||||
addr &= 0x7;
|
addr &= 0x7;
|
||||||
|
|
||||||
@@ -1361,7 +1358,7 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv)
|
|||||||
old = dev->devctl;
|
old = dev->devctl;
|
||||||
dev->devctl = val;
|
dev->devctl = val;
|
||||||
if (!(val & 0x02) && (old & 0x02))
|
if (!(val & 0x02) && (old & 0x02))
|
||||||
ide_irq_update(ide_boards[ide->board]);
|
ide_irq_update(ide_boards[ide->board], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1429,7 +1426,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
#ifdef WRITE_PARAM_TO_BOTH_DEVICES
|
#ifdef WRITE_PARAM_TO_BOTH_DEVICES
|
||||||
ide_other->tf->cylprecomp = val;
|
ide_other->tf->cylprecomp = val;
|
||||||
#endif
|
#endif
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case 0x2: /* Sector count */
|
case 0x2: /* Sector count */
|
||||||
ide->tf->secount = val;
|
ide->tf->secount = val;
|
||||||
@@ -1439,6 +1436,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
case 0x3: /* Sector */
|
case 0x3: /* Sector */
|
||||||
ide->sector = val;
|
ide->sector = val;
|
||||||
ide->lba_addr = (ide->lba_addr & 0xfffff00) | val;
|
ide->lba_addr = (ide->lba_addr & 0xfffff00) | val;
|
||||||
|
|
||||||
ide_other->sector = val;
|
ide_other->sector = val;
|
||||||
ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val;
|
ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val;
|
||||||
break;
|
break;
|
||||||
@@ -1482,7 +1480,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
|||||||
ide_set_board_callback(ide->board, 0.0);
|
ide_set_board_callback(ide->board, 0.0);
|
||||||
reset = 1;
|
reset = 1;
|
||||||
} else
|
} else
|
||||||
ide_irq_update(ide_boards[ide->board]);
|
ide_irq_update(ide_boards[ide->board], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reset) {
|
if (!reset) {
|
||||||
@@ -1911,7 +1909,7 @@ ide_readb(uint16_t addr, void *priv)
|
|||||||
/* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is
|
/* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is
|
||||||
DF (drive fault). */
|
DF (drive fault). */
|
||||||
case 0x7: /* Status */
|
case 0x7: /* Status */
|
||||||
ide_irq_lower(ide);
|
ide_irq(ide, 0, 0);
|
||||||
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
|
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1969,7 +1967,9 @@ ide_readw(uint16_t addr, void *priv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef IDE_MORE_SPECIFIC_LOGS
|
||||||
ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret);
|
ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2002,7 +2002,9 @@ ide_readl(uint16_t addr, void *priv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef IDE_MORE_SPECIFIC_LOGS
|
||||||
ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret);
|
ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2012,9 +2014,7 @@ ide_board_callback(void *priv)
|
|||||||
ide_board_t *dev = (ide_board_t *) priv;
|
ide_board_t *dev = (ide_board_t *) priv;
|
||||||
ide_t *ide;
|
ide_t *ide;
|
||||||
|
|
||||||
#ifdef ENABLE_IDE_LOG
|
|
||||||
ide_log("ide_board_callback(%i)\n", dev->cur_dev >> 1);
|
ide_log("ide_board_callback(%i)\n", dev->cur_dev >> 1);
|
||||||
#endif
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
ide = dev->ide[i];
|
ide = dev->ide[i];
|
||||||
|
@@ -27,7 +27,9 @@
|
|||||||
#define HAVE_STDARG_H
|
#define HAVE_STDARG_H
|
||||||
#include <86box/86box.h>
|
#include <86box/86box.h>
|
||||||
#include <86box/cdrom.h>
|
#include <86box/cdrom.h>
|
||||||
|
#include <86box/hdd.h>
|
||||||
#include <86box/scsi_device.h>
|
#include <86box/scsi_device.h>
|
||||||
|
#include <86box/scsi_disk.h>
|
||||||
#include <86box/scsi_cdrom.h>
|
#include <86box/scsi_cdrom.h>
|
||||||
#include <86box/dma.h>
|
#include <86box/dma.h>
|
||||||
#include <86box/io.h>
|
#include <86box/io.h>
|
||||||
@@ -389,7 +391,6 @@ sff_bus_master_set_irq(uint8_t status, void *priv)
|
|||||||
{
|
{
|
||||||
sff8038i_t *dev = (sff8038i_t *) priv;
|
sff8038i_t *dev = (sff8038i_t *) priv;
|
||||||
uint8_t irq = !!(status & 0x04);
|
uint8_t irq = !!(status & 0x04);
|
||||||
int irq_shift = 0;
|
|
||||||
|
|
||||||
if (!(dev->status & 0x04) || (status & 0x04))
|
if (!(dev->status & 0x04) || (status & 0x04))
|
||||||
dev->status = (dev->status & ~0x04) | status;
|
dev->status = (dev->status & ~0x04) | status;
|
||||||
@@ -410,16 +411,12 @@ sff_bus_master_set_irq(uint8_t status, void *priv)
|
|||||||
else
|
else
|
||||||
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
|
||||||
break;
|
break;
|
||||||
case IRQ_MODE_MIRQ_0:
|
case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3:
|
||||||
case IRQ_MODE_MIRQ_1:
|
/* MIRQ 0, 1, 2, or 3. */
|
||||||
/* MIRQ 0 or 1. */
|
|
||||||
case IRQ_MODE_MIRQ_2:
|
|
||||||
case IRQ_MODE_MIRQ_3:
|
|
||||||
/* MIRQ 2 or 3. */
|
|
||||||
if (irq)
|
if (irq)
|
||||||
pci_set_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state);
|
pci_set_mirq(dev->irq_mode & 3, 0, &dev->irq_state);
|
||||||
else
|
else
|
||||||
pci_clear_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state);
|
pci_clear_mirq(dev->irq_mode & 3, 0, &dev->irq_state);
|
||||||
break;
|
break;
|
||||||
/* TODO: Redo this as a MIRQ. */
|
/* TODO: Redo this as a MIRQ. */
|
||||||
case IRQ_MODE_PCI_IRQ_LINE:
|
case IRQ_MODE_PCI_IRQ_LINE:
|
||||||
@@ -477,6 +474,10 @@ sff_reset(void *priv)
|
|||||||
sff_log("SFF8038i: Reset\n");
|
sff_log("SFF8038i: Reset\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < HDD_NUM; i++) {
|
||||||
|
if ((hdd[i].bus == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv)
|
||||||
|
scsi_disk_reset((scsi_common_t *) hdd[i].priv);
|
||||||
|
}
|
||||||
for (uint8_t i = 0; i < CDROM_NUM; i++) {
|
for (uint8_t i = 0; i < CDROM_NUM; i++) {
|
||||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
|
||||||
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
|
||||||
@@ -522,21 +523,15 @@ sff_set_irq_mode(sff8038i_t *dev, int irq_mode)
|
|||||||
default:
|
default:
|
||||||
case IRQ_MODE_LEGACY:
|
case IRQ_MODE_LEGACY:
|
||||||
/* Legacy IRQ mode. */
|
/* Legacy IRQ mode. */
|
||||||
sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, 14 + channel);
|
sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, dev->irq_line);
|
||||||
break;
|
break;
|
||||||
case IRQ_MODE_PCI_IRQ_PIN:
|
case IRQ_MODE_PCI_IRQ_PIN:
|
||||||
/* Native PCI IRQ mode with interrupt pin. */
|
/* Native PCI IRQ mode with interrupt pin. */
|
||||||
sff_log("[%08X] Setting IRQ mode to native PCI INT%c\n", dev, 0x40 + dev->irq_pin);
|
sff_log("[%08X] Setting IRQ mode to native PCI INT%c\n", dev, 0x40 + dev->irq_pin);
|
||||||
break;
|
break;
|
||||||
case IRQ_MODE_MIRQ_0:
|
case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3:
|
||||||
case IRQ_MODE_MIRQ_1:
|
/* MIRQ 0, 1, 2, or 3. */
|
||||||
/* MIRQ 0 or 1. */
|
sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, dev->irq_mode & 3);
|
||||||
sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, irq_mode & 1);
|
|
||||||
break;
|
|
||||||
case IRQ_MODE_MIRQ_2:
|
|
||||||
case IRQ_MODE_MIRQ_3:
|
|
||||||
/* MIRQ 0 or 1. */
|
|
||||||
sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, (irq_mode & 1) + 1);
|
|
||||||
break;
|
break;
|
||||||
case IRQ_MODE_PCI_IRQ_LINE:
|
case IRQ_MODE_PCI_IRQ_LINE:
|
||||||
/* Native PCI IRQ mode with specified interrupt line. */
|
/* Native PCI IRQ mode with specified interrupt line. */
|
||||||
|
@@ -179,8 +179,7 @@ extern int ide_qua_enabled;
|
|||||||
|
|
||||||
#ifdef SCSI_DEVICE_H
|
#ifdef SCSI_DEVICE_H
|
||||||
extern ide_t *ide_get_drive(int ch);
|
extern ide_t *ide_get_drive(int ch);
|
||||||
extern void ide_irq_raise(ide_t *ide);
|
extern void ide_irq(ide_t *ide, int set, int log);
|
||||||
extern void ide_irq_lower(ide_t *ide);
|
|
||||||
extern void ide_allocate_buffer(ide_t *dev);
|
extern void ide_allocate_buffer(ide_t *dev);
|
||||||
extern void ide_atapi_attach(ide_t *dev);
|
extern void ide_atapi_attach(ide_t *dev);
|
||||||
#endif
|
#endif
|
||||||
@@ -224,6 +223,9 @@ extern uint8_t ide_read_ali_75(void);
|
|||||||
extern uint8_t ide_read_ali_76(void);
|
extern uint8_t ide_read_ali_76(void);
|
||||||
|
|
||||||
/* Legacy #define's. */
|
/* Legacy #define's. */
|
||||||
|
#define ide_irq_raise(ide) ide_irq(ide, 1, 1)
|
||||||
|
#define ide_irq_lower(ide) ide_irq(ide, 0, 1)
|
||||||
|
|
||||||
#define ide_set_base(board, port) ide_set_base_addr(board, 0, port)
|
#define ide_set_base(board, port) ide_set_base_addr(board, 0, port)
|
||||||
#define ide_set_side(board, port) ide_set_base_addr(board, 1, port)
|
#define ide_set_side(board, port) ide_set_base_addr(board, 1, port)
|
||||||
|
|
||||||
|
@@ -68,6 +68,8 @@ typedef struct scsi_disk_t {
|
|||||||
|
|
||||||
extern scsi_disk_t *scsi_disk[HDD_NUM];
|
extern scsi_disk_t *scsi_disk[HDD_NUM];
|
||||||
|
|
||||||
|
extern void scsi_disk_reset(scsi_common_t *sc);
|
||||||
|
|
||||||
extern void scsi_disk_hard_reset(void);
|
extern void scsi_disk_hard_reset(void);
|
||||||
extern void scsi_disk_close(void);
|
extern void scsi_disk_close(void);
|
||||||
|
|
||||||
|
@@ -128,7 +128,6 @@ static void scsi_disk_command_complete(scsi_disk_t *dev);
|
|||||||
static void scsi_disk_mode_sense_load(scsi_disk_t *dev);
|
static void scsi_disk_mode_sense_load(scsi_disk_t *dev);
|
||||||
|
|
||||||
static void scsi_disk_init(scsi_disk_t *dev);
|
static void scsi_disk_init(scsi_disk_t *dev);
|
||||||
static void scsi_disk_reset(scsi_common_t *sc);
|
|
||||||
|
|
||||||
#ifdef ENABLE_SCSI_DISK_LOG
|
#ifdef ENABLE_SCSI_DISK_LOG
|
||||||
int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG;
|
int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG;
|
||||||
@@ -787,7 +786,7 @@ scsi_disk_rezero(scsi_disk_t *dev)
|
|||||||
scsi_disk_seek(dev, 0);
|
scsi_disk_seek(dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
scsi_disk_reset(scsi_common_t *sc)
|
scsi_disk_reset(scsi_common_t *sc)
|
||||||
{
|
{
|
||||||
scsi_disk_t *dev = (scsi_disk_t *) sc;
|
scsi_disk_t *dev = (scsi_disk_t *) sc;
|
||||||
|
Reference in New Issue
Block a user