aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSøren Schmidt <sos@FreeBSD.org>2004-08-05 21:13:41 +0000
committerSøren Schmidt <sos@FreeBSD.org>2004-08-05 21:13:41 +0000
commit7e6d75884fac3f1a3298328409ebf22e745e4098 (patch)
treefef880fd3fbfb215f0710bc58da3a5427a75a2d1 /sys
parentd5a9dcbf23b73de991127af79f2f81e688fb7a40 (diff)
downloadsrc-7e6d75884fac3f1a3298328409ebf22e745e4098.tar.gz
src-7e6d75884fac3f1a3298328409ebf22e745e4098.zip
Try to narrow down the race window on HW that does not have ways to
poll for which channel actually pulled the irq line.
Notes
Notes: svn path=/head/; revision=133184
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/ata-all.c14
-rw-r--r--sys/dev/ata/ata-all.h5
-rw-r--r--sys/dev/ata/ata-chipset.c14
-rw-r--r--sys/dev/ata/ata-dma.c6
-rw-r--r--sys/dev/ata/ata-lowlevel.c26
-rw-r--r--sys/dev/ata/ata-pci.c2
-rw-r--r--sys/dev/ata/ata-queue.c28
7 files changed, 46 insertions, 49 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 3028a8890c16..6b87979b8ef6 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -231,7 +231,6 @@ ata_detach(device_t dev)
int
ata_reinit(struct ata_channel *ch)
{
- struct ata_request *request = ch->running;
int devices, misdev, newdev;
if (!ch->r_irq)
@@ -242,10 +241,8 @@ ata_reinit(struct ata_channel *ch)
ata_printf(ch, -1, "reiniting channel ..\n");
ATA_FORCELOCK_CH(ch);
ch->flags |= ATA_IMMEDIATE_MODE;
- ch->running = NULL;
devices = ch->devices;
ch->hw.reset(ch);
- ATA_UNLOCK_CH(ch);
if (bootverbose)
ata_printf(ch, -1, "resetting done ..\n");
@@ -254,10 +251,6 @@ ata_reinit(struct ata_channel *ch)
if ((misdev = devices & ~ch->devices)) {
if ((misdev & (ATA_ATA_MASTER | ATA_ATAPI_MASTER)) &&
ch->device[MASTER].detach) {
- if (request && (request->device == &ch->device[MASTER])) {
- request->result = ENXIO;
- request->retries = 0;
- }
ch->device[MASTER].detach(&ch->device[MASTER]);
ata_fail_requests(ch, &ch->device[MASTER]);
free(ch->device[MASTER].param, M_ATA);
@@ -265,10 +258,6 @@ ata_reinit(struct ata_channel *ch)
}
if ((misdev & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) &&
ch->device[SLAVE].detach) {
- if (request && (request->device == &ch->device[SLAVE])) {
- request->result = ENXIO;
- request->retries = 0;
- }
ch->device[SLAVE].detach(&ch->device[SLAVE]);
ata_fail_requests(ch, &ch->device[SLAVE]);
free(ch->device[SLAVE].param, M_ATA);
@@ -276,6 +265,9 @@ ata_reinit(struct ata_channel *ch)
}
}
+ ch->running = NULL;
+ ATA_UNLOCK_CH(ch);
+
/* identify what is present on the channel now */
ata_identify_devices(ch);
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 7e78c2fb86dd..60698dfae907 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -297,8 +297,9 @@ struct ata_dma {
u_int32_t max_iosize; /* DMA engine max IO size */
u_int32_t cur_iosize; /* DMA engine current IO size */
int flags;
-#define ATA_DMA_ACTIVE 0x01 /* DMA transfer in progress */
-#define ATA_DMA_READ 0x02 /* transaction is a read */
+#define ATA_DMA_READ 0x01 /* transaction is a read */
+#define ATA_DMA_LOADED 0x02 /* DMA tables etc loaded */
+#define ATA_DMA_ACTIVE 0x04 /* DMA transfer in progress */
void (*alloc)(struct ata_channel *ch);
void (*free)(struct ata_channel *ch);
diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c
index 394667c2620a..69ecee52ce1e 100644
--- a/sys/dev/ata/ata-chipset.c
+++ b/sys/dev/ata/ata-chipset.c
@@ -1278,16 +1278,16 @@ ata_promise_chipinit(device_t dev)
break;
case PRMIO:
- if (ctlr->r_res1)
- bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1,ctlr->r_res1);
+// if (ctlr->r_res1)
+// bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1,ctlr->r_res1);
ctlr->r_type1 = SYS_RES_MEMORY;
- ctlr->r_rid1 = 0x20;
+ ctlr->r_rid1 = PCIR_BAR(4);
if (!(ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1,
&ctlr->r_rid1, RF_ACTIVE)))
return ENXIO;
ctlr->r_type2 = SYS_RES_MEMORY;
- ctlr->r_rid2 = 0x1c;
+ ctlr->r_rid2 = PCIR_BAR(3);
if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
&ctlr->r_rid2, RF_ACTIVE)))
return ENXIO;
@@ -1433,12 +1433,14 @@ ata_promise_sx4_intr(void *data)
static int
ata_promise_mio_dmastart(struct ata_channel *ch)
{
+ ch->flags |= ATA_DMA_ACTIVE;
return 0;
}
static int
ata_promise_mio_dmastop(struct ata_channel *ch)
{
+ ch->flags &= ~ATA_DMA_ACTIVE;
/* get status XXX SOS */
return 0;
}
@@ -1777,6 +1779,7 @@ ata_promise_new_dmastart(struct ata_channel *ch)
ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
((ch->dma->flags & ATA_DMA_READ) ? ATA_BMCMD_WRITE_READ : 0) |
ATA_BMCMD_START_STOP);
+ ch->flags |= ATA_DMA_ACTIVE;
return 0;
}
@@ -1795,6 +1798,7 @@ ata_promise_new_dmastop(struct ata_channel *ch)
error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT);
ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
+ ch->flags &= ~ATA_DMA_ACTIVE;
ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
return error;
}
@@ -2057,7 +2061,7 @@ ata_sii_chipinit(device_t dev)
}
ctlr->r_type2 = SYS_RES_MEMORY;
- ctlr->r_rid2 = 0x24;
+ ctlr->r_rid2 = PCIR_BAR(5);
if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
&ctlr->r_rid2, RF_ACTIVE)))
return ENXIO;
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index d140d7d012fe..910ffddca72d 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -265,8 +265,7 @@ ata_dmaload(struct ata_device *atadev, caddr_t data, int32_t count, int dir)
dir ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
ch->dma->cur_iosize = count;
- ch->dma->flags = dir ? (ATA_DMA_ACTIVE | ATA_DMA_READ) : ATA_DMA_ACTIVE;
-
+ ch->dma->flags = dir ? (ATA_DMA_LOADED | ATA_DMA_READ) : ATA_DMA_LOADED;
return 0;
}
@@ -281,7 +280,6 @@ ata_dmaunload(struct ata_channel *ch)
bus_dmamap_unload(ch->dma->ddmatag, ch->dma->ddmamap);
ch->dma->cur_iosize = 0;
- ch->dma->flags = 0;
-
+ ch->dma->flags &= ~ATA_DMA_LOADED;
return 0;
}
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c
index 29a95ad2e5b6..e305085f03e2 100644
--- a/sys/dev/ata/ata-lowlevel.c
+++ b/sys/dev/ata/ata-lowlevel.c
@@ -80,9 +80,6 @@ ata_generic_transaction(struct ata_request *request)
return ATA_OP_FINISHED;
}
- /* record the request as running */
- ch->running = request;
-
ATA_DEBUG_RQ(request, "transaction");
/* disable ATAPI DMA writes if HW doesn't support it */
@@ -120,10 +117,8 @@ ata_generic_transaction(struct ata_request *request)
else
printf("ATAPI_RESET timeout\n");
- if (request->status & ATA_S_ERROR) {
+ if (request->status & ATA_S_ERROR)
request->error = ATA_IDX_INB(ch, ATA_ERROR);
- //request->result = EIO;
- }
break;
}
@@ -139,7 +134,8 @@ ata_generic_transaction(struct ata_request *request)
}
}
- /* return and wait for interrupt */
+ /* record the request as running and return for interrupt */
+ ch->running = request;
return ATA_OP_CONTINUES;
/* ATA DMA data transfer commands */
@@ -168,7 +164,8 @@ ata_generic_transaction(struct ata_request *request)
break;
}
- /* return and wait for interrupt */
+ /* record the request as running and return for interrupt */
+ ch->running = request;
return ATA_OP_CONTINUES;
/* ATAPI PIO commands */
@@ -192,8 +189,10 @@ ata_generic_transaction(struct ata_request *request)
}
/* command interrupt device ? just return and wait for interrupt */
- if ((request->device->param->config & ATA_DRQ_MASK) == ATA_DRQ_INTR)
+ if ((request->device->param->config & ATA_DRQ_MASK) == ATA_DRQ_INTR) {
+ ch->running = request;
return ATA_OP_CONTINUES;
+ }
/* wait for ready to write ATAPI command block */
{
@@ -224,7 +223,8 @@ ata_generic_transaction(struct ata_request *request)
(request->device->param->config & ATA_PROTO_MASK) ==
ATA_PROTO_ATAPI_12 ? 6 : 8);
- /* return and wait for interrupt */
+ /* record the request as running and return for interrupt */
+ ch->running = request;
return ATA_OP_CONTINUES;
case ATA_R_ATAPI|ATA_R_DMA:
@@ -289,14 +289,14 @@ ata_generic_transaction(struct ata_request *request)
break;
}
- /* return and wait for interrupt */
+ /* record the request as running and return for interrupt */
+ ch->running = request;
return ATA_OP_CONTINUES;
}
/* request finish here */
- if (ch->dma->flags & ATA_DMA_ACTIVE)
+ if (ch->dma->flags & ATA_DMA_LOADED)
ch->dma->unload(ch);
- ch->running = NULL;
return ATA_OP_FINISHED;
}
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 16ac6f452cb6..24691488c2ad 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -454,6 +454,7 @@ ata_pci_dmastart(struct ata_channel *ch)
(ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_WRITE_READ) |
((ch->dma->flags & ATA_DMA_READ) ? ATA_BMCMD_WRITE_READ : 0) |
ATA_BMCMD_START_STOP);
+ ch->dma->flags |= ATA_DMA_ACTIVE;
return 0;
}
@@ -465,6 +466,7 @@ ata_pci_dmastop(struct ata_channel *ch)
error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
ATA_IDX_INB(ch, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
+ ch->dma->flags &= ~ATA_DMA_ACTIVE;
ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
return error;
}
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index 8b2b318cfaf6..34edd2dd759e 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -160,15 +160,8 @@ ata_start(struct ata_channel *ch)
if (ch->flags & ATA_IMMEDIATE_MODE)
return;
- /* lock the ATA HW for this request */
- mtx_lock(&ch->queue_mtx);
- ch->locking(ch, ATA_LF_LOCK);
- if (!ATA_LOCK_CH(ch)) {
- mtx_unlock(&ch->queue_mtx);
- return;
- }
-
/* if we dont have any work, ask the subdriver(s) */
+ mtx_lock(&ch->queue_mtx);
if (TAILQ_EMPTY(&ch->ata_queue)) {
mtx_unlock(&ch->queue_mtx);
if (ch->device[MASTER].start)
@@ -177,7 +170,15 @@ ata_start(struct ata_channel *ch)
ch->device[SLAVE].start(&ch->device[SLAVE]);
mtx_lock(&ch->queue_mtx);
}
+
+ /* if we have work todo, try to lock the ATA HW and start transaction */
if ((request = TAILQ_FIRST(&ch->ata_queue))) {
+ ch->locking(ch, ATA_LF_LOCK);
+ if (!ATA_LOCK_CH(ch)) {
+ mtx_unlock(&ch->queue_mtx);
+ return;
+ }
+
TAILQ_REMOVE(&ch->ata_queue, request, chain);
mtx_unlock(&ch->queue_mtx);
@@ -192,15 +193,14 @@ ata_start(struct ata_channel *ch)
/* kick HW into action and wait for interrupt if it flies*/
if (ch->hw.transaction(request) == ATA_OP_CONTINUES)
return;
- }
- /* unlock ATA channel HW */
- ATA_UNLOCK_CH(ch);
- ch->locking(ch, ATA_LF_UNLOCK);
+ /* unlock ATA channel HW */
+ ATA_UNLOCK_CH(ch);
+ ch->locking(ch, ATA_LF_UNLOCK);
- /* if we have a request here it failed and should be completed */
- if (request)
+ /* finish up this (failed) request */
ata_finish(request);
+ }
else
mtx_unlock(&ch->queue_mtx);
}