Home | History | Annotate | Line # | Download | only in ic
ahcisata_core.c revision 1.107
      1  1.106   mlelstv /*	$NetBSD: ahcisata_core.c,v 1.107 2022/08/01 07:37:18 mlelstv Exp $	*/
      2    1.1    bouyer 
      3    1.1    bouyer /*
      4    1.1    bouyer  * Copyright (c) 2006 Manuel Bouyer.
      5    1.1    bouyer  *
      6    1.1    bouyer  * Redistribution and use in source and binary forms, with or without
      7    1.1    bouyer  * modification, are permitted provided that the following conditions
      8    1.1    bouyer  * are met:
      9    1.1    bouyer  * 1. Redistributions of source code must retain the above copyright
     10    1.1    bouyer  *    notice, this list of conditions and the following disclaimer.
     11    1.1    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     12    1.1    bouyer  *    notice, this list of conditions and the following disclaimer in the
     13    1.1    bouyer  *    documentation and/or other materials provided with the distribution.
     14    1.1    bouyer  *
     15    1.1    bouyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16    1.1    bouyer  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17    1.1    bouyer  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18    1.1    bouyer  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19    1.1    bouyer  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20    1.1    bouyer  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21    1.1    bouyer  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22    1.1    bouyer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23    1.1    bouyer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24    1.1    bouyer  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25    1.1    bouyer  *
     26    1.1    bouyer  */
     27    1.1    bouyer 
     28    1.1    bouyer #include <sys/cdefs.h>
     29  1.106   mlelstv __KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.107 2022/08/01 07:37:18 mlelstv Exp $");
     30    1.1    bouyer 
     31    1.1    bouyer #include <sys/types.h>
     32    1.1    bouyer #include <sys/malloc.h>
     33    1.1    bouyer #include <sys/param.h>
     34    1.1    bouyer #include <sys/kernel.h>
     35    1.1    bouyer #include <sys/systm.h>
     36    1.1    bouyer #include <sys/disklabel.h>
     37    1.4        ad #include <sys/proc.h>
     38    1.8    bouyer #include <sys/buf.h>
     39    1.1    bouyer 
     40    1.1    bouyer #include <dev/ata/atareg.h>
     41    1.1    bouyer #include <dev/ata/satavar.h>
     42    1.1    bouyer #include <dev/ata/satareg.h>
     43   1.26  jakllsch #include <dev/ata/satafisvar.h>
     44   1.20  jakllsch #include <dev/ata/satafisreg.h>
     45   1.40    bouyer #include <dev/ata/satapmpreg.h>
     46    1.1    bouyer #include <dev/ic/ahcisatavar.h>
     47   1.40    bouyer #include <dev/ic/wdcreg.h>
     48    1.1    bouyer 
     49   1.16    bouyer #include <dev/scsipi/scsi_all.h> /* for SCSI status */
     50   1.16    bouyer 
     51    1.8    bouyer #include "atapibus.h"
     52    1.8    bouyer 
     53  1.103  jmcneill #include "opt_ahcisata.h"
     54  1.103  jmcneill 
     55    1.1    bouyer #ifdef AHCI_DEBUG
     56   1.40    bouyer int ahcidebug_mask = 0;
     57    1.1    bouyer #endif
     58    1.1    bouyer 
     59   1.29  jakllsch static void ahci_probe_drive(struct ata_channel *);
     60   1.29  jakllsch static void ahci_setup_channel(struct ata_channel *);
     61    1.1    bouyer 
     62   1.83  jdolecek static void ahci_ata_bio(struct ata_drive_datas *, struct ata_xfer *);
     63   1.58  jdolecek static int  ahci_do_reset_drive(struct ata_channel *, int, int, uint32_t *,
     64   1.64  jdolecek 	uint8_t);
     65   1.40    bouyer static void ahci_reset_drive(struct ata_drive_datas *, int, uint32_t *);
     66   1.29  jakllsch static void ahci_reset_channel(struct ata_channel *, int);
     67   1.93     skrll static void ahci_exec_command(struct ata_drive_datas *, struct ata_xfer *);
     68   1.29  jakllsch static int  ahci_ata_addref(struct ata_drive_datas *);
     69   1.29  jakllsch static void ahci_ata_delref(struct ata_drive_datas *);
     70   1.29  jakllsch static void ahci_killpending(struct ata_drive_datas *);
     71   1.29  jakllsch 
     72   1.93     skrll static int  ahci_cmd_start(struct ata_channel *, struct ata_xfer *);
     73   1.29  jakllsch static int  ahci_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
     74  1.102       rin static int  ahci_cmd_poll(struct ata_channel *, struct ata_xfer *);
     75   1.58  jdolecek static void ahci_cmd_abort(struct ata_channel *, struct ata_xfer *);
     76   1.58  jdolecek static void ahci_cmd_done(struct ata_channel *, struct ata_xfer *);
     77   1.58  jdolecek static void ahci_cmd_done_end(struct ata_channel *, struct ata_xfer *);
     78   1.58  jdolecek static void ahci_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
     79   1.93     skrll static int  ahci_bio_start(struct ata_channel *, struct ata_xfer *);
     80  1.102       rin static int  ahci_bio_poll(struct ata_channel *, struct ata_xfer *);
     81   1.58  jdolecek static void ahci_bio_abort(struct ata_channel *, struct ata_xfer *);
     82   1.29  jakllsch static int  ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int);
     83   1.29  jakllsch static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ;
     84   1.29  jakllsch static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int);
     85   1.40    bouyer static void ahci_channel_start(struct ahci_softc *, struct ata_channel *,
     86   1.40    bouyer 				int, int);
     87   1.64  jdolecek static void ahci_channel_recover(struct ata_channel *, int, uint32_t);
     88   1.29  jakllsch static int  ahci_dma_setup(struct ata_channel *, int, void *, size_t, int);
     89   1.93     skrll static int  ahci_intr_port_common(struct ata_channel *);
     90    1.1    bouyer 
     91    1.8    bouyer #if NATAPIBUS > 0
     92   1.29  jakllsch static void ahci_atapibus_attach(struct atabus_softc *);
     93   1.29  jakllsch static void ahci_atapi_kill_pending(struct scsipi_periph *);
     94   1.29  jakllsch static void ahci_atapi_minphys(struct buf *);
     95   1.29  jakllsch static void ahci_atapi_scsipi_request(struct scsipi_channel *,
     96    1.8    bouyer     scsipi_adapter_req_t, void *);
     97   1.93     skrll static int  ahci_atapi_start(struct ata_channel *, struct ata_xfer *);
     98  1.102       rin static int  ahci_atapi_poll(struct ata_channel *, struct ata_xfer *);
     99   1.58  jdolecek static void ahci_atapi_abort(struct ata_channel *, struct ata_xfer *);
    100   1.29  jakllsch static int  ahci_atapi_complete(struct ata_channel *, struct ata_xfer *, int);
    101   1.29  jakllsch static void ahci_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
    102   1.29  jakllsch static void ahci_atapi_probe_device(struct atapibus_softc *, int);
    103    1.8    bouyer 
    104    1.8    bouyer static const struct scsipi_bustype ahci_atapi_bustype = {
    105   1.82  riastrad 	.bustype_type = SCSIPI_BUSTYPE_ATAPI,
    106   1.82  riastrad 	.bustype_cmd = atapi_scsipi_cmd,
    107   1.82  riastrad 	.bustype_interpret_sense = atapi_interpret_sense,
    108   1.82  riastrad 	.bustype_printaddr = atapi_print_addr,
    109   1.82  riastrad 	.bustype_kill_pending = ahci_atapi_kill_pending,
    110   1.82  riastrad 	.bustype_async_event_xfer_mode = NULL,
    111    1.8    bouyer };
    112    1.8    bouyer #endif /* NATAPIBUS */
    113    1.8    bouyer 
    114    1.1    bouyer #define ATA_DELAY 10000 /* 10s for a drive I/O */
    115   1.24    bouyer #define ATA_RESET_DELAY 31000 /* 31s for a drive reset */
    116   1.24    bouyer #define AHCI_RST_WAIT (ATA_RESET_DELAY / 10)
    117    1.1    bouyer 
    118  1.105       rin #ifndef AHCISATA_EXTRA_DELAY_MS
    119  1.105       rin #define	AHCISATA_EXTRA_DELAY_MS	500	/* XXX need to adjust */
    120  1.105       rin #endif
    121  1.105       rin 
    122  1.105       rin #ifdef AHCISATA_EXTRA_DELAY
    123  1.105       rin #define	AHCISATA_DO_EXTRA_DELAY(sc, chp, msg, flags)			\
    124  1.105       rin     ata_delay(chp, AHCISATA_EXTRA_DELAY_MS, msg, flags)
    125  1.105       rin #else
    126  1.105       rin #define	AHCISATA_DO_EXTRA_DELAY(sc, chp, msg, flags)			\
    127  1.105       rin     do {								\
    128  1.105       rin 	if ((sc)->sc_ahci_quirks & AHCI_QUIRK_EXTRA_DELAY)		\
    129  1.105       rin 		ata_delay(chp, AHCISATA_EXTRA_DELAY_MS, msg, flags);	\
    130  1.105       rin     } while (0)
    131  1.105       rin #endif
    132  1.105       rin 
    133    1.1    bouyer const struct ata_bustype ahci_ata_bustype = {
    134   1.86     skrll 	.bustype_type = SCSIPI_BUSTYPE_ATA,
    135   1.86     skrll 	.ata_bio = ahci_ata_bio,
    136   1.86     skrll 	.ata_reset_drive = ahci_reset_drive,
    137   1.86     skrll 	.ata_reset_channel = ahci_reset_channel,
    138   1.86     skrll 	.ata_exec_command = ahci_exec_command,
    139   1.86     skrll 	.ata_get_params = ata_get_params,
    140   1.86     skrll 	.ata_addref = ahci_ata_addref,
    141   1.86     skrll 	.ata_delref = ahci_ata_delref,
    142   1.86     skrll 	.ata_killpending = ahci_killpending,
    143   1.86     skrll 	.ata_recovery = ahci_channel_recover,
    144    1.1    bouyer };
    145    1.1    bouyer 
    146    1.7     joerg static void ahci_setup_port(struct ahci_softc *sc, int i);
    147    1.7     joerg 
    148   1.51  jmcneill static void
    149   1.51  jmcneill ahci_enable(struct ahci_softc *sc)
    150   1.51  jmcneill {
    151   1.51  jmcneill 	uint32_t ghc;
    152   1.51  jmcneill 
    153   1.51  jmcneill 	ghc = AHCI_READ(sc, AHCI_GHC);
    154   1.51  jmcneill 	if (!(ghc & AHCI_GHC_AE)) {
    155   1.51  jmcneill 		ghc |= AHCI_GHC_AE;
    156   1.51  jmcneill 		AHCI_WRITE(sc, AHCI_GHC, ghc);
    157   1.51  jmcneill 	}
    158   1.51  jmcneill }
    159   1.51  jmcneill 
    160   1.29  jakllsch static int
    161    1.7     joerg ahci_reset(struct ahci_softc *sc)
    162    1.1    bouyer {
    163    1.7     joerg 	int i;
    164    1.1    bouyer 
    165    1.1    bouyer 	/* reset controller */
    166    1.1    bouyer 	AHCI_WRITE(sc, AHCI_GHC, AHCI_GHC_HR);
    167  1.101       mrg 	/* wait up to 1s for reset to complete */
    168  1.101       mrg 	for (i = 0; i < 1000; i++) {
    169    1.6    bouyer 		delay(1000);
    170    1.1    bouyer 		if ((AHCI_READ(sc, AHCI_GHC) & AHCI_GHC_HR) == 0)
    171    1.1    bouyer 			break;
    172    1.1    bouyer 	}
    173  1.101       mrg 	if ((AHCI_READ(sc, AHCI_GHC) & AHCI_GHC_HR)) {
    174  1.101       mrg 		aprint_error("%s: reset failed\n", AHCINAME(sc));
    175    1.7     joerg 		return -1;
    176    1.1    bouyer 	}
    177    1.1    bouyer 	/* enable ahci mode */
    178   1.51  jmcneill 	ahci_enable(sc);
    179   1.51  jmcneill 
    180   1.51  jmcneill 	if (sc->sc_save_init_data) {
    181   1.51  jmcneill 		AHCI_WRITE(sc, AHCI_CAP, sc->sc_init_data.cap);
    182   1.51  jmcneill 		if (sc->sc_init_data.cap2)
    183   1.51  jmcneill 			AHCI_WRITE(sc, AHCI_CAP2, sc->sc_init_data.cap2);
    184   1.51  jmcneill 		AHCI_WRITE(sc, AHCI_PI, sc->sc_init_data.ports);
    185   1.51  jmcneill 	}
    186   1.51  jmcneill 
    187   1.72  jdolecek 	/* Check if hardware reverted to single message MSI */
    188   1.72  jdolecek 	sc->sc_ghc_mrsm = ISSET(AHCI_READ(sc, AHCI_GHC), AHCI_GHC_MRSM);
    189   1.72  jdolecek 
    190    1.7     joerg 	return 0;
    191    1.7     joerg }
    192    1.1    bouyer 
    193   1.29  jakllsch static void
    194    1.7     joerg ahci_setup_ports(struct ahci_softc *sc)
    195    1.7     joerg {
    196    1.7     joerg 	int i, port;
    197   1.87     skrll 
    198    1.7     joerg 	for (i = 0, port = 0; i < AHCI_MAX_PORTS; i++) {
    199   1.62     kamil 		if ((sc->sc_ahci_ports & (1U << i)) == 0)
    200    1.7     joerg 			continue;
    201    1.7     joerg 		if (port >= sc->sc_atac.atac_nchannels) {
    202    1.7     joerg 			aprint_error("%s: more ports than announced\n",
    203    1.7     joerg 			    AHCINAME(sc));
    204    1.7     joerg 			break;
    205    1.7     joerg 		}
    206    1.7     joerg 		ahci_setup_port(sc, i);
    207   1.66  jdolecek 		port++;
    208    1.7     joerg 	}
    209    1.7     joerg }
    210    1.7     joerg 
    211   1.29  jakllsch static void
    212    1.7     joerg ahci_reprobe_drives(struct ahci_softc *sc)
    213    1.7     joerg {
    214    1.7     joerg 	int i, port;
    215    1.7     joerg 	struct ahci_channel *achp;
    216    1.7     joerg 	struct ata_channel *chp;
    217    1.7     joerg 
    218    1.7     joerg 	for (i = 0, port = 0; i < AHCI_MAX_PORTS; i++) {
    219   1.62     kamil 		if ((sc->sc_ahci_ports & (1U << i)) == 0)
    220    1.7     joerg 			continue;
    221    1.7     joerg 		if (port >= sc->sc_atac.atac_nchannels) {
    222    1.7     joerg 			aprint_error("%s: more ports than announced\n",
    223    1.7     joerg 			    AHCINAME(sc));
    224    1.7     joerg 			break;
    225    1.7     joerg 		}
    226    1.7     joerg 		achp = &sc->sc_channels[i];
    227    1.7     joerg 		chp = &achp->ata_channel;
    228    1.7     joerg 
    229    1.7     joerg 		ahci_probe_drive(chp);
    230   1.66  jdolecek 		port++;
    231    1.7     joerg 	}
    232    1.7     joerg }
    233    1.7     joerg 
    234    1.7     joerg static void
    235    1.7     joerg ahci_setup_port(struct ahci_softc *sc, int i)
    236    1.7     joerg {
    237    1.7     joerg 	struct ahci_channel *achp;
    238    1.7     joerg 
    239    1.7     joerg 	achp = &sc->sc_channels[i];
    240    1.7     joerg 
    241   1.97     skrll 	AHCI_WRITE(sc, AHCI_P_CLB(i), BUS_ADDR_LO32(achp->ahcic_bus_cmdh));
    242   1.97     skrll 	AHCI_WRITE(sc, AHCI_P_CLBU(i), BUS_ADDR_HI32(achp->ahcic_bus_cmdh));
    243   1.97     skrll 	AHCI_WRITE(sc, AHCI_P_FB(i), BUS_ADDR_LO32(achp->ahcic_bus_rfis));
    244   1.97     skrll 	AHCI_WRITE(sc, AHCI_P_FBU(i), BUS_ADDR_HI32(achp->ahcic_bus_rfis));
    245    1.7     joerg }
    246    1.7     joerg 
    247   1.29  jakllsch static void
    248    1.7     joerg ahci_enable_intrs(struct ahci_softc *sc)
    249    1.7     joerg {
    250    1.7     joerg 
    251    1.7     joerg 	/* clear interrupts */
    252    1.7     joerg 	AHCI_WRITE(sc, AHCI_IS, AHCI_READ(sc, AHCI_IS));
    253    1.7     joerg 	/* enable interrupts */
    254    1.7     joerg 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
    255    1.7     joerg }
    256    1.7     joerg 
    257    1.7     joerg void
    258    1.7     joerg ahci_attach(struct ahci_softc *sc)
    259    1.7     joerg {
    260   1.50      matt 	uint32_t ahci_rev;
    261    1.7     joerg 	int i, j, port;
    262    1.7     joerg 	struct ahci_channel *achp;
    263    1.7     joerg 	struct ata_channel *chp;
    264    1.7     joerg 	int error;
    265    1.7     joerg 	int dmasize;
    266   1.32  jakllsch 	char buf[128];
    267    1.7     joerg 	void *cmdhp;
    268    1.7     joerg 	void *cmdtblp;
    269    1.7     joerg 
    270   1.51  jmcneill 	if (sc->sc_save_init_data) {
    271   1.51  jmcneill 		ahci_enable(sc);
    272   1.51  jmcneill 
    273   1.51  jmcneill 		sc->sc_init_data.cap = AHCI_READ(sc, AHCI_CAP);
    274   1.51  jmcneill 		sc->sc_init_data.ports = AHCI_READ(sc, AHCI_PI);
    275   1.87     skrll 
    276   1.51  jmcneill 		ahci_rev = AHCI_READ(sc, AHCI_VS);
    277   1.51  jmcneill 		if (AHCI_VS_MJR(ahci_rev) > 1 ||
    278   1.51  jmcneill 		    (AHCI_VS_MJR(ahci_rev) == 1 && AHCI_VS_MNR(ahci_rev) >= 20)) {
    279   1.51  jmcneill 			sc->sc_init_data.cap2 = AHCI_READ(sc, AHCI_CAP2);
    280   1.51  jmcneill 		} else {
    281   1.51  jmcneill 			sc->sc_init_data.cap2 = 0;
    282   1.51  jmcneill 		}
    283   1.51  jmcneill 		if (sc->sc_init_data.ports == 0) {
    284   1.51  jmcneill 			sc->sc_init_data.ports = sc->sc_ahci_ports;
    285   1.51  jmcneill 		}
    286   1.51  jmcneill 	}
    287   1.51  jmcneill 
    288    1.7     joerg 	if (ahci_reset(sc) != 0)
    289    1.7     joerg 		return;
    290    1.1    bouyer 
    291   1.40    bouyer 	sc->sc_ahci_cap = AHCI_READ(sc, AHCI_CAP);
    292   1.43    bouyer 	if (sc->sc_ahci_quirks & AHCI_QUIRK_BADPMP) {
    293   1.41    bouyer 		aprint_verbose_dev(sc->sc_atac.atac_dev,
    294   1.41    bouyer 		    "ignoring broken port multiplier support\n");
    295   1.41    bouyer 		sc->sc_ahci_cap &= ~AHCI_CAP_SPM;
    296   1.41    bouyer 	}
    297   1.81    simonb 	if (sc->sc_ahci_quirks & AHCI_QUIRK_BADNCQ) {
    298   1.81    simonb 		aprint_verbose_dev(sc->sc_atac.atac_dev,
    299   1.81    simonb 		    "ignoring broken NCQ support\n");
    300   1.81    simonb 		sc->sc_ahci_cap &= ~AHCI_CAP_NCQ;
    301   1.81    simonb 	}
    302   1.40    bouyer 	sc->sc_atac.atac_nchannels = (sc->sc_ahci_cap & AHCI_CAP_NPMASK) + 1;
    303   1.40    bouyer 	sc->sc_ncmds = ((sc->sc_ahci_cap & AHCI_CAP_NCS) >> 8) + 1;
    304    1.1    bouyer 	ahci_rev = AHCI_READ(sc, AHCI_VS);
    305   1.32  jakllsch 	snprintb(buf, sizeof(buf), "\177\020"
    306   1.32  jakllsch 			/* "f\000\005NP\0" */
    307   1.32  jakllsch 			"b\005SXS\0"
    308   1.32  jakllsch 			"b\006EMS\0"
    309   1.32  jakllsch 			"b\007CCCS\0"
    310   1.32  jakllsch 			/* "f\010\005NCS\0" */
    311   1.32  jakllsch 			"b\015PSC\0"
    312   1.32  jakllsch 			"b\016SSC\0"
    313   1.32  jakllsch 			"b\017PMD\0"
    314   1.32  jakllsch 			"b\020FBSS\0"
    315   1.32  jakllsch 			"b\021SPM\0"
    316   1.32  jakllsch 			"b\022SAM\0"
    317   1.32  jakllsch 			"b\023SNZO\0"
    318   1.32  jakllsch 			"f\024\003ISS\0"
    319   1.32  jakllsch 			"=\001Gen1\0"
    320   1.32  jakllsch 			"=\002Gen2\0"
    321   1.32  jakllsch 			"=\003Gen3\0"
    322   1.32  jakllsch 			"b\030SCLO\0"
    323   1.32  jakllsch 			"b\031SAL\0"
    324   1.32  jakllsch 			"b\032SALP\0"
    325   1.32  jakllsch 			"b\033SSS\0"
    326   1.32  jakllsch 			"b\034SMPS\0"
    327   1.32  jakllsch 			"b\035SSNTF\0"
    328   1.32  jakllsch 			"b\036SNCQ\0"
    329   1.32  jakllsch 			"b\037S64A\0"
    330   1.40    bouyer 			"\0", sc->sc_ahci_cap);
    331   1.32  jakllsch 	aprint_normal_dev(sc->sc_atac.atac_dev, "AHCI revision %u.%u"
    332   1.49      matt 	    ", %d port%s, %d slot%s, CAP %s\n",
    333   1.32  jakllsch 	    AHCI_VS_MJR(ahci_rev), AHCI_VS_MNR(ahci_rev),
    334   1.49      matt 	    sc->sc_atac.atac_nchannels,
    335   1.87     skrll 	    (sc->sc_atac.atac_nchannels == 1 ? "" : "s"),
    336   1.49      matt 	    sc->sc_ncmds, (sc->sc_ncmds == 1 ? "" : "s"), buf);
    337    1.1    bouyer 
    338   1.58  jdolecek 	sc->sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DMA | ATAC_CAP_UDMA
    339   1.58  jdolecek 		| ((sc->sc_ahci_cap & AHCI_CAP_NCQ) ? ATAC_CAP_NCQ : 0);
    340   1.12   xtraeme 	sc->sc_atac.atac_cap |= sc->sc_atac_capflags;
    341    1.1    bouyer 	sc->sc_atac.atac_pio_cap = 4;
    342    1.1    bouyer 	sc->sc_atac.atac_dma_cap = 2;
    343    1.1    bouyer 	sc->sc_atac.atac_udma_cap = 6;
    344    1.1    bouyer 	sc->sc_atac.atac_channels = sc->sc_chanarray;
    345    1.1    bouyer 	sc->sc_atac.atac_probe = ahci_probe_drive;
    346    1.1    bouyer 	sc->sc_atac.atac_bustype_ata = &ahci_ata_bustype;
    347    1.1    bouyer 	sc->sc_atac.atac_set_modes = ahci_setup_channel;
    348    1.8    bouyer #if NATAPIBUS > 0
    349    1.8    bouyer 	sc->sc_atac.atac_atapibus_attach = ahci_atapibus_attach;
    350    1.8    bouyer #endif
    351    1.1    bouyer 
    352    1.1    bouyer 	dmasize =
    353    1.1    bouyer 	    (AHCI_RFIS_SIZE + AHCI_CMDH_SIZE) * sc->sc_atac.atac_nchannels;
    354    1.1    bouyer 	error = bus_dmamem_alloc(sc->sc_dmat, dmasize, PAGE_SIZE, 0,
    355   1.29  jakllsch 	    &sc->sc_cmd_hdr_seg, 1, &sc->sc_cmd_hdr_nseg, BUS_DMA_NOWAIT);
    356    1.1    bouyer 	if (error) {
    357    1.1    bouyer 		aprint_error("%s: unable to allocate command header memory"
    358    1.1    bouyer 		    ", error=%d\n", AHCINAME(sc), error);
    359    1.1    bouyer 		return;
    360    1.1    bouyer 	}
    361   1.29  jakllsch 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_hdr_seg,
    362   1.29  jakllsch 	    sc->sc_cmd_hdr_nseg, dmasize,
    363    1.1    bouyer 	    &cmdhp, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
    364    1.1    bouyer 	if (error) {
    365    1.1    bouyer 		aprint_error("%s: unable to map command header memory"
    366    1.1    bouyer 		    ", error=%d\n", AHCINAME(sc), error);
    367    1.1    bouyer 		return;
    368    1.1    bouyer 	}
    369    1.1    bouyer 	error = bus_dmamap_create(sc->sc_dmat, dmasize, 1, dmasize, 0,
    370    1.1    bouyer 	    BUS_DMA_NOWAIT, &sc->sc_cmd_hdrd);
    371    1.1    bouyer 	if (error) {
    372    1.1    bouyer 		aprint_error("%s: unable to create command header map"
    373    1.1    bouyer 		    ", error=%d\n", AHCINAME(sc), error);
    374    1.1    bouyer 		return;
    375    1.1    bouyer 	}
    376    1.1    bouyer 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_hdrd,
    377    1.1    bouyer 	    cmdhp, dmasize, NULL, BUS_DMA_NOWAIT);
    378    1.1    bouyer 	if (error) {
    379    1.1    bouyer 		aprint_error("%s: unable to load command header map"
    380    1.1    bouyer 		    ", error=%d\n", AHCINAME(sc), error);
    381    1.1    bouyer 		return;
    382    1.1    bouyer 	}
    383    1.1    bouyer 	sc->sc_cmd_hdr = cmdhp;
    384   1.88  jmcneill 	memset(cmdhp, 0, dmasize);
    385   1.88  jmcneill 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_hdrd, 0, dmasize,
    386   1.88  jmcneill 	    BUS_DMASYNC_PREWRITE);
    387    1.1    bouyer 
    388    1.7     joerg 	ahci_enable_intrs(sc);
    389    1.1    bouyer 
    390   1.50      matt 	if (sc->sc_ahci_ports == 0) {
    391   1.50      matt 		sc->sc_ahci_ports = AHCI_READ(sc, AHCI_PI);
    392   1.50      matt 		AHCIDEBUG_PRINT(("active ports %#x\n", sc->sc_ahci_ports),
    393   1.50      matt 		    DEBUG_PROBE);
    394   1.50      matt 	}
    395    1.1    bouyer 	for (i = 0, port = 0; i < AHCI_MAX_PORTS; i++) {
    396   1.62     kamil 		if ((sc->sc_ahci_ports & (1U << i)) == 0)
    397    1.1    bouyer 			continue;
    398    1.1    bouyer 		if (port >= sc->sc_atac.atac_nchannels) {
    399    1.1    bouyer 			aprint_error("%s: more ports than announced\n",
    400    1.1    bouyer 			    AHCINAME(sc));
    401    1.1    bouyer 			break;
    402    1.1    bouyer 		}
    403   1.72  jdolecek 
    404   1.72  jdolecek 		/* Optional intr establish per active port */
    405   1.72  jdolecek 		if (sc->sc_intr_establish && sc->sc_intr_establish(sc, i) != 0){
    406   1.72  jdolecek 			aprint_error("%s: intr establish hook failed\n",
    407   1.72  jdolecek 			    AHCINAME(sc));
    408   1.72  jdolecek 			break;
    409   1.72  jdolecek 		}
    410   1.72  jdolecek 
    411    1.1    bouyer 		achp = &sc->sc_channels[i];
    412   1.29  jakllsch 		chp = &achp->ata_channel;
    413    1.1    bouyer 		sc->sc_chanarray[i] = chp;
    414    1.1    bouyer 		chp->ch_channel = i;
    415    1.1    bouyer 		chp->ch_atac = &sc->sc_atac;
    416   1.58  jdolecek 		chp->ch_queue = ata_queue_alloc(sc->sc_ncmds);
    417    1.1    bouyer 		if (chp->ch_queue == NULL) {
    418    1.1    bouyer 			aprint_error("%s port %d: can't allocate memory for "
    419    1.1    bouyer 			    "command queue", AHCINAME(sc), i);
    420    1.1    bouyer 			break;
    421    1.1    bouyer 		}
    422    1.1    bouyer 		dmasize = AHCI_CMDTBL_SIZE * sc->sc_ncmds;
    423    1.1    bouyer 		error = bus_dmamem_alloc(sc->sc_dmat, dmasize, PAGE_SIZE, 0,
    424   1.29  jakllsch 		    &achp->ahcic_cmd_tbl_seg, 1, &achp->ahcic_cmd_tbl_nseg,
    425   1.29  jakllsch 		    BUS_DMA_NOWAIT);
    426    1.1    bouyer 		if (error) {
    427    1.1    bouyer 			aprint_error("%s: unable to allocate command table "
    428    1.1    bouyer 			    "memory, error=%d\n", AHCINAME(sc), error);
    429    1.1    bouyer 			break;
    430    1.1    bouyer 		}
    431   1.29  jakllsch 		error = bus_dmamem_map(sc->sc_dmat, &achp->ahcic_cmd_tbl_seg,
    432   1.29  jakllsch 		    achp->ahcic_cmd_tbl_nseg, dmasize,
    433    1.1    bouyer 		    &cmdtblp, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
    434    1.1    bouyer 		if (error) {
    435    1.1    bouyer 			aprint_error("%s: unable to map command table memory"
    436    1.1    bouyer 			    ", error=%d\n", AHCINAME(sc), error);
    437    1.1    bouyer 			break;
    438    1.1    bouyer 		}
    439    1.1    bouyer 		error = bus_dmamap_create(sc->sc_dmat, dmasize, 1, dmasize, 0,
    440    1.1    bouyer 		    BUS_DMA_NOWAIT, &achp->ahcic_cmd_tbld);
    441    1.1    bouyer 		if (error) {
    442    1.1    bouyer 			aprint_error("%s: unable to create command table map"
    443    1.1    bouyer 			    ", error=%d\n", AHCINAME(sc), error);
    444    1.1    bouyer 			break;
    445    1.1    bouyer 		}
    446    1.1    bouyer 		error = bus_dmamap_load(sc->sc_dmat, achp->ahcic_cmd_tbld,
    447    1.1    bouyer 		    cmdtblp, dmasize, NULL, BUS_DMA_NOWAIT);
    448    1.1    bouyer 		if (error) {
    449    1.1    bouyer 			aprint_error("%s: unable to load command table map"
    450    1.1    bouyer 			    ", error=%d\n", AHCINAME(sc), error);
    451    1.1    bouyer 			break;
    452    1.1    bouyer 		}
    453   1.88  jmcneill 		memset(cmdtblp, 0, dmasize);
    454   1.88  jmcneill 		bus_dmamap_sync(sc->sc_dmat, achp->ahcic_cmd_tbld, 0,
    455   1.88  jmcneill 		    dmasize, BUS_DMASYNC_PREWRITE);
    456    1.1    bouyer 		achp->ahcic_cmdh  = (struct ahci_cmd_header *)
    457    1.1    bouyer 		    ((char *)cmdhp + AHCI_CMDH_SIZE * port);
    458    1.1    bouyer 		achp->ahcic_bus_cmdh = sc->sc_cmd_hdrd->dm_segs[0].ds_addr +
    459    1.1    bouyer 		    AHCI_CMDH_SIZE * port;
    460    1.1    bouyer 		achp->ahcic_rfis = (struct ahci_r_fis *)
    461   1.87     skrll 		    ((char *)cmdhp +
    462   1.87     skrll 		     AHCI_CMDH_SIZE * sc->sc_atac.atac_nchannels +
    463    1.1    bouyer 		     AHCI_RFIS_SIZE * port);
    464    1.1    bouyer 		achp->ahcic_bus_rfis = sc->sc_cmd_hdrd->dm_segs[0].ds_addr +
    465   1.87     skrll 		     AHCI_CMDH_SIZE * sc->sc_atac.atac_nchannels +
    466    1.1    bouyer 		     AHCI_RFIS_SIZE * port;
    467   1.28  jakllsch 		AHCIDEBUG_PRINT(("port %d cmdh %p (0x%" PRIx64 ") "
    468   1.28  jakllsch 				         "rfis %p (0x%" PRIx64 ")\n", i,
    469   1.28  jakllsch 		   achp->ahcic_cmdh, (uint64_t)achp->ahcic_bus_cmdh,
    470   1.28  jakllsch 		   achp->ahcic_rfis, (uint64_t)achp->ahcic_bus_rfis),
    471    1.1    bouyer 		   DEBUG_PROBE);
    472   1.87     skrll 
    473    1.1    bouyer 		for (j = 0; j < sc->sc_ncmds; j++) {
    474    1.1    bouyer 			achp->ahcic_cmd_tbl[j] = (struct ahci_cmd_tbl *)
    475    1.1    bouyer 			    ((char *)cmdtblp + AHCI_CMDTBL_SIZE * j);
    476    1.1    bouyer 			achp->ahcic_bus_cmd_tbl[j] =
    477    1.1    bouyer 			     achp->ahcic_cmd_tbld->dm_segs[0].ds_addr +
    478    1.1    bouyer 			     AHCI_CMDTBL_SIZE * j;
    479    1.1    bouyer 			achp->ahcic_cmdh[j].cmdh_cmdtba =
    480   1.28  jakllsch 			    htole64(achp->ahcic_bus_cmd_tbl[j]);
    481   1.28  jakllsch 			AHCIDEBUG_PRINT(("port %d/%d tbl %p (0x%" PRIx64 ")\n", i, j,
    482    1.1    bouyer 			    achp->ahcic_cmd_tbl[j],
    483   1.28  jakllsch 			    (uint64_t)achp->ahcic_bus_cmd_tbl[j]), DEBUG_PROBE);
    484    1.1    bouyer 			/* The xfer DMA map */
    485    1.1    bouyer 			error = bus_dmamap_create(sc->sc_dmat, MAXPHYS,
    486    1.1    bouyer 			    AHCI_NPRD, 0x400000 /* 4MB */, 0,
    487    1.1    bouyer 			    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
    488    1.1    bouyer 			    &achp->ahcic_datad[j]);
    489    1.1    bouyer 			if (error) {
    490    1.1    bouyer 				aprint_error("%s: couldn't alloc xfer DMA map, "
    491    1.1    bouyer 				    "error=%d\n", AHCINAME(sc), error);
    492    1.1    bouyer 				goto end;
    493    1.1    bouyer 			}
    494    1.1    bouyer 		}
    495    1.7     joerg 		ahci_setup_port(sc, i);
    496    1.1    bouyer 		if (bus_space_subregion(sc->sc_ahcit, sc->sc_ahcih,
    497   1.22  jakllsch 		    AHCI_P_SSTS(i), 4,  &achp->ahcic_sstatus) != 0) {
    498   1.67  jdolecek 			aprint_error("%s: couldn't map port %d "
    499    1.1    bouyer 			    "sata_status regs\n", AHCINAME(sc), i);
    500    1.1    bouyer 			break;
    501    1.1    bouyer 		}
    502    1.1    bouyer 		if (bus_space_subregion(sc->sc_ahcit, sc->sc_ahcih,
    503   1.22  jakllsch 		    AHCI_P_SCTL(i), 4,  &achp->ahcic_scontrol) != 0) {
    504   1.67  jdolecek 			aprint_error("%s: couldn't map port %d "
    505    1.1    bouyer 			    "sata_control regs\n", AHCINAME(sc), i);
    506    1.1    bouyer 			break;
    507    1.1    bouyer 		}
    508    1.1    bouyer 		if (bus_space_subregion(sc->sc_ahcit, sc->sc_ahcih,
    509   1.22  jakllsch 		    AHCI_P_SERR(i), 4,  &achp->ahcic_serror) != 0) {
    510   1.67  jdolecek 			aprint_error("%s: couldn't map port %d "
    511    1.1    bouyer 			    "sata_error regs\n", AHCINAME(sc), i);
    512    1.1    bouyer 			break;
    513    1.1    bouyer 		}
    514    1.1    bouyer 		ata_channel_attach(chp);
    515    1.1    bouyer 		port++;
    516    1.1    bouyer end:
    517    1.1    bouyer 		continue;
    518    1.1    bouyer 	}
    519    1.1    bouyer }
    520    1.1    bouyer 
    521   1.65  jdolecek void
    522   1.65  jdolecek ahci_childdetached(struct ahci_softc *sc, device_t child)
    523   1.65  jdolecek {
    524   1.65  jdolecek 	struct ahci_channel *achp;
    525   1.65  jdolecek 	struct ata_channel *chp;
    526   1.65  jdolecek 
    527   1.65  jdolecek 	for (int i = 0; i < AHCI_MAX_PORTS; i++) {
    528   1.65  jdolecek 		achp = &sc->sc_channels[i];
    529   1.65  jdolecek 		chp = &achp->ata_channel;
    530   1.65  jdolecek 
    531   1.65  jdolecek 		if ((sc->sc_ahci_ports & (1U << i)) == 0)
    532   1.65  jdolecek 			continue;
    533   1.65  jdolecek 
    534   1.65  jdolecek 		if (child == chp->atabus)
    535   1.65  jdolecek 			chp->atabus = NULL;
    536   1.65  jdolecek 	}
    537   1.65  jdolecek }
    538   1.65  jdolecek 
    539    1.1    bouyer int
    540   1.29  jakllsch ahci_detach(struct ahci_softc *sc, int flags)
    541   1.29  jakllsch {
    542   1.29  jakllsch 	struct atac_softc *atac;
    543   1.29  jakllsch 	struct ahci_channel *achp;
    544   1.29  jakllsch 	struct ata_channel *chp;
    545   1.29  jakllsch 	struct scsipi_adapter *adapt;
    546   1.66  jdolecek 	int i, j, port;
    547   1.29  jakllsch 	int error;
    548   1.29  jakllsch 
    549   1.29  jakllsch 	atac = &sc->sc_atac;
    550   1.29  jakllsch 	adapt = &atac->atac_atapi_adapter._generic;
    551   1.29  jakllsch 
    552   1.66  jdolecek 	for (i = 0, port = 0; i < AHCI_MAX_PORTS; i++) {
    553   1.29  jakllsch 		achp = &sc->sc_channels[i];
    554   1.29  jakllsch 		chp = &achp->ata_channel;
    555   1.29  jakllsch 
    556   1.62     kamil 		if ((sc->sc_ahci_ports & (1U << i)) == 0)
    557   1.29  jakllsch 			continue;
    558   1.66  jdolecek 		if (port >= sc->sc_atac.atac_nchannels) {
    559   1.29  jakllsch 			aprint_error("%s: more ports than announced\n",
    560   1.29  jakllsch 			    AHCINAME(sc));
    561   1.29  jakllsch 			break;
    562   1.29  jakllsch 		}
    563   1.29  jakllsch 
    564   1.65  jdolecek 		if (chp->atabus != NULL) {
    565   1.65  jdolecek 			if ((error = config_detach(chp->atabus, flags)) != 0)
    566   1.65  jdolecek 				return error;
    567   1.65  jdolecek 
    568   1.65  jdolecek 			KASSERT(chp->atabus == NULL);
    569   1.65  jdolecek 		}
    570   1.65  jdolecek 
    571   1.65  jdolecek 		if (chp->ch_flags & ATACH_DETACHED)
    572   1.29  jakllsch 			continue;
    573   1.29  jakllsch 
    574   1.29  jakllsch 		for (j = 0; j < sc->sc_ncmds; j++)
    575   1.29  jakllsch 			bus_dmamap_destroy(sc->sc_dmat, achp->ahcic_datad[j]);
    576   1.29  jakllsch 
    577   1.29  jakllsch 		bus_dmamap_unload(sc->sc_dmat, achp->ahcic_cmd_tbld);
    578   1.29  jakllsch 		bus_dmamap_destroy(sc->sc_dmat, achp->ahcic_cmd_tbld);
    579   1.29  jakllsch 		bus_dmamem_unmap(sc->sc_dmat, achp->ahcic_cmd_tbl[0],
    580   1.29  jakllsch 		    AHCI_CMDTBL_SIZE * sc->sc_ncmds);
    581   1.29  jakllsch 		bus_dmamem_free(sc->sc_dmat, &achp->ahcic_cmd_tbl_seg,
    582   1.29  jakllsch 		    achp->ahcic_cmd_tbl_nseg);
    583   1.29  jakllsch 
    584   1.58  jdolecek 		ata_channel_detach(chp);
    585   1.66  jdolecek 		port++;
    586   1.29  jakllsch 	}
    587   1.29  jakllsch 
    588   1.29  jakllsch 	bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_hdrd);
    589   1.29  jakllsch 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmd_hdrd);
    590   1.29  jakllsch 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_cmd_hdr,
    591   1.29  jakllsch 	    (AHCI_RFIS_SIZE + AHCI_CMDH_SIZE) * sc->sc_atac.atac_nchannels);
    592   1.29  jakllsch 	bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_hdr_seg, sc->sc_cmd_hdr_nseg);
    593   1.29  jakllsch 
    594   1.29  jakllsch 	if (adapt->adapt_refcnt != 0)
    595   1.29  jakllsch 		return EBUSY;
    596   1.29  jakllsch 
    597   1.29  jakllsch 	return 0;
    598   1.29  jakllsch }
    599   1.29  jakllsch 
    600   1.29  jakllsch void
    601   1.29  jakllsch ahci_resume(struct ahci_softc *sc)
    602   1.29  jakllsch {
    603   1.29  jakllsch 	ahci_reset(sc);
    604   1.29  jakllsch 	ahci_setup_ports(sc);
    605   1.29  jakllsch 	ahci_reprobe_drives(sc);
    606   1.29  jakllsch 	ahci_enable_intrs(sc);
    607   1.29  jakllsch }
    608   1.29  jakllsch 
    609   1.29  jakllsch int
    610    1.1    bouyer ahci_intr(void *v)
    611    1.1    bouyer {
    612    1.1    bouyer 	struct ahci_softc *sc = v;
    613   1.89  jmcneill 	uint32_t is, ports;
    614   1.89  jmcneill 	int bit, r = 0;
    615    1.1    bouyer 
    616    1.1    bouyer 	while ((is = AHCI_READ(sc, AHCI_IS))) {
    617    1.1    bouyer 		AHCIDEBUG_PRINT(("%s ahci_intr 0x%x\n", AHCINAME(sc), is),
    618    1.1    bouyer 		    DEBUG_INTR);
    619    1.1    bouyer 		r = 1;
    620   1.89  jmcneill 		ports = is;
    621   1.89  jmcneill 		while ((bit = ffs(ports)) != 0) {
    622   1.89  jmcneill 			bit--;
    623   1.91  jmcneill 			ahci_intr_port_common(&sc->sc_channels[bit].ata_channel);
    624   1.96     skrll 			ports &= ~__BIT(bit);
    625   1.89  jmcneill 		}
    626   1.90  jmcneill 		AHCI_WRITE(sc, AHCI_IS, is);
    627    1.1    bouyer 	}
    628   1.72  jdolecek 
    629    1.1    bouyer 	return r;
    630    1.1    bouyer }
    631    1.1    bouyer 
    632   1.72  jdolecek int
    633   1.72  jdolecek ahci_intr_port(void *v)
    634    1.1    bouyer {
    635   1.72  jdolecek 	struct ahci_channel *achp = v;
    636   1.72  jdolecek 	struct ata_channel *chp = &achp->ata_channel;
    637   1.72  jdolecek 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
    638   1.91  jmcneill 	int ret;
    639   1.91  jmcneill 
    640   1.91  jmcneill 	ret = ahci_intr_port_common(chp);
    641   1.91  jmcneill 	if (ret) {
    642   1.91  jmcneill 		AHCI_WRITE(sc, AHCI_IS, 1U << chp->ch_channel);
    643   1.91  jmcneill 	}
    644   1.91  jmcneill 
    645   1.91  jmcneill 	return ret;
    646   1.91  jmcneill }
    647   1.91  jmcneill 
    648   1.91  jmcneill static int
    649   1.91  jmcneill ahci_intr_port_common(struct ata_channel *chp)
    650   1.91  jmcneill {
    651   1.91  jmcneill 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
    652   1.58  jdolecek 	uint32_t is, tfd, sact;
    653   1.58  jdolecek 	struct ata_xfer *xfer;
    654   1.58  jdolecek 	int slot = -1;
    655   1.58  jdolecek 	bool recover = false;
    656   1.64  jdolecek 	uint32_t aslots;
    657    1.1    bouyer 
    658    1.1    bouyer 	is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
    659    1.1    bouyer 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), is);
    660   1.60  jdolecek 
    661   1.91  jmcneill 	AHCIDEBUG_PRINT(("ahci_intr_port_common %s port %d "
    662   1.91  jmcneill 	    "is 0x%x CI 0x%x SACT 0x%x TFD 0x%x\n",
    663   1.58  jdolecek 	    AHCINAME(sc),
    664   1.58  jdolecek 	    chp->ch_channel, is,
    665   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)),
    666   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel)),
    667   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel))),
    668    1.1    bouyer 	    DEBUG_INTR);
    669    1.1    bouyer 
    670   1.58  jdolecek 	if ((chp->ch_flags & ATACH_NCQ) == 0) {
    671   1.58  jdolecek 		/* Non-NCQ operation */
    672   1.58  jdolecek 		sact = AHCI_READ(sc, AHCI_P_CI(chp->ch_channel));
    673   1.58  jdolecek 	} else {
    674   1.58  jdolecek 		/* NCQ operation */
    675   1.58  jdolecek 		sact = AHCI_READ(sc, AHCI_P_SACT(chp->ch_channel));
    676   1.58  jdolecek 	}
    677   1.58  jdolecek 
    678   1.58  jdolecek 	/* Handle errors */
    679   1.58  jdolecek 	if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS |
    680   1.58  jdolecek 	    AHCI_P_IX_IFS | AHCI_P_IX_OFS | AHCI_P_IX_UFS)) {
    681   1.58  jdolecek 		/* Fatal errors */
    682    1.1    bouyer 		if (is & AHCI_P_IX_TFES) {
    683    1.1    bouyer 			tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
    684   1.58  jdolecek 
    685   1.58  jdolecek 			if ((chp->ch_flags & ATACH_NCQ) == 0) {
    686   1.58  jdolecek 				/* Slot valid only for Non-NCQ operation */
    687   1.58  jdolecek 				slot = (AHCI_READ(sc,
    688   1.58  jdolecek 				    AHCI_P_CMD(chp->ch_channel))
    689   1.58  jdolecek 				    & AHCI_P_CMD_CCS_MASK)
    690   1.58  jdolecek 				    >> AHCI_P_CMD_CCS_SHIFT;
    691   1.58  jdolecek 			}
    692   1.58  jdolecek 
    693   1.60  jdolecek 			AHCIDEBUG_PRINT((
    694   1.60  jdolecek 			    "%s port %d: TFE: sact 0x%x is 0x%x tfd 0x%x\n",
    695   1.60  jdolecek 			    AHCINAME(sc), chp->ch_channel, sact, is, tfd),
    696   1.60  jdolecek 			    DEBUG_INTR);
    697    1.1    bouyer 		} else {
    698   1.58  jdolecek 			/* mark an error, and set BSY */
    699   1.58  jdolecek 			tfd = (WDCE_ABRT << AHCI_P_TFD_ERR_SHIFT) |
    700   1.58  jdolecek 			    WDCS_ERR | WDCS_BSY;
    701    1.1    bouyer 		}
    702   1.58  jdolecek 
    703   1.40    bouyer 		if (is & AHCI_P_IX_IFS) {
    704   1.60  jdolecek 			AHCIDEBUG_PRINT(("%s port %d: SERR 0x%x\n",
    705   1.40    bouyer 			    AHCINAME(sc), chp->ch_channel,
    706   1.60  jdolecek 			    AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel))),
    707   1.60  jdolecek 			    DEBUG_INTR);
    708   1.40    bouyer 		}
    709   1.58  jdolecek 
    710   1.64  jdolecek 		if (!ISSET(chp->ch_flags, ATACH_RECOVERING))
    711   1.58  jdolecek 			recover = true;
    712   1.58  jdolecek 	} else if (is & (AHCI_P_IX_DHRS|AHCI_P_IX_SDBS)) {
    713   1.58  jdolecek 		tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
    714   1.58  jdolecek 
    715   1.58  jdolecek 		/* D2H Register FIS or Set Device Bits */
    716   1.58  jdolecek 		if ((tfd & WDCS_ERR) != 0) {
    717   1.64  jdolecek 			if (!ISSET(chp->ch_flags, ATACH_RECOVERING))
    718   1.58  jdolecek 				recover = true;
    719   1.58  jdolecek 
    720   1.60  jdolecek 			AHCIDEBUG_PRINT(("%s port %d: transfer aborted 0x%x\n",
    721   1.60  jdolecek 			    AHCINAME(sc), chp->ch_channel, tfd), DEBUG_INTR);
    722   1.58  jdolecek 		}
    723   1.58  jdolecek 	} else {
    724   1.58  jdolecek 		tfd = 0;
    725   1.58  jdolecek 	}
    726   1.58  jdolecek 
    727   1.58  jdolecek 	if (__predict_false(recover))
    728   1.58  jdolecek 		ata_channel_freeze(chp);
    729   1.58  jdolecek 
    730   1.64  jdolecek 	aslots = ata_queue_active(chp);
    731   1.64  jdolecek 
    732   1.58  jdolecek 	if (slot >= 0) {
    733   1.64  jdolecek 		if ((aslots & __BIT(slot)) != 0 &&
    734   1.58  jdolecek 		    (sact & __BIT(slot)) == 0) {
    735   1.58  jdolecek 			xfer = ata_queue_hwslot_to_xfer(chp, slot);
    736   1.64  jdolecek 			xfer->ops->c_intr(chp, xfer, tfd);
    737   1.58  jdolecek 		}
    738    1.1    bouyer 	} else {
    739   1.58  jdolecek 		/*
    740   1.58  jdolecek 		 * For NCQ, HBA halts processing when error is notified,
    741   1.58  jdolecek 		 * and any further D2H FISes are ignored until the error
    742   1.58  jdolecek 		 * condition is cleared. Hence if a command is inactive,
    743   1.58  jdolecek 		 * it means it actually already finished successfully.
    744   1.58  jdolecek 		 * Note: active slots can change as c_intr() callback
    745   1.58  jdolecek 		 * can activate another command(s), so must only process
    746   1.58  jdolecek 		 * commands active before we start processing.
    747   1.58  jdolecek 		 */
    748   1.58  jdolecek 
    749   1.95     skrll 		for (slot = 0; slot < sc->sc_ncmds; slot++) {
    750   1.58  jdolecek 			if ((aslots & __BIT(slot)) != 0 &&
    751   1.58  jdolecek 			    (sact & __BIT(slot)) == 0) {
    752   1.58  jdolecek 				xfer = ata_queue_hwslot_to_xfer(chp, slot);
    753   1.64  jdolecek 				xfer->ops->c_intr(chp, xfer, tfd);
    754   1.58  jdolecek 			}
    755    1.1    bouyer 		}
    756    1.1    bouyer 	}
    757   1.58  jdolecek 
    758   1.58  jdolecek 	if (__predict_false(recover)) {
    759   1.64  jdolecek 		ata_channel_lock(chp);
    760   1.64  jdolecek 		ata_channel_thaw_locked(chp);
    761   1.87     skrll 		ata_thread_run(chp, 0, ATACH_TH_RECOVERY, tfd);
    762   1.64  jdolecek 		ata_channel_unlock(chp);
    763   1.58  jdolecek 	}
    764   1.72  jdolecek 
    765   1.72  jdolecek 	return 1;
    766    1.1    bouyer }
    767    1.1    bouyer 
    768   1.29  jakllsch static void
    769   1.40    bouyer ahci_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp)
    770    1.1    bouyer {
    771    1.1    bouyer 	struct ata_channel *chp = drvp->chnl_softc;
    772   1.40    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
    773   1.64  jdolecek 	uint8_t c_slot;
    774   1.58  jdolecek 
    775   1.64  jdolecek 	ata_channel_lock_owned(chp);
    776   1.58  jdolecek 
    777   1.64  jdolecek 	/* get a slot for running the command on */
    778   1.64  jdolecek 	if (!ata_queue_alloc_slot(chp, &c_slot, ATA_MAX_OPENINGS)) {
    779   1.64  jdolecek 		panic("%s: %s: failed to get xfer for reset, port %d\n",
    780   1.64  jdolecek 		    device_xname(sc->sc_atac.atac_dev),
    781   1.64  jdolecek 		    __func__, chp->ch_channel);
    782   1.64  jdolecek 		/* NOTREACHED */
    783   1.64  jdolecek 	}
    784   1.58  jdolecek 
    785   1.40    bouyer 	AHCI_WRITE(sc, AHCI_GHC,
    786   1.40    bouyer 	    AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
    787   1.40    bouyer 	ahci_channel_stop(sc, chp, flags);
    788   1.64  jdolecek 	ahci_do_reset_drive(chp, drvp->drive, flags, sigp, c_slot);
    789   1.40    bouyer 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
    790   1.58  jdolecek 
    791   1.64  jdolecek 	ata_queue_free_slot(chp, c_slot);
    792    1.1    bouyer }
    793    1.1    bouyer 
    794   1.40    bouyer /* return error code from ata_bio */
    795   1.40    bouyer static int
    796   1.58  jdolecek ahci_exec_fis(struct ata_channel *chp, int timeout, int flags, int slot)
    797   1.40    bouyer {
    798   1.40    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
    799   1.40    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
    800   1.40    bouyer 	int i;
    801   1.40    bouyer 	uint32_t is;
    802   1.40    bouyer 
    803   1.52     joerg 	/*
    804   1.84  jmcneill 	 * Base timeout is specified in ms. Delay for 10ms
    805   1.84  jmcneill 	 * on each round.
    806   1.52     joerg 	 */
    807   1.84  jmcneill 	timeout = timeout / 10;
    808   1.52     joerg 
    809   1.77  jakllsch 	AHCI_CMDTBL_SYNC(sc, achp, slot, BUS_DMASYNC_PREWRITE);
    810   1.58  jdolecek 	AHCI_CMDH_SYNC(sc, achp, slot,
    811   1.58  jdolecek 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    812   1.40    bouyer 	/* start command */
    813   1.62     kamil 	AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1U << slot);
    814   1.40    bouyer 	for (i = 0; i < timeout; i++) {
    815   1.62     kamil 		if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & (1U << slot)) ==
    816   1.58  jdolecek 		    0)
    817   1.40    bouyer 			return 0;
    818   1.40    bouyer 		is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel));
    819   1.58  jdolecek 		if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS |
    820   1.58  jdolecek 		    AHCI_P_IX_IFS |
    821   1.40    bouyer 		    AHCI_P_IX_OFS | AHCI_P_IX_UFS)) {
    822   1.40    bouyer 			if ((is & (AHCI_P_IX_DHRS|AHCI_P_IX_TFES)) ==
    823   1.40    bouyer 			    (AHCI_P_IX_DHRS|AHCI_P_IX_TFES)) {
    824   1.40    bouyer 				/*
    825   1.40    bouyer 				 * we got the D2H FIS anyway,
    826   1.40    bouyer 				 * assume sig is valid.
    827   1.40    bouyer 				 * channel is restarted later
    828   1.40    bouyer 				 */
    829   1.40    bouyer 				return ERROR;
    830   1.40    bouyer 			}
    831  1.107   mlelstv 			aprint_debug("%s port %d: error 0x%x sending FIS\n",
    832  1.107   mlelstv 			    AHCINAME(sc), chp->ch_channel, is);
    833   1.40    bouyer 			return ERR_DF;
    834   1.40    bouyer 		}
    835   1.58  jdolecek 		ata_delay(chp, 10, "ahcifis", flags);
    836   1.40    bouyer 	}
    837   1.52     joerg 
    838   1.67  jdolecek 	aprint_debug("%s port %d: timeout sending FIS\n",
    839   1.40    bouyer 	    AHCINAME(sc), chp->ch_channel);
    840   1.40    bouyer 	return TIMEOUT;
    841   1.40    bouyer }
    842   1.40    bouyer 
    843   1.40    bouyer static int
    844   1.40    bouyer ahci_do_reset_drive(struct ata_channel *chp, int drive, int flags,
    845   1.64  jdolecek     uint32_t *sigp, uint8_t c_slot)
    846   1.40    bouyer {
    847   1.40    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
    848   1.40    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
    849   1.40    bouyer 	struct ahci_cmd_tbl *cmd_tbl;
    850   1.40    bouyer 	struct ahci_cmd_header *cmd_h;
    851   1.68  jdolecek 	int i, error = 0;
    852   1.79  jmcneill 	uint32_t sig, cmd;
    853   1.85  jmcneill 	int noclo_retry = 0, retry;
    854   1.40    bouyer 
    855   1.58  jdolecek 	ata_channel_lock_owned(chp);
    856   1.58  jdolecek 
    857   1.75    bouyer again:
    858   1.40    bouyer 	/* clear port interrupt register */
    859   1.40    bouyer 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff);
    860   1.40    bouyer 	/* clear SErrors and start operations */
    861   1.40    bouyer 	if ((sc->sc_ahci_cap & AHCI_CAP_CLO) == AHCI_CAP_CLO) {
    862   1.40    bouyer 		/*
    863   1.40    bouyer 		 * issue a command list override to clear BSY.
    864   1.40    bouyer 		 * This is needed if there's a PMP with no drive
    865   1.40    bouyer 		 * on port 0
    866   1.40    bouyer 		 */
    867   1.40    bouyer 		ahci_channel_start(sc, chp, flags, 1);
    868   1.40    bouyer 	} else {
    869   1.68  jdolecek 		/* Can't handle command still running without CLO */
    870   1.79  jmcneill 		cmd = AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel));
    871   1.79  jmcneill 		if ((cmd & AHCI_P_CMD_CR) != 0) {
    872   1.79  jmcneill 			ahci_channel_stop(sc, chp, flags);
    873   1.79  jmcneill 			cmd = AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel));
    874   1.79  jmcneill 			if ((cmd & AHCI_P_CMD_CR) != 0) {
    875   1.79  jmcneill 				aprint_error("%s port %d: DMA engine busy "
    876   1.79  jmcneill 				    "for drive %d\n", AHCINAME(sc),
    877   1.79  jmcneill 				    chp->ch_channel, drive);
    878   1.79  jmcneill 				error = EBUSY;
    879   1.79  jmcneill 				goto end;
    880   1.79  jmcneill 			}
    881   1.79  jmcneill 		}
    882   1.79  jmcneill 
    883   1.68  jdolecek 		KASSERT((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) == 0);
    884   1.68  jdolecek 
    885   1.40    bouyer 		ahci_channel_start(sc, chp, flags, 0);
    886   1.40    bouyer 	}
    887   1.40    bouyer 	if (drive > 0) {
    888   1.40    bouyer 		KASSERT(sc->sc_ahci_cap & AHCI_CAP_SPM);
    889   1.40    bouyer 	}
    890   1.54  jmcneill 
    891   1.40    bouyer 	/* polled command, assume interrupts are disabled */
    892   1.58  jdolecek 
    893   1.64  jdolecek 	cmd_h = &achp->ahcic_cmdh[c_slot];
    894   1.64  jdolecek 	cmd_tbl = achp->ahcic_cmd_tbl[c_slot];
    895   1.40    bouyer 	cmd_h->cmdh_flags = htole16(AHCI_CMDH_F_RST | AHCI_CMDH_F_CBSY |
    896   1.40    bouyer 	    RHD_FISLEN / 4 | (drive << AHCI_CMDH_F_PMP_SHIFT));
    897   1.76  jakllsch 	cmd_h->cmdh_prdtl = 0;
    898   1.40    bouyer 	cmd_h->cmdh_prdbc = 0;
    899   1.40    bouyer 	memset(cmd_tbl->cmdt_cfis, 0, 64);
    900   1.40    bouyer 	cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE;
    901   1.40    bouyer 	cmd_tbl->cmdt_cfis[rhd_c] = drive;
    902   1.70  jdolecek 	cmd_tbl->cmdt_cfis[rhd_control] = WDCTL_RST | WDCTL_4BIT;
    903   1.67  jdolecek 	switch (ahci_exec_fis(chp, 100, flags, c_slot)) {
    904   1.40    bouyer 	case ERR_DF:
    905   1.40    bouyer 	case TIMEOUT:
    906   1.75    bouyer 		/*
    907   1.75    bouyer 		 * without CLO we can't make sure a software reset will
    908   1.75    bouyer 		 * success, as the drive may still have BSY or DRQ set.
    909   1.75    bouyer 		 * in this case, reset the whole channel and retry the
    910   1.75    bouyer 		 * drive reset. The channel reset should clear BSY and DRQ
    911   1.75    bouyer 		 */
    912   1.75    bouyer 		if ((sc->sc_ahci_cap & AHCI_CAP_CLO) == 0 && noclo_retry == 0) {
    913   1.75    bouyer 			noclo_retry++;
    914   1.75    bouyer 			ahci_reset_channel(chp, flags);
    915   1.75    bouyer 			goto again;
    916   1.75    bouyer 		}
    917   1.67  jdolecek 		aprint_error("%s port %d: setting WDCTL_RST failed "
    918   1.40    bouyer 		    "for drive %d\n", AHCINAME(sc), chp->ch_channel, drive);
    919   1.68  jdolecek 		error = EBUSY;
    920   1.40    bouyer 		goto end;
    921   1.40    bouyer 	default:
    922   1.40    bouyer 		break;
    923   1.40    bouyer 	}
    924   1.68  jdolecek 
    925   1.69  jdolecek 	/*
    926   1.69  jdolecek 	 * SATA specification has toggle period for SRST bit of 5 usec. Some
    927   1.69  jdolecek 	 * controllers fail to process the SRST clear operation unless
    928   1.69  jdolecek 	 * we wait for at least this period between the set and clear commands.
    929   1.69  jdolecek 	 */
    930   1.69  jdolecek 	ata_delay(chp, 10, "ahcirstw", flags);
    931   1.69  jdolecek 
    932   1.85  jmcneill 	/*
    933   1.85  jmcneill 	 * Try to clear WDCTL_RST a few times before giving up.
    934   1.85  jmcneill 	 */
    935   1.85  jmcneill 	for (error = EBUSY, retry = 0; error != 0 && retry < 5; retry++) {
    936   1.85  jmcneill 		cmd_h->cmdh_flags = htole16(RHD_FISLEN / 4 |
    937   1.85  jmcneill 		    (drive << AHCI_CMDH_F_PMP_SHIFT));
    938   1.85  jmcneill 		cmd_h->cmdh_prdbc = 0;
    939   1.85  jmcneill 		memset(cmd_tbl->cmdt_cfis, 0, 64);
    940   1.85  jmcneill 		cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE;
    941   1.85  jmcneill 		cmd_tbl->cmdt_cfis[rhd_c] = drive;
    942   1.85  jmcneill 		cmd_tbl->cmdt_cfis[rhd_control] = WDCTL_4BIT;
    943   1.85  jmcneill 		switch (ahci_exec_fis(chp, 310, flags, c_slot)) {
    944   1.85  jmcneill 		case ERR_DF:
    945   1.85  jmcneill 		case TIMEOUT:
    946   1.85  jmcneill 			error = EBUSY;
    947   1.85  jmcneill 			break;
    948   1.85  jmcneill 		default:
    949   1.85  jmcneill 			error = 0;
    950   1.85  jmcneill 			break;
    951   1.85  jmcneill 		}
    952   1.85  jmcneill 		if (error == 0) {
    953   1.85  jmcneill 			break;
    954   1.85  jmcneill 		}
    955   1.85  jmcneill 	}
    956   1.85  jmcneill 	if (error == EBUSY) {
    957   1.67  jdolecek 		aprint_error("%s port %d: clearing WDCTL_RST failed "
    958   1.40    bouyer 		    "for drive %d\n", AHCINAME(sc), chp->ch_channel, drive);
    959   1.40    bouyer 		goto end;
    960   1.40    bouyer 	}
    961   1.54  jmcneill 
    962   1.40    bouyer 	/*
    963   1.40    bouyer 	 * wait 31s for BSY to clear
    964   1.40    bouyer 	 * This should not be needed, but some controllers clear the
    965   1.40    bouyer 	 * command slot before receiving the D2H FIS ...
    966   1.40    bouyer 	 */
    967   1.46      matt 	for (i = 0; i < AHCI_RST_WAIT; i++) {
    968   1.40    bouyer 		sig = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
    969   1.46      matt 		if ((__SHIFTOUT(sig, AHCI_P_TFD_ST) & WDCS_BSY) == 0)
    970   1.40    bouyer 			break;
    971   1.58  jdolecek 		ata_delay(chp, 10, "ahcid2h", flags);
    972   1.40    bouyer 	}
    973   1.40    bouyer 	if (i == AHCI_RST_WAIT) {
    974   1.40    bouyer 		aprint_error("%s: BSY never cleared, TD 0x%x\n",
    975   1.40    bouyer 		    AHCINAME(sc), sig);
    976   1.40    bouyer 		goto end;
    977   1.40    bouyer 	}
    978   1.40    bouyer 	AHCIDEBUG_PRINT(("%s: BSY took %d ms\n", AHCINAME(sc), i * 10),
    979   1.40    bouyer 	    DEBUG_PROBE);
    980   1.40    bouyer 	sig = AHCI_READ(sc, AHCI_P_SIG(chp->ch_channel));
    981   1.40    bouyer 	if (sigp)
    982   1.40    bouyer 		*sigp = sig;
    983   1.40    bouyer 	AHCIDEBUG_PRINT(("%s: port %d: sig=0x%x CMD=0x%x\n",
    984   1.40    bouyer 	    AHCINAME(sc), chp->ch_channel, sig,
    985   1.40    bouyer 	    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE);
    986   1.40    bouyer end:
    987   1.40    bouyer 	ahci_channel_stop(sc, chp, flags);
    988  1.105       rin 	AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahcirst", flags);
    989   1.40    bouyer 	/* clear port interrupt register */
    990   1.40    bouyer 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff);
    991   1.47    bouyer 	ahci_channel_start(sc, chp, flags,
    992   1.40    bouyer 	    (sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0);
    993   1.68  jdolecek 	return error;
    994   1.40    bouyer }
    995   1.40    bouyer 
    996   1.29  jakllsch static void
    997    1.1    bouyer ahci_reset_channel(struct ata_channel *chp, int flags)
    998    1.1    bouyer {
    999    1.1    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1000    1.1    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1001   1.18    bouyer 	int i, tfd;
   1002    1.1    bouyer 
   1003   1.64  jdolecek 	ata_channel_lock_owned(chp);
   1004   1.58  jdolecek 
   1005    1.5    bouyer 	ahci_channel_stop(sc, chp, flags);
   1006    1.1    bouyer 	if (sata_reset_interface(chp, sc->sc_ahcit, achp->ahcic_scontrol,
   1007   1.47    bouyer 	    achp->ahcic_sstatus, flags) != SStatus_DET_DEV) {
   1008   1.33  jakllsch 		printf("%s: port %d reset failed\n", AHCINAME(sc), chp->ch_channel);
   1009    1.1    bouyer 		/* XXX and then ? */
   1010    1.1    bouyer 	}
   1011   1.58  jdolecek 	ata_kill_active(chp, KILL_RESET, flags);
   1012  1.105       rin 	AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahcirst", flags);
   1013   1.24    bouyer 	/* clear port interrupt register */
   1014   1.24    bouyer 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff);
   1015   1.24    bouyer 	/* clear SErrors and start operations */
   1016   1.57  jmcneill 	ahci_channel_start(sc, chp, flags,
   1017   1.57  jmcneill 	    (sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0);
   1018   1.18    bouyer 	/* wait 31s for BSY to clear */
   1019   1.67  jdolecek 	for (i = 0; i < AHCI_RST_WAIT; i++) {
   1020   1.18    bouyer 		tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel));
   1021   1.58  jdolecek 		if ((AHCI_TFD_ST(tfd) & WDCS_BSY) == 0)
   1022    1.8    bouyer 			break;
   1023   1.58  jdolecek 		ata_delay(chp, 10, "ahcid2h", flags);
   1024    1.8    bouyer 	}
   1025   1.58  jdolecek 	if ((AHCI_TFD_ST(tfd) & WDCS_BSY) != 0)
   1026   1.18    bouyer 		aprint_error("%s: BSY never cleared, TD 0x%x\n",
   1027   1.18    bouyer 		    AHCINAME(sc), tfd);
   1028   1.18    bouyer 	AHCIDEBUG_PRINT(("%s: BSY took %d ms\n", AHCINAME(sc), i * 10),
   1029   1.18    bouyer 	    DEBUG_PROBE);
   1030    1.8    bouyer 	/* clear port interrupt register */
   1031    1.8    bouyer 	AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff);
   1032    1.8    bouyer 
   1033    1.1    bouyer 	return;
   1034    1.1    bouyer }
   1035    1.1    bouyer 
   1036   1.29  jakllsch static int
   1037    1.1    bouyer ahci_ata_addref(struct ata_drive_datas *drvp)
   1038    1.1    bouyer {
   1039    1.1    bouyer 	return 0;
   1040    1.1    bouyer }
   1041    1.1    bouyer 
   1042   1.29  jakllsch static void
   1043    1.1    bouyer ahci_ata_delref(struct ata_drive_datas *drvp)
   1044    1.1    bouyer {
   1045    1.1    bouyer 	return;
   1046    1.1    bouyer }
   1047    1.1    bouyer 
   1048   1.29  jakllsch static void
   1049    1.1    bouyer ahci_killpending(struct ata_drive_datas *drvp)
   1050    1.1    bouyer {
   1051    1.1    bouyer 	return;
   1052    1.1    bouyer }
   1053    1.1    bouyer 
   1054   1.29  jakllsch static void
   1055    1.1    bouyer ahci_probe_drive(struct ata_channel *chp)
   1056    1.1    bouyer {
   1057    1.1    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1058    1.1    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1059   1.27  jakllsch 	uint32_t sig;
   1060   1.64  jdolecek 	uint8_t c_slot;
   1061   1.68  jdolecek 	int error;
   1062   1.64  jdolecek 
   1063   1.64  jdolecek 	ata_channel_lock(chp);
   1064   1.58  jdolecek 
   1065   1.64  jdolecek 	/* get a slot for running the command on */
   1066   1.64  jdolecek 	if (!ata_queue_alloc_slot(chp, &c_slot, ATA_MAX_OPENINGS)) {
   1067   1.58  jdolecek 		aprint_error_dev(sc->sc_atac.atac_dev,
   1068   1.58  jdolecek 		    "%s: failed to get xfer port %d\n",
   1069   1.58  jdolecek 		    __func__, chp->ch_channel);
   1070   1.64  jdolecek 		ata_channel_unlock(chp);
   1071   1.58  jdolecek 		return;
   1072   1.64  jdolecek 	}
   1073    1.1    bouyer 
   1074   1.18    bouyer 	/* bring interface up, accept FISs, power up and spin up device */
   1075    1.1    bouyer 	AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
   1076   1.18    bouyer 	    AHCI_P_CMD_ICC_AC | AHCI_P_CMD_FRE |
   1077   1.18    bouyer 	    AHCI_P_CMD_POD | AHCI_P_CMD_SUD);
   1078    1.1    bouyer 	/* reset the PHY and bring online */
   1079    1.1    bouyer 	switch (sata_reset_interface(chp, sc->sc_ahcit, achp->ahcic_scontrol,
   1080   1.47    bouyer 	    achp->ahcic_sstatus, AT_WAIT)) {
   1081    1.1    bouyer 	case SStatus_DET_DEV:
   1082  1.105       rin 		AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahcidv", AT_WAIT);
   1083   1.68  jdolecek 
   1084   1.74  jdolecek 		/* Initial value, used in case the soft reset fails */
   1085   1.74  jdolecek 		sig = AHCI_READ(sc, AHCI_P_SIG(chp->ch_channel));
   1086   1.74  jdolecek 
   1087   1.40    bouyer 		if (sc->sc_ahci_cap & AHCI_CAP_SPM) {
   1088   1.68  jdolecek 			error = ahci_do_reset_drive(chp, PMP_PORT_CTL, AT_WAIT,
   1089   1.68  jdolecek 			    &sig, c_slot);
   1090   1.68  jdolecek 
   1091   1.68  jdolecek 			/* If probe for PMP failed, just fallback to drive 0 */
   1092   1.68  jdolecek 			if (error) {
   1093   1.68  jdolecek 				aprint_error("%s port %d: drive %d reset "
   1094   1.71  jdolecek 				    "failed, disabling PMP\n",
   1095   1.68  jdolecek 				    AHCINAME(sc), chp->ch_channel,
   1096   1.68  jdolecek 				PMP_PORT_CTL);
   1097   1.68  jdolecek 
   1098   1.68  jdolecek 				sc->sc_ahci_cap &= ~AHCI_CAP_SPM;
   1099   1.74  jdolecek 				ahci_reset_channel(chp, AT_WAIT);
   1100   1.68  jdolecek 			}
   1101   1.40    bouyer 		} else {
   1102   1.64  jdolecek 			ahci_do_reset_drive(chp, 0, AT_WAIT, &sig, c_slot);
   1103    1.8    bouyer 		}
   1104   1.40    bouyer 		sata_interpret_sig(chp, 0, sig);
   1105   1.40    bouyer 		/* if we have a PMP attached, inform the controller */
   1106   1.40    bouyer 		if (chp->ch_ndrives > PMP_PORT_CTL &&
   1107   1.40    bouyer 		    chp->ch_drive[PMP_PORT_CTL].drive_type == ATA_DRIVET_PM) {
   1108   1.40    bouyer 			AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
   1109   1.40    bouyer 			    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) |
   1110   1.40    bouyer 			    AHCI_P_CMD_PMA);
   1111   1.23    bouyer 		}
   1112   1.23    bouyer 		/* clear port interrupt register */
   1113   1.23    bouyer 		AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff);
   1114   1.64  jdolecek 
   1115   1.23    bouyer 		/* and enable interrupts */
   1116    1.1    bouyer 		AHCI_WRITE(sc, AHCI_P_IE(chp->ch_channel),
   1117   1.58  jdolecek 		    AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_HBDS |
   1118   1.58  jdolecek 		    AHCI_P_IX_IFS |
   1119    1.1    bouyer 		    AHCI_P_IX_OFS | AHCI_P_IX_DPS | AHCI_P_IX_UFS |
   1120   1.58  jdolecek 		    AHCI_P_IX_PSS | AHCI_P_IX_DHRS | AHCI_P_IX_SDBS);
   1121  1.105       rin 		/*
   1122  1.105       rin 		 * optionally, wait AHCISATA_EXTRA_DELAY_MS msec before
   1123  1.105       rin 		 * actually starting operations
   1124  1.105       rin 		 */
   1125  1.105       rin 		AHCISATA_DO_EXTRA_DELAY(sc, chp, "ahciprb", AT_WAIT);
   1126    1.1    bouyer 		break;
   1127    1.1    bouyer 
   1128    1.1    bouyer 	default:
   1129    1.1    bouyer 		break;
   1130    1.1    bouyer 	}
   1131   1.64  jdolecek 
   1132   1.64  jdolecek 	ata_queue_free_slot(chp, c_slot);
   1133   1.64  jdolecek 
   1134   1.58  jdolecek 	ata_channel_unlock(chp);
   1135    1.1    bouyer }
   1136    1.1    bouyer 
   1137   1.29  jakllsch static void
   1138    1.1    bouyer ahci_setup_channel(struct ata_channel *chp)
   1139    1.1    bouyer {
   1140    1.1    bouyer 	return;
   1141    1.1    bouyer }
   1142    1.1    bouyer 
   1143   1.64  jdolecek static const struct ata_xfer_ops ahci_cmd_xfer_ops = {
   1144   1.64  jdolecek 	.c_start = ahci_cmd_start,
   1145   1.64  jdolecek 	.c_poll = ahci_cmd_poll,
   1146   1.64  jdolecek 	.c_abort = ahci_cmd_abort,
   1147   1.64  jdolecek 	.c_intr = ahci_cmd_complete,
   1148   1.64  jdolecek 	.c_kill_xfer = ahci_cmd_kill_xfer,
   1149   1.64  jdolecek };
   1150   1.64  jdolecek 
   1151   1.83  jdolecek static void
   1152   1.58  jdolecek ahci_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
   1153    1.1    bouyer {
   1154    1.1    bouyer 	struct ata_channel *chp = drvp->chnl_softc;
   1155   1.58  jdolecek 	struct ata_command *ata_c = &xfer->c_ata_c;
   1156    1.1    bouyer 
   1157    1.1    bouyer 	AHCIDEBUG_PRINT(("ahci_exec_command port %d CI 0x%x\n",
   1158   1.58  jdolecek 	    chp->ch_channel,
   1159   1.58  jdolecek 	    AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))),
   1160    1.1    bouyer 	    DEBUG_XFERS);
   1161    1.1    bouyer 	if (ata_c->flags & AT_POLL)
   1162    1.1    bouyer 		xfer->c_flags |= C_POLL;
   1163    1.1    bouyer 	if (ata_c->flags & AT_WAIT)
   1164    1.1    bouyer 		xfer->c_flags |= C_WAIT;
   1165    1.1    bouyer 	xfer->c_drive = drvp->drive;
   1166    1.1    bouyer 	xfer->c_databuf = ata_c->data;
   1167    1.1    bouyer 	xfer->c_bcount = ata_c->bcount;
   1168   1.64  jdolecek 	xfer->ops = &ahci_cmd_xfer_ops;
   1169   1.83  jdolecek 
   1170    1.1    bouyer 	ata_exec_xfer(chp, xfer);
   1171    1.1    bouyer }
   1172    1.1    bouyer 
   1173   1.58  jdolecek static int
   1174    1.1    bouyer ahci_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer)
   1175    1.1    bouyer {
   1176   1.58  jdolecek 	struct ahci_softc *sc = AHCI_CH2SC(chp);
   1177    1.1    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1178   1.58  jdolecek 	struct ata_command *ata_c = &xfer->c_ata_c;
   1179   1.58  jdolecek 	int slot = xfer->c_slot;
   1180    1.1    bouyer 	struct ahci_cmd_tbl *cmd_tbl;
   1181    1.1    bouyer 	struct ahci_cmd_header *cmd_h;
   1182    1.1    bouyer 
   1183   1.58  jdolecek 	AHCIDEBUG_PRINT(("ahci_cmd_start CI 0x%x timo %d\n slot %d",
   1184   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)),
   1185   1.58  jdolecek 	    ata_c->timeout, slot),
   1186   1.44      matt 	    DEBUG_XFERS);
   1187    1.1    bouyer 
   1188   1.58  jdolecek 	ata_channel_lock_owned(chp);
   1189   1.58  jdolecek 
   1190    1.1    bouyer 	cmd_tbl = achp->ahcic_cmd_tbl[slot];
   1191    1.1    bouyer 	AHCIDEBUG_PRINT(("%s port %d tbl %p\n", AHCINAME(sc), chp->ch_channel,
   1192   1.94     skrll 	    cmd_tbl), DEBUG_XFERS);
   1193    1.1    bouyer 
   1194   1.20  jakllsch 	satafis_rhd_construct_cmd(ata_c, cmd_tbl->cmdt_cfis);
   1195   1.40    bouyer 	cmd_tbl->cmdt_cfis[rhd_c] |= xfer->c_drive;
   1196    1.1    bouyer 
   1197    1.1    bouyer 	cmd_h = &achp->ahcic_cmdh[slot];
   1198    1.1    bouyer 	AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc),
   1199    1.1    bouyer 	    chp->ch_channel, cmd_h), DEBUG_XFERS);
   1200    1.1    bouyer 	if (ahci_dma_setup(chp, slot,
   1201   1.31   tsutsui 	    (ata_c->flags & (AT_READ|AT_WRITE) && ata_c->bcount > 0) ?
   1202   1.31   tsutsui 	    ata_c->data : NULL,
   1203    1.1    bouyer 	    ata_c->bcount,
   1204    1.1    bouyer 	    (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
   1205    1.1    bouyer 		ata_c->flags |= AT_DF;
   1206   1.58  jdolecek 		return ATASTART_ABORT;
   1207    1.1    bouyer 	}
   1208    1.1    bouyer 	cmd_h->cmdh_flags = htole16(
   1209    1.1    bouyer 	    ((ata_c->flags & AT_WRITE) ? AHCI_CMDH_F_WR : 0) |
   1210   1.40    bouyer 	    RHD_FISLEN / 4 | (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT));
   1211    1.1    bouyer 	cmd_h->cmdh_prdbc = 0;
   1212    1.1    bouyer 	AHCI_CMDH_SYNC(sc, achp, slot,
   1213    1.1    bouyer 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1214    1.1    bouyer 
   1215    1.1    bouyer 	if (ata_c->flags & AT_POLL) {
   1216    1.1    bouyer 		/* polled command, disable interrupts */
   1217    1.1    bouyer 		AHCI_WRITE(sc, AHCI_GHC,
   1218    1.1    bouyer 		    AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
   1219    1.1    bouyer 	}
   1220    1.1    bouyer 	/* start command */
   1221   1.62     kamil 	AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1U << slot);
   1222    1.1    bouyer 
   1223    1.1    bouyer 	if ((ata_c->flags & AT_POLL) == 0) {
   1224   1.64  jdolecek 		callout_reset(&chp->c_timo_callout, mstohz(ata_c->timeout),
   1225   1.64  jdolecek 		    ata_timeout, chp);
   1226   1.58  jdolecek 		return ATASTART_STARTED;
   1227   1.58  jdolecek 	} else
   1228   1.58  jdolecek 		return ATASTART_POLL;
   1229   1.58  jdolecek }
   1230   1.58  jdolecek 
   1231  1.102       rin static int
   1232   1.58  jdolecek ahci_cmd_poll(struct ata_channel *chp, struct ata_xfer *xfer)
   1233   1.58  jdolecek {
   1234   1.58  jdolecek 	struct ahci_softc *sc = AHCI_CH2SC(chp);
   1235   1.58  jdolecek 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1236   1.58  jdolecek 
   1237   1.58  jdolecek 	ata_channel_lock(chp);
   1238   1.58  jdolecek 
   1239    1.1    bouyer 	/*
   1240   1.87     skrll 	 * Polled command.
   1241    1.1    bouyer 	 */
   1242   1.58  jdolecek 	for (int i = 0; i < xfer->c_ata_c.timeout / 10; i++) {
   1243   1.58  jdolecek 		if (xfer->c_ata_c.flags & AT_DONE)
   1244    1.1    bouyer 			break;
   1245   1.58  jdolecek 		ata_channel_unlock(chp);
   1246   1.72  jdolecek 		ahci_intr_port(achp);
   1247   1.58  jdolecek 		ata_channel_lock(chp);
   1248   1.58  jdolecek 		ata_delay(chp, 10, "ahcipl", xfer->c_ata_c.flags);
   1249    1.1    bouyer 	}
   1250   1.87     skrll 	AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), chp->ch_channel,
   1251    1.1    bouyer 	    AHCI_READ(sc, AHCI_GHC), AHCI_READ(sc, AHCI_IS),
   1252   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CLBU(chp->ch_channel)),
   1253   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CLB(chp->ch_channel)),
   1254   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_FBU(chp->ch_channel)),
   1255   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_FB(chp->ch_channel)),
   1256   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)),
   1257   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
   1258    1.1    bouyer 	    DEBUG_XFERS);
   1259   1.58  jdolecek 
   1260   1.58  jdolecek 	ata_channel_unlock(chp);
   1261   1.58  jdolecek 
   1262   1.58  jdolecek 	if ((xfer->c_ata_c.flags & AT_DONE) == 0) {
   1263   1.58  jdolecek 		xfer->c_ata_c.flags |= AT_TIMEOU;
   1264   1.64  jdolecek 		xfer->ops->c_intr(chp, xfer, 0);
   1265    1.1    bouyer 	}
   1266    1.1    bouyer 	/* reenable interrupts */
   1267    1.1    bouyer 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
   1268  1.102       rin 
   1269  1.102       rin 	return ATAPOLL_DONE;
   1270    1.1    bouyer }
   1271    1.1    bouyer 
   1272   1.29  jakllsch static void
   1273   1.58  jdolecek ahci_cmd_abort(struct ata_channel *chp, struct ata_xfer *xfer)
   1274   1.58  jdolecek {
   1275   1.58  jdolecek 	ahci_cmd_complete(chp, xfer, 0);
   1276   1.58  jdolecek }
   1277   1.58  jdolecek 
   1278   1.58  jdolecek static void
   1279    1.1    bouyer ahci_cmd_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
   1280    1.1    bouyer {
   1281   1.58  jdolecek 	struct ata_command *ata_c = &xfer->c_ata_c;
   1282   1.58  jdolecek 	bool deactivate = true;
   1283   1.58  jdolecek 
   1284   1.67  jdolecek 	AHCIDEBUG_PRINT(("ahci_cmd_kill_xfer port %d\n", chp->ch_channel),
   1285    1.1    bouyer 	    DEBUG_FUNCS);
   1286    1.1    bouyer 
   1287    1.1    bouyer 	switch (reason) {
   1288   1.58  jdolecek 	case KILL_GONE_INACTIVE:
   1289   1.58  jdolecek 		deactivate = false;
   1290   1.58  jdolecek 		/* FALLTHROUGH */
   1291    1.1    bouyer 	case KILL_GONE:
   1292    1.1    bouyer 		ata_c->flags |= AT_GONE;
   1293    1.1    bouyer 		break;
   1294    1.1    bouyer 	case KILL_RESET:
   1295    1.1    bouyer 		ata_c->flags |= AT_RESET;
   1296    1.1    bouyer 		break;
   1297   1.58  jdolecek 	case KILL_REQUEUE:
   1298   1.58  jdolecek 		panic("%s: not supposed to be requeued\n", __func__);
   1299   1.58  jdolecek 		break;
   1300    1.1    bouyer 	default:
   1301    1.1    bouyer 		printf("ahci_cmd_kill_xfer: unknown reason %d\n", reason);
   1302    1.1    bouyer 		panic("ahci_cmd_kill_xfer");
   1303    1.1    bouyer 	}
   1304   1.58  jdolecek 
   1305   1.64  jdolecek 	ahci_cmd_done_end(chp, xfer);
   1306   1.64  jdolecek 
   1307   1.64  jdolecek 	if (deactivate)
   1308   1.58  jdolecek 		ata_deactivate_xfer(chp, xfer);
   1309    1.1    bouyer }
   1310    1.1    bouyer 
   1311   1.29  jakllsch static int
   1312   1.58  jdolecek ahci_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int tfd)
   1313    1.1    bouyer {
   1314   1.58  jdolecek 	struct ata_command *ata_c = &xfer->c_ata_c;
   1315   1.26  jakllsch 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1316   1.78  jakllsch 	struct ahci_softc *sc = AHCI_CH2SC(chp);
   1317    1.1    bouyer 
   1318   1.67  jdolecek 	AHCIDEBUG_PRINT(("ahci_cmd_complete port %d CMD 0x%x CI 0x%x\n",
   1319   1.58  jdolecek 	    chp->ch_channel,
   1320   1.58  jdolecek 	    AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CMD(chp->ch_channel)),
   1321   1.58  jdolecek 	    AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))),
   1322    1.1    bouyer 	    DEBUG_FUNCS);
   1323   1.58  jdolecek 
   1324   1.58  jdolecek 	if (ata_waitdrain_xfer_check(chp, xfer))
   1325   1.58  jdolecek 		return 0;
   1326   1.58  jdolecek 
   1327    1.1    bouyer 	if (xfer->c_flags & C_TIMEOU) {
   1328    1.1    bouyer 		ata_c->flags |= AT_TIMEOU;
   1329    1.1    bouyer 	}
   1330   1.26  jakllsch 
   1331   1.58  jdolecek 	if (AHCI_TFD_ST(tfd) & WDCS_BSY) {
   1332   1.26  jakllsch 		ata_c->flags |= AT_TIMEOU;
   1333   1.58  jdolecek 	} else if (AHCI_TFD_ST(tfd) & WDCS_ERR) {
   1334   1.58  jdolecek 		ata_c->r_error = AHCI_TFD_ERR(tfd);
   1335   1.26  jakllsch 		ata_c->flags |= AT_ERROR;
   1336    1.1    bouyer 	}
   1337   1.26  jakllsch 
   1338   1.78  jakllsch 	if (ata_c->flags & AT_READREG) {
   1339   1.78  jakllsch 		AHCI_RFIS_SYNC(sc, achp, BUS_DMASYNC_POSTREAD);
   1340   1.26  jakllsch 		satafis_rdh_cmd_readreg(ata_c, achp->ahcic_rfis->rfis_rfis);
   1341   1.78  jakllsch 	}
   1342   1.26  jakllsch 
   1343   1.58  jdolecek 	ahci_cmd_done(chp, xfer);
   1344   1.64  jdolecek 
   1345   1.64  jdolecek 	ata_deactivate_xfer(chp, xfer);
   1346   1.64  jdolecek 
   1347   1.64  jdolecek 	if ((ata_c->flags & (AT_TIMEOU|AT_ERROR)) == 0)
   1348   1.64  jdolecek 		atastart(chp);
   1349   1.64  jdolecek 
   1350    1.1    bouyer 	return 0;
   1351    1.1    bouyer }
   1352    1.1    bouyer 
   1353   1.29  jakllsch static void
   1354   1.58  jdolecek ahci_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer)
   1355    1.1    bouyer {
   1356    1.1    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1357    1.1    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1358   1.58  jdolecek 	struct ata_command *ata_c = &xfer->c_ata_c;
   1359   1.25  jakllsch 	uint16_t *idwordbuf;
   1360   1.25  jakllsch 	int i;
   1361    1.1    bouyer 
   1362   1.67  jdolecek 	AHCIDEBUG_PRINT(("ahci_cmd_done port %d flags %#x/%#x\n",
   1363   1.58  jdolecek 	    chp->ch_channel, xfer->c_flags, ata_c->flags), DEBUG_FUNCS);
   1364    1.1    bouyer 
   1365   1.31   tsutsui 	if (ata_c->flags & (AT_READ|AT_WRITE) && ata_c->bcount > 0) {
   1366   1.58  jdolecek 		bus_dmamap_t map = achp->ahcic_datad[xfer->c_slot];
   1367   1.44      matt 		bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
   1368    1.1    bouyer 		    (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD :
   1369    1.1    bouyer 		    BUS_DMASYNC_POSTWRITE);
   1370   1.44      matt 		bus_dmamap_unload(sc->sc_dmat, map);
   1371    1.1    bouyer 	}
   1372    1.1    bouyer 
   1373   1.58  jdolecek 	AHCI_CMDH_SYNC(sc, achp, xfer->c_slot,
   1374    1.2      fvdl 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1375    1.2      fvdl 
   1376  1.104   msaitoh 	/* ata(4) expects IDENTIFY data to be in host endianness */
   1377   1.25  jakllsch 	if (ata_c->r_command == WDCC_IDENTIFY ||
   1378   1.25  jakllsch 	    ata_c->r_command == ATAPI_IDENTIFY_DEVICE) {
   1379   1.25  jakllsch 		idwordbuf = xfer->c_databuf;
   1380   1.25  jakllsch 		for (i = 0; i < (xfer->c_bcount / sizeof(*idwordbuf)); i++) {
   1381   1.25  jakllsch 			idwordbuf[i] = le16toh(idwordbuf[i]);
   1382   1.25  jakllsch 		}
   1383   1.25  jakllsch 	}
   1384   1.25  jakllsch 
   1385   1.58  jdolecek 	if (achp->ahcic_cmdh[xfer->c_slot].cmdh_prdbc)
   1386   1.58  jdolecek 		ata_c->flags |= AT_XFDONE;
   1387   1.64  jdolecek 
   1388   1.58  jdolecek 	ahci_cmd_done_end(chp, xfer);
   1389   1.58  jdolecek }
   1390   1.58  jdolecek 
   1391   1.58  jdolecek static void
   1392   1.58  jdolecek ahci_cmd_done_end(struct ata_channel *chp, struct ata_xfer *xfer)
   1393   1.58  jdolecek {
   1394   1.58  jdolecek 	struct ata_command *ata_c = &xfer->c_ata_c;
   1395   1.58  jdolecek 
   1396    1.1    bouyer 	ata_c->flags |= AT_DONE;
   1397   1.64  jdolecek }
   1398    1.1    bouyer 
   1399   1.64  jdolecek static const struct ata_xfer_ops ahci_bio_xfer_ops = {
   1400   1.64  jdolecek 	.c_start = ahci_bio_start,
   1401   1.64  jdolecek 	.c_poll = ahci_bio_poll,
   1402   1.64  jdolecek 	.c_abort = ahci_bio_abort,
   1403   1.64  jdolecek 	.c_intr = ahci_bio_complete,
   1404   1.64  jdolecek 	.c_kill_xfer = ahci_bio_kill_xfer,
   1405   1.64  jdolecek };
   1406    1.1    bouyer 
   1407   1.83  jdolecek static void
   1408   1.58  jdolecek ahci_ata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
   1409    1.1    bouyer {
   1410    1.1    bouyer 	struct ata_channel *chp = drvp->chnl_softc;
   1411   1.58  jdolecek 	struct ata_bio *ata_bio = &xfer->c_bio;
   1412    1.1    bouyer 
   1413    1.1    bouyer 	AHCIDEBUG_PRINT(("ahci_ata_bio port %d CI 0x%x\n",
   1414   1.58  jdolecek 	    chp->ch_channel,
   1415   1.58  jdolecek 	    AHCI_READ(AHCI_CH2SC(chp), AHCI_P_CI(chp->ch_channel))),
   1416    1.1    bouyer 	    DEBUG_XFERS);
   1417    1.1    bouyer 	if (ata_bio->flags & ATA_POLL)
   1418    1.1    bouyer 		xfer->c_flags |= C_POLL;
   1419    1.1    bouyer 	xfer->c_drive = drvp->drive;
   1420    1.1    bouyer 	xfer->c_databuf = ata_bio->databuf;
   1421    1.1    bouyer 	xfer->c_bcount = ata_bio->bcount;
   1422   1.64  jdolecek 	xfer->ops = &ahci_bio_xfer_ops;
   1423    1.1    bouyer 	ata_exec_xfer(chp, xfer);
   1424    1.1    bouyer }
   1425    1.1    bouyer 
   1426   1.58  jdolecek static int
   1427    1.1    bouyer ahci_bio_start(struct ata_channel *chp, struct ata_xfer *xfer)
   1428    1.1    bouyer {
   1429    1.1    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1430    1.1    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1431   1.58  jdolecek 	struct ata_bio *ata_bio = &xfer->c_bio;
   1432    1.1    bouyer 	struct ahci_cmd_tbl *cmd_tbl;
   1433    1.1    bouyer 	struct ahci_cmd_header *cmd_h;
   1434    1.1    bouyer 
   1435    1.1    bouyer 	AHCIDEBUG_PRINT(("ahci_bio_start CI 0x%x\n",
   1436    1.1    bouyer 	    AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS);
   1437    1.1    bouyer 
   1438   1.58  jdolecek 	ata_channel_lock_owned(chp);
   1439   1.58  jdolecek 
   1440   1.58  jdolecek 	cmd_tbl = achp->ahcic_cmd_tbl[xfer->c_slot];
   1441    1.1    bouyer 	AHCIDEBUG_PRINT(("%s port %d tbl %p\n", AHCINAME(sc), chp->ch_channel,
   1442    1.1    bouyer 	      cmd_tbl), DEBUG_XFERS);
   1443    1.1    bouyer 
   1444   1.20  jakllsch 	satafis_rhd_construct_bio(xfer, cmd_tbl->cmdt_cfis);
   1445   1.40    bouyer 	cmd_tbl->cmdt_cfis[rhd_c] |= xfer->c_drive;
   1446    1.1    bouyer 
   1447   1.58  jdolecek 	cmd_h = &achp->ahcic_cmdh[xfer->c_slot];
   1448    1.1    bouyer 	AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc),
   1449    1.1    bouyer 	    chp->ch_channel, cmd_h), DEBUG_XFERS);
   1450   1.58  jdolecek 	if (ahci_dma_setup(chp, xfer->c_slot, ata_bio->databuf, ata_bio->bcount,
   1451    1.1    bouyer 	    (ata_bio->flags & ATA_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
   1452    1.1    bouyer 		ata_bio->error = ERR_DMA;
   1453    1.1    bouyer 		ata_bio->r_error = 0;
   1454   1.58  jdolecek 		return ATASTART_ABORT;
   1455    1.1    bouyer 	}
   1456    1.1    bouyer 	cmd_h->cmdh_flags = htole16(
   1457    1.1    bouyer 	    ((ata_bio->flags & ATA_READ) ? 0 :  AHCI_CMDH_F_WR) |
   1458   1.40    bouyer 	    RHD_FISLEN / 4 | (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT));
   1459    1.1    bouyer 	cmd_h->cmdh_prdbc = 0;
   1460   1.58  jdolecek 	AHCI_CMDH_SYNC(sc, achp, xfer->c_slot,
   1461    1.2      fvdl 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1462    1.1    bouyer 
   1463    1.1    bouyer 	if (xfer->c_flags & C_POLL) {
   1464    1.1    bouyer 		/* polled command, disable interrupts */
   1465    1.1    bouyer 		AHCI_WRITE(sc, AHCI_GHC,
   1466    1.1    bouyer 		    AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
   1467    1.1    bouyer 	}
   1468   1.58  jdolecek 	if (xfer->c_flags & C_NCQ)
   1469   1.62     kamil 		AHCI_WRITE(sc, AHCI_P_SACT(chp->ch_channel), 1U << xfer->c_slot);
   1470    1.1    bouyer 	/* start command */
   1471   1.62     kamil 	AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1U << xfer->c_slot);
   1472    1.1    bouyer 
   1473    1.1    bouyer 	if ((xfer->c_flags & C_POLL) == 0) {
   1474   1.64  jdolecek 		callout_reset(&chp->c_timo_callout, mstohz(ATA_DELAY),
   1475   1.64  jdolecek 		    ata_timeout, chp);
   1476   1.58  jdolecek 		return ATASTART_STARTED;
   1477   1.58  jdolecek 	} else
   1478   1.58  jdolecek 		return ATASTART_POLL;
   1479   1.58  jdolecek }
   1480   1.58  jdolecek 
   1481  1.102       rin static int
   1482   1.58  jdolecek ahci_bio_poll(struct ata_channel *chp, struct ata_xfer *xfer)
   1483   1.58  jdolecek {
   1484   1.58  jdolecek 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1485   1.58  jdolecek 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1486   1.58  jdolecek 
   1487    1.1    bouyer 	/*
   1488   1.87     skrll 	 * Polled command.
   1489    1.1    bouyer 	 */
   1490   1.58  jdolecek 	for (int i = 0; i < ATA_DELAY * 10; i++) {
   1491   1.58  jdolecek 		if (xfer->c_bio.flags & ATA_ITSDONE)
   1492    1.1    bouyer 			break;
   1493   1.72  jdolecek 		ahci_intr_port(achp);
   1494   1.47    bouyer 		delay(100);
   1495    1.1    bouyer 	}
   1496   1.87     skrll 	AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), chp->ch_channel,
   1497    1.1    bouyer 	    AHCI_READ(sc, AHCI_GHC), AHCI_READ(sc, AHCI_IS),
   1498   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CLBU(chp->ch_channel)),
   1499   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CLB(chp->ch_channel)),
   1500   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_FBU(chp->ch_channel)),
   1501   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_FB(chp->ch_channel)),
   1502   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)),
   1503   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
   1504    1.1    bouyer 	    DEBUG_XFERS);
   1505   1.58  jdolecek 	if ((xfer->c_bio.flags & ATA_ITSDONE) == 0) {
   1506   1.58  jdolecek 		xfer->c_bio.error = TIMEOUT;
   1507   1.64  jdolecek 		xfer->ops->c_intr(chp, xfer, 0);
   1508    1.1    bouyer 	}
   1509    1.1    bouyer 	/* reenable interrupts */
   1510    1.1    bouyer 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
   1511  1.102       rin 	return ATAPOLL_DONE;
   1512    1.1    bouyer }
   1513    1.1    bouyer 
   1514   1.29  jakllsch static void
   1515   1.58  jdolecek ahci_bio_abort(struct ata_channel *chp, struct ata_xfer *xfer)
   1516   1.58  jdolecek {
   1517   1.58  jdolecek 	ahci_bio_complete(chp, xfer, 0);
   1518   1.58  jdolecek }
   1519   1.58  jdolecek 
   1520   1.58  jdolecek static void
   1521    1.1    bouyer ahci_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
   1522    1.1    bouyer {
   1523    1.1    bouyer 	int drive = xfer->c_drive;
   1524   1.58  jdolecek 	struct ata_bio *ata_bio = &xfer->c_bio;
   1525   1.58  jdolecek 	bool deactivate = true;
   1526   1.58  jdolecek 
   1527   1.67  jdolecek 	AHCIDEBUG_PRINT(("ahci_bio_kill_xfer port %d\n", chp->ch_channel),
   1528    1.1    bouyer 	    DEBUG_FUNCS);
   1529    1.1    bouyer 
   1530    1.1    bouyer 	ata_bio->flags |= ATA_ITSDONE;
   1531    1.1    bouyer 	switch (reason) {
   1532   1.58  jdolecek 	case KILL_GONE_INACTIVE:
   1533   1.58  jdolecek 		deactivate = false;
   1534   1.58  jdolecek 		/* FALLTHROUGH */
   1535    1.1    bouyer 	case KILL_GONE:
   1536    1.1    bouyer 		ata_bio->error = ERR_NODEV;
   1537    1.1    bouyer 		break;
   1538    1.1    bouyer 	case KILL_RESET:
   1539    1.1    bouyer 		ata_bio->error = ERR_RESET;
   1540    1.1    bouyer 		break;
   1541   1.58  jdolecek 	case KILL_REQUEUE:
   1542   1.58  jdolecek 		ata_bio->error = REQUEUE;
   1543   1.58  jdolecek 		break;
   1544    1.1    bouyer 	default:
   1545    1.1    bouyer 		printf("ahci_bio_kill_xfer: unknown reason %d\n", reason);
   1546    1.1    bouyer 		panic("ahci_bio_kill_xfer");
   1547    1.1    bouyer 	}
   1548    1.1    bouyer 	ata_bio->r_error = WDCE_ABRT;
   1549   1.58  jdolecek 
   1550   1.64  jdolecek 	if (deactivate)
   1551   1.58  jdolecek 		ata_deactivate_xfer(chp, xfer);
   1552   1.58  jdolecek 
   1553   1.58  jdolecek 	(*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer);
   1554    1.1    bouyer }
   1555    1.1    bouyer 
   1556   1.29  jakllsch static int
   1557   1.58  jdolecek ahci_bio_complete(struct ata_channel *chp, struct ata_xfer *xfer, int tfd)
   1558    1.1    bouyer {
   1559   1.58  jdolecek 	struct ata_bio *ata_bio = &xfer->c_bio;
   1560    1.1    bouyer 	int drive = xfer->c_drive;
   1561    1.1    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1562    1.1    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1563    1.1    bouyer 
   1564   1.67  jdolecek 	AHCIDEBUG_PRINT(("ahci_bio_complete port %d\n", chp->ch_channel),
   1565    1.1    bouyer 	    DEBUG_FUNCS);
   1566    1.1    bouyer 
   1567   1.58  jdolecek 	if (ata_waitdrain_xfer_check(chp, xfer))
   1568   1.58  jdolecek 		return 0;
   1569   1.58  jdolecek 
   1570    1.5    bouyer 	if (xfer->c_flags & C_TIMEOU) {
   1571    1.5    bouyer 		ata_bio->error = TIMEOUT;
   1572    1.5    bouyer 	}
   1573    1.1    bouyer 
   1574   1.58  jdolecek 	bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[xfer->c_slot], 0,
   1575   1.58  jdolecek 	    achp->ahcic_datad[xfer->c_slot]->dm_mapsize,
   1576    1.1    bouyer 	    (ata_bio->flags & ATA_READ) ? BUS_DMASYNC_POSTREAD :
   1577    1.1    bouyer 	    BUS_DMASYNC_POSTWRITE);
   1578   1.58  jdolecek 	bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[xfer->c_slot]);
   1579    1.1    bouyer 
   1580    1.1    bouyer 	ata_bio->flags |= ATA_ITSDONE;
   1581   1.87     skrll 	if (AHCI_TFD_ERR(tfd) & WDCS_DWF) {
   1582    1.1    bouyer 		ata_bio->error = ERR_DF;
   1583   1.58  jdolecek 	} else if (AHCI_TFD_ST(tfd) & WDCS_ERR) {
   1584    1.1    bouyer 		ata_bio->error = ERROR;
   1585   1.58  jdolecek 		ata_bio->r_error = AHCI_TFD_ERR(tfd);
   1586   1.58  jdolecek 	} else if (AHCI_TFD_ST(tfd) & WDCS_CORR)
   1587    1.1    bouyer 		ata_bio->flags |= ATA_CORR;
   1588    1.1    bouyer 
   1589   1.58  jdolecek 	AHCI_CMDH_SYNC(sc, achp, xfer->c_slot,
   1590    1.1    bouyer 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1591    1.1    bouyer 	AHCIDEBUG_PRINT(("ahci_bio_complete bcount %ld",
   1592    1.1    bouyer 	    ata_bio->bcount), DEBUG_XFERS);
   1593   1.87     skrll 	/*
   1594   1.80   msaitoh 	 * If it was a write, complete data buffer may have been transferred
   1595   1.19    bouyer 	 * before error detection; in this case don't use cmdh_prdbc
   1596   1.19    bouyer 	 * as it won't reflect what was written to media. Assume nothing
   1597   1.80   msaitoh 	 * was transferred and leave bcount as-is.
   1598   1.58  jdolecek 	 * For queued commands, PRD Byte Count should not be used, and is
   1599   1.58  jdolecek 	 * not required to be valid; in that case underflow is always illegal.
   1600   1.19    bouyer 	 */
   1601   1.58  jdolecek 	if ((xfer->c_flags & C_NCQ) != 0) {
   1602   1.58  jdolecek 		if (ata_bio->error == NOERROR)
   1603   1.58  jdolecek 			ata_bio->bcount = 0;
   1604   1.58  jdolecek 	} else {
   1605   1.61  jdolecek 		if ((ata_bio->flags & ATA_READ) || ata_bio->error == NOERROR)
   1606   1.61  jdolecek 			ata_bio->bcount -=
   1607   1.61  jdolecek 			    le32toh(achp->ahcic_cmdh[xfer->c_slot].cmdh_prdbc);
   1608   1.58  jdolecek 	}
   1609    1.1    bouyer 	AHCIDEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS);
   1610   1.64  jdolecek 
   1611   1.64  jdolecek 	ata_deactivate_xfer(chp, xfer);
   1612   1.64  jdolecek 
   1613   1.58  jdolecek 	(*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer);
   1614   1.58  jdolecek 	if ((AHCI_TFD_ST(tfd) & WDCS_ERR) == 0)
   1615   1.58  jdolecek 		atastart(chp);
   1616    1.1    bouyer 	return 0;
   1617    1.1    bouyer }
   1618    1.1    bouyer 
   1619   1.29  jakllsch static void
   1620    1.5    bouyer ahci_channel_stop(struct ahci_softc *sc, struct ata_channel *chp, int flags)
   1621    1.5    bouyer {
   1622    1.5    bouyer 	int i;
   1623    1.5    bouyer 	/* stop channel */
   1624    1.5    bouyer 	AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
   1625    1.5    bouyer 	    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & ~AHCI_P_CMD_ST);
   1626    1.5    bouyer 	/* wait 1s for channel to stop */
   1627    1.5    bouyer 	for (i = 0; i <100; i++) {
   1628    1.5    bouyer 		if ((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR)
   1629    1.5    bouyer 		    == 0)
   1630    1.5    bouyer 			break;
   1631   1.58  jdolecek 		ata_delay(chp, 10, "ahcistop", flags);
   1632    1.5    bouyer 	}
   1633    1.5    bouyer 	if (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) {
   1634    1.5    bouyer 		printf("%s: channel wouldn't stop\n", AHCINAME(sc));
   1635    1.5    bouyer 		/* XXX controller reset ? */
   1636    1.5    bouyer 		return;
   1637    1.5    bouyer 	}
   1638  1.107   mlelstv 
   1639   1.51  jmcneill 	if (sc->sc_channel_stop)
   1640   1.51  jmcneill 		sc->sc_channel_stop(sc, chp);
   1641    1.5    bouyer }
   1642    1.5    bouyer 
   1643   1.29  jakllsch static void
   1644   1.40    bouyer ahci_channel_start(struct ahci_softc *sc, struct ata_channel *chp,
   1645   1.40    bouyer     int flags, int clo)
   1646    1.1    bouyer {
   1647   1.40    bouyer 	int i;
   1648   1.40    bouyer 	uint32_t p_cmd;
   1649    1.1    bouyer 	/* clear error */
   1650   1.18    bouyer 	AHCI_WRITE(sc, AHCI_P_SERR(chp->ch_channel),
   1651   1.18    bouyer 	    AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel)));
   1652    1.1    bouyer 
   1653   1.40    bouyer 	if (clo) {
   1654   1.40    bouyer 		/* issue command list override */
   1655   1.40    bouyer 		KASSERT(sc->sc_ahci_cap & AHCI_CAP_CLO);
   1656   1.40    bouyer 		AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
   1657   1.40    bouyer 		    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) | AHCI_P_CMD_CLO);
   1658   1.40    bouyer 		/* wait 1s for AHCI_CAP_CLO to clear */
   1659   1.40    bouyer 		for (i = 0; i <100; i++) {
   1660   1.40    bouyer 			if ((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) &
   1661   1.40    bouyer 			    AHCI_P_CMD_CLO) == 0)
   1662   1.40    bouyer 				break;
   1663   1.58  jdolecek 			ata_delay(chp, 10, "ahciclo", flags);
   1664   1.40    bouyer 		}
   1665   1.40    bouyer 		if (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CLO) {
   1666   1.40    bouyer 			printf("%s: channel wouldn't CLO\n", AHCINAME(sc));
   1667   1.40    bouyer 			/* XXX controller reset ? */
   1668   1.40    bouyer 			return;
   1669   1.40    bouyer 		}
   1670   1.40    bouyer 	}
   1671   1.51  jmcneill 
   1672   1.51  jmcneill 	if (sc->sc_channel_start)
   1673   1.51  jmcneill 		sc->sc_channel_start(sc, chp);
   1674   1.51  jmcneill 
   1675    1.1    bouyer 	/* and start controller */
   1676   1.40    bouyer 	p_cmd = AHCI_P_CMD_ICC_AC | AHCI_P_CMD_POD | AHCI_P_CMD_SUD |
   1677   1.40    bouyer 	    AHCI_P_CMD_FRE | AHCI_P_CMD_ST;
   1678   1.40    bouyer 	if (chp->ch_ndrives > PMP_PORT_CTL &&
   1679   1.40    bouyer 	    chp->ch_drive[PMP_PORT_CTL].drive_type == ATA_DRIVET_PM) {
   1680   1.40    bouyer 		p_cmd |= AHCI_P_CMD_PMA;
   1681   1.40    bouyer 	}
   1682   1.40    bouyer 	AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel), p_cmd);
   1683    1.1    bouyer }
   1684    1.1    bouyer 
   1685   1.64  jdolecek /* Recover channel after command failure */
   1686   1.29  jakllsch static void
   1687   1.64  jdolecek ahci_channel_recover(struct ata_channel *chp, int flags, uint32_t tfd)
   1688   1.58  jdolecek {
   1689   1.64  jdolecek 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1690   1.64  jdolecek 	int drive = ATACH_NODRIVE;
   1691   1.58  jdolecek 	bool reset = false;
   1692   1.58  jdolecek 
   1693   1.64  jdolecek 	ata_channel_lock_owned(chp);
   1694   1.58  jdolecek 
   1695   1.58  jdolecek 	/*
   1696   1.58  jdolecek 	 * Read FBS to get the drive which caused the error, if PM is in use.
   1697   1.58  jdolecek 	 * According to AHCI 1.3 spec, this register is available regardless
   1698   1.58  jdolecek 	 * if FIS-based switching (FBSS) feature is supported, or disabled.
   1699   1.58  jdolecek 	 * If FIS-based switching is not in use, it merely maintains single
   1700   1.58  jdolecek 	 * pair of DRQ/BSY state, but it is enough since in that case we
   1701   1.58  jdolecek 	 * never issue commands for more than one device at the time anyway.
   1702   1.58  jdolecek 	 * XXX untested
   1703   1.58  jdolecek 	 */
   1704   1.58  jdolecek 	if (chp->ch_ndrives > PMP_PORT_CTL) {
   1705   1.58  jdolecek 		uint32_t fbs = AHCI_READ(sc, AHCI_P_FBS(chp->ch_channel));
   1706   1.58  jdolecek 		if (fbs & AHCI_P_FBS_SDE) {
   1707   1.58  jdolecek 			drive = (fbs & AHCI_P_FBS_DWE) >> AHCI_P_FBS_DWE_SHIFT;
   1708   1.58  jdolecek 
   1709   1.58  jdolecek 			/*
   1710   1.58  jdolecek 			 * Tell HBA to reset PM port X (value in DWE) state,
   1711   1.58  jdolecek 			 * and resume processing commands for other ports.
   1712   1.58  jdolecek 			 */
   1713   1.58  jdolecek 			fbs |= AHCI_P_FBS_DEC;
   1714   1.58  jdolecek 			AHCI_WRITE(sc, AHCI_P_FBS(chp->ch_channel), fbs);
   1715   1.58  jdolecek 			for (int i = 0; i < 1000; i++) {
   1716   1.58  jdolecek 				fbs = AHCI_READ(sc,
   1717   1.58  jdolecek 				    AHCI_P_FBS(chp->ch_channel));
   1718   1.58  jdolecek 				if ((fbs & AHCI_P_FBS_DEC) == 0)
   1719   1.58  jdolecek 					break;
   1720   1.58  jdolecek 				DELAY(1000);
   1721   1.58  jdolecek 			}
   1722   1.58  jdolecek 			if ((fbs & AHCI_P_FBS_DEC) != 0) {
   1723   1.58  jdolecek 				/* follow non-device specific recovery */
   1724   1.64  jdolecek 				drive = ATACH_NODRIVE;
   1725   1.58  jdolecek 				reset = true;
   1726   1.58  jdolecek 			}
   1727   1.58  jdolecek 		} else {
   1728   1.58  jdolecek 			/* not device specific, reset channel */
   1729   1.64  jdolecek 			drive = ATACH_NODRIVE;
   1730   1.58  jdolecek 			reset = true;
   1731   1.58  jdolecek 		}
   1732   1.58  jdolecek 	} else
   1733   1.58  jdolecek 		drive = 0;
   1734   1.58  jdolecek 
   1735   1.58  jdolecek 	/*
   1736   1.58  jdolecek 	 * If BSY or DRQ bits are set, must execute COMRESET to return
   1737   1.58  jdolecek 	 * device to idle state. If drive is idle, it's enough to just
   1738   1.58  jdolecek 	 * reset CMD.ST, it's not necessary to do software reset.
   1739   1.58  jdolecek 	 * After resetting CMD.ST, need to execute READ LOG EXT for NCQ
   1740   1.58  jdolecek 	 * to unblock device processing if COMRESET was not done.
   1741   1.58  jdolecek 	 */
   1742   1.64  jdolecek 	if (reset || (AHCI_TFD_ST(tfd) & (WDCS_BSY|WDCS_DRQ)) != 0) {
   1743   1.64  jdolecek 		ahci_reset_channel(chp, flags);
   1744   1.58  jdolecek 		goto out;
   1745   1.58  jdolecek 	}
   1746   1.58  jdolecek 
   1747   1.64  jdolecek 	KASSERT(drive != ATACH_NODRIVE && drive >= 0);
   1748   1.64  jdolecek 	ahci_channel_stop(sc, chp, flags);
   1749   1.64  jdolecek 	ahci_channel_start(sc, chp, flags,
   1750   1.64  jdolecek    	    (sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0);
   1751   1.58  jdolecek 
   1752   1.64  jdolecek 	ata_recovery_resume(chp, drive, tfd, flags);
   1753   1.58  jdolecek 
   1754   1.58  jdolecek out:
   1755   1.58  jdolecek 	/* Drive unblocked, back to normal operation */
   1756   1.64  jdolecek 	return;
   1757    1.1    bouyer }
   1758    1.1    bouyer 
   1759   1.29  jakllsch static int
   1760    1.1    bouyer ahci_dma_setup(struct ata_channel *chp, int slot, void *data,
   1761    1.1    bouyer     size_t count, int op)
   1762    1.1    bouyer {
   1763    1.1    bouyer 	int error, seg;
   1764    1.1    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1765    1.1    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1766    1.1    bouyer 	struct ahci_cmd_tbl *cmd_tbl;
   1767    1.1    bouyer 	struct ahci_cmd_header *cmd_h;
   1768    1.1    bouyer 
   1769    1.1    bouyer 	cmd_h = &achp->ahcic_cmdh[slot];
   1770    1.1    bouyer 	cmd_tbl = achp->ahcic_cmd_tbl[slot];
   1771    1.1    bouyer 
   1772    1.1    bouyer 	if (data == NULL) {
   1773    1.1    bouyer 		cmd_h->cmdh_prdtl = 0;
   1774    1.1    bouyer 		goto end;
   1775    1.1    bouyer 	}
   1776    1.1    bouyer 
   1777    1.1    bouyer 	error = bus_dmamap_load(sc->sc_dmat, achp->ahcic_datad[slot],
   1778    1.1    bouyer 	    data, count, NULL,
   1779    1.1    bouyer 	    BUS_DMA_NOWAIT | BUS_DMA_STREAMING | op);
   1780    1.1    bouyer 	if (error) {
   1781    1.1    bouyer 		printf("%s port %d: failed to load xfer: %d\n",
   1782    1.1    bouyer 		    AHCINAME(sc), chp->ch_channel, error);
   1783    1.1    bouyer 		return error;
   1784    1.1    bouyer 	}
   1785    1.1    bouyer 	bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[slot], 0,
   1786   1.87     skrll 	    achp->ahcic_datad[slot]->dm_mapsize,
   1787    1.1    bouyer 	    (op == BUS_DMA_READ) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
   1788   1.94     skrll 	for (seg = 0; seg < achp->ahcic_datad[slot]->dm_nsegs; seg++) {
   1789   1.28  jakllsch 		cmd_tbl->cmdt_prd[seg].prd_dba = htole64(
   1790    1.1    bouyer 		     achp->ahcic_datad[slot]->dm_segs[seg].ds_addr);
   1791    1.1    bouyer 		cmd_tbl->cmdt_prd[seg].prd_dbc = htole32(
   1792    1.1    bouyer 		    achp->ahcic_datad[slot]->dm_segs[seg].ds_len - 1);
   1793    1.1    bouyer 	}
   1794    1.1    bouyer 	cmd_tbl->cmdt_prd[seg - 1].prd_dbc |= htole32(AHCI_PRD_DBC_IPC);
   1795    1.1    bouyer 	cmd_h->cmdh_prdtl = htole16(achp->ahcic_datad[slot]->dm_nsegs);
   1796    1.1    bouyer end:
   1797    1.1    bouyer 	AHCI_CMDTBL_SYNC(sc, achp, slot, BUS_DMASYNC_PREWRITE);
   1798    1.1    bouyer 	return 0;
   1799    1.1    bouyer }
   1800    1.8    bouyer 
   1801    1.8    bouyer #if NATAPIBUS > 0
   1802   1.29  jakllsch static void
   1803    1.8    bouyer ahci_atapibus_attach(struct atabus_softc * ata_sc)
   1804    1.8    bouyer {
   1805    1.8    bouyer 	struct ata_channel *chp = ata_sc->sc_chan;
   1806    1.8    bouyer 	struct atac_softc *atac = chp->ch_atac;
   1807    1.8    bouyer 	struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic;
   1808    1.8    bouyer 	struct scsipi_channel *chan = &chp->ch_atapi_channel;
   1809    1.8    bouyer 	/*
   1810    1.8    bouyer 	 * Fill in the scsipi_adapter.
   1811    1.8    bouyer 	 */
   1812   1.13      cube 	adapt->adapt_dev = atac->atac_dev;
   1813    1.8    bouyer 	adapt->adapt_nchannels = atac->atac_nchannels;
   1814    1.8    bouyer 	adapt->adapt_request = ahci_atapi_scsipi_request;
   1815    1.8    bouyer 	adapt->adapt_minphys = ahci_atapi_minphys;
   1816    1.8    bouyer 	atac->atac_atapi_adapter.atapi_probe_device = ahci_atapi_probe_device;
   1817    1.8    bouyer 
   1818    1.8    bouyer 	/*
   1819    1.8    bouyer 	 * Fill in the scsipi_channel.
   1820    1.8    bouyer 	 */
   1821    1.8    bouyer 	memset(chan, 0, sizeof(*chan));
   1822    1.8    bouyer 	chan->chan_adapter = adapt;
   1823    1.8    bouyer 	chan->chan_bustype = &ahci_atapi_bustype;
   1824    1.8    bouyer 	chan->chan_channel = chp->ch_channel;
   1825    1.8    bouyer 	chan->chan_flags = SCSIPI_CHAN_OPENINGS;
   1826    1.8    bouyer 	chan->chan_openings = 1;
   1827    1.8    bouyer 	chan->chan_max_periph = 1;
   1828    1.8    bouyer 	chan->chan_ntargets = 1;
   1829    1.8    bouyer 	chan->chan_nluns = 1;
   1830   1.98   thorpej 	chp->atapibus = config_found(ata_sc->sc_dev, chan, atapiprint,
   1831  1.100   thorpej 	    CFARGS(.iattr = "atapi"));
   1832    1.8    bouyer }
   1833    1.8    bouyer 
   1834   1.29  jakllsch static void
   1835    1.8    bouyer ahci_atapi_minphys(struct buf *bp)
   1836    1.8    bouyer {
   1837    1.8    bouyer 	if (bp->b_bcount > MAXPHYS)
   1838    1.8    bouyer 		bp->b_bcount = MAXPHYS;
   1839    1.8    bouyer 	minphys(bp);
   1840    1.8    bouyer }
   1841    1.8    bouyer 
   1842    1.8    bouyer /*
   1843    1.8    bouyer  * Kill off all pending xfers for a periph.
   1844    1.8    bouyer  *
   1845    1.8    bouyer  * Must be called at splbio().
   1846    1.8    bouyer  */
   1847   1.29  jakllsch static void
   1848    1.8    bouyer ahci_atapi_kill_pending(struct scsipi_periph *periph)
   1849    1.8    bouyer {
   1850    1.8    bouyer 	struct atac_softc *atac =
   1851   1.13      cube 	    device_private(periph->periph_channel->chan_adapter->adapt_dev);
   1852    1.8    bouyer 	struct ata_channel *chp =
   1853    1.8    bouyer 	    atac->atac_channels[periph->periph_channel->chan_channel];
   1854    1.8    bouyer 
   1855    1.8    bouyer 	ata_kill_pending(&chp->ch_drive[periph->periph_target]);
   1856    1.8    bouyer }
   1857    1.8    bouyer 
   1858   1.64  jdolecek static const struct ata_xfer_ops ahci_atapi_xfer_ops = {
   1859   1.64  jdolecek 	.c_start = ahci_atapi_start,
   1860   1.64  jdolecek 	.c_poll = ahci_atapi_poll,
   1861   1.64  jdolecek 	.c_abort = ahci_atapi_abort,
   1862   1.64  jdolecek 	.c_intr = ahci_atapi_complete,
   1863   1.64  jdolecek 	.c_kill_xfer = ahci_atapi_kill_xfer,
   1864   1.64  jdolecek };
   1865   1.64  jdolecek 
   1866   1.29  jakllsch static void
   1867    1.8    bouyer ahci_atapi_scsipi_request(struct scsipi_channel *chan,
   1868    1.8    bouyer     scsipi_adapter_req_t req, void *arg)
   1869    1.8    bouyer {
   1870    1.8    bouyer 	struct scsipi_adapter *adapt = chan->chan_adapter;
   1871    1.8    bouyer 	struct scsipi_periph *periph;
   1872    1.8    bouyer 	struct scsipi_xfer *sc_xfer;
   1873   1.13      cube 	struct ahci_softc *sc = device_private(adapt->adapt_dev);
   1874    1.8    bouyer 	struct atac_softc *atac = &sc->sc_atac;
   1875    1.8    bouyer 	struct ata_xfer *xfer;
   1876    1.8    bouyer 	int channel = chan->chan_channel;
   1877    1.8    bouyer 	int drive, s;
   1878    1.8    bouyer 
   1879    1.8    bouyer 	switch (req) {
   1880    1.8    bouyer 	case ADAPTER_REQ_RUN_XFER:
   1881    1.8    bouyer 		sc_xfer = arg;
   1882    1.8    bouyer 		periph = sc_xfer->xs_periph;
   1883    1.8    bouyer 		drive = periph->periph_target;
   1884   1.13      cube 		if (!device_is_active(atac->atac_dev)) {
   1885    1.8    bouyer 			sc_xfer->error = XS_DRIVER_STUFFUP;
   1886    1.8    bouyer 			scsipi_done(sc_xfer);
   1887    1.8    bouyer 			return;
   1888    1.8    bouyer 		}
   1889   1.64  jdolecek 		xfer = ata_get_xfer(atac->atac_channels[channel], false);
   1890    1.8    bouyer 		if (xfer == NULL) {
   1891    1.8    bouyer 			sc_xfer->error = XS_RESOURCE_SHORTAGE;
   1892    1.8    bouyer 			scsipi_done(sc_xfer);
   1893    1.8    bouyer 			return;
   1894    1.8    bouyer 		}
   1895    1.8    bouyer 
   1896    1.8    bouyer 		if (sc_xfer->xs_control & XS_CTL_POLL)
   1897    1.8    bouyer 			xfer->c_flags |= C_POLL;
   1898    1.8    bouyer 		xfer->c_drive = drive;
   1899    1.8    bouyer 		xfer->c_flags |= C_ATAPI;
   1900    1.8    bouyer 		xfer->c_databuf = sc_xfer->data;
   1901    1.8    bouyer 		xfer->c_bcount = sc_xfer->datalen;
   1902   1.64  jdolecek 		xfer->ops = &ahci_atapi_xfer_ops;
   1903   1.64  jdolecek 		xfer->c_scsipi = sc_xfer;
   1904   1.64  jdolecek 		xfer->c_atapi.c_dscpoll = 0;
   1905    1.8    bouyer 		s = splbio();
   1906    1.8    bouyer 		ata_exec_xfer(atac->atac_channels[channel], xfer);
   1907    1.8    bouyer #ifdef DIAGNOSTIC
   1908    1.8    bouyer 		if ((sc_xfer->xs_control & XS_CTL_POLL) != 0 &&
   1909    1.8    bouyer 		    (sc_xfer->xs_status & XS_STS_DONE) == 0)
   1910    1.8    bouyer 			panic("ahci_atapi_scsipi_request: polled command "
   1911    1.8    bouyer 			    "not done");
   1912    1.8    bouyer #endif
   1913    1.8    bouyer 		splx(s);
   1914    1.8    bouyer 		return;
   1915    1.8    bouyer 	default:
   1916    1.8    bouyer 		/* Not supported, nothing to do. */
   1917    1.8    bouyer 		;
   1918    1.8    bouyer 	}
   1919    1.8    bouyer }
   1920    1.8    bouyer 
   1921   1.58  jdolecek static int
   1922    1.8    bouyer ahci_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer)
   1923    1.8    bouyer {
   1924    1.8    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1925    1.8    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1926   1.58  jdolecek 	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
   1927    1.8    bouyer 	struct ahci_cmd_tbl *cmd_tbl;
   1928    1.8    bouyer 	struct ahci_cmd_header *cmd_h;
   1929    1.8    bouyer 
   1930    1.8    bouyer 	AHCIDEBUG_PRINT(("ahci_atapi_start CI 0x%x\n",
   1931    1.8    bouyer 	    AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))), DEBUG_XFERS);
   1932    1.8    bouyer 
   1933   1.58  jdolecek 	ata_channel_lock_owned(chp);
   1934   1.58  jdolecek 
   1935   1.58  jdolecek 	cmd_tbl = achp->ahcic_cmd_tbl[xfer->c_slot];
   1936    1.8    bouyer 	AHCIDEBUG_PRINT(("%s port %d tbl %p\n", AHCINAME(sc), chp->ch_channel,
   1937    1.8    bouyer 	      cmd_tbl), DEBUG_XFERS);
   1938    1.8    bouyer 
   1939   1.20  jakllsch 	satafis_rhd_construct_atapi(xfer, cmd_tbl->cmdt_cfis);
   1940   1.40    bouyer 	cmd_tbl->cmdt_cfis[rhd_c] |= xfer->c_drive;
   1941    1.8    bouyer 	memset(&cmd_tbl->cmdt_acmd, 0, sizeof(cmd_tbl->cmdt_acmd));
   1942    1.8    bouyer 	memcpy(cmd_tbl->cmdt_acmd, sc_xfer->cmd, sc_xfer->cmdlen);
   1943    1.8    bouyer 
   1944   1.58  jdolecek 	cmd_h = &achp->ahcic_cmdh[xfer->c_slot];
   1945    1.8    bouyer 	AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc),
   1946    1.8    bouyer 	    chp->ch_channel, cmd_h), DEBUG_XFERS);
   1947   1.58  jdolecek 	if (ahci_dma_setup(chp, xfer->c_slot,
   1948   1.58  jdolecek 	    sc_xfer->datalen ? sc_xfer->data : NULL,
   1949    1.8    bouyer 	    sc_xfer->datalen,
   1950    1.8    bouyer 	    (sc_xfer->xs_control & XS_CTL_DATA_IN) ?
   1951    1.8    bouyer 	    BUS_DMA_READ : BUS_DMA_WRITE)) {
   1952    1.8    bouyer 		sc_xfer->error = XS_DRIVER_STUFFUP;
   1953   1.58  jdolecek 		return ATASTART_ABORT;
   1954    1.8    bouyer 	}
   1955    1.8    bouyer 	cmd_h->cmdh_flags = htole16(
   1956    1.8    bouyer 	    ((sc_xfer->xs_control & XS_CTL_DATA_OUT) ? AHCI_CMDH_F_WR : 0) |
   1957   1.40    bouyer 	    RHD_FISLEN / 4 | AHCI_CMDH_F_A |
   1958   1.40    bouyer 	    (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT));
   1959    1.8    bouyer 	cmd_h->cmdh_prdbc = 0;
   1960   1.58  jdolecek 	AHCI_CMDH_SYNC(sc, achp, xfer->c_slot,
   1961    1.8    bouyer 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1962    1.8    bouyer 
   1963    1.8    bouyer 	if (xfer->c_flags & C_POLL) {
   1964    1.8    bouyer 		/* polled command, disable interrupts */
   1965    1.8    bouyer 		AHCI_WRITE(sc, AHCI_GHC,
   1966    1.8    bouyer 		    AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE);
   1967    1.8    bouyer 	}
   1968    1.8    bouyer 	/* start command */
   1969   1.62     kamil 	AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1U << xfer->c_slot);
   1970    1.8    bouyer 
   1971    1.8    bouyer 	if ((xfer->c_flags & C_POLL) == 0) {
   1972   1.64  jdolecek 		callout_reset(&chp->c_timo_callout, mstohz(sc_xfer->timeout),
   1973   1.64  jdolecek 		    ata_timeout, chp);
   1974   1.58  jdolecek 		return ATASTART_STARTED;
   1975   1.58  jdolecek 	} else
   1976   1.58  jdolecek 		return ATASTART_POLL;
   1977   1.58  jdolecek }
   1978   1.58  jdolecek 
   1979  1.102       rin static int
   1980   1.58  jdolecek ahci_atapi_poll(struct ata_channel *chp, struct ata_xfer *xfer)
   1981   1.58  jdolecek {
   1982   1.58  jdolecek 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   1983   1.58  jdolecek 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   1984   1.58  jdolecek 
   1985    1.8    bouyer 	/*
   1986   1.87     skrll 	 * Polled command.
   1987    1.8    bouyer 	 */
   1988   1.58  jdolecek 	for (int i = 0; i < ATA_DELAY / 10; i++) {
   1989   1.58  jdolecek 		if (xfer->c_scsipi->xs_status & XS_STS_DONE)
   1990    1.8    bouyer 			break;
   1991   1.72  jdolecek 		ahci_intr_port(achp);
   1992    1.8    bouyer 		delay(10000);
   1993    1.8    bouyer 	}
   1994   1.87     skrll 	AHCIDEBUG_PRINT(("%s port %d poll end GHC 0x%x IS 0x%x list 0x%x%x fis 0x%x%x CMD 0x%x CI 0x%x\n", AHCINAME(sc), chp->ch_channel,
   1995    1.8    bouyer 	    AHCI_READ(sc, AHCI_GHC), AHCI_READ(sc, AHCI_IS),
   1996   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CLBU(chp->ch_channel)),
   1997   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CLB(chp->ch_channel)),
   1998   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_FBU(chp->ch_channel)),
   1999   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_FB(chp->ch_channel)),
   2000   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)),
   2001   1.58  jdolecek 	    AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
   2002    1.8    bouyer 	    DEBUG_XFERS);
   2003   1.58  jdolecek 	if ((xfer->c_scsipi->xs_status & XS_STS_DONE) == 0) {
   2004   1.58  jdolecek 		xfer->c_scsipi->error = XS_TIMEOUT;
   2005   1.64  jdolecek 		xfer->ops->c_intr(chp, xfer, 0);
   2006    1.8    bouyer 	}
   2007    1.8    bouyer 	/* reenable interrupts */
   2008    1.8    bouyer 	AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE);
   2009  1.102       rin 	return ATAPOLL_DONE;
   2010    1.8    bouyer }
   2011    1.8    bouyer 
   2012   1.58  jdolecek static void
   2013   1.58  jdolecek ahci_atapi_abort(struct ata_channel *chp, struct ata_xfer *xfer)
   2014   1.58  jdolecek {
   2015   1.58  jdolecek 	ahci_atapi_complete(chp, xfer, 0);
   2016   1.58  jdolecek }
   2017   1.58  jdolecek 
   2018   1.29  jakllsch static int
   2019   1.58  jdolecek ahci_atapi_complete(struct ata_channel *chp, struct ata_xfer *xfer, int tfd)
   2020    1.8    bouyer {
   2021   1.58  jdolecek 	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
   2022    1.8    bouyer 	struct ahci_channel *achp = (struct ahci_channel *)chp;
   2023    1.8    bouyer 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
   2024    1.8    bouyer 
   2025   1.67  jdolecek 	AHCIDEBUG_PRINT(("ahci_atapi_complete port %d\n", chp->ch_channel),
   2026    1.8    bouyer 	    DEBUG_FUNCS);
   2027    1.8    bouyer 
   2028   1.58  jdolecek 	if (ata_waitdrain_xfer_check(chp, xfer))
   2029   1.58  jdolecek 		return 0;
   2030   1.58  jdolecek 
   2031    1.8    bouyer 	if (xfer->c_flags & C_TIMEOU) {
   2032    1.8    bouyer 		sc_xfer->error = XS_TIMEOUT;
   2033    1.8    bouyer 	}
   2034    1.8    bouyer 
   2035   1.55  jakllsch 	if (xfer->c_bcount > 0) {
   2036   1.58  jdolecek 		bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[xfer->c_slot], 0,
   2037   1.58  jdolecek 		    achp->ahcic_datad[xfer->c_slot]->dm_mapsize,
   2038   1.55  jakllsch 		    (sc_xfer->xs_control & XS_CTL_DATA_IN) ?
   2039   1.55  jakllsch 		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
   2040   1.58  jdolecek 		bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[xfer->c_slot]);
   2041   1.55  jakllsch 	}
   2042    1.8    bouyer 
   2043   1.58  jdolecek 	AHCI_CMDH_SYNC(sc, achp, xfer->c_slot,
   2044    1.8    bouyer 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   2045    1.8    bouyer 	sc_xfer->resid = sc_xfer->datalen;
   2046   1.58  jdolecek 	sc_xfer->resid -= le32toh(achp->ahcic_cmdh[xfer->c_slot].cmdh_prdbc);
   2047    1.8    bouyer 	AHCIDEBUG_PRINT(("ahci_atapi_complete datalen %d resid %d\n",
   2048    1.8    bouyer 	    sc_xfer->datalen, sc_xfer->resid), DEBUG_XFERS);
   2049   1.87     skrll 	if (AHCI_TFD_ST(tfd) & WDCS_ERR &&
   2050   1.16    bouyer 	    ((sc_xfer->xs_control & XS_CTL_REQSENSE) == 0 ||
   2051   1.16    bouyer 	    sc_xfer->resid == sc_xfer->datalen)) {
   2052   1.16    bouyer 		sc_xfer->error = XS_SHORTSENSE;
   2053   1.58  jdolecek 		sc_xfer->sense.atapi_sense = AHCI_TFD_ERR(tfd);
   2054   1.16    bouyer 		if ((sc_xfer->xs_periph->periph_quirks &
   2055   1.16    bouyer 		    PQUIRK_NOSENSE) == 0) {
   2056   1.16    bouyer 			/* ask scsipi to send a REQUEST_SENSE */
   2057   1.16    bouyer 			sc_xfer->error = XS_BUSY;
   2058   1.16    bouyer 			sc_xfer->status = SCSI_CHECK;
   2059   1.16    bouyer 		}
   2060   1.64  jdolecek 	}
   2061   1.64  jdolecek 
   2062   1.64  jdolecek 	ata_deactivate_xfer(chp, xfer);
   2063   1.64  jdolecek 
   2064   1.58  jdolecek 	ata_free_xfer(chp, xfer);
   2065    1.8    bouyer 	scsipi_done(sc_xfer);
   2066   1.58  jdolecek 	if ((AHCI_TFD_ST(tfd) & WDCS_ERR) == 0)
   2067   1.58  jdolecek 		atastart(chp);
   2068    1.8    bouyer 	return 0;
   2069    1.8    bouyer }
   2070    1.8    bouyer 
   2071   1.29  jakllsch static void
   2072    1.8    bouyer ahci_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
   2073    1.8    bouyer {
   2074   1.58  jdolecek 	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
   2075   1.58  jdolecek 	bool deactivate = true;
   2076    1.8    bouyer 
   2077    1.8    bouyer 	/* remove this command from xfer queue */
   2078    1.8    bouyer 	switch (reason) {
   2079   1.58  jdolecek 	case KILL_GONE_INACTIVE:
   2080   1.58  jdolecek 		deactivate = false;
   2081   1.58  jdolecek 		/* FALLTHROUGH */
   2082    1.8    bouyer 	case KILL_GONE:
   2083    1.8    bouyer 		sc_xfer->error = XS_DRIVER_STUFFUP;
   2084    1.8    bouyer 		break;
   2085    1.8    bouyer 	case KILL_RESET:
   2086    1.8    bouyer 		sc_xfer->error = XS_RESET;
   2087    1.8    bouyer 		break;
   2088   1.58  jdolecek 	case KILL_REQUEUE:
   2089   1.58  jdolecek 		sc_xfer->error = XS_REQUEUE;
   2090   1.58  jdolecek 		break;
   2091    1.8    bouyer 	default:
   2092    1.8    bouyer 		printf("ahci_ata_atapi_kill_xfer: unknown reason %d\n", reason);
   2093    1.8    bouyer 		panic("ahci_ata_atapi_kill_xfer");
   2094    1.8    bouyer 	}
   2095   1.58  jdolecek 
   2096   1.64  jdolecek 	if (deactivate)
   2097   1.58  jdolecek 		ata_deactivate_xfer(chp, xfer);
   2098   1.58  jdolecek 
   2099    1.8    bouyer 	ata_free_xfer(chp, xfer);
   2100    1.8    bouyer 	scsipi_done(sc_xfer);
   2101    1.8    bouyer }
   2102    1.8    bouyer 
   2103   1.29  jakllsch static void
   2104    1.8    bouyer ahci_atapi_probe_device(struct atapibus_softc *sc, int target)
   2105    1.8    bouyer {
   2106    1.8    bouyer 	struct scsipi_channel *chan = sc->sc_channel;
   2107    1.8    bouyer 	struct scsipi_periph *periph;
   2108    1.8    bouyer 	struct ataparams ids;
   2109    1.8    bouyer 	struct ataparams *id = &ids;
   2110   1.13      cube 	struct ahci_softc *ahcic =
   2111   1.13      cube 	    device_private(chan->chan_adapter->adapt_dev);
   2112    1.8    bouyer 	struct atac_softc *atac = &ahcic->sc_atac;
   2113    1.8    bouyer 	struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
   2114    1.8    bouyer 	struct ata_drive_datas *drvp = &chp->ch_drive[target];
   2115    1.8    bouyer 	struct scsipibus_attach_args sa;
   2116    1.8    bouyer 	char serial_number[21], model[41], firmware_revision[9];
   2117    1.8    bouyer 	int s;
   2118    1.8    bouyer 
   2119    1.8    bouyer 	/* skip if already attached */
   2120    1.8    bouyer 	if (scsipi_lookup_periph(chan, target, 0) != NULL)
   2121    1.8    bouyer 		return;
   2122    1.8    bouyer 
   2123    1.8    bouyer 	/* if no ATAPI device detected at attach time, skip */
   2124   1.40    bouyer 	if (drvp->drive_type != ATA_DRIVET_ATAPI) {
   2125    1.8    bouyer 		AHCIDEBUG_PRINT(("ahci_atapi_probe_device: drive %d "
   2126    1.8    bouyer 		    "not present\n", target), DEBUG_PROBE);
   2127    1.8    bouyer 		return;
   2128    1.8    bouyer 	}
   2129    1.8    bouyer 
   2130    1.8    bouyer 	/* Some ATAPI devices need a bit more time after software reset. */
   2131    1.8    bouyer 	delay(5000);
   2132    1.8    bouyer 	if (ata_get_params(drvp,  AT_WAIT, id) == 0) {
   2133    1.8    bouyer #ifdef ATAPI_DEBUG_PROBE
   2134    1.8    bouyer 		printf("%s drive %d: cmdsz 0x%x drqtype 0x%x\n",
   2135   1.14      cube 		    AHCINAME(ahcic), target,
   2136    1.8    bouyer 		    id->atap_config & ATAPI_CFG_CMD_MASK,
   2137    1.8    bouyer 		    id->atap_config & ATAPI_CFG_DRQ_MASK);
   2138    1.8    bouyer #endif
   2139    1.8    bouyer 		periph = scsipi_alloc_periph(M_NOWAIT);
   2140    1.8    bouyer 		if (periph == NULL) {
   2141   1.14      cube 			aprint_error_dev(sc->sc_dev,
   2142   1.14      cube 			    "unable to allocate periph for drive %d\n",
   2143   1.14      cube 			    target);
   2144    1.8    bouyer 			return;
   2145    1.8    bouyer 		}
   2146    1.8    bouyer 		periph->periph_dev = NULL;
   2147    1.8    bouyer 		periph->periph_channel = chan;
   2148    1.8    bouyer 		periph->periph_switch = &atapi_probe_periphsw;
   2149    1.8    bouyer 		periph->periph_target = target;
   2150    1.8    bouyer 		periph->periph_lun = 0;
   2151    1.8    bouyer 		periph->periph_quirks = PQUIRK_ONLYBIG;
   2152    1.8    bouyer 
   2153    1.8    bouyer #ifdef SCSIPI_DEBUG
   2154    1.8    bouyer 		if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_ATAPI &&
   2155    1.8    bouyer 		    SCSIPI_DEBUG_TARGET == target)
   2156    1.8    bouyer 			periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS;
   2157    1.8    bouyer #endif
   2158    1.8    bouyer 		periph->periph_type = ATAPI_CFG_TYPE(id->atap_config);
   2159    1.8    bouyer 		if (id->atap_config & ATAPI_CFG_REMOV)
   2160    1.8    bouyer 			periph->periph_flags |= PERIPH_REMOVABLE;
   2161    1.8    bouyer 		if (periph->periph_type == T_SEQUENTIAL) {
   2162    1.8    bouyer 			s = splbio();
   2163   1.40    bouyer 			drvp->drive_flags |= ATA_DRIVE_ATAPIDSCW;
   2164    1.8    bouyer 			splx(s);
   2165    1.8    bouyer 		}
   2166    1.8    bouyer 
   2167    1.8    bouyer 		sa.sa_periph = periph;
   2168    1.8    bouyer 		sa.sa_inqbuf.type =  ATAPI_CFG_TYPE(id->atap_config);
   2169    1.8    bouyer 		sa.sa_inqbuf.removable = id->atap_config & ATAPI_CFG_REMOV ?
   2170    1.8    bouyer 		    T_REMOV : T_FIXED;
   2171   1.56  christos 		strnvisx(model, sizeof(model), id->atap_model, 40,
   2172   1.56  christos 		    VIS_TRIM|VIS_SAFE|VIS_OCTAL);
   2173   1.56  christos 		strnvisx(serial_number, sizeof(serial_number), id->atap_serial,
   2174   1.56  christos 		    20, VIS_TRIM|VIS_SAFE|VIS_OCTAL);
   2175   1.56  christos 		strnvisx(firmware_revision, sizeof(firmware_revision),
   2176   1.56  christos 		    id->atap_revision, 8, VIS_TRIM|VIS_SAFE|VIS_OCTAL);
   2177    1.8    bouyer 		sa.sa_inqbuf.vendor = model;
   2178    1.8    bouyer 		sa.sa_inqbuf.product = serial_number;
   2179    1.8    bouyer 		sa.sa_inqbuf.revision = firmware_revision;
   2180    1.8    bouyer 
   2181    1.8    bouyer 		/*
   2182    1.8    bouyer 		 * Determine the operating mode capabilities of the device.
   2183    1.8    bouyer 		 */
   2184    1.8    bouyer 		if ((id->atap_config & ATAPI_CFG_CMD_MASK) == ATAPI_CFG_CMD_16)
   2185    1.8    bouyer 			periph->periph_cap |= PERIPH_CAP_CMD16;
   2186    1.8    bouyer 		/* XXX This is gross. */
   2187    1.8    bouyer 		periph->periph_cap |= (id->atap_config & ATAPI_CFG_DRQ_MASK);
   2188    1.8    bouyer 
   2189    1.8    bouyer 		drvp->drv_softc = atapi_probe_device(sc, target, periph, &sa);
   2190    1.8    bouyer 
   2191    1.8    bouyer 		if (drvp->drv_softc)
   2192    1.8    bouyer 			ata_probe_caps(drvp);
   2193    1.8    bouyer 		else {
   2194    1.8    bouyer 			s = splbio();
   2195   1.40    bouyer 			drvp->drive_type = ATA_DRIVET_NONE;
   2196    1.8    bouyer 			splx(s);
   2197    1.8    bouyer 		}
   2198    1.8    bouyer 	} else {
   2199    1.8    bouyer 		AHCIDEBUG_PRINT(("ahci_atapi_get_params: ATAPI_IDENTIFY_DEVICE "
   2200   1.58  jdolecek 		    "failed for drive %s:%d:%d\n",
   2201   1.58  jdolecek 		    AHCINAME(ahcic), chp->ch_channel, target), DEBUG_PROBE);
   2202    1.8    bouyer 		s = splbio();
   2203   1.40    bouyer 		drvp->drive_type = ATA_DRIVET_NONE;
   2204    1.8    bouyer 		splx(s);
   2205    1.8    bouyer 	}
   2206    1.8    bouyer }
   2207    1.8    bouyer #endif /* NATAPIBUS */
   2208