| @@ -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 |
67 | static void ahci_killpending(struct ata_drive_datas *); | | 67 | static void ahci_killpending(struct ata_drive_datas *); |
68 | | | 68 | |
69 | static void ahci_cmd_start(struct ata_channel *, struct ata_xfer *); | | 69 | static void ahci_cmd_start(struct ata_channel *, struct ata_xfer *); |
70 | static int ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int); | | 70 | static int ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int); |
71 | static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *, int); | | 71 | static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *, int); |
72 | static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *); | | 72 | static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *); |
73 | static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); | | 73 | static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); |
74 | static void ahci_bio_start(struct ata_channel *, struct ata_xfer *); | | 74 | static void ahci_bio_start(struct ata_channel *, struct ata_xfer *); |
75 | static int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int); | | 75 | static int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int); |
76 | static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ; | | 76 | static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ; |
77 | static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); | | 77 | static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); |
78 | static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, | | 78 | static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, |
79 | int, int); | | 79 | int, int); |
80 | static void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, | | 80 | void ahci_channel_recover(struct ahci_softc *, struct ata_channel *, int); |
81 | int); | | | |
82 | static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); | | 81 | static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); |
83 | | | 82 | |
84 | #if NATAPIBUS > 0 | | 83 | #if NATAPIBUS > 0 |
85 | static void ahci_atapibus_attach(struct atabus_softc *); | | 84 | static void ahci_atapibus_attach(struct atabus_softc *); |
86 | static void ahci_atapi_kill_pending(struct scsipi_periph *); | | 85 | static void ahci_atapi_kill_pending(struct scsipi_periph *); |
87 | static void ahci_atapi_minphys(struct buf *); | | 86 | static void ahci_atapi_minphys(struct buf *); |
88 | static void ahci_atapi_scsipi_request(struct scsipi_channel *, | | 87 | static void ahci_atapi_scsipi_request(struct scsipi_channel *, |
89 | scsipi_adapter_req_t, void *); | | 88 | scsipi_adapter_req_t, void *); |
90 | static void ahci_atapi_start(struct ata_channel *, struct ata_xfer *); | | 89 | static void ahci_atapi_start(struct ata_channel *, struct ata_xfer *); |
91 | static int ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int); | | 90 | static int ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int); |
92 | static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int); | | 91 | static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int); |
93 | static void ahci_atapi_probe_device(struct atapibus_softc *, int); | | 92 | static 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 | |
661 | static void | | 660 | static void |
662 | ahci_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) | | 661 | ahci_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); |