Module Name: src
Committed By: jakllsch
Date: Tue Jun 13 00:02:19 UTC 2017
Modified Files:
src/sys/dev/ata [jdolecek-ncq]: TODO.ncq
src/sys/dev/ic [jdolecek-ncq]: siisata.c siisatavar.h
Log Message:
Add NCQ support to siisata(4).
There are still issues that need to be address before I consider this
mergable.
To generate a diff of this commit:
cvs rdiff -u -r1.1.2.13 -r1.1.2.14 src/sys/dev/ata/TODO.ncq
cvs rdiff -u -r1.30.4.14 -r1.30.4.15 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.6 -r1.6.48.1 src/sys/dev/ic/siisatavar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ata/TODO.ncq
diff -u src/sys/dev/ata/TODO.ncq:1.1.2.13 src/sys/dev/ata/TODO.ncq:1.1.2.14
--- src/sys/dev/ata/TODO.ncq:1.1.2.13 Mon Jun 12 23:25:06 2017
+++ src/sys/dev/ata/TODO.ncq Tue Jun 13 00:02:19 2017
@@ -3,7 +3,7 @@ Bugs
test crashdump with ahci
-siisata - fix all 'XXX slot' -- jakllsch has this done but uncommited
+siisata - fix all new XXX and unmergable bits
test crashdump with siisata
Index: src/sys/dev/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.14 src/sys/dev/ic/siisata.c:1.30.4.15
--- src/sys/dev/ic/siisata.c:1.30.4.14 Mon Apr 24 21:19:21 2017
+++ src/sys/dev/ic/siisata.c Tue Jun 13 00:02:19 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.14 2017/04/24 21:19:21 jakllsch Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.15 2017/06/13 00:02:19 jakllsch Exp $ */
/* from ahcisata_core.c */
@@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.14 2017/04/24 21:19:21 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.15 2017/06/13 00:02:19 jakllsch Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -148,7 +148,7 @@ void siisata_killpending(struct ata_driv
void siisata_cmd_start(struct ata_channel *, struct ata_xfer *);
int siisata_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
-void siisata_cmd_done(struct ata_channel *, struct ata_xfer *, int);
+void siisata_cmd_done(struct ata_channel *, struct ata_xfer *);
void siisata_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
void siisata_bio_start(struct ata_channel *, struct ata_xfer *);
@@ -209,7 +209,7 @@ siisata_attach(struct siisata_softc *sc)
SIISATA_DEBUG_PRINT(("%s: %s: GR_GC: 0x%08x\n",
SIISATANAME(sc), __func__, GRREAD(sc, GR_GC)), DEBUG_FUNCS);
- sc->sc_atac.atac_cap = ATAC_CAP_DMA | ATAC_CAP_UDMA;
+ sc->sc_atac.atac_cap = ATAC_CAP_DMA | ATAC_CAP_UDMA | ATAC_CAP_NCQ;
sc->sc_atac.atac_pio_cap = 4;
sc->sc_atac.atac_dma_cap = 2;
sc->sc_atac.atac_udma_cap = 6;
@@ -246,10 +246,7 @@ siisata_enable_port_interrupt(struct ata
{
struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
- /* clear any interrupts */
- (void)PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
- PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff);
- /* and enable CmdErrr+CmdCmpl interrupting */
+ /* enable CmdErrr+CmdCmpl interrupting */
PRWRITE(sc, PRX(chp->ch_channel, PRO_PIES),
PR_PIS_CMDERRR | PR_PIS_CMDCMPL);
}
@@ -263,9 +260,12 @@ siisata_init_port(struct siisata_softc *
schp = &sc->sc_channels[port];
chp = (struct ata_channel *)schp;
- /* come out of reset, 64-bit activation */
+ /*
+ * Come out of reset. Disable no clearing of PR_PIS_CMDCMPL on read
+ * of PR_PSS. Disable 32-bit PRB activation, we use 64-bit activation.
+ */
PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC),
- PR_PC_32BA | PR_PC_PORT_RESET);
+ PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET);
/* initialize port */
siisata_reinit_port(chp);
/* enable CmdErrr+CmdCmpl interrupting */
@@ -473,53 +473,71 @@ siisata_intr_port(struct siisata_channel
struct siisata_softc *sc;
struct ata_channel *chp;
struct ata_xfer *xfer;
- int slot;
+ u_int slot;
uint32_t pss, pis;
uint32_t prbfis;
sc = (struct siisata_softc *)schp->ata_channel.ch_atac;
chp = &schp->ata_channel;
- xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, 0); /* XXX slot */
- slot = SIISATA_NON_NCQ_SLOT;
+
+ /* get slot status, clearing completion interrupt (PR_PIS_CMDCMPL) */
+ pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
+ SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x\n",
+ SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR);
+
+ for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) {
+ if (((schp->sch_active_slots >> slot) & 1) == 0)
+ /* there's nothing executing here, skip */
+ continue;
+ if (((pss >> slot) & 1) != 0)
+ /* execution is incomplete or unsuccessful, skip for now */
+ continue;
+ xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, slot);
+ if (xfer->c_intr == NULL) {
+ wakeup(schp);
+ continue;
+ }
+ KASSERT(xfer != NULL);
+ KASSERT(xfer->c_intr != NULL);
+ xfer->c_intr(chp, xfer, 0);
+ }
+ /* if no errors, we're done now */
+ if ((pss & PR_PSS_ATTENTION) == 0) {
+ pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
+ pis &= 0xffff;
+ if (pis) {
+ PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS),
+ pis & 0xfffcfffc);
+ }
+ return;
+ }
pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc),
__func__, chp->ch_channel, pis), DEBUG_INTR);
- if (pis & PR_PIS_CMDCMPL) {
- /* get slot status, clearing completion interrupt */
- pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
- SIISATA_DEBUG_PRINT(("pss 0x%x\n", pss), DEBUG_INTR);
- /* is this expected? */
- /* XXX improve */
- if ((schp->sch_active_slots & __BIT(slot)) == 0) {
- aprint_error( "%s: unexpected command "
- "completion on port %d\n",
- SIISATANAME(sc), chp->ch_channel);
- return;
- }
- if ((~pss & __BIT(slot)) == 0) {
- aprint_error( "%s: unknown slot "
- "completion on port %d, pss 0x%x\n",
- SIISATANAME(sc), chp->ch_channel, pss);
- return;
- }
- } else if (pis & PR_PIS_CMDERRR) {
+ if (pis & PR_PIS_CMDERRR) {
uint32_t ec;
+ uint32_t ps;
+
+ ps = PRREAD(sc, PRX(chp->ch_channel, PRO_PS));
+ ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE));
+ SIISATA_DEBUG_PRINT(("ec %d\n", ec), DEBUG_INTR);
+
+ slot = PR_PS_ACTIVE_SLOT(ps); /* XXX invalid for NCQ? */
/* emulate a CRC error by default */
chp->ch_status = WDCS_ERR;
chp->ch_error = WDCE_CRC;
- ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE));
- SIISATA_DEBUG_PRINT(("ec %d\n", ec), DEBUG_INTR);
if (ec <= PR_PCE_DATAFISERROR) {
- if (ec == PR_PCE_DEVICEERROR && xfer != NULL) {
+ if (ec == PR_PCE_DEVICEERROR) {
/* read in specific information about error */
prbfis = bus_space_read_stream_4(
sc->sc_prt, sc->sc_prh,
- PRSX(chp->ch_channel, slot, PRSO_FIS));
+ PRSX(chp->ch_channel, slot,
+ PRSO_FIS));
/* set ch_status and ch_error */
satafis_rdh_parse(chp, (uint8_t *)&prbfis);
}
@@ -532,12 +550,19 @@ siisata_intr_port(struct siisata_channel
/* okay, we have a "Fatal Error" */
siisata_device_reset(chp);
}
+ for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) {
+ /* there's nothing executing here, skip */
+ if (((schp->sch_active_slots >> slot) & 1) == 0)
+ continue;
+ xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, slot);
+ if (xfer == NULL)
+ continue;
+ xfer->c_intr(chp, xfer, 0);
+ }
}
- /* clear some (ok, all) ints */
- PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff);
- if (xfer && xfer->c_intr)
- xfer->c_intr(chp, xfer, 0);
+ /* clear */
+ PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis);
return;
}
@@ -549,49 +574,80 @@ siisata_reset_drive(struct ata_drive_dat
struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
struct siisata_channel *schp = (struct siisata_channel *)chp;
struct siisata_prb *prb;
- int slot = SIISATA_NON_NCQ_SLOT;
+ struct ata_xfer *xfer;
+ uint32_t pss, pis;
int i;
/* wait for ready */
while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY))
DELAY(10);
- prb = schp->sch_prb[slot];
+ xfer = ata_get_xfer(chp); /* Is this right? What if the slots are full? */
+ if (xfer == NULL)
+ return;
+
+ prb = schp->sch_prb[xfer->c_slot];
memset(prb, 0, SIISATA_CMD_SIZE);
prb->prb_control =
- htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK);
+ htole16(PRB_CF_SOFT_RESET /* | PRB_CF_INTERRUPT_MASK */);
KASSERT(drvp->drive <= PMP_PORT_CTL);
prb->prb_fis[rhd_c] = drvp->drive;
- siisata_activate_prb(schp, slot);
+ ata_activate_xfer(chp, xfer);
+ siisata_activate_prb(schp, xfer->c_slot);
for(i = 0; i < 3100; i++) {
- if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) &
- PR_PXSS(slot)) == 0)
+#if 0 /* XXX-jak-jd-ncq this block needs re-work... XXX */
+ PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), PR_PC_INCOR);
+ pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
+ PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), PR_PC_INCOR);
+ if ((pss & PR_PXSS(xfer->c_slot)) == 0)
+ break;
+ if (pss & PR_PSS_ATTENTION)
break;
- if (flags & AT_WAIT)
+#else
+ pss = PR_PXSS(xfer->c_slot);
+ /* XXX DO NOT MERGE UNTIL THIS IS FIXED XXX */
+#endif
+ if ((flags & AT_POLL) == 0)
tsleep(schp, PRIBIO, "siiprb", mstohz(10));
else
DELAY(10000);
}
- siisata_deactivate_prb(schp, slot);
+ siisata_deactivate_prb(schp, xfer->c_slot);
+
+ if ((pss & PR_PSS_ATTENTION) != 0) {
+ pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
+ const uint32_t ps = PRREAD(sc, PRX(chp->ch_channel, PRO_PS));
+ const u_int slot = PR_PS_ACTIVE_SLOT(ps);
+ if (slot != xfer->c_slot)
+ device_printf(sc->sc_atac.atac_dev, "%s port %d "
+ "drive %d slot %d c_slot %d", __func__,
+ chp->ch_channel, drvp->drive, slot, xfer->c_slot);
+ PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis &
+ PR_PIS_CMDERRR);
+ }
+
if (i == 3100) {
/* timeout */
- siisata_device_reset(chp);
+ siisata_device_reset(chp); /* XXX is this right? */
if (sigp)
*sigp = 0xffffffff;
} else {
/* read the signature out of the FIS */
if (sigp) {
*sigp = 0;
- *sigp |= (PRREAD(sc, PRSX(chp->ch_channel, slot,
+ *sigp |= (PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot,
PRSO_FIS+0x4)) & 0x00ffffff) << 8;
- *sigp |= PRREAD(sc, PRSX(chp->ch_channel, slot,
+ *sigp |= PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot,
PRSO_FIS+0xc)) & 0xff;
}
}
+ ata_deactivate_xfer(chp, xfer);
+ ata_free_xfer(chp, xfer);
+
#if 1
/* attempt to downgrade signaling in event of CRC error */
/* XXX should be part of the MI (S)ATA subsystem */
@@ -624,8 +680,8 @@ siisata_reset_channel(struct ata_channel
struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
struct siisata_channel *schp = (struct siisata_channel *)chp;
- SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__),
- DEBUG_FUNCS);
+ SIISATA_DEBUG_PRINT(("%s: %s channel %d\n", SIISATANAME(sc), __func__,
+ chp->ch_channel), DEBUG_FUNCS);
if (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol,
schp->sch_sstatus, flags) != SStatus_DET_DEV) {
@@ -668,9 +724,9 @@ siisata_probe_drive(struct ata_channel *
struct siisata_channel *schp = (struct siisata_channel *)chp;
int i;
uint32_t sig;
- int slot = SIISATA_NON_NCQ_SLOT;
struct siisata_prb *prb;
bool timed_out;
+ const u_int slot0 = 0; /* XXX this is a problem */
SIISATA_DEBUG_PRINT(("%s: %s: port %d start\n", SIISATANAME(sc),
__func__, chp->ch_channel), DEBUG_FUNCS);
@@ -684,24 +740,27 @@ siisata_probe_drive(struct ata_channel *
switch(sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol,
schp->sch_sstatus, AT_WAIT)) {
case SStatus_DET_DEV:
+#if 0 /* XXX Including this seems to cause problems. */
+ /* XXX DO NOT MERGE UNTIL THIS IS ADDRESSED PROPERLY XXX */
/* clear any interrupts */
(void)PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff);
+#endif
/* wait for ready */
while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS))
& PR_PS_PORT_READY))
DELAY(10);
- prb = schp->sch_prb[slot];
+ prb = schp->sch_prb[slot0];
memset(prb, 0, SIISATA_CMD_SIZE);
prb->prb_control = htole16(PRB_CF_SOFT_RESET);
prb->prb_fis[rhd_c] = PMP_PORT_CTL;
- siisata_activate_prb(schp, slot);
+ siisata_activate_prb(schp, slot0);
timed_out = 1;
for(i = 0; i < 3100; i++) {
if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) &
- PR_PXSS(slot)) == 0) {
+ PR_PXSS(slot0)) == 0) {
/* prb completed */
timed_out = 0;
break;
@@ -715,7 +774,7 @@ siisata_probe_drive(struct ata_channel *
tsleep(schp, PRIBIO, "siiprb", mstohz(10));
}
- siisata_deactivate_prb(schp, slot);
+ siisata_deactivate_prb(schp, slot0);
if (timed_out) {
aprint_error_dev(sc->sc_atac.atac_dev,
"SOFT_RESET failed on port %d (error %d PSS 0x%x), "
@@ -728,9 +787,9 @@ siisata_probe_drive(struct ata_channel *
/* read the signature out of the FIS */
sig = 0;
- sig |= (PRREAD(sc, PRSX(chp->ch_channel, slot,
+ sig |= (PRREAD(sc, PRSX(chp->ch_channel, slot0,
PRSO_FIS+0x4)) & 0x00ffffff) << 8;
- sig |= PRREAD(sc, PRSX(chp->ch_channel, slot,
+ sig |= PRREAD(sc, PRSX(chp->ch_channel, slot0,
PRSO_FIS+0xc)) & 0xff;
SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc),
@@ -814,19 +873,18 @@ siisata_cmd_start(struct ata_channel *ch
{
struct siisata_channel *schp = (struct siisata_channel *)chp;
struct ata_command *ata_c = &xfer->c_ata_c;
- int slot = SIISATA_NON_NCQ_SLOT;
struct siisata_prb *prb;
int i;
SIISATA_DEBUG_PRINT(("%s: %s port %d drive %d command 0x%x, slot %d\n",
SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__,
- chp->ch_channel, xfer->c_drive, ata_c->r_command, slot),
+ chp->ch_channel, xfer->c_drive, ata_c->r_command, xfer->c_slot),
DEBUG_FUNCS|DEBUG_XFERS);
chp->ch_status = 0;
chp->ch_error = 0;
- prb = schp->sch_prb[slot];
+ prb = schp->sch_prb[xfer->c_slot];
memset(prb, 0, SIISATA_CMD_SIZE);
satafis_rhd_construct_cmd(ata_c, prb->prb_fis);
@@ -838,7 +896,7 @@ siisata_cmd_start(struct ata_channel *ch
prb->prb_protocol_override |= htole16(PRB_PO_WRITE);
}
- if (siisata_dma_setup(chp, slot,
+ if (siisata_dma_setup(chp, xfer->c_slot,
(ata_c->flags & (AT_READ | AT_WRITE)) ? ata_c->data : NULL,
ata_c->bcount,
(ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
@@ -854,7 +912,7 @@ siisata_cmd_start(struct ata_channel *ch
}
/* go for it */
- siisata_activate_prb(schp, slot);
+ siisata_activate_prb(schp, xfer->c_slot);
if ((ata_c->flags & AT_POLL) == 0) {
chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
@@ -890,9 +948,11 @@ void
siisata_cmd_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer,
int reason)
{
- int slot = SIISATA_NON_NCQ_SLOT;
-
struct ata_command *ata_c = &xfer->c_ata_c;
+ struct siisata_channel *schp = (struct siisata_channel *)chp;
+
+ siisata_deactivate_prb(schp, xfer->c_slot);
+
switch (reason) {
case KILL_GONE:
ata_c->flags |= AT_GONE;
@@ -904,21 +964,25 @@ siisata_cmd_kill_xfer(struct ata_channel
panic("%s: port %d: unknown reason %d",
__func__, chp->ch_channel, reason);
}
- siisata_cmd_done(chp, xfer, slot);
+ siisata_cmd_done(chp, xfer);
}
int
siisata_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is)
{
+ struct siisata_channel *schp = (struct siisata_channel *)chp;
struct ata_command *ata_c = &xfer->c_ata_c;
#ifdef SIISATA_DEBUG
struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
#endif
- int slot = SIISATA_NON_NCQ_SLOT;
+ SIISATA_DEBUG_PRINT(("%s: %s: port %d slot %d\n",
+ SIISATANAME(sc), __func__,
+ chp->ch_channel, xfer->c_slot), DEBUG_FUNCS);
SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__),
DEBUG_FUNCS|DEBUG_XFERS);
+ siisata_deactivate_prb(schp, xfer->c_slot);
chp->ch_flags &= ~ATACH_IRQ_WAIT;
if (xfer->c_flags & C_TIMEOU)
ata_c->flags |= AT_TIMEOU;
@@ -935,14 +999,14 @@ siisata_cmd_complete(struct ata_channel
ata_deactivate_xfer(chp, xfer);
if (!ata_waitdrain_xfer_check(chp, xfer)) {
- siisata_cmd_done(chp, xfer, slot);
+ siisata_cmd_done(chp, xfer);
}
return 0;
}
void
-siisata_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer, int slot)
+siisata_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer)
{
uint32_t fis[howmany(RDH_FISLEN,sizeof(uint32_t))];
struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
@@ -954,19 +1018,17 @@ siisata_cmd_done(struct ata_channel *chp
SIISATA_DEBUG_PRINT(("%s: %s flags 0x%x error 0x%x\n", SIISATANAME(sc),
__func__, ata_c->flags, ata_c->r_error), DEBUG_FUNCS|DEBUG_XFERS);
- siisata_deactivate_prb(schp, slot);
-
if (ata_c->flags & (AT_READ | AT_WRITE)) {
- bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0,
- schp->sch_datad[slot]->dm_mapsize,
+ bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[xfer->c_slot], 0,
+ schp->sch_datad[xfer->c_slot]->dm_mapsize,
(ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]);
+ bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[xfer->c_slot]);
}
if (ata_c->flags & AT_READREG) {
bus_space_read_region_stream_4(sc->sc_prt, sc->sc_prh,
- PRSX(chp->ch_channel, slot, PRSO_FIS),
+ PRSX(chp->ch_channel, xfer->c_slot, PRSO_FIS),
fis, __arraycount(fis));
satafis_rdh_cmd_readreg(ata_c, (uint8_t *)fis);
}
@@ -981,7 +1043,7 @@ siisata_cmd_done(struct ata_channel *chp
}
ata_c->flags |= AT_DONE;
- if (PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC)))
+ if (PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot, PRSO_RTC)))
ata_c->flags |= AT_XFDONE;
if (ata_c->flags & AT_WAIT)
@@ -1023,24 +1085,23 @@ siisata_bio_start(struct ata_channel *ch
struct siisata_channel *schp = (struct siisata_channel *)chp;
struct siisata_prb *prb;
struct ata_bio *ata_bio = &xfer->c_bio;
- int slot = SIISATA_NON_NCQ_SLOT;
int i;
- SIISATA_DEBUG_PRINT(("%s: %s port %d, slot %d\n",
+ SIISATA_DEBUG_PRINT(("%s: %s port %d slot %d drive %d\n",
SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__,
- chp->ch_channel, slot), DEBUG_FUNCS);
+ chp->ch_channel, xfer->c_slot, xfer->c_drive), DEBUG_FUNCS);
chp->ch_status = 0;
chp->ch_error = 0;
- prb = schp->sch_prb[slot];
+ prb = schp->sch_prb[xfer->c_slot];
memset(prb, 0, SIISATA_CMD_SIZE);
satafis_rhd_construct_bio(xfer, prb->prb_fis);
KASSERT(xfer->c_drive <= PMP_PORT_CTL);
prb->prb_fis[rhd_c] |= xfer->c_drive;
- if (siisata_dma_setup(chp, slot, ata_bio->databuf, ata_bio->bcount,
+ if (siisata_dma_setup(chp, xfer->c_slot, ata_bio->databuf, ata_bio->bcount,
(ata_bio->flags & ATA_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
ata_bio->error = ERR_DMA;
ata_bio->r_error = 0;
@@ -1054,7 +1115,7 @@ siisata_bio_start(struct ata_channel *ch
siisata_disable_port_interrupt(chp);
}
- siisata_activate_prb(schp, slot);
+ siisata_activate_prb(schp, xfer->c_slot);
if ((ata_bio->flags & ATA_POLL) == 0) {
chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
@@ -1088,13 +1149,12 @@ siisata_bio_kill_xfer(struct ata_channel
struct siisata_channel *schp = (struct siisata_channel *)chp;
struct ata_bio *ata_bio = &xfer->c_bio;
int drive = xfer->c_drive;
- int slot = SIISATA_NON_NCQ_SLOT;
- SIISATA_DEBUG_PRINT(("%s: %s: port %d\n",
+ SIISATA_DEBUG_PRINT(("%s: %s: port %d slot %d\n",
SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__,
- chp->ch_channel), DEBUG_FUNCS);
+ chp->ch_channel, xfer->c_slot), DEBUG_FUNCS);
- siisata_deactivate_prb(schp, slot);
+ siisata_deactivate_prb(schp, xfer->c_slot);
ata_bio->flags |= ATA_ITSDONE;
switch (reason) {
@@ -1119,9 +1179,12 @@ siisata_bio_complete(struct ata_channel
struct siisata_channel *schp = (struct siisata_channel *)chp;
struct ata_bio *ata_bio = &xfer->c_bio;
int drive = xfer->c_drive;
- int slot = SIISATA_NON_NCQ_SLOT;
- schp->sch_active_slots &= ~__BIT(slot);
+ SIISATA_DEBUG_PRINT(("%s: %s: port %d slot %d drive %d\n",
+ SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__,
+ chp->ch_channel, xfer->c_slot, xfer->c_drive), DEBUG_FUNCS);
+
+ siisata_deactivate_prb(schp, xfer->c_slot);
chp->ch_flags &= ~ATACH_IRQ_WAIT;
if (xfer->c_flags & C_TIMEOU) {
ata_bio->error = TIMEOUT;
@@ -1130,11 +1193,11 @@ siisata_bio_complete(struct ata_channel
ata_bio->error = NOERROR;
}
- bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0,
- schp->sch_datad[slot]->dm_mapsize,
+ bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[xfer->c_slot], 0,
+ schp->sch_datad[xfer->c_slot]->dm_mapsize,
(ata_bio->flags & ATA_READ) ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]);
+ bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[xfer->c_slot]);
ata_deactivate_xfer(chp, xfer);
@@ -1156,7 +1219,7 @@ siisata_bio_complete(struct ata_channel
if (ata_bio->error == NOERROR) {
if (ata_bio->flags & ATA_READ)
ata_bio->bcount -=
- PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC));
+ PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot, PRSO_RTC));
else
ata_bio->bcount = 0;
}
@@ -1356,6 +1419,9 @@ siisata_atapi_kill_xfer(struct ata_chann
int reason)
{
struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
+ struct siisata_channel *schp = (struct siisata_channel *)chp;
+
+ siisata_deactivate_prb(schp, xfer->c_slot);
/* remove this command from xfer queue */
switch (reason) {
@@ -1553,8 +1619,6 @@ siisata_atapi_start(struct ata_channel *
struct siisata_prb *prbp;
struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
-
- int slot = SIISATA_NON_NCQ_SLOT;
int i;
SIISATA_DEBUG_PRINT( ("%s: %s:%d:%d, scsi flags 0x%x\n", __func__,
@@ -1565,7 +1629,7 @@ siisata_atapi_start(struct ata_channel *
chp->ch_status = 0;
chp->ch_error = 0;
- prbp = schp->sch_prb[slot];
+ prbp = schp->sch_prb[xfer->c_slot];
memset(prbp, 0, SIISATA_CMD_SIZE);
/* fill in direction for ATAPI command */
@@ -1581,7 +1645,7 @@ siisata_atapi_start(struct ata_channel *
/* copy over ATAPI command */
memcpy(prbp->prb_atapi, sc_xfer->cmd, sc_xfer->cmdlen);
- if (siisata_dma_setup(chp, slot,
+ if (siisata_dma_setup(chp, xfer->c_slot,
(sc_xfer->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) ?
xfer->c_databuf : NULL,
xfer->c_bcount,
@@ -1596,7 +1660,7 @@ siisata_atapi_start(struct ata_channel *
siisata_disable_port_interrupt(chp);
}
- siisata_activate_prb(schp, slot);
+ siisata_activate_prb(schp, xfer->c_slot);
if ((xfer->c_flags & C_POLL) == 0) {
chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
@@ -1633,13 +1697,12 @@ siisata_atapi_complete(struct ata_channe
struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
struct siisata_channel *schp = (struct siisata_channel *)chp;
struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
- int slot = SIISATA_NON_NCQ_SLOT;
SIISATA_DEBUG_PRINT(("%s: %s()\n", SIISATANAME(sc), __func__),
DEBUG_INTR);
/* this command is not active any more */
- schp->sch_active_slots &= ~__BIT(slot);
+ siisata_deactivate_prb(schp, xfer->c_slot);
chp->ch_flags &= ~ATACH_IRQ_WAIT;
if (xfer->c_flags & C_TIMEOU) {
sc_xfer->error = XS_TIMEOUT;
@@ -1648,11 +1711,11 @@ siisata_atapi_complete(struct ata_channe
sc_xfer->error = XS_NOERROR;
}
- bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0,
- schp->sch_datad[slot]->dm_mapsize,
+ bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[xfer->c_slot], 0,
+ schp->sch_datad[xfer->c_slot]->dm_mapsize,
(sc_xfer->xs_control & XS_CTL_DATA_IN) ?
BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]);
+ bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[xfer->c_slot]);
ata_deactivate_xfer(chp, xfer);
@@ -1663,7 +1726,8 @@ siisata_atapi_complete(struct ata_channe
ata_free_xfer(chp, xfer);
sc_xfer->resid = sc_xfer->datalen;
- sc_xfer->resid -= PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC));
+ sc_xfer->resid -= PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot,
+ PRSO_RTC));
SIISATA_DEBUG_PRINT(("%s: %s datalen %d resid %d\n", SIISATANAME(sc),
__func__, sc_xfer->datalen, sc_xfer->resid), DEBUG_XFERS);
if ((chp->ch_status & WDCS_ERR) &&
Index: src/sys/dev/ic/siisatavar.h
diff -u src/sys/dev/ic/siisatavar.h:1.6 src/sys/dev/ic/siisatavar.h:1.6.48.1
--- src/sys/dev/ic/siisatavar.h:1.6 Mon Jul 26 15:41:33 2010
+++ src/sys/dev/ic/siisatavar.h Tue Jun 13 00:02:19 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisatavar.h,v 1.6 2010/07/26 15:41:33 jakllsch Exp $ */
+/* $NetBSD: siisatavar.h,v 1.6.48.1 2017/06/13 00:02:19 jakllsch Exp $ */
/* from ahcisatavar.h */
@@ -114,8 +114,6 @@ struct siisata_softc {
#define SIISATA_PRB_SYNC(sc, schp, slot, op) bus_dmamap_sync((sc)->sc_dmat, \
(schp)->sch_prbd, slot * SIISATA_CMD_SIZE, SIISATA_CMD_SIZE, (op))
-#define SIISATA_NON_NCQ_SLOT 27
-
void siisata_attach(struct siisata_softc *);
int siisata_detach(struct siisata_softc *, int);
void siisata_resume(struct siisata_softc *);