Mon Dec 28 11:05:54 2020 UTC ()
Make sure to ack IS after PxIS when polling and when using multiple MSI-X
messages.


(jmcneill)
diff -r1.90 -r1.91 src/sys/dev/ic/ahcisata_core.c

cvs diff -r1.90 -r1.91 src/sys/dev/ic/ahcisata_core.c (expand / switch to unified diff)

--- src/sys/dev/ic/ahcisata_core.c 2020/12/27 15:13:07 1.90
+++ src/sys/dev/ic/ahcisata_core.c 2020/12/28 11:05:54 1.91
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ahcisata_core.c,v 1.90 2020/12/27 15:13:07 jmcneill Exp $ */ 1/* $NetBSD: ahcisata_core.c,v 1.91 2020/12/28 11:05:54 jmcneill Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Manuel Bouyer. 4 * Copyright (c) 2006 Manuel Bouyer.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -16,27 +16,27 @@ @@ -16,27 +16,27 @@
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * 25 *
26 */ 26 */
27 27
28#include <sys/cdefs.h> 28#include <sys/cdefs.h>
29__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.90 2020/12/27 15:13:07 jmcneill Exp $"); 29__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.91 2020/12/28 11:05:54 jmcneill Exp $");
30 30
31#include <sys/types.h> 31#include <sys/types.h>
32#include <sys/malloc.h> 32#include <sys/malloc.h>
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/kernel.h> 34#include <sys/kernel.h>
35#include <sys/systm.h> 35#include <sys/systm.h>
36#include <sys/disklabel.h> 36#include <sys/disklabel.h>
37#include <sys/proc.h> 37#include <sys/proc.h>
38#include <sys/buf.h> 38#include <sys/buf.h>
39 39
40#include <dev/ata/atareg.h> 40#include <dev/ata/atareg.h>
41#include <dev/ata/satavar.h> 41#include <dev/ata/satavar.h>
42#include <dev/ata/satareg.h> 42#include <dev/ata/satareg.h>
@@ -74,26 +74,27 @@ static void ahci_cmd_abort(struct ata_ch @@ -74,26 +74,27 @@ static void ahci_cmd_abort(struct ata_ch
74static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *); 74static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *);
75static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *); 75static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *);
76static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); 76static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
77static int ahci_bio_start(struct ata_channel *, struct ata_xfer *); 77static int ahci_bio_start(struct ata_channel *, struct ata_xfer *);
78static void ahci_bio_poll(struct ata_channel *, struct ata_xfer *); 78static void ahci_bio_poll(struct ata_channel *, struct ata_xfer *);
79static void ahci_bio_abort(struct ata_channel *, struct ata_xfer *); 79static void ahci_bio_abort(struct ata_channel *, struct ata_xfer *);
80static int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int); 80static int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int);
81static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ; 81static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ;
82static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); 82static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int);
83static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, 83static void ahci_channel_start(struct ahci_softc *, struct ata_channel *,
84 int, int); 84 int, int);
85static void ahci_channel_recover(struct ata_channel *, int, uint32_t); 85static void ahci_channel_recover(struct ata_channel *, int, uint32_t);
86static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); 86static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int);
 87static int ahci_intr_port_common(struct ata_channel *);
87 88
88#if NATAPIBUS > 0 89#if NATAPIBUS > 0
89static void ahci_atapibus_attach(struct atabus_softc *); 90static void ahci_atapibus_attach(struct atabus_softc *);
90static void ahci_atapi_kill_pending(struct scsipi_periph *); 91static void ahci_atapi_kill_pending(struct scsipi_periph *);
91static void ahci_atapi_minphys(struct buf *); 92static void ahci_atapi_minphys(struct buf *);
92static void ahci_atapi_scsipi_request(struct scsipi_channel *, 93static void ahci_atapi_scsipi_request(struct scsipi_channel *,
93 scsipi_adapter_req_t, void *); 94 scsipi_adapter_req_t, void *);
94static int ahci_atapi_start(struct ata_channel *, struct ata_xfer *); 95static int ahci_atapi_start(struct ata_channel *, struct ata_xfer *);
95static void ahci_atapi_poll(struct ata_channel *, struct ata_xfer *); 96static void ahci_atapi_poll(struct ata_channel *, struct ata_xfer *);
96static void ahci_atapi_abort(struct ata_channel *, struct ata_xfer *); 97static void ahci_atapi_abort(struct ata_channel *, struct ata_xfer *);
97static int ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int); 98static int ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int);
98static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int); 99static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
99static void ahci_atapi_probe_device(struct atapibus_softc *, int); 100static void ahci_atapi_probe_device(struct atapibus_softc *, int);
@@ -592,52 +593,66 @@ int @@ -592,52 +593,66 @@ int
592ahci_intr(void *v) 593ahci_intr(void *v)
593{ 594{
594 struct ahci_softc *sc = v; 595 struct ahci_softc *sc = v;
595 uint32_t is, ports; 596 uint32_t is, ports;
596 int bit, r = 0; 597 int bit, r = 0;
597 598
598 while ((is = AHCI_READ(sc, AHCI_IS))) { 599 while ((is = AHCI_READ(sc, AHCI_IS))) {
599 AHCIDEBUG_PRINT(("%s ahci_intr 0x%x\n", AHCINAME(sc), is), 600 AHCIDEBUG_PRINT(("%s ahci_intr 0x%x\n", AHCINAME(sc), is),
600 DEBUG_INTR); 601 DEBUG_INTR);
601 r = 1; 602 r = 1;
602 ports = is; 603 ports = is;
603 while ((bit = ffs(ports)) != 0) { 604 while ((bit = ffs(ports)) != 0) {
604 bit--; 605 bit--;
605 ahci_intr_port(&sc->sc_channels[bit]); 606 ahci_intr_port_common(&sc->sc_channels[bit].ata_channel);
606 ports &= ~(1U << bit); 607 ports &= ~(1U << bit);
607 } 608 }
608 AHCI_WRITE(sc, AHCI_IS, is); 609 AHCI_WRITE(sc, AHCI_IS, is);
609 } 610 }
610 611
611 return r; 612 return r;
612} 613}
613 614
614int 615int
615ahci_intr_port(void *v) 616ahci_intr_port(void *v)
616{ 617{
617 struct ahci_channel *achp = v; 618 struct ahci_channel *achp = v;
618 struct ata_channel *chp = &achp->ata_channel; 619 struct ata_channel *chp = &achp->ata_channel;
619 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; 620 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 621 int ret;
 622
 623 ret = ahci_intr_port_common(chp);
 624 if (ret) {
 625 AHCI_WRITE(sc, AHCI_IS, 1U << chp->ch_channel);
 626 }
 627
 628 return ret;
 629}
 630
 631static int
 632ahci_intr_port_common(struct ata_channel *chp)
 633{
 634 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
620 uint32_t is, tfd, sact; 635 uint32_t is, tfd, sact;
621 struct ata_xfer *xfer; 636 struct ata_xfer *xfer;
622 int slot = -1; 637 int slot = -1;
623 bool recover = false; 638 bool recover = false;
624 uint32_t aslots; 639 uint32_t aslots;
625 640
626 is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); 641 is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
627 AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is); 642 AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is);
628 643
629 AHCIDEBUG_PRINT(( 644 AHCIDEBUG_PRINT(("ahci_intr_port_common %s port %d "
630 "ahci_intr_port %s port %d is 0x%x CI 0x%x SACT 0x%x TFD 0x%x\n", 645 "is 0x%x CI 0x%x SACT 0x%x TFD 0x%x\n",
631 AHCINAME(sc), 646 AHCINAME(sc),
632 chp->ch_channel, is, 647 chp->ch_channel, is,
633 AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)), 648 AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)),
634 AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)), 649 AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)),
635 AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))), 650 AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))),
636 DEBUG_INTR); 651 DEBUG_INTR);
637 652
638 if ((chp->ch_flags & ATACH_NCQ) == 0) { 653 if ((chp->ch_flags & ATACH_NCQ) == 0) {
639 /* Non-NCQ operation */ 654 /* Non-NCQ operation */
640 sact = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)); 655 sact = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel));
641 } else { 656 } else {
642 /* NCQ operation */ 657 /* NCQ operation */
643 sact = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)); 658 sact = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel));