mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
Fix the breakage that snatched the ioports from the fdc device.
Fix promise support.
This commit is contained in:
parent
a898bb8d0d
commit
511e9e7251
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=66326
@ -124,7 +124,7 @@ ata_isa_probe(device_t dev)
|
||||
/* alloctate the altport range */
|
||||
if (bus_get_resource(dev, SYS_RES_IOPORT, 1, &tmp, &tmp)) {
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, 1,
|
||||
rman_get_start(port) + ATA_ALTPORT,
|
||||
rman_get_start(port) + ATA_ALTOFFSET,
|
||||
ATA_ALTIOSIZE);
|
||||
}
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
|
||||
@ -172,7 +172,7 @@ ata_pccard_probe(device_t dev)
|
||||
*/
|
||||
if (len <= ATA_IOSIZE) {
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID,
|
||||
rman_get_start(port) + ATA_ALTPORT, ATA_ALTIOSIZE);
|
||||
rman_get_start(port) + ATA_ALTOFFSET, ATA_ALTIOSIZE);
|
||||
}
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
|
||||
scp->unit = device_get_unit(dev);
|
||||
@ -538,7 +538,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
case ATA_ALTADDR_RID:
|
||||
if (masterdev) {
|
||||
myrid = 0;
|
||||
start = (unit == 0 ? IO_WD1 : IO_WD2) + ATA_ALTPORT;
|
||||
start = (unit == 0 ? IO_WD1 : IO_WD2) + ATA_ALTOFFSET;
|
||||
end = start + ATA_ALTIOSIZE - 1;
|
||||
count = ATA_ALTIOSIZE;
|
||||
}
|
||||
@ -787,10 +787,14 @@ ata_probe(device_t dev)
|
||||
rid = ATA_ALTADDR_RID;
|
||||
altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
|
||||
ATA_ALTIOSIZE, RF_ACTIVE);
|
||||
if (altio)
|
||||
altioaddr = rman_get_start(altio);
|
||||
if (altio) {
|
||||
if (pci_get_progif(device_get_parent(dev)) & PCIP_STORAGE_IDE_MASTERDEV)
|
||||
altioaddr = rman_get_start(altio);
|
||||
else
|
||||
altioaddr = rman_get_start(altio) + 0x02;
|
||||
}
|
||||
else
|
||||
altioaddr = ioaddr + ATA_IOSIZE - 2; /* pccard ?? XXX */
|
||||
altioaddr = ioaddr + ATA_IOSIZE;
|
||||
|
||||
rid = ATA_BMADDR_RID;
|
||||
bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
|
||||
@ -969,7 +973,7 @@ ata_getparam(struct ata_softc *scp, int device, u_int8_t command)
|
||||
DELAY(1);
|
||||
|
||||
/* enable interrupt */
|
||||
outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
|
||||
outb(scp->altioaddr, ATA_A_4BIT);
|
||||
DELAY(1);
|
||||
|
||||
/* apparently some devices needs this repeated */
|
||||
@ -1107,7 +1111,7 @@ ata_intr(void *data)
|
||||
DELAY(1);
|
||||
|
||||
/* if drive is busy it didn't interrupt */
|
||||
if (inb(scp->altioaddr + ATA_ALTSTAT) & ATA_S_BUSY)
|
||||
if (inb(scp->altioaddr) & ATA_S_BUSY)
|
||||
return;
|
||||
|
||||
/* clear interrupt and get status */
|
||||
@ -1226,9 +1230,9 @@ ata_reset(struct ata_softc *scp, int *mask)
|
||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
|
||||
DELAY(1);
|
||||
inb(scp->ioaddr + ATA_STATUS);
|
||||
outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_IDS | ATA_A_RESET);
|
||||
outb(scp->altioaddr, ATA_A_IDS | ATA_A_RESET);
|
||||
DELAY(10000);
|
||||
outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_IDS);
|
||||
outb(scp->altioaddr, ATA_A_IDS);
|
||||
DELAY(10000);
|
||||
inb(scp->ioaddr + ATA_ERROR);
|
||||
DELAY(3000);
|
||||
@ -1269,7 +1273,7 @@ ata_reset(struct ata_softc *scp, int *mask)
|
||||
DELAY(100);
|
||||
}
|
||||
DELAY(1);
|
||||
outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
|
||||
outb(scp->altioaddr, ATA_A_4BIT);
|
||||
if (status0 & ATA_S_BUSY)
|
||||
*mask &= ~0x01;
|
||||
if (status1 & ATA_S_BUSY)
|
||||
@ -1368,17 +1372,18 @@ int
|
||||
ata_wait(struct ata_softc *scp, int device, u_int8_t mask)
|
||||
{
|
||||
int timeout = 0;
|
||||
int statio = scp->ioaddr + ATA_STATUS;
|
||||
|
||||
DELAY(1);
|
||||
while (timeout < 5000000) { /* timeout 5 secs */
|
||||
scp->status = inb(scp->altioaddr + ATA_ALTSTAT);
|
||||
scp->status = inb(statio);
|
||||
|
||||
/* if drive fails status, reselect the drive just to be sure */
|
||||
if (scp->status == 0xff) {
|
||||
ata_printf(scp, device, "no status, reselecting device\n");
|
||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
|
||||
DELAY(1);
|
||||
scp->status = inb(scp->altioaddr + ATA_ALTSTAT);
|
||||
scp->status = inb(statio);
|
||||
}
|
||||
|
||||
/* are we done ? */
|
||||
@ -1404,7 +1409,7 @@ ata_wait(struct ata_softc *scp, int device, u_int8_t mask)
|
||||
/* Wait 50 msec for bits wanted. */
|
||||
timeout = 5000;
|
||||
while (timeout--) {
|
||||
scp->status = inb(scp->altioaddr + ATA_ALTSTAT);
|
||||
scp->status = inb(statio);
|
||||
if ((scp->status & mask) == mask) {
|
||||
if (scp->status & ATA_S_ERROR)
|
||||
scp->error = inb(scp->ioaddr + ATA_ERROR);
|
||||
@ -1430,7 +1435,7 @@ ata_command(struct ata_softc *scp, int device, u_int8_t command,
|
||||
|
||||
/* disable interrupt from device */
|
||||
if (scp->flags & ATA_QUEUED)
|
||||
outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_IDS | ATA_A_4BIT);
|
||||
outb(scp->altioaddr, ATA_A_IDS | ATA_A_4BIT);
|
||||
|
||||
/* select device */
|
||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
|
||||
@ -1461,7 +1466,7 @@ ata_command(struct ata_softc *scp, int device, u_int8_t command,
|
||||
|
||||
/* enable interrupt */
|
||||
if (scp->flags & ATA_QUEUED)
|
||||
outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
|
||||
outb(scp->altioaddr, ATA_A_4BIT);
|
||||
|
||||
if (await(PRIBIO, 10 * hz)) {
|
||||
ata_printf(scp, device, "ata_command: timeout waiting for intr\n");
|
||||
@ -1497,7 +1502,7 @@ ata_command(struct ata_softc *scp, int device, u_int8_t command,
|
||||
}
|
||||
/* enable interrupt */
|
||||
if (scp->flags & ATA_QUEUED)
|
||||
outb(scp->altioaddr + ATA_ALTCTRL, ATA_A_4BIT);
|
||||
outb(scp->altioaddr, ATA_A_4BIT);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -74,13 +74,17 @@
|
||||
#define ATA_C_READ_DMA 0xc8 /* read w/DMA command */
|
||||
#define ATA_C_WRITE_DMA 0xca /* write w/DMA command */
|
||||
#define ATA_C_WRITE_DMA_QUEUED 0xcc /* write w/DMA QUEUED command */
|
||||
#define ATA_C_FLUSHCACHE 0xe7 /* flush cache to disk */
|
||||
#define ATA_C_ATA_IDENTIFY 0xec /* get ATA params */
|
||||
#define ATA_C_SETFEATURES 0xef /* features command */
|
||||
#define ATA_C_F_SETXFER 0x03 /* set transfer mode */
|
||||
#define ATA_C_F_ENAB_WCACHE 0x02 /* enable write cache */
|
||||
#define ATA_C_F_ENAB_SRVIRQ 0x5e /* enable service interrupt */
|
||||
#define ATA_C_F_DIS_WCACHE 0x82 /* disable write cache */
|
||||
#define ATA_C_F_ENAB_RCACHE 0xaa /* enable readahead cache */
|
||||
#define ATA_C_F_DIS_RCACHE 0x55 /* disable readahead cache */
|
||||
#define ATA_C_F_ENAB_RELIRQ 0x5d /* enable release interrupt */
|
||||
#define ATA_C_F_DIS_RELIRQ 0xdd /* disable release interrupt */
|
||||
#define ATA_C_F_ENAB_SRVIRQ 0x5e /* enable service interrupt */
|
||||
#define ATA_C_F_DIS_SRVIRQ 0xde /* disable service interrupt */
|
||||
|
||||
#define ATA_STATUS 0x07 /* status register */
|
||||
@ -95,15 +99,12 @@
|
||||
#define ATA_S_READY 0x40 /* drive ready */
|
||||
#define ATA_S_BUSY 0x80 /* busy */
|
||||
|
||||
#define ATA_ALTSTAT 0x02 /* alternate status register */
|
||||
#define ATA_ALTCTRL 0X02 /* alternate device control */
|
||||
#define ATA_ALTOFFSET 0x206 /* alternate registers offset */
|
||||
#define ATA_ALTIOSIZE 0x01 /* alternate registers size */
|
||||
#define ATA_A_IDS 0x02 /* disable interrupts */
|
||||
#define ATA_A_RESET 0x04 /* RESET controller */
|
||||
#define ATA_A_4BIT 0x08 /* 4 head bits */
|
||||
|
||||
#define ATA_ALTPORT 0x204 /* alternate registers offset */
|
||||
#define ATA_ALTIOSIZE 0x01 /* alternate registers size */
|
||||
|
||||
/* misc defines */
|
||||
#define ATA_MASTER 0x00
|
||||
#define ATA_SLAVE 0x10
|
||||
|
@ -1,3 +1,4 @@
|
||||
#define ATA_FLUSHCACHE_ON
|
||||
/*-
|
||||
* Copyright (c) 1998,1999,2000 Søren Schmidt
|
||||
* All rights reserved.
|
||||
@ -316,7 +317,17 @@ ad_start(struct ad_softc *adp)
|
||||
if (!bp)
|
||||
return;
|
||||
|
||||
/* if tagged queueing enabled get free tag */
|
||||
#ifdef ATA_FLUSHCACHE_ON
|
||||
/*
|
||||
* if BIO_ORDERED is set cache should be flushed, if there are
|
||||
* any outstanding requests, hold off and wait for them to finish
|
||||
*/
|
||||
if (adp->flags & AD_F_TAG_ENABLED &&
|
||||
bp->bio_flags & BIO_ORDERED && adp->outstanding > 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* if tagged queueing enabled get next free tag */
|
||||
if (adp->flags & AD_F_TAG_ENABLED) {
|
||||
while (tag <= adp->num_tags && adp->tags[tag])
|
||||
tag++;
|
||||
@ -337,7 +348,8 @@ ad_start(struct ad_softc *adp)
|
||||
request->bytecount = bp->bio_bcount;
|
||||
request->data = bp->bio_data;
|
||||
request->tag = tag;
|
||||
request->flags = (bp->bio_cmd == BIO_READ) ? ADR_F_READ : 0;
|
||||
if (bp->bio_cmd == BIO_READ)
|
||||
request->flags |= ADR_F_READ;
|
||||
if (adp->controller->mode[ATA_DEV(adp->unit)] >= ATA_DMA) {
|
||||
if (!(request->dmatab = ata_dmaalloc(adp->controller, adp->unit)))
|
||||
adp->controller->mode[ATA_DEV(adp->unit)] = ATA_PIO;
|
||||
@ -442,6 +454,8 @@ ad_transfer(struct ad_request *request)
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* wait for data transfer phase
|
||||
*
|
||||
* well this should be here acording to specs, but
|
||||
* promise controllers doesn't like it, they lockup!
|
||||
* thats probably why tags doesn't work on the promise
|
||||
@ -455,12 +469,6 @@ ad_transfer(struct ad_request *request)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* check for possible error from controller */
|
||||
if (adp->controller->status & ATA_S_ERROR) {
|
||||
printf("ad%d: error executing transfer cmd\n", adp->lun);
|
||||
goto transfer_failed;
|
||||
}
|
||||
|
||||
/* start transfer, return and wait for interrupt */
|
||||
ata_dmastart(adp->controller, adp->unit,
|
||||
request->dmatab, request->flags & ADR_F_READ);
|
||||
@ -534,6 +542,9 @@ ad_interrupt(struct ad_request *request)
|
||||
struct ad_softc *adp = request->device;
|
||||
int dma_stat = 0;
|
||||
|
||||
if (request->flags & ADR_F_FLUSHCACHE)
|
||||
goto finish;
|
||||
|
||||
/* finish DMA transfer */
|
||||
if (request->flags & ADR_F_DMA_USED)
|
||||
dma_stat = ata_dmadone(adp->controller);
|
||||
@ -632,6 +643,18 @@ ad_interrupt(struct ad_request *request)
|
||||
untimeout((timeout_t *)ad_timeout, request, request->timeout_handle);
|
||||
|
||||
request->bp->bio_resid = request->bytecount;
|
||||
|
||||
#ifdef ATA_FLUSHCACHE_ON
|
||||
if (request->bp->bio_flags & BIO_ORDERED) {
|
||||
request->flags |= ADR_F_FLUSHCACHE;
|
||||
if (ata_command(adp->controller, adp->unit, ATA_C_FLUSHCACHE,
|
||||
0, 0, 0, 0, 0, ATA_IMMEDIATE))
|
||||
printf("ad%d: flushing cache failed\n", adp->lun);
|
||||
else
|
||||
return ATA_OP_CONTINUES;
|
||||
}
|
||||
#endif
|
||||
finish:
|
||||
devstat_end_transaction_bio(&adp->stats, request->bp);
|
||||
biodone(request->bp);
|
||||
ad_free(request);
|
||||
@ -670,10 +693,11 @@ ad_service(struct ad_softc *adp, int change)
|
||||
DELAY(1);
|
||||
}
|
||||
}
|
||||
adp->controller->status = inb(adp->controller->altioaddr + ATA_ALTSTAT);
|
||||
adp->controller->status = inb(adp->controller->altioaddr);
|
||||
|
||||
/* do we have a SERVICE request from the drive ? */
|
||||
if (adp->flags & AD_F_TAG_ENABLED &&
|
||||
adp->outstanding > 0 &&
|
||||
adp->controller->status & ATA_S_SERVICE) {
|
||||
struct ad_request *request;
|
||||
int tag;
|
||||
|
@ -43,6 +43,7 @@ struct ad_request {
|
||||
#define ADR_F_DMA_USED 0x0004
|
||||
#define ADR_F_QUEUED 0x0008
|
||||
#define ADR_F_FORCE_PIO 0x0010
|
||||
#define ADR_F_FLUSHCACHE 0x0020
|
||||
|
||||
caddr_t data; /* pointer to data buf */
|
||||
struct bio *bp; /* associated bio ptr */
|
||||
|
@ -524,7 +524,7 @@ ata_dmainit(struct ata_softc *scp, int device,
|
||||
(device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
|
||||
break;
|
||||
|
||||
if (udmamode >=5 &&
|
||||
if (udmamode >= 5 &&
|
||||
(scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) &&
|
||||
!(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
@ -539,7 +539,7 @@ ata_dmainit(struct ata_softc *scp, int device,
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (udmamode >=4 && (scp->chiptype == 0x4d38105a ||
|
||||
if (udmamode >= 4 && (scp->chiptype == 0x4d38105a ||
|
||||
scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) &&
|
||||
!(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
|
Loading…
Reference in New Issue
Block a user