1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-29 12:03:03 +00:00

Further updates to the Marvell support code.

Should be reliable enough for actual use by now.
This commit is contained in:
Søren Schmidt 2005-12-28 11:55:43 +00:00
parent 086745614c
commit 796bd93e5e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153789

View File

@ -2261,12 +2261,20 @@ ata_marvell_allocate(device_t dev)
return 0;
}
struct ata_marvell_response {
u_int16_t tag;
u_int8_t edma_status;
u_int8_t dev_status;
u_int32_t timestamp;
};
static void
ata_marvell_intr(void *data)
{
struct ata_pci_controller *ctlr = data;
struct ata_channel *ch;
struct ata_request *request;
struct ata_marvell_response *response;
u_int32_t cause, icr0 = 0, icr1 = 0;
int unit;
@ -2318,16 +2326,22 @@ ata_marvell_intr(void *data)
slot = (((rsp_in & ~0xffffff00) >> 3)) & 0x1f;
rsp_out &= 0xffffff00;
rsp_out += (slot << 3);
response = (struct ata_marvell_response *)
(u_int8_t *)(ch->dma->work) + 1024 + (slot << 3);
/* XXX SOS get status and error into request */
request->status = 0; /* XXX SOS */
request->error = 0; /* XXX SOS */
if (!(request->flags & ATA_R_TIMEOUT))
request->donecount = request->bytecount;
/* record status for this request */
request->status = response->dev_status;
request->error = 0;
/* ack response */
ATA_OUTL(ctlr->r_res1, 0x02024 + ATA_MV_EDMA_BASE(ch), rsp_out);
/* update progress */
if (!(request->status & ATA_S_ERROR) &&
!(request->flags & ATA_R_TIMEOUT))
request->donecount = request->bytecount;
/* finish up this request */
ch->running = NULL;
if (ch->state == ATA_ACTIVE)
ch->state = ATA_IDLE;
@ -2412,7 +2426,7 @@ ata_marvell_command(struct ata_request *request)
{
struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
u_int32_t req_in, req_out;
u_int32_t req_in;
u_int8_t *bytep;
u_int16_t *wordp;
u_int32_t *quadp;
@ -2420,7 +2434,6 @@ ata_marvell_command(struct ata_request *request)
int slot;
/* only DMA R/W goes through the EMDA machine */
/* XXX SOS add ATAPI commands support later */
if (request->u.ata.command != ATA_READ_DMA &&
request->u.ata.command != ATA_READ_DMA48 &&
request->u.ata.command != ATA_WRITE_DMA &&
@ -2432,17 +2445,15 @@ ata_marvell_command(struct ata_request *request)
return ata_generic_command(request);
}
req_out = ATA_INL(ctlr->r_res1, 0x02018 + ATA_MV_EDMA_BASE(ch));
/* get next free request queue slot */
req_in = ATA_INL(ctlr->r_res1, 0x02014 + ATA_MV_EDMA_BASE(ch));
slot = (((req_in & ~0xfffffc00) >> 5) + 0) & 0x1f;
bytep = (u_int8_t *)(ch->dma->work);
bytep += (slot << 5);
wordp = (u_int16_t *)bytep;
quadp = (u_int32_t *)bytep;
/* fill in this request */
quadp[0] = (long)ch->dma->sg_bus & 0xffffffff;
quadp[1] = (ch->dma->sg_bus & 0xffffffff00000000) >> 32;
wordp[4] = (request->flags & ATA_R_READ ? 0x01 : 0x00) | (tag<<1);
@ -2481,11 +2492,10 @@ ata_marvell_command(struct ata_request *request)
DELAY(10);
}
/* tell EDMA it has a new request */
slot = (((req_in & ~0xfffffc00) >> 5) + 1) & 0x1f;
req_in &= 0xfffffc00;
req_in += (slot << 5);
/* tell EDMA it has a new request */
ATA_OUTL(ctlr->r_res1, 0x02014 + ATA_MV_EDMA_BASE(ch), req_in);
return 0;
@ -2499,7 +2509,8 @@ ata_marvell_reset(device_t dev)
/* disable the EDMA machinery */
ATA_OUTL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch), 0x00000002);
DELAY(100000); /* SOS should poll for disabled */
while ((ATA_INL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch)) & 0x00000001))
DELAY(10);
/* clear SATA error register */
ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));