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