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 *);

Reply via email to