| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ahcisata_core.c,v 1.30 2010/11/13 13:52:00 uebayasi Exp $ */ | | 1 | /* $NetBSD: ahcisata_core.c,v 1.31 2011/01/10 11:18:14 tsutsui 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.30 2010/11/13 13:52:00 uebayasi Exp $"); | | 29 | __KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.31 2011/01/10 11:18:14 tsutsui 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> |
| @@ -759,27 +759,28 @@ ahci_cmd_start(struct ata_channel *chp, | | | @@ -759,27 +759,28 @@ ahci_cmd_start(struct ata_channel *chp, |
759 | AHCIDEBUG_PRINT(("ahci_cmd_start CI 0x%x\n", | | 759 | AHCIDEBUG_PRINT(("ahci_cmd_start CI 0x%x\n", |
760 | AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS); | | 760 | AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS); |
761 | | | 761 | |
762 | cmd_tbl = achp->ahcic_cmd_tbl[slot]; | | 762 | cmd_tbl = achp->ahcic_cmd_tbl[slot]; |
763 | AHCIDEBUG_PRINT(("%s port %d tbl %p\n", AHCINAME(sc), chp->ch_channel, | | 763 | AHCIDEBUG_PRINT(("%s port %d tbl %p\n", AHCINAME(sc), chp->ch_channel, |
764 | cmd_tbl), DEBUG_XFERS); | | 764 | cmd_tbl), DEBUG_XFERS); |
765 | | | 765 | |
766 | satafis_rhd_construct_cmd(ata_c, cmd_tbl->cmdt_cfis); | | 766 | satafis_rhd_construct_cmd(ata_c, cmd_tbl->cmdt_cfis); |
767 | | | 767 | |
768 | cmd_h = &achp->ahcic_cmdh[slot]; | | 768 | cmd_h = &achp->ahcic_cmdh[slot]; |
769 | AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc), | | 769 | AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc), |
770 | chp->ch_channel, cmd_h), DEBUG_XFERS); | | 770 | chp->ch_channel, cmd_h), DEBUG_XFERS); |
771 | if (ahci_dma_setup(chp, slot, | | 771 | if (ahci_dma_setup(chp, slot, |
772 | (ata_c->flags & (AT_READ|AT_WRITE)) ? ata_c->data : NULL, | | 772 | (ata_c->flags & (AT_READ|AT_WRITE) && ata_c->bcount > 0) ? |
| | | 773 | ata_c->data : NULL, |
773 | ata_c->bcount, | | 774 | ata_c->bcount, |
774 | (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) { | | 775 | (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) { |
775 | ata_c->flags |= AT_DF; | | 776 | ata_c->flags |= AT_DF; |
776 | ahci_cmd_complete(chp, xfer, slot); | | 777 | ahci_cmd_complete(chp, xfer, slot); |
777 | return; | | 778 | return; |
778 | } | | 779 | } |
779 | cmd_h->cmdh_flags = htole16( | | 780 | cmd_h->cmdh_flags = htole16( |
780 | ((ata_c->flags & AT_WRITE) ? AHCI_CMDH_F_WR : 0) | | | 781 | ((ata_c->flags & AT_WRITE) ? AHCI_CMDH_F_WR : 0) | |
781 | RHD_FISLEN / 4); | | 782 | RHD_FISLEN / 4); |
782 | cmd_h->cmdh_prdbc = 0; | | 783 | cmd_h->cmdh_prdbc = 0; |
783 | AHCI_CMDH_SYNC(sc, achp, slot, | | 784 | AHCI_CMDH_SYNC(sc, achp, slot, |
784 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); | | 785 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); |
785 | | | 786 | |
| @@ -894,27 +895,27 @@ ahci_cmd_done(struct ata_channel *chp, s | | | @@ -894,27 +895,27 @@ ahci_cmd_done(struct ata_channel *chp, s |
894 | { | | 895 | { |
895 | struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; | | 896 | struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; |
896 | struct ahci_channel *achp = (struct ahci_channel *)chp; | | 897 | struct ahci_channel *achp = (struct ahci_channel *)chp; |
897 | struct ata_command *ata_c = xfer->c_cmd; | | 898 | struct ata_command *ata_c = xfer->c_cmd; |
898 | uint16_t *idwordbuf; | | 899 | uint16_t *idwordbuf; |
899 | int i; | | 900 | int i; |
900 | | | 901 | |
901 | AHCIDEBUG_PRINT(("ahci_cmd_done channel %d\n", chp->ch_channel), | | 902 | AHCIDEBUG_PRINT(("ahci_cmd_done channel %d\n", chp->ch_channel), |
902 | DEBUG_FUNCS); | | 903 | DEBUG_FUNCS); |
903 | | | 904 | |
904 | /* this comamnd is not active any more */ | | 905 | /* this comamnd is not active any more */ |
905 | achp->ahcic_cmds_active &= ~(1 << slot); | | 906 | achp->ahcic_cmds_active &= ~(1 << slot); |
906 | | | 907 | |
907 | if (ata_c->flags & (AT_READ|AT_WRITE)) { | | 908 | if (ata_c->flags & (AT_READ|AT_WRITE) && ata_c->bcount > 0) { |
908 | bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[slot], 0, | | 909 | bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[slot], 0, |
909 | achp->ahcic_datad[slot]->dm_mapsize, | | 910 | achp->ahcic_datad[slot]->dm_mapsize, |
910 | (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD : | | 911 | (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD : |
911 | BUS_DMASYNC_POSTWRITE); | | 912 | BUS_DMASYNC_POSTWRITE); |
912 | bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[slot]); | | 913 | bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[slot]); |
913 | } | | 914 | } |
914 | | | 915 | |
915 | AHCI_CMDH_SYNC(sc, achp, slot, | | 916 | AHCI_CMDH_SYNC(sc, achp, slot, |
916 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | | 917 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
917 | | | 918 | |
918 | /* ata(4) expects IDENTIFY data to be in host endianess */ | | 919 | /* ata(4) expects IDENTIFY data to be in host endianess */ |
919 | if (ata_c->r_command == WDCC_IDENTIFY || | | 920 | if (ata_c->r_command == WDCC_IDENTIFY || |
920 | ata_c->r_command == ATAPI_IDENTIFY_DEVICE) { | | 921 | ata_c->r_command == ATAPI_IDENTIFY_DEVICE) { |