Sat Jul 29 14:50:58 2017 UTC ()
make ahci_channel_recover() non-static, so that it's visible in backtrace,
and can set a separate breakpoint there


(jdolecek)
diff -r1.57.6.21 -r1.57.6.22 src/sys/dev/ic/ahcisata_core.c

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

--- src/sys/dev/ic/ahcisata_core.c 2017/07/29 13:02:50 1.57.6.21
+++ src/sys/dev/ic/ahcisata_core.c 2017/07/29 14:50:58 1.57.6.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ahcisata_core.c,v 1.57.6.21 2017/07/29 13:02:50 jdolecek Exp $ */ 1/* $NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek 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.57.6.21 2017/07/29 13:02:50 jdolecek Exp $"); 29__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.22 2017/07/29 14:50:58 jdolecek 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>
@@ -67,28 +67,27 @@ static void ahci_ata_delref(struct ata_d @@ -67,28 +67,27 @@ static void ahci_ata_delref(struct ata_d
67static void ahci_killpending(struct ata_drive_datas *); 67static void ahci_killpending(struct ata_drive_datas *);
68 68
69static void ahci_cmd_start(struct ata_channel *, struct ata_xfer *); 69static void ahci_cmd_start(struct ata_channel *, struct ata_xfer *);
70static int ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int); 70static int ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
71static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *, int); 71static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *, int);
72static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *); 72static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *);
73static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); 73static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
74static void ahci_bio_start(struct ata_channel *, struct ata_xfer *); 74static void ahci_bio_start(struct ata_channel *, struct ata_xfer *);
75static int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int); 75static int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int);
76static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ; 76static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ;
77static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); 77static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int);
78static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, 78static void ahci_channel_start(struct ahci_softc *, struct ata_channel *,
79 int, int); 79 int, int);
80static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, 80void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, int);
81 int); 
82static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); 81static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int);
83 82
84#if NATAPIBUS > 0 83#if NATAPIBUS > 0
85static void ahci_atapibus_attach(struct atabus_softc *); 84static void ahci_atapibus_attach(struct atabus_softc *);
86static void ahci_atapi_kill_pending(struct scsipi_periph *); 85static void ahci_atapi_kill_pending(struct scsipi_periph *);
87static void ahci_atapi_minphys(struct buf *); 86static void ahci_atapi_minphys(struct buf *);
88static void ahci_atapi_scsipi_request(struct scsipi_channel *, 87static void ahci_atapi_scsipi_request(struct scsipi_channel *,
89 scsipi_adapter_req_t, void *); 88 scsipi_adapter_req_t, void *);
90static void ahci_atapi_start(struct ata_channel *, struct ata_xfer *); 89static void ahci_atapi_start(struct ata_channel *, struct ata_xfer *);
91static int ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int); 90static int ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int);
92static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int); 91static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
93static void ahci_atapi_probe_device(struct atapibus_softc *, int); 92static void ahci_atapi_probe_device(struct atapibus_softc *, int);
94 93
@@ -617,52 +616,52 @@ ahci_intr_port(struct ahci_softc *sc, st @@ -617,52 +616,52 @@ ahci_intr_port(struct ahci_softc *sc, st
617 /* D2H Register FIS or Set Device Bits */ 616 /* D2H Register FIS or Set Device Bits */
618 if ((tfd & WDCS_ERR) != 0) { 617 if ((tfd & WDCS_ERR) != 0) {
619 if (!achp->ahcic_recovering) 618 if (!achp->ahcic_recovering)
620 recover = true; 619 recover = true;
621 620
622 aprint_error("%s port %d: transfer aborted 0x%x\n", 621 aprint_error("%s port %d: transfer aborted 0x%x\n",
623 AHCINAME(sc), chp->ch_channel, tfd); 622 AHCINAME(sc), chp->ch_channel, tfd);
624 623
625 } 624 }
626 } else { 625 } else {
627 tfd = 0; 626 tfd = 0;
628 } 627 }
629 628
630 if (recover) 629 if (__predict_false(recover))
631 ata_channel_freeze(chp); 630 ata_channel_freeze(chp);
632 631
633 if (slot >= 0) { 632 if (slot >= 0) {
634 if ((achp->ahcic_cmds_active & (1 << slot)) != 0 && 633 if ((achp->ahcic_cmds_active & (1 << slot)) != 0 &&
635 (active & (1 << slot)) == 0) { 634 (active & (1 << slot)) == 0) {
636 xfer = ata_queue_hwslot_to_xfer(chp, slot); 635 xfer = ata_queue_hwslot_to_xfer(chp, slot);
637 xfer->c_intr(chp, xfer, tfd); 636 xfer->c_intr(chp, xfer, tfd);
638 } 637 }
639 } else { 638 } else {
640 /* 639 /*
641 * For NCQ, HBA halts processing when error is notified, 640 * For NCQ, HBA halts processing when error is notified,
642 * and any further D2H FISes are ignored until the error 641 * and any further D2H FISes are ignored until the error
643 * condition is cleared. Hence if a command is inactive, 642 * condition is cleared. Hence if a command is inactive,
644 * it means it actually already finished successfully. 643 * it means it actually already finished successfully.
645 */ 644 */
646 for (slot=0; slot < sc->sc_ncmds; slot++) { 645 for (slot=0; slot < sc->sc_ncmds; slot++) {
647 if ((achp->ahcic_cmds_active & (1 << slot)) != 0 && 646 if ((achp->ahcic_cmds_active & (1 << slot)) != 0 &&
648 (active & (1 << slot)) == 0) { 647 (active & (1 << slot)) == 0) {
649 xfer = ata_queue_hwslot_to_xfer(chp, slot); 648 xfer = ata_queue_hwslot_to_xfer(chp, slot);
650 xfer->c_intr(chp, xfer, 0); 649 xfer->c_intr(chp, xfer, 0);
651 } 650 }
652 } 651 }
653 } 652 }
654 653
655 if (recover) { 654 if (__predict_false(recover)) {
656 ata_channel_thaw(chp); 655 ata_channel_thaw(chp);
657 ahci_channel_recover(sc, chp, tfd); 656 ahci_channel_recover(sc, chp, tfd);
658 } 657 }
659} 658}
660 659
661static void 660static void
662ahci_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) 661ahci_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp)
663{ 662{
664 struct ata_channel *chp = drvp->chnl_softc; 663 struct ata_channel *chp = drvp->chnl_softc;
665 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; 664 struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
666 AHCI_WRITE(sc, AHCI_GHC, 665 AHCI_WRITE(sc, AHCI_GHC,
667 AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE); 666 AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
668 ahci_channel_stop(sc, chp, flags); 667 ahci_channel_stop(sc, chp, flags);