Home | History | Annotate | Line # | Download | only in ic
wdc.c revision 1.185
      1  1.185    bouyer /*	$NetBSD: wdc.c,v 1.185 2004/08/02 22:20:54 bouyer Exp $ */
      2   1.31    bouyer 
      3   1.31    bouyer /*
      4  1.137    bouyer  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
      5   1.31    bouyer  *
      6   1.31    bouyer  * Redistribution and use in source and binary forms, with or without
      7   1.31    bouyer  * modification, are permitted provided that the following conditions
      8   1.31    bouyer  * are met:
      9   1.31    bouyer  * 1. Redistributions of source code must retain the above copyright
     10   1.31    bouyer  *    notice, this list of conditions and the following disclaimer.
     11   1.31    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.31    bouyer  *    notice, this list of conditions and the following disclaimer in the
     13   1.31    bouyer  *    documentation and/or other materials provided with the distribution.
     14   1.31    bouyer  * 3. All advertising materials mentioning features or use of this software
     15   1.31    bouyer  *    must display the following acknowledgement:
     16   1.31    bouyer  *  This product includes software developed by Manuel Bouyer.
     17   1.31    bouyer  * 4. The name of the author may not be used to endorse or promote products
     18   1.31    bouyer  *    derived from this software without specific prior written permission.
     19   1.31    bouyer  *
     20   1.31    bouyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21   1.31    bouyer  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22   1.31    bouyer  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23   1.31    bouyer  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24   1.31    bouyer  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25   1.31    bouyer  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26   1.31    bouyer  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27   1.31    bouyer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28   1.31    bouyer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29   1.31    bouyer  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30   1.31    bouyer  */
     31    1.2    bouyer 
     32   1.27   mycroft /*-
     33  1.125   mycroft  * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
     34   1.27   mycroft  * All rights reserved.
     35    1.2    bouyer  *
     36   1.27   mycroft  * This code is derived from software contributed to The NetBSD Foundation
     37   1.27   mycroft  * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
     38   1.12       cgd  *
     39    1.2    bouyer  * Redistribution and use in source and binary forms, with or without
     40    1.2    bouyer  * modification, are permitted provided that the following conditions
     41    1.2    bouyer  * are met:
     42    1.2    bouyer  * 1. Redistributions of source code must retain the above copyright
     43    1.2    bouyer  *    notice, this list of conditions and the following disclaimer.
     44    1.2    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     45    1.2    bouyer  *    notice, this list of conditions and the following disclaimer in the
     46    1.2    bouyer  *    documentation and/or other materials provided with the distribution.
     47    1.2    bouyer  * 3. All advertising materials mentioning features or use of this software
     48    1.2    bouyer  *    must display the following acknowledgement:
     49   1.27   mycroft  *        This product includes software developed by the NetBSD
     50   1.27   mycroft  *        Foundation, Inc. and its contributors.
     51   1.27   mycroft  * 4. Neither the name of The NetBSD Foundation nor the names of its
     52   1.27   mycroft  *    contributors may be used to endorse or promote products derived
     53   1.27   mycroft  *    from this software without specific prior written permission.
     54    1.2    bouyer  *
     55   1.27   mycroft  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     56   1.27   mycroft  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     57   1.27   mycroft  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     58   1.27   mycroft  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     59   1.27   mycroft  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     60   1.27   mycroft  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     61   1.27   mycroft  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     62   1.27   mycroft  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     63   1.27   mycroft  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     64   1.27   mycroft  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     65   1.27   mycroft  * POSSIBILITY OF SUCH DAMAGE.
     66    1.2    bouyer  */
     67    1.2    bouyer 
     68   1.12       cgd /*
     69   1.12       cgd  * CODE UNTESTED IN THE CURRENT REVISION:
     70   1.12       cgd  */
     71  1.100     lukem 
     72  1.100     lukem #include <sys/cdefs.h>
     73  1.185    bouyer __KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.185 2004/08/02 22:20:54 bouyer Exp $");
     74   1.12       cgd 
     75   1.59   hubertf #ifndef WDCDEBUG
     76   1.31    bouyer #define WDCDEBUG
     77   1.59   hubertf #endif /* WDCDEBUG */
     78   1.31    bouyer 
     79    1.2    bouyer #include <sys/param.h>
     80    1.2    bouyer #include <sys/systm.h>
     81    1.2    bouyer #include <sys/kernel.h>
     82    1.2    bouyer #include <sys/conf.h>
     83    1.2    bouyer #include <sys/buf.h>
     84   1.31    bouyer #include <sys/device.h>
     85    1.2    bouyer #include <sys/malloc.h>
     86   1.71    bouyer #include <sys/pool.h>
     87    1.2    bouyer #include <sys/syslog.h>
     88    1.2    bouyer #include <sys/proc.h>
     89    1.2    bouyer 
     90    1.2    bouyer #include <machine/intr.h>
     91    1.2    bouyer #include <machine/bus.h>
     92    1.2    bouyer 
     93   1.17  sakamoto #ifndef __BUS_SPACE_HAS_STREAM_METHODS
     94   1.31    bouyer #define bus_space_write_multi_stream_2	bus_space_write_multi_2
     95   1.31    bouyer #define bus_space_write_multi_stream_4	bus_space_write_multi_4
     96   1.31    bouyer #define bus_space_read_multi_stream_2	bus_space_read_multi_2
     97   1.31    bouyer #define bus_space_read_multi_stream_4	bus_space_read_multi_4
     98   1.17  sakamoto #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
     99   1.16  sakamoto 
    100  1.103    bouyer #include <dev/ata/atavar.h>
    101   1.31    bouyer #include <dev/ata/atareg.h>
    102   1.12       cgd #include <dev/ic/wdcreg.h>
    103   1.12       cgd #include <dev/ic/wdcvar.h>
    104   1.31    bouyer 
    105  1.137    bouyer #include "locators.h"
    106  1.137    bouyer 
    107  1.122   thorpej #include "ataraid.h"
    108    1.2    bouyer #include "atapibus.h"
    109  1.106    bouyer #include "wd.h"
    110    1.2    bouyer 
    111  1.122   thorpej #if NATARAID > 0
    112  1.122   thorpej #include <dev/ata/ata_raidvar.h>
    113  1.122   thorpej #endif
    114  1.122   thorpej 
    115   1.31    bouyer #define WDCDELAY  100 /* 100 microseconds */
    116   1.31    bouyer #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
    117    1.2    bouyer #if 0
    118   1.31    bouyer /* If you enable this, it will report any delays more than WDCDELAY * N long. */
    119    1.2    bouyer #define WDCNDELAY_DEBUG	50
    120    1.2    bouyer #endif
    121    1.2    bouyer 
    122  1.137    bouyer /* When polling wait that much and then tsleep for 1/hz seconds */
    123  1.137    bouyer #define WDCDELAY_POLL 1 /* ms */
    124  1.137    bouyer 
    125  1.137    bouyer /* timeout for the control commands */
    126  1.137    bouyer #define WDC_CTRL_DELAY 10000 /* 10s, for the recall command */
    127  1.137    bouyer 
    128   1.71    bouyer struct pool wdc_xfer_pool;
    129    1.2    bouyer 
    130  1.106    bouyer #if NWD > 0
    131  1.103    bouyer extern const struct ata_bustype wdc_ata_bustype; /* in ata_wdc.c */
    132  1.106    bouyer #else
    133  1.106    bouyer /* A fake one, the autoconfig will print "wd at foo ... not configured */
    134  1.106    bouyer const struct ata_bustype wdc_ata_bustype = {
    135  1.106    bouyer 	SCSIPI_BUSTYPE_ATA,
    136  1.106    bouyer 	NULL,
    137  1.106    bouyer 	NULL,
    138  1.106    bouyer 	NULL,
    139  1.106    bouyer 	NULL,
    140  1.106    bouyer 	NULL,
    141  1.106    bouyer 	NULL,
    142  1.106    bouyer 	NULL
    143  1.106    bouyer };
    144  1.106    bouyer #endif
    145  1.102    bouyer 
    146  1.168   thorpej static int	wdcprobe1(struct wdc_channel*, int);
    147  1.168   thorpej static void	__wdcerror(struct wdc_channel*, char *);
    148  1.168   thorpej static int	__wdcwait_reset(struct wdc_channel *, int, int);
    149  1.168   thorpej static void	__wdccommand_done(struct wdc_channel *, struct ata_xfer *);
    150  1.182    bouyer static void	__wdccommand_done_end(struct wdc_channel *, struct ata_xfer *);
    151  1.182    bouyer static void	__wdccommand_kill_xfer(struct wdc_channel *,
    152  1.182    bouyer 			               struct ata_xfer *, int);
    153  1.168   thorpej static void	__wdccommand_start(struct wdc_channel *, struct ata_xfer *);
    154  1.182    bouyer static int	__wdccommand_intr(struct wdc_channel *, struct ata_xfer *, int);
    155  1.168   thorpej static int	__wdcwait(struct wdc_channel *, int, int, int);
    156   1.31    bouyer 
    157   1.31    bouyer #define DEBUG_INTR   0x01
    158   1.31    bouyer #define DEBUG_XFERS  0x02
    159   1.31    bouyer #define DEBUG_STATUS 0x04
    160   1.31    bouyer #define DEBUG_FUNCS  0x08
    161   1.31    bouyer #define DEBUG_PROBE  0x10
    162   1.74     enami #define DEBUG_DETACH 0x20
    163   1.87    bouyer #define DEBUG_DELAY  0x40
    164   1.31    bouyer #ifdef WDCDEBUG
    165   1.32    bouyer int wdcdebug_mask = 0;
    166   1.31    bouyer int wdc_nxfer = 0;
    167   1.31    bouyer #define WDCDEBUG_PRINT(args, level)  if (wdcdebug_mask & (level)) printf args
    168    1.2    bouyer #else
    169   1.31    bouyer #define WDCDEBUG_PRINT(args, level)
    170    1.2    bouyer #endif
    171    1.2    bouyer 
    172  1.162   thorpej /*
    173  1.162   thorpej  * A queue of atabus instances, used to ensure the same bus probe order
    174  1.162   thorpej  * for a given hardware configuration at each boot.
    175  1.162   thorpej  */
    176  1.162   thorpej struct atabus_initq_head atabus_initq_head =
    177  1.162   thorpej     TAILQ_HEAD_INITIALIZER(atabus_initq_head);
    178  1.162   thorpej struct simplelock atabus_interlock = SIMPLELOCK_INITIALIZER;
    179  1.137    bouyer 
    180  1.176   thorpej /*
    181  1.176   thorpej  * Initialize the "shadow register" handles for a standard wdc controller.
    182  1.176   thorpej  */
    183  1.176   thorpej void
    184  1.176   thorpej wdc_init_shadow_regs(struct wdc_channel *chp)
    185  1.176   thorpej {
    186  1.176   thorpej 
    187  1.176   thorpej 	chp->cmd_iohs[wd_status] = chp->cmd_iohs[wd_command];
    188  1.176   thorpej 	chp->cmd_iohs[wd_features] = chp->cmd_iohs[wd_error];
    189  1.176   thorpej }
    190  1.176   thorpej 
    191  1.162   thorpej /* Test to see controller with at last one attached drive is there.
    192  1.162   thorpej  * Returns a bit for each possible drive found (0x01 for drive 0,
    193  1.162   thorpej  * 0x02 for drive 1).
    194  1.162   thorpej  * Logic:
    195  1.162   thorpej  * - If a status register is at 0xff, assume there is no drive here
    196  1.162   thorpej  *   (ISA has pull-up resistors).  Similarly if the status register has
    197  1.162   thorpej  *   the value we last wrote to the bus (for IDE interfaces without pullups).
    198  1.162   thorpej  *   If no drive at all -> return.
    199  1.162   thorpej  * - reset the controller, wait for it to complete (may take up to 31s !).
    200  1.162   thorpej  *   If timeout -> return.
    201  1.162   thorpej  * - test ATA/ATAPI signatures. If at last one drive found -> return.
    202  1.162   thorpej  * - try an ATA command on the master.
    203  1.162   thorpej  */
    204  1.137    bouyer 
    205  1.164   thorpej static void
    206  1.168   thorpej wdc_drvprobe(struct wdc_channel *chp)
    207  1.137    bouyer {
    208  1.137    bouyer 	struct ataparams params;
    209  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
    210  1.145  christos 	u_int8_t st0 = 0, st1 = 0;
    211  1.164   thorpej 	int i, error;
    212  1.137    bouyer 
    213  1.164   thorpej 	if (wdcprobe1(chp, 0) == 0) {
    214  1.164   thorpej 		/* No drives, abort the attach here. */
    215  1.164   thorpej 		return;
    216  1.161   thorpej 	}
    217  1.137    bouyer 
    218  1.137    bouyer 	/* for ATA/OLD drives, wait for DRDY, 3s timeout */
    219  1.137    bouyer 	for (i = 0; i < mstohz(3000); i++) {
    220  1.174    bouyer 		if (chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD)) {
    221  1.174    bouyer 			if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    222  1.174    bouyer 				wdc->select(chp,0);
    223  1.174    bouyer 			bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
    224  1.174    bouyer 			    0, WDSD_IBM);
    225  1.174    bouyer 			delay(10);	/* 400ns delay */
    226  1.174    bouyer 			st0 = bus_space_read_1(chp->cmd_iot,
    227  1.174    bouyer 			    chp->cmd_iohs[wd_status], 0);
    228  1.174    bouyer 		}
    229  1.137    bouyer 
    230  1.174    bouyer 		if (chp->ch_drive[1].drive_flags & (DRIVE_ATA|DRIVE_OLD)) {
    231  1.174    bouyer 			if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    232  1.174    bouyer 				wdc->select(chp,1);
    233  1.174    bouyer 			bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
    234  1.174    bouyer 			    0, WDSD_IBM | 0x10);
    235  1.174    bouyer 			delay(10);	/* 400ns delay */
    236  1.174    bouyer 			st1 = bus_space_read_1(chp->cmd_iot,
    237  1.174    bouyer 			    chp->cmd_iohs[wd_status], 0);
    238  1.174    bouyer 		}
    239  1.137    bouyer 
    240  1.137    bouyer 		if (((chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD))
    241  1.137    bouyer 			== 0 ||
    242  1.137    bouyer 		    (st0 & WDCS_DRDY)) &&
    243  1.137    bouyer 		    ((chp->ch_drive[1].drive_flags & (DRIVE_ATA|DRIVE_OLD))
    244  1.137    bouyer 			== 0 ||
    245  1.137    bouyer 		    (st1 & WDCS_DRDY)))
    246  1.137    bouyer 			break;
    247  1.164   thorpej 		tsleep(&params, PRIBIO, "atadrdy", 1);
    248  1.137    bouyer 	}
    249  1.137    bouyer 	if ((st0 & WDCS_DRDY) == 0)
    250  1.137    bouyer 		chp->ch_drive[0].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD);
    251  1.137    bouyer 	if ((st1 & WDCS_DRDY) == 0)
    252  1.137    bouyer 		chp->ch_drive[1].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD);
    253  1.137    bouyer 
    254  1.137    bouyer 	WDCDEBUG_PRINT(("%s:%d: wait DRDY st0 0x%x st1 0x%x\n",
    255  1.169   thorpej 	    wdc->sc_dev.dv_xname,
    256  1.169   thorpej 	    chp->ch_channel, st0, st1), DEBUG_PROBE);
    257  1.137    bouyer 
    258  1.137    bouyer 	/* Wait a bit, some devices are weird just after a reset. */
    259  1.137    bouyer 	delay(5000);
    260  1.137    bouyer 
    261  1.137    bouyer 	for (i = 0; i < 2; i++) {
    262  1.171   thorpej 		/* XXX This should be done by other code. */
    263  1.137    bouyer 		chp->ch_drive[i].chnl_softc = chp;
    264  1.137    bouyer 		chp->ch_drive[i].drive = i;
    265  1.171   thorpej 
    266  1.137    bouyer 		/*
    267  1.137    bouyer 		 * Init error counter so that an error withing the first xfers
    268  1.137    bouyer 		 * will trigger a downgrade
    269  1.137    bouyer 		 */
    270  1.137    bouyer 		chp->ch_drive[i].n_dmaerrs = NERRS_MAX-1;
    271  1.137    bouyer 
    272  1.137    bouyer 		/* If controller can't do 16bit flag the drives as 32bit */
    273  1.169   thorpej 		if ((wdc->cap &
    274  1.137    bouyer 		    (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
    275  1.137    bouyer 		    WDC_CAPABILITY_DATA32)
    276  1.137    bouyer 			chp->ch_drive[i].drive_flags |= DRIVE_CAP32;
    277  1.137    bouyer 		if ((chp->ch_drive[i].drive_flags & DRIVE) == 0)
    278  1.137    bouyer 			continue;
    279  1.137    bouyer 
    280  1.144    briggs 		/* Shortcut in case we've been shutdown */
    281  1.144    briggs 		if (chp->ch_flags & WDCF_SHUTDOWN)
    282  1.164   thorpej 			return;
    283  1.144    briggs 
    284  1.137    bouyer 		/* issue an identify, to try to detect ghosts */
    285  1.137    bouyer 		error = ata_get_params(&chp->ch_drive[i],
    286  1.137    bouyer 		    AT_WAIT | AT_POLL, &params);
    287  1.137    bouyer 		if (error != CMD_OK) {
    288  1.164   thorpej 			tsleep(&params, PRIBIO, "atacnf", mstohz(1000));
    289  1.144    briggs 
    290  1.144    briggs 			/* Shortcut in case we've been shutdown */
    291  1.144    briggs 			if (chp->ch_flags & WDCF_SHUTDOWN)
    292  1.164   thorpej 				return;
    293  1.144    briggs 
    294  1.137    bouyer 			error = ata_get_params(&chp->ch_drive[i],
    295  1.137    bouyer 			    AT_WAIT | AT_POLL, &params);
    296  1.137    bouyer 		}
    297  1.137    bouyer 		if (error == CMD_OK) {
    298  1.152       wiz 			/* If IDENTIFY succeeded, this is not an OLD ctrl */
    299  1.137    bouyer 			chp->ch_drive[0].drive_flags &= ~DRIVE_OLD;
    300  1.137    bouyer 			chp->ch_drive[1].drive_flags &= ~DRIVE_OLD;
    301  1.137    bouyer 		} else {
    302  1.155    bouyer 			chp->ch_drive[i].drive_flags &=
    303  1.137    bouyer 			    ~(DRIVE_ATA | DRIVE_ATAPI);
    304  1.137    bouyer 			WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed (%d)\n",
    305  1.169   thorpej 			    wdc->sc_dev.dv_xname,
    306  1.169   thorpej 			    chp->ch_channel, i, error), DEBUG_PROBE);
    307  1.137    bouyer 			if ((chp->ch_drive[i].drive_flags & DRIVE_OLD) == 0)
    308  1.137    bouyer 				continue;
    309  1.137    bouyer 			/*
    310  1.137    bouyer 			 * Pre-ATA drive ?
    311  1.137    bouyer 			 * Test registers writability (Error register not
    312  1.137    bouyer 			 * writable, but cyllo is), then try an ATA command.
    313  1.137    bouyer 			 */
    314  1.169   thorpej 			if (wdc->cap & WDC_CAPABILITY_SELECT)
    315  1.169   thorpej 				wdc->select(chp,i);
    316  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    317  1.157      fvdl 			    chp->cmd_iohs[wd_sdh], 0, WDSD_IBM | (i << 4));
    318  1.137    bouyer 			delay(10);	/* 400ns delay */
    319  1.157      fvdl 			bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_error],
    320  1.157      fvdl 			    0, 0x58);
    321  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    322  1.157      fvdl 			    chp->cmd_iohs[wd_cyl_lo], 0, 0xa5);
    323  1.157      fvdl 			if (bus_space_read_1(chp->cmd_iot,
    324  1.157      fvdl 				chp->cmd_iohs[wd_error], 0) == 0x58 ||
    325  1.157      fvdl 			    bus_space_read_1(chp->cmd_iot,
    326  1.157      fvdl 				chp->cmd_iohs[wd_cyl_lo], 0) != 0xa5) {
    327  1.137    bouyer 				WDCDEBUG_PRINT(("%s:%d:%d: register "
    328  1.137    bouyer 				    "writability failed\n",
    329  1.169   thorpej 				    wdc->sc_dev.dv_xname,
    330  1.169   thorpej 				    chp->ch_channel, i), DEBUG_PROBE);
    331  1.137    bouyer 				    chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
    332  1.155    bouyer 				    continue;
    333  1.137    bouyer 			}
    334  1.166   thorpej 			if (wdc_wait_for_ready(chp, 10000, 0) == WDCWAIT_TOUT) {
    335  1.137    bouyer 				WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
    336  1.169   thorpej 				    wdc->sc_dev.dv_xname,
    337  1.169   thorpej 				    chp->ch_channel, i), DEBUG_PROBE);
    338  1.137    bouyer 				chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
    339  1.137    bouyer 				continue;
    340  1.137    bouyer 			}
    341  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    342  1.157      fvdl 			    chp->cmd_iohs[wd_command], 0, WDCC_RECAL);
    343  1.137    bouyer 			delay(10);	/* 400ns delay */
    344  1.166   thorpej 			if (wdc_wait_for_ready(chp, 10000, 0) == WDCWAIT_TOUT) {
    345  1.137    bouyer 				WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
    346  1.169   thorpej 				    wdc->sc_dev.dv_xname,
    347  1.169   thorpej 				    chp->ch_channel, i), DEBUG_PROBE);
    348  1.137    bouyer 				chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
    349  1.155    bouyer 			} else {
    350  1.155    bouyer 				chp->ch_drive[0].drive_flags &=
    351  1.155    bouyer 				    ~(DRIVE_ATA | DRIVE_ATAPI);
    352  1.155    bouyer 				chp->ch_drive[1].drive_flags &=
    353  1.155    bouyer 				    ~(DRIVE_ATA | DRIVE_ATAPI);
    354  1.137    bouyer 			}
    355  1.137    bouyer 		}
    356  1.137    bouyer 	}
    357  1.164   thorpej }
    358  1.164   thorpej 
    359  1.164   thorpej void
    360  1.164   thorpej atabusconfig(struct atabus_softc *atabus_sc)
    361  1.164   thorpej {
    362  1.168   thorpej 	struct wdc_channel *chp = atabus_sc->sc_chan;
    363  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
    364  1.164   thorpej 	int i, error, need_delref = 0;
    365  1.164   thorpej 	struct atabus_initq *atabus_initq = NULL;
    366  1.164   thorpej 
    367  1.164   thorpej 	if ((error = wdc_addref(chp)) != 0) {
    368  1.164   thorpej 		aprint_error("%s: unable to enable controller\n",
    369  1.169   thorpej 		    wdc->sc_dev.dv_xname);
    370  1.164   thorpej 		goto out;
    371  1.164   thorpej 	}
    372  1.164   thorpej 	need_delref = 1;
    373  1.164   thorpej 
    374  1.164   thorpej 	/* Probe for the drives. */
    375  1.169   thorpej 	(*wdc->drv_probe)(chp);
    376  1.137    bouyer 
    377  1.137    bouyer 	WDCDEBUG_PRINT(("atabusattach: ch_drive_flags 0x%x 0x%x\n",
    378  1.137    bouyer 	    chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
    379  1.137    bouyer 	    DEBUG_PROBE);
    380  1.137    bouyer 
    381  1.137    bouyer 	/* If no drives, abort here */
    382  1.137    bouyer 	if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
    383  1.137    bouyer 	    (chp->ch_drive[1].drive_flags & DRIVE) == 0)
    384  1.137    bouyer 		goto out;
    385  1.137    bouyer 
    386  1.164   thorpej 	/* Shortcut in case we've been shutdown */
    387  1.164   thorpej 	if (chp->ch_flags & WDCF_SHUTDOWN)
    388  1.164   thorpej 		goto out;
    389  1.164   thorpej 
    390  1.137    bouyer 	/* Make sure the devices probe in atabus order to avoid jitter. */
    391  1.137    bouyer 	simple_lock(&atabus_interlock);
    392  1.137    bouyer 	while(1) {
    393  1.137    bouyer 		atabus_initq = TAILQ_FIRST(&atabus_initq_head);
    394  1.137    bouyer 		if (atabus_initq->atabus_sc == atabus_sc)
    395  1.137    bouyer 			break;
    396  1.137    bouyer 		ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0,
    397  1.137    bouyer 		    &atabus_interlock);
    398  1.137    bouyer 	}
    399  1.137    bouyer 	simple_unlock(&atabus_interlock);
    400  1.137    bouyer 
    401  1.137    bouyer 	/*
    402  1.137    bouyer 	 * Attach an ATAPI bus, if needed.
    403  1.137    bouyer 	 */
    404  1.137    bouyer 	if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
    405  1.137    bouyer 	    (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
    406  1.137    bouyer #if NATAPIBUS > 0
    407  1.137    bouyer 		wdc_atapibus_attach(atabus_sc);
    408  1.137    bouyer #else
    409  1.137    bouyer 		/*
    410  1.137    bouyer 		 * Fake the autoconfig "not configured" message
    411  1.137    bouyer 		 */
    412  1.137    bouyer 		aprint_normal("atapibus at %s not configured\n",
    413  1.169   thorpej 		    wdc->sc_dev.dv_xname);
    414  1.137    bouyer 		chp->atapibus = NULL;
    415  1.141    bouyer 		chp->ch_drive[0].drive_flags &= ~DRIVE_ATAPI;
    416  1.141    bouyer 		chp->ch_drive[1].drive_flags &= ~DRIVE_ATAPI;
    417  1.137    bouyer #endif
    418  1.137    bouyer 	}
    419  1.137    bouyer 
    420  1.137    bouyer 	for (i = 0; i < 2; i++) {
    421  1.137    bouyer 		struct ata_device adev;
    422  1.137    bouyer 		if ((chp->ch_drive[i].drive_flags &
    423  1.137    bouyer 		    (DRIVE_ATA | DRIVE_OLD)) == 0) {
    424  1.137    bouyer 			continue;
    425  1.137    bouyer 		}
    426  1.137    bouyer 		memset(&adev, 0, sizeof(struct ata_device));
    427  1.137    bouyer 		adev.adev_bustype = &wdc_ata_bustype;
    428  1.169   thorpej 		adev.adev_channel = chp->ch_channel;
    429  1.137    bouyer 		adev.adev_openings = 1;
    430  1.137    bouyer 		adev.adev_drv_data = &chp->ch_drive[i];
    431  1.137    bouyer 		chp->ata_drives[i] = config_found(&atabus_sc->sc_dev,
    432  1.162   thorpej 		    &adev, ataprint);
    433  1.141    bouyer 		if (chp->ata_drives[i] != NULL)
    434  1.137    bouyer 			wdc_probe_caps(&chp->ch_drive[i]);
    435  1.141    bouyer 		else
    436  1.141    bouyer 			chp->ch_drive[i].drive_flags &=
    437  1.141    bouyer 			    ~(DRIVE_ATA | DRIVE_OLD);
    438  1.137    bouyer 	}
    439  1.137    bouyer 
    440  1.137    bouyer 	/* now that we know the drives, the controller can set its modes */
    441  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_MODE) {
    442  1.169   thorpej 		wdc->set_modes(chp);
    443  1.137    bouyer 		wdc_print_modes(chp);
    444  1.137    bouyer 	}
    445  1.137    bouyer #if NATARAID > 0
    446  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_RAID)
    447  1.137    bouyer 		for (i = 0; i < 2; i++)
    448  1.137    bouyer 			if (chp->ata_drives[i] != NULL)
    449  1.137    bouyer 				ata_raid_check_component(chp->ata_drives[i]);
    450  1.137    bouyer #endif /* NATARAID > 0 */
    451  1.137    bouyer 
    452  1.137    bouyer 	/*
    453  1.152       wiz 	 * reset drive_flags for unattached devices, reset state for attached
    454  1.137    bouyer 	 *  ones
    455  1.137    bouyer 	 */
    456  1.137    bouyer 	for (i = 0; i < 2; i++) {
    457  1.137    bouyer 		if (chp->ch_drive[i].drv_softc == NULL)
    458  1.137    bouyer 			chp->ch_drive[i].drive_flags = 0;
    459  1.137    bouyer 		else
    460  1.137    bouyer 			chp->ch_drive[i].state = 0;
    461  1.137    bouyer 	}
    462  1.137    bouyer 
    463  1.163   thorpej  out:
    464  1.137    bouyer 	if (atabus_initq == NULL) {
    465  1.137    bouyer 		simple_lock(&atabus_interlock);
    466  1.137    bouyer 		while(1) {
    467  1.137    bouyer 			atabus_initq = TAILQ_FIRST(&atabus_initq_head);
    468  1.137    bouyer 			if (atabus_initq->atabus_sc == atabus_sc)
    469  1.137    bouyer 				break;
    470  1.137    bouyer 			ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0,
    471  1.137    bouyer 			    &atabus_interlock);
    472  1.137    bouyer 		}
    473  1.137    bouyer 		simple_unlock(&atabus_interlock);
    474  1.137    bouyer 	}
    475  1.137    bouyer         simple_lock(&atabus_interlock);
    476  1.137    bouyer         TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
    477  1.137    bouyer         simple_unlock(&atabus_interlock);
    478  1.137    bouyer 
    479  1.137    bouyer         free(atabus_initq, M_DEVBUF);
    480  1.137    bouyer         wakeup(&atabus_initq_head);
    481  1.137    bouyer 
    482  1.137    bouyer 	config_pending_decr();
    483  1.144    briggs 	if (need_delref)
    484  1.144    briggs 		wdc_delref(chp);
    485  1.137    bouyer }
    486  1.137    bouyer 
    487    1.2    bouyer int
    488  1.168   thorpej wdcprobe(struct wdc_channel *chp)
    489   1.12       cgd {
    490  1.163   thorpej 
    491  1.163   thorpej 	return (wdcprobe1(chp, 1));
    492  1.137    bouyer }
    493  1.137    bouyer 
    494  1.167   thorpej static int
    495  1.168   thorpej wdcprobe1(struct wdc_channel *chp, int poll)
    496  1.137    bouyer {
    497  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
    498   1.31    bouyer 	u_int8_t st0, st1, sc, sn, cl, ch;
    499   1.31    bouyer 	u_int8_t ret_value = 0x03;
    500   1.31    bouyer 	u_int8_t drive;
    501  1.156    bouyer 	int s;
    502   1.31    bouyer 
    503   1.31    bouyer 	/*
    504   1.31    bouyer 	 * Sanity check to see if the wdc channel responds at all.
    505   1.31    bouyer 	 */
    506   1.31    bouyer 
    507  1.174    bouyer 	s = splbio();
    508  1.169   thorpej 	if (wdc == NULL ||
    509  1.169   thorpej 	    (wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
    510  1.107       dbj 
    511  1.169   thorpej 		if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    512  1.169   thorpej 			wdc->select(chp,0);
    513  1.137    bouyer 
    514  1.157      fvdl 		bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
    515   1.43      kenh 		    WDSD_IBM);
    516  1.131   mycroft 		delay(10);	/* 400ns delay */
    517  1.157      fvdl 		st0 = bus_space_read_1(chp->cmd_iot,
    518  1.157      fvdl 		    chp->cmd_iohs[wd_status], 0);
    519  1.107       dbj 
    520  1.169   thorpej 		if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    521  1.169   thorpej 			wdc->select(chp,1);
    522  1.137    bouyer 
    523  1.157      fvdl 		bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
    524   1.43      kenh 		    WDSD_IBM | 0x10);
    525  1.131   mycroft 		delay(10);	/* 400ns delay */
    526  1.157      fvdl 		st1 = bus_space_read_1(chp->cmd_iot,
    527  1.157      fvdl 		    chp->cmd_iohs[wd_status], 0);
    528   1.43      kenh 
    529   1.43      kenh 		WDCDEBUG_PRINT(("%s:%d: before reset, st0=0x%x, st1=0x%x\n",
    530  1.169   thorpej 		    wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe",
    531  1.169   thorpej 		    chp->ch_channel, st0, st1), DEBUG_PROBE);
    532   1.43      kenh 
    533  1.142    bouyer 		if (st0 == 0xff || st0 == WDSD_IBM)
    534   1.43      kenh 			ret_value &= ~0x01;
    535  1.142    bouyer 		if (st1 == 0xff || st1 == (WDSD_IBM | 0x10))
    536   1.43      kenh 			ret_value &= ~0x02;
    537  1.125   mycroft 		/* Register writability test, drive 0. */
    538  1.125   mycroft 		if (ret_value & 0x01) {
    539  1.169   thorpej 			if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    540  1.169   thorpej 				wdc->select(chp,0);
    541  1.157      fvdl 			bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
    542  1.157      fvdl 			    0, WDSD_IBM);
    543  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    544  1.157      fvdl 			    chp->cmd_iohs[wd_cyl_lo], 0, 0x02);
    545  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    546  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
    547  1.174    bouyer 			if (cl != 0x02) {
    548  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 0 wd_cyl_lo: "
    549  1.174    bouyer 				    "got 0x%x != 0x02\n",
    550  1.174    bouyer 				    wdc != NULL ?
    551  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    552  1.174    bouyer 				    chp->ch_channel, cl),
    553  1.174    bouyer 				    DEBUG_PROBE);
    554  1.125   mycroft 				ret_value &= ~0x01;
    555  1.174    bouyer 			}
    556  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    557  1.157      fvdl 			    chp->cmd_iohs[wd_cyl_lo], 0, 0x01);
    558  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    559  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
    560  1.174    bouyer 			if (cl != 0x01) {
    561  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 0 wd_cyl_lo: "
    562  1.174    bouyer 				    "got 0x%x != 0x01\n",
    563  1.174    bouyer 				    wdc != NULL ?
    564  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    565  1.174    bouyer 				    chp->ch_channel, cl),
    566  1.174    bouyer 				    DEBUG_PROBE);
    567  1.125   mycroft 				ret_value &= ~0x01;
    568  1.174    bouyer 			}
    569  1.167   thorpej 			bus_space_write_1(chp->cmd_iot,
    570  1.167   thorpej 			    chp->cmd_iohs[wd_sector], 0, 0x01);
    571  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    572  1.174    bouyer 			    chp->cmd_iohs[wd_sector], 0);
    573  1.174    bouyer 			if (cl != 0x01) {
    574  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 0 wd_sector: "
    575  1.174    bouyer 				    "got 0x%x != 0x01\n",
    576  1.174    bouyer 				    wdc != NULL ?
    577  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    578  1.174    bouyer 				    chp->ch_channel, cl),
    579  1.174    bouyer 				    DEBUG_PROBE);
    580  1.125   mycroft 				ret_value &= ~0x01;
    581  1.174    bouyer 			}
    582  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    583  1.157      fvdl 			    chp->cmd_iohs[wd_sector], 0, 0x02);
    584  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    585  1.174    bouyer 			    chp->cmd_iohs[wd_sector], 0);
    586  1.174    bouyer 			if (cl != 0x02) {
    587  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 0 wd_sector: "
    588  1.174    bouyer 				    "got 0x%x != 0x02\n",
    589  1.174    bouyer 				    wdc != NULL ?
    590  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    591  1.174    bouyer 				    chp->ch_channel, cl),
    592  1.174    bouyer 				    DEBUG_PROBE);
    593  1.125   mycroft 				ret_value &= ~0x01;
    594  1.174    bouyer 			}
    595  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    596  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
    597  1.174    bouyer 			if (cl != 0x01) {
    598  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 0 wd_cyl_lo(2): "
    599  1.174    bouyer 				    "got 0x%x != 0x01\n",
    600  1.174    bouyer 				    wdc != NULL ?
    601  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    602  1.174    bouyer 				    chp->ch_channel, cl),
    603  1.174    bouyer 				    DEBUG_PROBE);
    604  1.131   mycroft 				ret_value &= ~0x01;
    605  1.174    bouyer 			}
    606  1.125   mycroft 		}
    607  1.125   mycroft 		/* Register writability test, drive 1. */
    608  1.125   mycroft 		if (ret_value & 0x02) {
    609  1.169   thorpej 			if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    610  1.169   thorpej 			     wdc->select(chp,1);
    611  1.157      fvdl 			bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
    612  1.157      fvdl 			     0, WDSD_IBM | 0x10);
    613  1.167   thorpej 			bus_space_write_1(chp->cmd_iot,
    614  1.167   thorpej 			    chp->cmd_iohs[wd_cyl_lo], 0, 0x02);
    615  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    616  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
    617  1.174    bouyer 			if (cl != 0x02) {
    618  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 1 wd_cyl_lo: "
    619  1.174    bouyer 				    "got 0x%x != 0x02\n",
    620  1.174    bouyer 				    wdc != NULL ?
    621  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    622  1.174    bouyer 				    chp->ch_channel, cl),
    623  1.174    bouyer 				    DEBUG_PROBE);
    624  1.125   mycroft 				ret_value &= ~0x02;
    625  1.174    bouyer 			}
    626  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    627  1.157      fvdl 			    chp->cmd_iohs[wd_cyl_lo], 0, 0x01);
    628  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    629  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
    630  1.174    bouyer 			if (cl != 0x01) {
    631  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 1 wd_cyl_lo: "
    632  1.174    bouyer 				    "got 0x%x != 0x01\n",
    633  1.174    bouyer 				    wdc != NULL ?
    634  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    635  1.174    bouyer 				    chp->ch_channel, cl),
    636  1.174    bouyer 				    DEBUG_PROBE);
    637  1.125   mycroft 				ret_value &= ~0x02;
    638  1.174    bouyer 			}
    639  1.157      fvdl 			bus_space_write_1(chp->cmd_iot,
    640  1.157      fvdl 			    chp->cmd_iohs[wd_sector], 0, 0x01);
    641  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    642  1.174    bouyer 			    chp->cmd_iohs[wd_sector], 0);
    643  1.174    bouyer 			if (cl != 0x01) {
    644  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 1 wd_sector: "
    645  1.174    bouyer 				    "got 0x%x != 0x01\n",
    646  1.174    bouyer 				    wdc != NULL ?
    647  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    648  1.174    bouyer 				    chp->ch_channel, cl),
    649  1.174    bouyer 				    DEBUG_PROBE);
    650  1.125   mycroft 				ret_value &= ~0x02;
    651  1.174    bouyer 			}
    652  1.167   thorpej 			bus_space_write_1(chp->cmd_iot,
    653  1.167   thorpej 			    chp->cmd_iohs[wd_sector], 0, 0x02);
    654  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    655  1.174    bouyer 			    chp->cmd_iohs[wd_sector], 0);
    656  1.174    bouyer 			if (cl != 0x02) {
    657  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 1 wd_sector: "
    658  1.174    bouyer 				    "got 0x%x != 0x02\n",
    659  1.174    bouyer 				    wdc != NULL ?
    660  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    661  1.174    bouyer 				    chp->ch_channel, cl),
    662  1.174    bouyer 				    DEBUG_PROBE);
    663  1.125   mycroft 				ret_value &= ~0x02;
    664  1.174    bouyer 			}
    665  1.174    bouyer 			cl = bus_space_read_1(chp->cmd_iot,
    666  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
    667  1.174    bouyer 			if (cl != 0x01) {
    668  1.174    bouyer 				WDCDEBUG_PRINT(("%s:%d drive 1 wd_cyl_lo(2): "
    669  1.174    bouyer 				    "got 0x%x != 0x01\n",
    670  1.174    bouyer 				    wdc != NULL ?
    671  1.174    bouyer 				    wdc->sc_dev.dv_xname : "wdcprobe",
    672  1.174    bouyer 				    chp->ch_channel, cl),
    673  1.174    bouyer 				    DEBUG_PROBE);
    674  1.131   mycroft 				ret_value &= ~0x02;
    675  1.174    bouyer 			}
    676  1.125   mycroft 		}
    677  1.137    bouyer 
    678  1.174    bouyer 		if (ret_value == 0) {
    679  1.174    bouyer 			splx(s);
    680  1.137    bouyer 			return 0;
    681  1.174    bouyer 		}
    682   1.62    bouyer 	}
    683   1.31    bouyer 
    684  1.174    bouyer 
    685  1.181    bouyer #if 0 /* XXX this break some ATA or ATAPI devices */
    686  1.174    bouyer 	/*
    687  1.174    bouyer 	 * reset bus. Also send an ATAPI_RESET to devices, in case there are
    688  1.174    bouyer 	 * ATAPI device out there which don't react to the bus reset
    689  1.174    bouyer 	 */
    690  1.174    bouyer 	if (ret_value & 0x01) {
    691  1.174    bouyer 		if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    692  1.174    bouyer 			wdc->select(chp,0);
    693  1.174    bouyer 		bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
    694  1.174    bouyer 		     0, WDSD_IBM);
    695  1.174    bouyer 		bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_command], 0,
    696  1.174    bouyer 		    ATAPI_SOFT_RESET);
    697  1.174    bouyer 	}
    698  1.174    bouyer 	if (ret_value & 0x02) {
    699  1.174    bouyer 		if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    700  1.174    bouyer 			wdc->select(chp,0);
    701  1.174    bouyer 		bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
    702  1.174    bouyer 		     0, WDSD_IBM | 0x10);
    703  1.174    bouyer 		bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_command], 0,
    704  1.174    bouyer 		    ATAPI_SOFT_RESET);
    705  1.174    bouyer 	}
    706  1.156    bouyer 
    707  1.175    bouyer 	delay(5000);
    708  1.181    bouyer #endif
    709  1.175    bouyer 
    710  1.169   thorpej 	if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
    711  1.169   thorpej 		wdc->select(chp,0);
    712  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0, WDSD_IBM);
    713  1.137    bouyer 	delay(10);	/* 400ns delay */
    714  1.174    bouyer 	/* assert SRST, wait for reset to complete */
    715  1.137    bouyer 	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
    716  1.137    bouyer 	    WDCTL_RST | WDCTL_IDS | WDCTL_4BIT);
    717  1.172    bouyer 	DELAY(1000);
    718  1.172    bouyer 	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
    719  1.172    bouyer 	    WDCTL_IDS | WDCTL_4BIT);
    720  1.137    bouyer 	DELAY(2000);
    721  1.157      fvdl 	(void) bus_space_read_1(chp->cmd_iot, chp->cmd_iohs[wd_error], 0);
    722  1.137    bouyer 	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
    723  1.137    bouyer 	delay(10);	/* 400ns delay */
    724  1.156    bouyer 	/* ACK interrupt in case there is one pending left (Promise ATA100) */
    725  1.169   thorpej 	if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_IRQACK))
    726  1.169   thorpej 		wdc->irqack(chp);
    727  1.156    bouyer 	splx(s);
    728  1.137    bouyer 
    729  1.137    bouyer 	ret_value = __wdcwait_reset(chp, ret_value, poll);
    730  1.137    bouyer 	WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
    731  1.169   thorpej 	    wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe", chp->ch_channel,
    732  1.137    bouyer 	    ret_value), DEBUG_PROBE);
    733   1.12       cgd 
    734  1.137    bouyer 	/* if reset failed, there's nothing here */
    735  1.137    bouyer 	if (ret_value == 0)
    736  1.137    bouyer 		return 0;
    737   1.67    bouyer 
    738   1.12       cgd 	/*
    739  1.167   thorpej 	 * Test presence of drives. First test register signatures looking
    740  1.167   thorpej 	 * for ATAPI devices. If it's not an ATAPI and reset said there may
    741  1.167   thorpej 	 * be something here assume it's ATA or OLD.  Ghost will be killed
    742  1.167   thorpej 	 * later in attach routine.
    743   1.12       cgd 	 */
    744  1.137    bouyer 	for (drive = 0; drive < 2; drive++) {
    745  1.137    bouyer 		if ((ret_value & (0x01 << drive)) == 0)
    746  1.137    bouyer 			continue;
    747  1.169   thorpej 		if (wdc != NULL && wdc->cap & WDC_CAPABILITY_SELECT)
    748  1.169   thorpej 			wdc->select(chp,drive);
    749  1.157      fvdl 		bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
    750  1.137    bouyer 		    WDSD_IBM | (drive << 4));
    751  1.137    bouyer 		delay(10);	/* 400ns delay */
    752  1.137    bouyer 		/* Save registers contents */
    753  1.157      fvdl 		sc = bus_space_read_1(chp->cmd_iot,
    754  1.157      fvdl 		    chp->cmd_iohs[wd_seccnt], 0);
    755  1.157      fvdl 		sn = bus_space_read_1(chp->cmd_iot,
    756  1.157      fvdl 		    chp->cmd_iohs[wd_sector], 0);
    757  1.157      fvdl 		cl = bus_space_read_1(chp->cmd_iot,
    758  1.157      fvdl 		    chp->cmd_iohs[wd_cyl_lo], 0);
    759  1.157      fvdl 		ch = bus_space_read_1(chp->cmd_iot,
    760  1.157      fvdl 		     chp->cmd_iohs[wd_cyl_hi], 0);
    761  1.137    bouyer 
    762  1.137    bouyer 		WDCDEBUG_PRINT(("%s:%d:%d: after reset, sc=0x%x sn=0x%x "
    763  1.137    bouyer 		    "cl=0x%x ch=0x%x\n",
    764  1.169   thorpej 		    wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe",
    765  1.169   thorpej 	    	    chp->ch_channel, drive, sc, sn, cl, ch), DEBUG_PROBE);
    766   1.31    bouyer 		/*
    767  1.137    bouyer 		 * sc & sn are supposted to be 0x1 for ATAPI but in some cases
    768  1.137    bouyer 		 * we get wrong values here, so ignore it.
    769   1.31    bouyer 		 */
    770  1.137    bouyer 		if (cl == 0x14 && ch == 0xeb) {
    771  1.137    bouyer 			chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
    772  1.137    bouyer 		} else {
    773  1.137    bouyer 			chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
    774  1.169   thorpej 			if (wdc == NULL ||
    775  1.169   thorpej 			    (wdc->cap & WDC_CAPABILITY_PREATA) != 0)
    776  1.137    bouyer 				chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
    777  1.137    bouyer 		}
    778   1.31    bouyer 	}
    779  1.137    bouyer 	return (ret_value);
    780  1.137    bouyer }
    781   1.31    bouyer 
    782  1.137    bouyer void
    783  1.168   thorpej wdcattach(struct wdc_channel *chp)
    784  1.137    bouyer {
    785  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
    786  1.137    bouyer 	static int inited = 0;
    787   1.32    bouyer 
    788  1.137    bouyer 	if (chp->ch_flags & WDCF_DISABLED)
    789  1.137    bouyer 		return;
    790   1.74     enami 
    791  1.137    bouyer 	/* initialise global data */
    792  1.137    bouyer 	callout_init(&chp->ch_callout);
    793  1.169   thorpej 	if (wdc->drv_probe == NULL)
    794  1.169   thorpej 		wdc->drv_probe = wdc_drvprobe;
    795  1.137    bouyer 	if (inited == 0) {
    796  1.165   thorpej 		/* Initialize the ata_xfer pool. */
    797  1.165   thorpej 		pool_init(&wdc_xfer_pool, sizeof(struct ata_xfer), 0,
    798  1.137    bouyer 		    0, 0, "wdcspl", NULL);
    799  1.137    bouyer 		inited++;
    800  1.133    bouyer 	}
    801  1.165   thorpej 	TAILQ_INIT(&chp->ch_queue->queue_xfer);
    802  1.148    bouyer 	chp->ch_queue->queue_freeze = 0;
    803  1.126     enami 
    804  1.169   thorpej 	chp->atabus = config_found(&wdc->sc_dev, chp, atabusprint);
    805   1.74     enami }
    806   1.74     enami 
    807  1.163   thorpej int
    808  1.163   thorpej wdcactivate(struct device *self, enum devact act)
    809  1.137    bouyer {
    810  1.137    bouyer 	struct wdc_softc *wdc = (struct wdc_softc *)self;
    811  1.137    bouyer 	int s, i, error = 0;
    812  1.137    bouyer 
    813  1.137    bouyer 	s = splbio();
    814  1.137    bouyer 	switch (act) {
    815  1.137    bouyer 	case DVACT_ACTIVATE:
    816  1.137    bouyer 		error = EOPNOTSUPP;
    817  1.137    bouyer 		break;
    818  1.137    bouyer 
    819  1.137    bouyer 	case DVACT_DEACTIVATE:
    820  1.137    bouyer 		for (i = 0; i < wdc->nchannels; i++) {
    821  1.137    bouyer 			error = config_deactivate(wdc->channels[i]->atabus);
    822  1.137    bouyer 			if (error)
    823  1.137    bouyer 				break;
    824  1.137    bouyer 		}
    825  1.137    bouyer 		break;
    826  1.137    bouyer 	}
    827  1.137    bouyer 	splx(s);
    828  1.137    bouyer 	return (error);
    829  1.137    bouyer }
    830  1.137    bouyer 
    831  1.137    bouyer int
    832  1.163   thorpej wdcdetach(struct device *self, int flags)
    833  1.137    bouyer {
    834  1.137    bouyer 	struct wdc_softc *wdc = (struct wdc_softc *)self;
    835  1.168   thorpej 	struct wdc_channel *chp;
    836  1.137    bouyer 	int i, error = 0;
    837  1.137    bouyer 
    838  1.137    bouyer 	for (i = 0; i < wdc->nchannels; i++) {
    839  1.137    bouyer 		chp = wdc->channels[i];
    840  1.137    bouyer 		WDCDEBUG_PRINT(("wdcdetach: %s: detaching %s\n",
    841  1.137    bouyer 		    wdc->sc_dev.dv_xname, chp->atabus->dv_xname), DEBUG_DETACH);
    842  1.137    bouyer 		error = config_detach(chp->atabus, flags);
    843  1.137    bouyer 		if (error)
    844  1.137    bouyer 			break;
    845  1.137    bouyer 	}
    846  1.137    bouyer 	return (error);
    847  1.137    bouyer }
    848  1.137    bouyer 
    849   1.31    bouyer /*
    850   1.31    bouyer  * Start I/O on a controller, for the given channel.
    851   1.31    bouyer  * The first xfer may be not for our channel if the channel queues
    852   1.31    bouyer  * are shared.
    853   1.31    bouyer  */
    854   1.31    bouyer void
    855  1.168   thorpej wdcstart(struct wdc_channel *chp)
    856   1.31    bouyer {
    857  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
    858  1.165   thorpej 	struct ata_xfer *xfer;
    859   1.38    bouyer 
    860   1.38    bouyer #ifdef WDC_DIAGNOSTIC
    861   1.38    bouyer 	int spl1, spl2;
    862   1.38    bouyer 
    863   1.38    bouyer 	spl1 = splbio();
    864   1.38    bouyer 	spl2 = splbio();
    865   1.38    bouyer 	if (spl2 != spl1) {
    866   1.38    bouyer 		printf("wdcstart: not at splbio()\n");
    867   1.38    bouyer 		panic("wdcstart");
    868   1.38    bouyer 	}
    869   1.38    bouyer 	splx(spl2);
    870   1.38    bouyer 	splx(spl1);
    871   1.38    bouyer #endif /* WDC_DIAGNOSTIC */
    872   1.12       cgd 
    873   1.31    bouyer 	/* is there a xfer ? */
    874  1.165   thorpej 	if ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) == NULL)
    875   1.31    bouyer 		return;
    876   1.47    bouyer 
    877   1.47    bouyer 	/* adjust chp, in case we have a shared queue */
    878  1.165   thorpej 	chp = xfer->c_chp;
    879   1.47    bouyer 
    880   1.31    bouyer 	if ((chp->ch_flags & WDCF_ACTIVE) != 0 ) {
    881   1.31    bouyer 		return; /* channel aleady active */
    882   1.31    bouyer 	}
    883  1.148    bouyer 	if (__predict_false(chp->ch_queue->queue_freeze > 0)) {
    884  1.147    bouyer 		return; /* queue froozen */
    885  1.137    bouyer 	}
    886   1.31    bouyer #ifdef DIAGNOSTIC
    887   1.31    bouyer 	if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0)
    888  1.118    provos 		panic("wdcstart: channel waiting for irq");
    889   1.31    bouyer #endif
    890  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_HWLOCK)
    891  1.169   thorpej 		if (!(*wdc->claim_hw)(chp, 0))
    892   1.31    bouyer 			return;
    893   1.12       cgd 
    894   1.31    bouyer 	WDCDEBUG_PRINT(("wdcstart: xfer %p channel %d drive %d\n", xfer,
    895  1.169   thorpej 	    chp->ch_channel, xfer->c_drive), DEBUG_XFERS);
    896   1.31    bouyer 	chp->ch_flags |= WDCF_ACTIVE;
    897  1.165   thorpej 	if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_RESET) {
    898  1.165   thorpej 		chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_RESET;
    899  1.165   thorpej 		chp->ch_drive[xfer->c_drive].state = 0;
    900   1.37    bouyer 	}
    901  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_NOIRQ)
    902   1.98     bjh21 		KASSERT(xfer->c_flags & C_POLL);
    903   1.31    bouyer 	xfer->c_start(chp, xfer);
    904   1.31    bouyer }
    905    1.2    bouyer 
    906   1.31    bouyer /* restart an interrupted I/O */
    907   1.31    bouyer void
    908  1.163   thorpej wdcrestart(void *v)
    909   1.31    bouyer {
    910  1.168   thorpej 	struct wdc_channel *chp = v;
    911   1.31    bouyer 	int s;
    912    1.2    bouyer 
    913   1.31    bouyer 	s = splbio();
    914   1.45  drochner 	wdcstart(chp);
    915   1.31    bouyer 	splx(s);
    916    1.2    bouyer }
    917   1.31    bouyer 
    918    1.2    bouyer 
    919   1.31    bouyer /*
    920   1.31    bouyer  * Interrupt routine for the controller.  Acknowledge the interrupt, check for
    921   1.31    bouyer  * errors on the current operation, mark it done if necessary, and start the
    922   1.31    bouyer  * next request.  Also check for a partially done transfer, and continue with
    923   1.31    bouyer  * the next chunk if so.
    924   1.31    bouyer  */
    925   1.12       cgd int
    926  1.163   thorpej wdcintr(void *arg)
    927   1.12       cgd {
    928  1.168   thorpej 	struct wdc_channel *chp = arg;
    929  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
    930  1.165   thorpej 	struct ata_xfer *xfer;
    931   1.76    bouyer 	int ret;
    932   1.12       cgd 
    933  1.169   thorpej 	if ((wdc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
    934   1.80     enami 		WDCDEBUG_PRINT(("wdcintr: deactivated controller\n"),
    935   1.80     enami 		    DEBUG_INTR);
    936   1.80     enami 		return (0);
    937   1.80     enami 	}
    938   1.31    bouyer 	if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
    939   1.31    bouyer 		WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
    940  1.113    bouyer 		/* try to clear the pending interrupt anyway */
    941  1.157      fvdl 		(void)bus_space_read_1(chp->cmd_iot,
    942  1.157      fvdl 		    chp->cmd_iohs[wd_status], 0);
    943   1.80     enami 		return (0);
    944   1.31    bouyer 	}
    945   1.12       cgd 
    946   1.31    bouyer 	WDCDEBUG_PRINT(("wdcintr\n"), DEBUG_INTR);
    947  1.165   thorpej 	xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
    948   1.84    bouyer 	if (chp->ch_flags & WDCF_DMA_WAIT) {
    949  1.169   thorpej 		wdc->dma_status =
    950  1.169   thorpej 		    (*wdc->dma_finish)(wdc->dma_arg, chp->ch_channel,
    951  1.185    bouyer 			xfer->c_drive, WDC_DMAEND_END);
    952  1.169   thorpej 		if (wdc->dma_status & WDC_DMAST_NOIRQ) {
    953   1.84    bouyer 			/* IRQ not for us, not detected by DMA engine */
    954   1.84    bouyer 			return 0;
    955   1.84    bouyer 		}
    956   1.84    bouyer 		chp->ch_flags &= ~WDCF_DMA_WAIT;
    957   1.84    bouyer 	}
    958   1.31    bouyer 	chp->ch_flags &= ~WDCF_IRQ_WAIT;
    959   1.76    bouyer 	ret = xfer->c_intr(chp, xfer, 1);
    960   1.76    bouyer 	if (ret == 0) /* irq was not for us, still waiting for irq */
    961   1.76    bouyer 		chp->ch_flags |= WDCF_IRQ_WAIT;
    962   1.76    bouyer 	return (ret);
    963   1.12       cgd }
    964   1.12       cgd 
    965   1.31    bouyer /* Put all disk in RESET state */
    966  1.125   mycroft void
    967  1.183    bouyer wdc_reset_drive(struct ata_drive_datas *drvp, int flags)
    968    1.2    bouyer {
    969  1.168   thorpej 	struct wdc_channel *chp = drvp->chnl_softc;
    970  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
    971   1.34    bouyer 	WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",
    972  1.169   thorpej 	    wdc->sc_dev.dv_xname, chp->ch_channel, drvp->drive),
    973   1.34    bouyer 	    DEBUG_FUNCS);
    974  1.182    bouyer 
    975  1.182    bouyer 
    976  1.183    bouyer 	wdc_reset_channel(chp, flags);
    977  1.182    bouyer }
    978  1.182    bouyer 
    979  1.183    bouyer void
    980  1.183    bouyer wdc_reset_channel(struct wdc_channel *chp, int flags)
    981  1.182    bouyer {
    982  1.183    bouyer 	struct ata_xfer *xfer, *next_xfer;
    983  1.182    bouyer 	int drive;
    984  1.182    bouyer 
    985  1.184    bouyer 	chp->ch_queue->queue_freeze++;
    986  1.184    bouyer 
    987  1.184    bouyer 	/* if we can poll or wait it's OK, otherwise wake up the kernel
    988  1.184    bouyer 	 * thread
    989  1.184    bouyer 	 */
    990  1.184    bouyer 	if ((flags & (AT_POLL | AT_WAIT)) == 0) {
    991  1.184    bouyer 		if (chp->ch_flags & WDCF_TH_RESET) {
    992  1.184    bouyer 			/* no need to schedule a reset more than one time */
    993  1.184    bouyer 			return;
    994  1.184    bouyer 		}
    995  1.184    bouyer 		chp->ch_flags |= WDCF_TH_RESET;
    996  1.184    bouyer 		chp->ch_reset_flags = flags & (AT_RST_EMERG | AT_RST_NOCMD);
    997  1.184    bouyer 		wakeup(&chp->ch_thread);
    998  1.184    bouyer 		return;
    999  1.184    bouyer 	}
   1000  1.184    bouyer 
   1001  1.184    bouyer 	/* reset the channel */
   1002  1.184    bouyer 	chp->ch_flags &= ~WDCF_IRQ_WAIT;
   1003  1.184    bouyer 	if ((flags & AT_WAIT) == 0) {
   1004  1.184    bouyer 		(void) wdcreset(chp, RESET_POLL);
   1005  1.184    bouyer 	} else {
   1006  1.184    bouyer 		(void) wdcreset(chp, RESET_SLEEP);
   1007  1.184    bouyer 	}
   1008  1.184    bouyer 
   1009  1.184    bouyer 	/*
   1010  1.184    bouyer 	 * wait a bit after reset; in case the the DMA engines needs some time
   1011  1.184    bouyer 	 * to recover.
   1012  1.184    bouyer 	 */
   1013  1.184    bouyer 	if (flags & AT_WAIT)
   1014  1.184    bouyer 		tsleep(&flags, PRIBIO, "atardl", 1);
   1015  1.184    bouyer 	else
   1016  1.184    bouyer 		delay(1000);
   1017  1.182    bouyer 	/*
   1018  1.182    bouyer 	 * look for pending xfers. If we have a shared queue, we'll also reset
   1019  1.182    bouyer 	 * the other channel if the current xfer is running on it.
   1020  1.184    bouyer 	 * Then we'll dequeue only the xfers for this channel.
   1021  1.184    bouyer 	 * xfer->c_kill_xfer() will reset any ATAPI device when needed.
   1022  1.182    bouyer 	 */
   1023  1.182    bouyer 	if ((flags & AT_RST_NOCMD) == 0) {
   1024  1.182    bouyer 		xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
   1025  1.184    bouyer 		if (xfer) {
   1026  1.184    bouyer 			if (xfer->c_chp != chp)
   1027  1.184    bouyer 				wdc_reset_channel(xfer->c_chp, flags);
   1028  1.184    bouyer 			else {
   1029  1.184    bouyer 				/*
   1030  1.184    bouyer 				 * If we're waiting for DMA, stop the
   1031  1.184    bouyer 				 * DMA engine
   1032  1.184    bouyer 				 */
   1033  1.184    bouyer 				if (chp->ch_flags & WDCF_DMA_WAIT) {
   1034  1.184    bouyer 					(*chp->ch_wdc->dma_finish)(
   1035  1.184    bouyer 					    chp->ch_wdc->dma_arg,
   1036  1.184    bouyer 					    chp->ch_channel,
   1037  1.184    bouyer 					    xfer->c_drive,
   1038  1.185    bouyer 					    WDC_DMAEND_ABRT_QUIET);
   1039  1.184    bouyer 					chp->ch_flags &= WDCF_DMA_WAIT;
   1040  1.184    bouyer 				}
   1041  1.184    bouyer 			}
   1042  1.184    bouyer 		}
   1043  1.182    bouyer 		for (xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
   1044  1.183    bouyer 		    xfer != NULL; xfer = next_xfer) {
   1045  1.183    bouyer 			next_xfer = TAILQ_NEXT(xfer, c_xferchain);
   1046  1.182    bouyer 			if (xfer->c_chp != chp)
   1047  1.182    bouyer 				continue;
   1048  1.182    bouyer 			if ((flags & AT_RST_EMERG) == 0)
   1049  1.182    bouyer 				xfer->c_kill_xfer(chp, xfer, KILL_RESET);
   1050  1.182    bouyer 		}
   1051  1.182    bouyer 	}
   1052   1.31    bouyer 	for (drive = 0; drive < 2; drive++) {
   1053   1.31    bouyer 		chp->ch_drive[drive].state = 0;
   1054   1.12       cgd 	}
   1055  1.184    bouyer 	chp->ch_flags &= ~WDCF_TH_RESET;
   1056  1.182    bouyer 	if ((flags & AT_RST_EMERG) == 0)  {
   1057  1.182    bouyer 		chp->ch_queue->queue_freeze--;
   1058  1.182    bouyer 		wdcstart(chp);
   1059  1.182    bouyer 	} else {
   1060  1.182    bouyer 		/* make sure that we can use polled commands */
   1061  1.182    bouyer 		TAILQ_INIT(&chp->ch_queue->queue_xfer);
   1062  1.182    bouyer 		chp->ch_queue->queue_freeze = 0;
   1063  1.182    bouyer 	}
   1064   1.31    bouyer }
   1065   1.12       cgd 
   1066   1.31    bouyer int
   1067  1.168   thorpej wdcreset(struct wdc_channel *chp, int poll)
   1068   1.31    bouyer {
   1069  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1070   1.31    bouyer 	int drv_mask1, drv_mask2;
   1071  1.156    bouyer 	int s = 0;
   1072    1.2    bouyer 
   1073  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_SELECT)
   1074  1.169   thorpej 		wdc->select(chp,0);
   1075  1.156    bouyer 	if (poll != RESET_SLEEP)
   1076  1.156    bouyer 		s = splbio();
   1077  1.157      fvdl 	/* master */
   1078  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0, WDSD_IBM);
   1079  1.131   mycroft 	delay(10);	/* 400ns delay */
   1080   1.31    bouyer 	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
   1081  1.131   mycroft 	    WDCTL_RST | WDCTL_IDS | WDCTL_4BIT);
   1082  1.131   mycroft 	delay(2000);
   1083  1.157      fvdl 	(void) bus_space_read_1(chp->cmd_iot, chp->cmd_iohs[wd_error], 0);
   1084  1.137    bouyer 	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
   1085  1.137    bouyer 	    WDCTL_4BIT | WDCTL_IDS);
   1086  1.131   mycroft 	delay(10);	/* 400ns delay */
   1087  1.156    bouyer 	if (poll != RESET_SLEEP) {
   1088  1.169   thorpej 		if (wdc->cap & WDC_CAPABILITY_IRQACK)
   1089  1.169   thorpej 			wdc->irqack(chp);
   1090  1.156    bouyer 		splx(s);
   1091  1.156    bouyer 	}
   1092    1.2    bouyer 
   1093   1.31    bouyer 	drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00;
   1094   1.31    bouyer 	drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
   1095  1.137    bouyer 	drv_mask2 = __wdcwait_reset(chp, drv_mask1,
   1096  1.137    bouyer 	    (poll == RESET_SLEEP) ? 0 : 1);
   1097  1.137    bouyer 	if (drv_mask2 != drv_mask1) {
   1098   1.31    bouyer 		printf("%s channel %d: reset failed for",
   1099  1.169   thorpej 		    wdc->sc_dev.dv_xname, chp->ch_channel);
   1100   1.31    bouyer 		if ((drv_mask1 & 0x01) != 0 && (drv_mask2 & 0x01) == 0)
   1101   1.31    bouyer 			printf(" drive 0");
   1102   1.31    bouyer 		if ((drv_mask1 & 0x02) != 0 && (drv_mask2 & 0x02) == 0)
   1103   1.31    bouyer 			printf(" drive 1");
   1104   1.31    bouyer 		printf("\n");
   1105   1.31    bouyer 	}
   1106  1.137    bouyer 	bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
   1107   1.31    bouyer 	return  (drv_mask1 != drv_mask2) ? 1 : 0;
   1108   1.31    bouyer }
   1109   1.31    bouyer 
   1110   1.31    bouyer static int
   1111  1.168   thorpej __wdcwait_reset(struct wdc_channel *chp, int drv_mask, int poll)
   1112   1.31    bouyer {
   1113  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1114  1.137    bouyer 	int timeout, nloop;
   1115  1.149    bouyer 	u_int8_t st0 = 0, st1 = 0;
   1116   1.70    bouyer #ifdef WDCDEBUG
   1117  1.146  christos 	u_int8_t sc0 = 0, sn0 = 0, cl0 = 0, ch0 = 0;
   1118  1.146  christos 	u_int8_t sc1 = 0, sn1 = 0, cl1 = 0, ch1 = 0;
   1119   1.70    bouyer #endif
   1120  1.137    bouyer 
   1121  1.137    bouyer 	if (poll)
   1122  1.137    bouyer 		nloop = WDCNDELAY_RST;
   1123  1.137    bouyer 	else
   1124  1.137    bouyer 		nloop = WDC_RESET_WAIT * hz / 1000;
   1125   1.31    bouyer 	/* wait for BSY to deassert */
   1126  1.137    bouyer 	for (timeout = 0; timeout < nloop; timeout++) {
   1127  1.174    bouyer 		if ((drv_mask & 0x01) != 0) {
   1128  1.174    bouyer 			if (wdc && wdc->cap & WDC_CAPABILITY_SELECT)
   1129  1.174    bouyer 				wdc->select(chp,0);
   1130  1.174    bouyer 			bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
   1131  1.174    bouyer 			    0, WDSD_IBM); /* master */
   1132  1.174    bouyer 			delay(10);
   1133  1.174    bouyer 			st0 = bus_space_read_1(chp->cmd_iot,
   1134  1.174    bouyer 			    chp->cmd_iohs[wd_status], 0);
   1135   1.70    bouyer #ifdef WDCDEBUG
   1136  1.174    bouyer 			sc0 = bus_space_read_1(chp->cmd_iot,
   1137  1.174    bouyer 			    chp->cmd_iohs[wd_seccnt], 0);
   1138  1.174    bouyer 			sn0 = bus_space_read_1(chp->cmd_iot,
   1139  1.174    bouyer 			    chp->cmd_iohs[wd_sector], 0);
   1140  1.174    bouyer 			cl0 = bus_space_read_1(chp->cmd_iot,
   1141  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
   1142  1.174    bouyer 			ch0 = bus_space_read_1(chp->cmd_iot,
   1143  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_hi], 0);
   1144   1.70    bouyer #endif
   1145  1.174    bouyer 		}
   1146  1.174    bouyer 		if ((drv_mask & 0x02) != 0) {
   1147  1.174    bouyer 			if (wdc && wdc->cap & WDC_CAPABILITY_SELECT)
   1148  1.174    bouyer 				wdc->select(chp,1);
   1149  1.174    bouyer 			bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
   1150  1.174    bouyer 			    0, WDSD_IBM | 0x10); /* slave */
   1151  1.174    bouyer 			delay(10);
   1152  1.174    bouyer 			st1 = bus_space_read_1(chp->cmd_iot,
   1153  1.174    bouyer 			    chp->cmd_iohs[wd_status], 0);
   1154   1.70    bouyer #ifdef WDCDEBUG
   1155  1.174    bouyer 			sc1 = bus_space_read_1(chp->cmd_iot,
   1156  1.174    bouyer 			    chp->cmd_iohs[wd_seccnt], 0);
   1157  1.174    bouyer 			sn1 = bus_space_read_1(chp->cmd_iot,
   1158  1.174    bouyer 			    chp->cmd_iohs[wd_sector], 0);
   1159  1.174    bouyer 			cl1 = bus_space_read_1(chp->cmd_iot,
   1160  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_lo], 0);
   1161  1.174    bouyer 			ch1 = bus_space_read_1(chp->cmd_iot,
   1162  1.174    bouyer 			    chp->cmd_iohs[wd_cyl_hi], 0);
   1163   1.70    bouyer #endif
   1164  1.174    bouyer 		}
   1165   1.31    bouyer 
   1166   1.31    bouyer 		if ((drv_mask & 0x01) == 0) {
   1167   1.31    bouyer 			/* no master */
   1168   1.31    bouyer 			if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
   1169   1.31    bouyer 				/* No master, slave is ready, it's done */
   1170   1.65    bouyer 				goto end;
   1171   1.31    bouyer 			}
   1172   1.31    bouyer 		} else if ((drv_mask & 0x02) == 0) {
   1173   1.31    bouyer 			/* no slave */
   1174   1.31    bouyer 			if ((drv_mask & 0x01) != 0 && (st0 & WDCS_BSY) == 0) {
   1175   1.31    bouyer 				/* No slave, master is ready, it's done */
   1176   1.65    bouyer 				goto end;
   1177   1.31    bouyer 			}
   1178    1.2    bouyer 		} else {
   1179   1.31    bouyer 			/* Wait for both master and slave to be ready */
   1180   1.31    bouyer 			if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
   1181   1.65    bouyer 				goto end;
   1182    1.2    bouyer 			}
   1183    1.2    bouyer 		}
   1184  1.137    bouyer 		if (poll)
   1185  1.137    bouyer 			delay(WDCDELAY);
   1186  1.137    bouyer 		else
   1187  1.137    bouyer 			tsleep(&nloop, PRIBIO, "atarst", 1);
   1188    1.2    bouyer 	}
   1189  1.116       wiz 	/* Reset timed out. Maybe it's because drv_mask was not right */
   1190   1.31    bouyer 	if (st0 & WDCS_BSY)
   1191   1.31    bouyer 		drv_mask &= ~0x01;
   1192   1.31    bouyer 	if (st1 & WDCS_BSY)
   1193   1.31    bouyer 		drv_mask &= ~0x02;
   1194   1.65    bouyer end:
   1195   1.70    bouyer 	WDCDEBUG_PRINT(("%s:%d:0: after reset, sc=0x%x sn=0x%x "
   1196   1.70    bouyer 	    "cl=0x%x ch=0x%x\n",
   1197  1.169   thorpej 	     wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe",
   1198  1.169   thorpej 	     chp->ch_channel, sc0, sn0, cl0, ch0), DEBUG_PROBE);
   1199   1.70    bouyer 	WDCDEBUG_PRINT(("%s:%d:1: after reset, sc=0x%x sn=0x%x "
   1200   1.70    bouyer 	    "cl=0x%x ch=0x%x\n",
   1201  1.169   thorpej 	     wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe",
   1202  1.169   thorpej 	     chp->ch_channel, sc1, sn1, cl1, ch1), DEBUG_PROBE);
   1203   1.70    bouyer 
   1204  1.149    bouyer 	WDCDEBUG_PRINT(("%s:%d: wdcwait_reset() end, st0=0x%x st1=0x%x\n",
   1205  1.169   thorpej 	    wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe", chp->ch_channel,
   1206  1.149    bouyer 	    st0, st1), DEBUG_PROBE);
   1207   1.65    bouyer 
   1208   1.31    bouyer 	return drv_mask;
   1209    1.2    bouyer }
   1210    1.2    bouyer 
   1211    1.2    bouyer /*
   1212   1.31    bouyer  * Wait for a drive to be !BSY, and have mask in its status register.
   1213   1.31    bouyer  * return -1 for a timeout after "timeout" ms.
   1214    1.2    bouyer  */
   1215  1.167   thorpej static int
   1216  1.168   thorpej __wdcwait(struct wdc_channel *chp, int mask, int bits, int timeout)
   1217    1.2    bouyer {
   1218  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1219   1.31    bouyer 	u_char status;
   1220   1.31    bouyer 	int time = 0;
   1221   1.60       abs 
   1222  1.169   thorpej 	WDCDEBUG_PRINT(("__wdcwait %s:%d\n", wdc != NULL ?
   1223  1.169   thorpej 			wdc->sc_dev.dv_xname : "none",
   1224  1.169   thorpej 			chp->ch_channel), DEBUG_STATUS);
   1225   1.31    bouyer 	chp->ch_error = 0;
   1226   1.31    bouyer 
   1227   1.31    bouyer 	timeout = timeout * 1000 / WDCDELAY; /* delay uses microseconds */
   1228    1.2    bouyer 
   1229   1.31    bouyer 	for (;;) {
   1230   1.31    bouyer 		chp->ch_status = status =
   1231  1.157      fvdl 		    bus_space_read_1(chp->cmd_iot, chp->cmd_iohs[wd_status], 0);
   1232  1.131   mycroft 		if ((status & (WDCS_BSY | mask)) == bits)
   1233   1.31    bouyer 			break;
   1234   1.31    bouyer 		if (++time > timeout) {
   1235  1.137    bouyer 			WDCDEBUG_PRINT(("__wdcwait: timeout (time=%d), "
   1236   1.87    bouyer 			    "status %x error %x (mask 0x%x bits 0x%x)\n",
   1237   1.87    bouyer 			    time, status,
   1238  1.157      fvdl 			    bus_space_read_1(chp->cmd_iot,
   1239  1.157      fvdl 				chp->cmd_iohs[wd_error], 0), mask, bits),
   1240   1.87    bouyer 			    DEBUG_STATUS | DEBUG_PROBE | DEBUG_DELAY);
   1241  1.137    bouyer 			return(WDCWAIT_TOUT);
   1242   1.31    bouyer 		}
   1243   1.31    bouyer 		delay(WDCDELAY);
   1244    1.2    bouyer 	}
   1245   1.87    bouyer #ifdef WDCDEBUG
   1246   1.87    bouyer 	if (time > 0 && (wdcdebug_mask & DEBUG_DELAY))
   1247  1.137    bouyer 		printf("__wdcwait: did busy-wait, time=%d\n", time);
   1248   1.87    bouyer #endif
   1249   1.31    bouyer 	if (status & WDCS_ERR)
   1250  1.157      fvdl 		chp->ch_error = bus_space_read_1(chp->cmd_iot,
   1251  1.157      fvdl 		    chp->cmd_iohs[wd_error], 0);
   1252   1.31    bouyer #ifdef WDCNDELAY_DEBUG
   1253   1.31    bouyer 	/* After autoconfig, there should be no long delays. */
   1254   1.31    bouyer 	if (!cold && time > WDCNDELAY_DEBUG) {
   1255  1.165   thorpej 		struct ata_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
   1256   1.31    bouyer 		if (xfer == NULL)
   1257   1.31    bouyer 			printf("%s channel %d: warning: busy-wait took %dus\n",
   1258  1.169   thorpej 			    wdc->sc_dev.dv_xname, chp->ch_channel,
   1259   1.31    bouyer 			    WDCDELAY * time);
   1260   1.31    bouyer 		else
   1261   1.31    bouyer 			printf("%s:%d:%d: warning: busy-wait took %dus\n",
   1262  1.169   thorpej 			    wdc->sc_dev.dv_xname, chp->ch_channel,
   1263   1.31    bouyer 			    xfer->drive,
   1264   1.31    bouyer 			    WDCDELAY * time);
   1265    1.2    bouyer 	}
   1266    1.2    bouyer #endif
   1267  1.137    bouyer 	return(WDCWAIT_OK);
   1268  1.137    bouyer }
   1269  1.137    bouyer 
   1270  1.137    bouyer /*
   1271  1.137    bouyer  * Call __wdcwait(), polling using tsleep() or waking up the kernel
   1272  1.137    bouyer  * thread if possible
   1273  1.137    bouyer  */
   1274  1.137    bouyer int
   1275  1.168   thorpej wdcwait(struct wdc_channel *chp, int mask, int bits, int timeout, int flags)
   1276  1.137    bouyer {
   1277  1.137    bouyer 	int error, i, timeout_hz = mstohz(timeout);
   1278  1.137    bouyer 
   1279  1.137    bouyer 	if (timeout_hz == 0 ||
   1280  1.137    bouyer 	    (flags & (AT_WAIT | AT_POLL)) == AT_POLL)
   1281  1.137    bouyer 		error = __wdcwait(chp, mask, bits, timeout);
   1282  1.137    bouyer 	else {
   1283  1.137    bouyer 		error = __wdcwait(chp, mask, bits, WDCDELAY_POLL);
   1284  1.137    bouyer 		if (error != 0) {
   1285  1.147    bouyer 			if ((chp->ch_flags & WDCF_TH_RUN) ||
   1286  1.147    bouyer 			    (flags & AT_WAIT)) {
   1287  1.137    bouyer 				/*
   1288  1.147    bouyer 				 * we're running in the channel thread
   1289  1.147    bouyer 				 * or some userland thread context
   1290  1.137    bouyer 				 */
   1291  1.137    bouyer 				for (i = 0; i < timeout_hz; i++) {
   1292  1.137    bouyer 					if (__wdcwait(chp, mask, bits,
   1293  1.137    bouyer 					    WDCDELAY_POLL) == 0) {
   1294  1.137    bouyer 						error = 0;
   1295  1.137    bouyer 						break;
   1296  1.137    bouyer 					}
   1297  1.137    bouyer 					tsleep(&chp, PRIBIO, "atapoll", 1);
   1298  1.137    bouyer 				}
   1299  1.137    bouyer 			} else {
   1300  1.137    bouyer 				/*
   1301  1.137    bouyer 				 * we're probably in interrupt context,
   1302  1.137    bouyer 				 * ask the thread to come back here
   1303  1.137    bouyer 				 */
   1304  1.147    bouyer #ifdef DIAGNOSTIC
   1305  1.148    bouyer 				if (chp->ch_queue->queue_freeze > 0)
   1306  1.148    bouyer 					panic("wdcwait: queue_freeze");
   1307  1.147    bouyer #endif
   1308  1.148    bouyer 				chp->ch_queue->queue_freeze++;
   1309  1.170   thorpej 				wakeup(&chp->ch_thread);
   1310  1.137    bouyer 				return(WDCWAIT_THR);
   1311  1.137    bouyer 			}
   1312  1.137    bouyer 		}
   1313  1.137    bouyer 	}
   1314  1.163   thorpej 	return (error);
   1315    1.2    bouyer }
   1316    1.2    bouyer 
   1317  1.137    bouyer 
   1318   1.84    bouyer /*
   1319   1.84    bouyer  * Busy-wait for DMA to complete
   1320   1.84    bouyer  */
   1321   1.84    bouyer int
   1322  1.168   thorpej wdc_dmawait(struct wdc_channel *chp, struct ata_xfer *xfer, int timeout)
   1323   1.84    bouyer {
   1324  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1325   1.84    bouyer 	int time;
   1326  1.169   thorpej 
   1327   1.84    bouyer 	for (time = 0;  time < timeout * 1000 / WDCDELAY; time++) {
   1328  1.169   thorpej 		wdc->dma_status =
   1329  1.169   thorpej 		    (*wdc->dma_finish)(wdc->dma_arg,
   1330  1.185    bouyer 			chp->ch_channel, xfer->c_drive, WDC_DMAEND_END);
   1331  1.169   thorpej 		if ((wdc->dma_status & WDC_DMAST_NOIRQ) == 0)
   1332   1.84    bouyer 			return 0;
   1333   1.84    bouyer 		delay(WDCDELAY);
   1334   1.84    bouyer 	}
   1335   1.84    bouyer 	/* timeout, force a DMA halt */
   1336  1.169   thorpej 	wdc->dma_status = (*wdc->dma_finish)(wdc->dma_arg,
   1337  1.185    bouyer 	    chp->ch_channel, xfer->c_drive, WDC_DMAEND_ABRT);
   1338   1.84    bouyer 	return 1;
   1339   1.84    bouyer }
   1340   1.84    bouyer 
   1341   1.31    bouyer void
   1342  1.163   thorpej wdctimeout(void *arg)
   1343    1.2    bouyer {
   1344  1.168   thorpej 	struct wdc_channel *chp = (struct wdc_channel *)arg;
   1345  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1346  1.165   thorpej 	struct ata_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
   1347   1.31    bouyer 	int s;
   1348    1.2    bouyer 
   1349   1.31    bouyer 	WDCDEBUG_PRINT(("wdctimeout\n"), DEBUG_FUNCS);
   1350   1.31    bouyer 
   1351   1.31    bouyer 	s = splbio();
   1352   1.31    bouyer 	if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0) {
   1353   1.31    bouyer 		__wdcerror(chp, "lost interrupt");
   1354   1.88       mrg 		printf("\ttype: %s tc_bcount: %d tc_skip: %d\n",
   1355   1.88       mrg 		    (xfer->c_flags & C_ATAPI) ?  "atapi" : "ata",
   1356   1.88       mrg 		    xfer->c_bcount,
   1357   1.88       mrg 		    xfer->c_skip);
   1358   1.84    bouyer 		if (chp->ch_flags & WDCF_DMA_WAIT) {
   1359  1.169   thorpej 			wdc->dma_status =
   1360  1.169   thorpej 			    (*wdc->dma_finish)(wdc->dma_arg,
   1361  1.185    bouyer 				chp->ch_channel, xfer->c_drive,
   1362  1.185    bouyer 				WDC_DMAEND_ABRT);
   1363   1.84    bouyer 			chp->ch_flags &= ~WDCF_DMA_WAIT;
   1364   1.84    bouyer 		}
   1365   1.31    bouyer 		/*
   1366  1.119  drochner 		 * Call the interrupt routine. If we just missed an interrupt,
   1367   1.31    bouyer 		 * it will do what's needed. Else, it will take the needed
   1368   1.31    bouyer 		 * action (reset the device).
   1369   1.70    bouyer 		 * Before that we need to reinstall the timeout callback,
   1370   1.70    bouyer 		 * in case it will miss another irq while in this transfer
   1371   1.70    bouyer 		 * We arbitray chose it to be 1s
   1372   1.31    bouyer 		 */
   1373   1.81   thorpej 		callout_reset(&chp->ch_callout, hz, wdctimeout, chp);
   1374   1.31    bouyer 		xfer->c_flags |= C_TIMEOU;
   1375   1.31    bouyer 		chp->ch_flags &= ~WDCF_IRQ_WAIT;
   1376   1.66    bouyer 		xfer->c_intr(chp, xfer, 1);
   1377   1.31    bouyer 	} else
   1378   1.31    bouyer 		__wdcerror(chp, "missing untimeout");
   1379   1.31    bouyer 	splx(s);
   1380    1.2    bouyer }
   1381    1.2    bouyer 
   1382   1.31    bouyer /*
   1383  1.152       wiz  * Probe drive's capabilities, for use by the controller later
   1384   1.31    bouyer  * Assumes drvp points to an existing drive.
   1385   1.31    bouyer  * XXX this should be a controller-indep function
   1386   1.31    bouyer  */
   1387    1.2    bouyer void
   1388  1.163   thorpej wdc_probe_caps(struct ata_drive_datas *drvp)
   1389    1.2    bouyer {
   1390   1.31    bouyer 	struct ataparams params, params2;
   1391  1.168   thorpej 	struct wdc_channel *chp = drvp->chnl_softc;
   1392  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1393   1.31    bouyer 	struct device *drv_dev = drvp->drv_softc;
   1394   1.31    bouyer 	int i, printed;
   1395   1.31    bouyer 	char *sep = "";
   1396   1.48    bouyer 	int cf_flags;
   1397   1.31    bouyer 
   1398  1.125   mycroft 	if (ata_get_params(drvp, AT_WAIT, &params) != CMD_OK) {
   1399   1.31    bouyer 		/* IDENTIFY failed. Can't tell more about the device */
   1400    1.2    bouyer 		return;
   1401    1.2    bouyer 	}
   1402   1.31    bouyer 	if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
   1403   1.31    bouyer 	    (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
   1404    1.2    bouyer 		/*
   1405   1.39    bouyer 		 * Controller claims 16 and 32 bit transfers.
   1406   1.39    bouyer 		 * Re-do an IDENTIFY with 32-bit transfers,
   1407   1.31    bouyer 		 * and compare results.
   1408    1.2    bouyer 		 */
   1409   1.31    bouyer 		drvp->drive_flags |= DRIVE_CAP32;
   1410  1.125   mycroft 		ata_get_params(drvp, AT_WAIT, &params2);
   1411   1.31    bouyer 		if (memcmp(&params, &params2, sizeof(struct ataparams)) != 0) {
   1412   1.31    bouyer 			/* Not good. fall back to 16bits */
   1413   1.31    bouyer 			drvp->drive_flags &= ~DRIVE_CAP32;
   1414   1.31    bouyer 		} else {
   1415  1.125   mycroft 			aprint_normal("%s: 32-bit data port\n",
   1416  1.123   thorpej 			    drv_dev->dv_xname);
   1417    1.2    bouyer 		}
   1418    1.2    bouyer 	}
   1419   1.55    bouyer #if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
   1420   1.55    bouyer 	if (params.atap_ata_major > 0x01 &&
   1421   1.55    bouyer 	    params.atap_ata_major != 0xffff) {
   1422   1.55    bouyer 		for (i = 14; i > 0; i--) {
   1423   1.55    bouyer 			if (params.atap_ata_major & (1 << i)) {
   1424  1.125   mycroft 				aprint_normal("%s: ATA version %d\n",
   1425  1.125   mycroft 				    drv_dev->dv_xname, i);
   1426   1.55    bouyer 				drvp->ata_vers = i;
   1427   1.55    bouyer 				break;
   1428   1.55    bouyer 			}
   1429   1.55    bouyer 		}
   1430  1.125   mycroft 	}
   1431   1.55    bouyer #endif
   1432    1.2    bouyer 
   1433   1.31    bouyer 	/* An ATAPI device is at last PIO mode 3 */
   1434   1.31    bouyer 	if (drvp->drive_flags & DRIVE_ATAPI)
   1435   1.31    bouyer 		drvp->PIO_mode = 3;
   1436    1.2    bouyer 
   1437    1.2    bouyer 	/*
   1438   1.31    bouyer 	 * It's not in the specs, but it seems that some drive
   1439   1.31    bouyer 	 * returns 0xffff in atap_extensions when this field is invalid
   1440    1.2    bouyer 	 */
   1441   1.31    bouyer 	if (params.atap_extensions != 0xffff &&
   1442   1.31    bouyer 	    (params.atap_extensions & WDC_EXT_MODES)) {
   1443   1.31    bouyer 		printed = 0;
   1444   1.31    bouyer 		/*
   1445   1.31    bouyer 		 * XXX some drives report something wrong here (they claim to
   1446   1.31    bouyer 		 * support PIO mode 8 !). As mode is coded on 3 bits in
   1447   1.31    bouyer 		 * SET FEATURE, limit it to 7 (so limit i to 4).
   1448  1.116       wiz 		 * If higher mode than 7 is found, abort.
   1449   1.31    bouyer 		 */
   1450   1.39    bouyer 		for (i = 7; i >= 0; i--) {
   1451   1.31    bouyer 			if ((params.atap_piomode_supp & (1 << i)) == 0)
   1452   1.31    bouyer 				continue;
   1453   1.39    bouyer 			if (i > 4)
   1454   1.39    bouyer 				return;
   1455   1.31    bouyer 			/*
   1456   1.31    bouyer 			 * See if mode is accepted.
   1457   1.31    bouyer 			 * If the controller can't set its PIO mode,
   1458   1.31    bouyer 			 * assume the defaults are good, so don't try
   1459   1.31    bouyer 			 * to set it
   1460   1.31    bouyer 			 */
   1461   1.31    bouyer 			if ((wdc->cap & WDC_CAPABILITY_MODE) != 0)
   1462  1.137    bouyer 				/*
   1463  1.137    bouyer 				 * It's OK to pool here, it's fast enouth
   1464  1.137    bouyer 				 * to not bother waiting for interrupt
   1465  1.137    bouyer 				 */
   1466   1.31    bouyer 				if (ata_set_mode(drvp, 0x08 | (i + 3),
   1467  1.125   mycroft 				   AT_WAIT) != CMD_OK)
   1468    1.2    bouyer 					continue;
   1469   1.31    bouyer 			if (!printed) {
   1470  1.123   thorpej 				aprint_normal("%s: drive supports PIO mode %d",
   1471   1.39    bouyer 				    drv_dev->dv_xname, i + 3);
   1472   1.31    bouyer 				sep = ",";
   1473   1.31    bouyer 				printed = 1;
   1474   1.31    bouyer 			}
   1475   1.31    bouyer 			/*
   1476   1.31    bouyer 			 * If controller's driver can't set its PIO mode,
   1477   1.31    bouyer 			 * get the highter one for the drive.
   1478   1.31    bouyer 			 */
   1479   1.31    bouyer 			if ((wdc->cap & WDC_CAPABILITY_MODE) == 0 ||
   1480   1.52    bouyer 			    wdc->PIO_cap >= i + 3) {
   1481   1.31    bouyer 				drvp->PIO_mode = i + 3;
   1482   1.48    bouyer 				drvp->PIO_cap = i + 3;
   1483    1.2    bouyer 				break;
   1484    1.2    bouyer 			}
   1485    1.2    bouyer 		}
   1486   1.31    bouyer 		if (!printed) {
   1487   1.31    bouyer 			/*
   1488   1.31    bouyer 			 * We didn't find a valid PIO mode.
   1489   1.31    bouyer 			 * Assume the values returned for DMA are buggy too
   1490   1.31    bouyer 			 */
   1491   1.31    bouyer 			return;
   1492    1.2    bouyer 		}
   1493   1.35    bouyer 		drvp->drive_flags |= DRIVE_MODE;
   1494   1.31    bouyer 		printed = 0;
   1495   1.31    bouyer 		for (i = 7; i >= 0; i--) {
   1496   1.31    bouyer 			if ((params.atap_dmamode_supp & (1 << i)) == 0)
   1497   1.31    bouyer 				continue;
   1498   1.31    bouyer 			if ((wdc->cap & WDC_CAPABILITY_DMA) &&
   1499   1.31    bouyer 			    (wdc->cap & WDC_CAPABILITY_MODE))
   1500  1.125   mycroft 				if (ata_set_mode(drvp, 0x20 | i, AT_WAIT)
   1501   1.31    bouyer 				    != CMD_OK)
   1502   1.31    bouyer 					continue;
   1503   1.31    bouyer 			if (!printed) {
   1504  1.123   thorpej 				aprint_normal("%s DMA mode %d", sep, i);
   1505   1.31    bouyer 				sep = ",";
   1506   1.31    bouyer 				printed = 1;
   1507   1.31    bouyer 			}
   1508   1.31    bouyer 			if (wdc->cap & WDC_CAPABILITY_DMA) {
   1509   1.31    bouyer 				if ((wdc->cap & WDC_CAPABILITY_MODE) &&
   1510   1.52    bouyer 				    wdc->DMA_cap < i)
   1511   1.31    bouyer 					continue;
   1512   1.31    bouyer 				drvp->DMA_mode = i;
   1513   1.48    bouyer 				drvp->DMA_cap = i;
   1514   1.31    bouyer 				drvp->drive_flags |= DRIVE_DMA;
   1515   1.31    bouyer 			}
   1516    1.2    bouyer 			break;
   1517    1.2    bouyer 		}
   1518   1.31    bouyer 		if (params.atap_extensions & WDC_EXT_UDMA_MODES) {
   1519   1.71    bouyer 			printed = 0;
   1520   1.31    bouyer 			for (i = 7; i >= 0; i--) {
   1521   1.31    bouyer 				if ((params.atap_udmamode_supp & (1 << i))
   1522   1.31    bouyer 				    == 0)
   1523   1.31    bouyer 					continue;
   1524   1.31    bouyer 				if ((wdc->cap & WDC_CAPABILITY_MODE) &&
   1525   1.31    bouyer 				    (wdc->cap & WDC_CAPABILITY_UDMA))
   1526   1.31    bouyer 					if (ata_set_mode(drvp, 0x40 | i,
   1527  1.125   mycroft 					    AT_WAIT) != CMD_OK)
   1528   1.31    bouyer 						continue;
   1529   1.71    bouyer 				if (!printed) {
   1530  1.123   thorpej 					aprint_normal("%s Ultra-DMA mode %d",
   1531  1.123   thorpej 					    sep, i);
   1532   1.93  wrstuden 					if (i == 2)
   1533  1.123   thorpej 						aprint_normal(" (Ultra/33)");
   1534   1.93  wrstuden 					else if (i == 4)
   1535  1.123   thorpej 						aprint_normal(" (Ultra/66)");
   1536   1.93  wrstuden 					else if (i == 5)
   1537  1.123   thorpej 						aprint_normal(" (Ultra/100)");
   1538  1.117    bouyer 					else if (i == 6)
   1539  1.123   thorpej 						aprint_normal(" (Ultra/133)");
   1540   1.71    bouyer 					sep = ",";
   1541   1.71    bouyer 					printed = 1;
   1542   1.71    bouyer 				}
   1543   1.31    bouyer 				if (wdc->cap & WDC_CAPABILITY_UDMA) {
   1544   1.50    bouyer 					if ((wdc->cap & WDC_CAPABILITY_MODE) &&
   1545   1.52    bouyer 					    wdc->UDMA_cap < i)
   1546   1.50    bouyer 						continue;
   1547   1.31    bouyer 					drvp->UDMA_mode = i;
   1548   1.48    bouyer 					drvp->UDMA_cap = i;
   1549   1.31    bouyer 					drvp->drive_flags |= DRIVE_UDMA;
   1550   1.31    bouyer 				}
   1551   1.31    bouyer 				break;
   1552   1.31    bouyer 			}
   1553   1.31    bouyer 		}
   1554  1.123   thorpej 		aprint_normal("\n");
   1555   1.55    bouyer 	}
   1556   1.55    bouyer 
   1557   1.55    bouyer 	/* Try to guess ATA version here, if it didn't get reported */
   1558   1.55    bouyer 	if (drvp->ata_vers == 0) {
   1559   1.55    bouyer 		if (drvp->drive_flags & DRIVE_UDMA)
   1560   1.55    bouyer 			drvp->ata_vers = 4; /* should be at last ATA-4 */
   1561   1.55    bouyer 		else if (drvp->PIO_cap > 2)
   1562   1.55    bouyer 			drvp->ata_vers = 2; /* should be at last ATA-2 */
   1563   1.48    bouyer 	}
   1564   1.48    bouyer 	cf_flags = drv_dev->dv_cfdata->cf_flags;
   1565   1.48    bouyer 	if (cf_flags & ATA_CONFIG_PIO_SET) {
   1566   1.48    bouyer 		drvp->PIO_mode =
   1567   1.48    bouyer 		    (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
   1568   1.48    bouyer 		drvp->drive_flags |= DRIVE_MODE;
   1569   1.48    bouyer 	}
   1570   1.48    bouyer 	if ((wdc->cap & WDC_CAPABILITY_DMA) == 0) {
   1571   1.48    bouyer 		/* don't care about DMA modes */
   1572   1.48    bouyer 		return;
   1573   1.48    bouyer 	}
   1574   1.48    bouyer 	if (cf_flags & ATA_CONFIG_DMA_SET) {
   1575   1.48    bouyer 		if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
   1576   1.48    bouyer 		    ATA_CONFIG_DMA_DISABLE) {
   1577   1.48    bouyer 			drvp->drive_flags &= ~DRIVE_DMA;
   1578   1.48    bouyer 		} else {
   1579   1.48    bouyer 			drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >>
   1580   1.48    bouyer 			    ATA_CONFIG_DMA_OFF;
   1581   1.48    bouyer 			drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
   1582   1.48    bouyer 		}
   1583  1.101    bouyer 	}
   1584  1.101    bouyer 	if ((wdc->cap & WDC_CAPABILITY_UDMA) == 0) {
   1585  1.101    bouyer 		/* don't care about UDMA modes */
   1586  1.101    bouyer 		return;
   1587   1.48    bouyer 	}
   1588   1.48    bouyer 	if (cf_flags & ATA_CONFIG_UDMA_SET) {
   1589   1.48    bouyer 		if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
   1590   1.48    bouyer 		    ATA_CONFIG_UDMA_DISABLE) {
   1591   1.48    bouyer 			drvp->drive_flags &= ~DRIVE_UDMA;
   1592   1.48    bouyer 		} else {
   1593   1.48    bouyer 			drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >>
   1594   1.48    bouyer 			    ATA_CONFIG_UDMA_OFF;
   1595   1.48    bouyer 			drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
   1596   1.48    bouyer 		}
   1597    1.2    bouyer 	}
   1598   1.54    bouyer }
   1599   1.54    bouyer 
   1600   1.54    bouyer /*
   1601   1.56    bouyer  * downgrade the transfer mode of a drive after an error. return 1 if
   1602   1.54    bouyer  * downgrade was possible, 0 otherwise.
   1603   1.54    bouyer  */
   1604   1.54    bouyer int
   1605  1.163   thorpej wdc_downgrade_mode(struct ata_drive_datas *drvp, int flags)
   1606   1.54    bouyer {
   1607  1.168   thorpej 	struct wdc_channel *chp = drvp->chnl_softc;
   1608  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1609   1.54    bouyer 	struct device *drv_dev = drvp->drv_softc;
   1610   1.54    bouyer 	int cf_flags = drv_dev->dv_cfdata->cf_flags;
   1611   1.54    bouyer 
   1612   1.54    bouyer 	/* if drive or controller don't know its mode, we can't do much */
   1613   1.54    bouyer 	if ((drvp->drive_flags & DRIVE_MODE) == 0 ||
   1614   1.54    bouyer 	    (wdc->cap & WDC_CAPABILITY_MODE) == 0)
   1615   1.54    bouyer 		return 0;
   1616   1.54    bouyer 	/* current drive mode was set by a config flag, let it this way */
   1617   1.54    bouyer 	if ((cf_flags & ATA_CONFIG_PIO_SET) ||
   1618   1.54    bouyer 	    (cf_flags & ATA_CONFIG_DMA_SET) ||
   1619   1.54    bouyer 	    (cf_flags & ATA_CONFIG_UDMA_SET))
   1620   1.54    bouyer 		return 0;
   1621   1.54    bouyer 
   1622   1.61    bouyer 	/*
   1623  1.180   mycroft 	 * If we were using Ultra-DMA mode, downgrade to the next lower mode.
   1624   1.73    bouyer 	 */
   1625   1.78    bouyer 	if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode >= 2) {
   1626  1.180   mycroft 		drvp->UDMA_mode--;
   1627   1.78    bouyer 		printf("%s: transfer error, downgrading to Ultra-DMA mode %d\n",
   1628   1.73    bouyer 		    drv_dev->dv_xname, drvp->UDMA_mode);
   1629   1.73    bouyer 	}
   1630   1.73    bouyer 
   1631   1.73    bouyer 	/*
   1632  1.180   mycroft 	 * If we were using ultra-DMA, don't downgrade to multiword DMA.
   1633   1.61    bouyer 	 */
   1634  1.180   mycroft 	else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
   1635   1.61    bouyer 		drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
   1636   1.54    bouyer 		drvp->PIO_mode = drvp->PIO_cap;
   1637   1.56    bouyer 		printf("%s: transfer error, downgrading to PIO mode %d\n",
   1638   1.54    bouyer 		    drv_dev->dv_xname, drvp->PIO_mode);
   1639   1.54    bouyer 	} else /* already using PIO, can't downgrade */
   1640   1.54    bouyer 		return 0;
   1641   1.54    bouyer 
   1642   1.54    bouyer 	wdc->set_modes(chp);
   1643  1.137    bouyer 	wdc_print_modes(chp);
   1644  1.137    bouyer 	/* reset the channel, which will shedule all drives for setup */
   1645  1.183    bouyer 	wdc_reset_channel(chp, flags | AT_RST_NOCMD);
   1646   1.54    bouyer 	return 1;
   1647    1.2    bouyer }
   1648    1.2    bouyer 
   1649    1.2    bouyer int
   1650  1.163   thorpej wdc_exec_command(struct ata_drive_datas *drvp, struct wdc_command *wdc_c)
   1651   1.31    bouyer {
   1652  1.168   thorpej 	struct wdc_channel *chp = drvp->chnl_softc;
   1653  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1654  1.165   thorpej 	struct ata_xfer *xfer;
   1655   1.31    bouyer 	int s, ret;
   1656    1.2    bouyer 
   1657   1.34    bouyer 	WDCDEBUG_PRINT(("wdc_exec_command %s:%d:%d\n",
   1658  1.169   thorpej 	    wdc->sc_dev.dv_xname, chp->ch_channel, drvp->drive),
   1659   1.34    bouyer 	    DEBUG_FUNCS);
   1660    1.2    bouyer 
   1661   1.31    bouyer 	/* set up an xfer and queue. Wait for completion */
   1662   1.31    bouyer 	xfer = wdc_get_xfer(wdc_c->flags & AT_WAIT ? WDC_CANSLEEP :
   1663   1.31    bouyer 	    WDC_NOSLEEP);
   1664   1.31    bouyer 	if (xfer == NULL) {
   1665   1.31    bouyer 		return WDC_TRY_AGAIN;
   1666   1.31    bouyer 	 }
   1667    1.2    bouyer 
   1668  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_NOIRQ)
   1669   1.98     bjh21 		wdc_c->flags |= AT_POLL;
   1670   1.31    bouyer 	if (wdc_c->flags & AT_POLL)
   1671   1.31    bouyer 		xfer->c_flags |= C_POLL;
   1672  1.165   thorpej 	xfer->c_drive = drvp->drive;
   1673  1.165   thorpej 	xfer->c_databuf = wdc_c->data;
   1674   1.31    bouyer 	xfer->c_bcount = wdc_c->bcount;
   1675  1.165   thorpej 	xfer->c_cmd = wdc_c;
   1676   1.31    bouyer 	xfer->c_start = __wdccommand_start;
   1677   1.31    bouyer 	xfer->c_intr = __wdccommand_intr;
   1678  1.182    bouyer 	xfer->c_kill_xfer = __wdccommand_kill_xfer;
   1679    1.2    bouyer 
   1680   1.31    bouyer 	s = splbio();
   1681   1.31    bouyer 	wdc_exec_xfer(chp, xfer);
   1682   1.31    bouyer #ifdef DIAGNOSTIC
   1683   1.31    bouyer 	if ((wdc_c->flags & AT_POLL) != 0 &&
   1684   1.31    bouyer 	    (wdc_c->flags & AT_DONE) == 0)
   1685  1.118    provos 		panic("wdc_exec_command: polled command not done");
   1686    1.2    bouyer #endif
   1687   1.31    bouyer 	if (wdc_c->flags & AT_DONE) {
   1688   1.31    bouyer 		ret = WDC_COMPLETE;
   1689   1.31    bouyer 	} else {
   1690   1.31    bouyer 		if (wdc_c->flags & AT_WAIT) {
   1691   1.69    bouyer 			while ((wdc_c->flags & AT_DONE) == 0) {
   1692   1.69    bouyer 				tsleep(wdc_c, PRIBIO, "wdccmd", 0);
   1693   1.69    bouyer 			}
   1694   1.31    bouyer 			ret = WDC_COMPLETE;
   1695   1.31    bouyer 		} else {
   1696   1.31    bouyer 			ret = WDC_QUEUED;
   1697    1.2    bouyer 		}
   1698    1.2    bouyer 	}
   1699   1.31    bouyer 	splx(s);
   1700   1.31    bouyer 	return ret;
   1701    1.2    bouyer }
   1702    1.2    bouyer 
   1703  1.167   thorpej static void
   1704  1.168   thorpej __wdccommand_start(struct wdc_channel *chp, struct ata_xfer *xfer)
   1705   1.31    bouyer {
   1706  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1707  1.165   thorpej 	int drive = xfer->c_drive;
   1708  1.165   thorpej 	struct wdc_command *wdc_c = xfer->c_cmd;
   1709   1.31    bouyer 
   1710   1.34    bouyer 	WDCDEBUG_PRINT(("__wdccommand_start %s:%d:%d\n",
   1711  1.169   thorpej 	    wdc->sc_dev.dv_xname, chp->ch_channel, xfer->c_drive),
   1712   1.34    bouyer 	    DEBUG_FUNCS);
   1713   1.31    bouyer 
   1714  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_SELECT)
   1715  1.169   thorpej 		wdc->select(chp,drive);
   1716  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
   1717   1.31    bouyer 	    WDSD_IBM | (drive << 4));
   1718  1.137    bouyer 	switch(wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
   1719  1.137    bouyer 	    wdc_c->r_st_bmask, wdc_c->timeout, wdc_c->flags)) {
   1720  1.137    bouyer 	case WDCWAIT_OK:
   1721  1.137    bouyer 		break;
   1722  1.137    bouyer 	case WDCWAIT_TOUT:
   1723   1.31    bouyer 		wdc_c->flags |= AT_TIMEOU;
   1724   1.31    bouyer 		__wdccommand_done(chp, xfer);
   1725   1.53    bouyer 		return;
   1726  1.137    bouyer 	case WDCWAIT_THR:
   1727  1.137    bouyer 		return;
   1728   1.31    bouyer 	}
   1729  1.135    bouyer 	if (wdc_c->flags & AT_POLL) {
   1730  1.135    bouyer 		/* polled command, disable interrupts */
   1731  1.135    bouyer 		bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
   1732  1.135    bouyer 		    WDCTL_4BIT | WDCTL_IDS);
   1733  1.135    bouyer 	}
   1734   1.31    bouyer 	wdccommand(chp, drive, wdc_c->r_command, wdc_c->r_cyl, wdc_c->r_head,
   1735  1.178   thorpej 	    wdc_c->r_sector, wdc_c->r_count, wdc_c->r_features);
   1736  1.139    bouyer 
   1737   1.31    bouyer 	if ((wdc_c->flags & AT_POLL) == 0) {
   1738   1.31    bouyer 		chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
   1739   1.81   thorpej 		callout_reset(&chp->ch_callout, wdc_c->timeout / 1000 * hz,
   1740   1.81   thorpej 		    wdctimeout, chp);
   1741   1.31    bouyer 		return;
   1742    1.2    bouyer 	}
   1743    1.2    bouyer 	/*
   1744   1.31    bouyer 	 * Polled command. Wait for drive ready or drq. Done in intr().
   1745   1.31    bouyer 	 * Wait for at last 400ns for status bit to be valid.
   1746    1.2    bouyer 	 */
   1747  1.134   mycroft 	delay(10);	/* 400ns delay */
   1748   1.66    bouyer 	__wdccommand_intr(chp, xfer, 0);
   1749    1.2    bouyer }
   1750    1.2    bouyer 
   1751  1.167   thorpej static int
   1752  1.168   thorpej __wdccommand_intr(struct wdc_channel *chp, struct ata_xfer *xfer, int irq)
   1753    1.2    bouyer {
   1754  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1755  1.165   thorpej 	struct wdc_command *wdc_c = xfer->c_cmd;
   1756   1.31    bouyer 	int bcount = wdc_c->bcount;
   1757   1.31    bouyer 	char *data = wdc_c->data;
   1758  1.137    bouyer 	int wflags;
   1759  1.137    bouyer 
   1760  1.137    bouyer 	if ((wdc_c->flags & (AT_WAIT | AT_POLL)) == (AT_WAIT | AT_POLL)) {
   1761  1.137    bouyer 		/* both wait and poll, we can tsleep here */
   1762  1.147    bouyer 		wflags = AT_WAIT | AT_POLL;
   1763  1.137    bouyer 	} else {
   1764  1.137    bouyer 		wflags = AT_POLL;
   1765  1.137    bouyer 	}
   1766   1.31    bouyer 
   1767  1.163   thorpej  again:
   1768   1.34    bouyer 	WDCDEBUG_PRINT(("__wdccommand_intr %s:%d:%d\n",
   1769  1.169   thorpej 	    wdc->sc_dev.dv_xname, chp->ch_channel, xfer->c_drive),
   1770  1.165   thorpej 	    DEBUG_INTR);
   1771  1.137    bouyer 	/*
   1772  1.137    bouyer 	 * after a ATAPI_SOFT_RESET, the device will have released the bus.
   1773  1.137    bouyer 	 * Reselect again, it doesn't hurt for others commands, and the time
   1774  1.137    bouyer 	 * penalty for the extra regiter write is acceptable,
   1775  1.137    bouyer 	 * wdc_exec_command() isn't called often (mosly for autoconfig)
   1776  1.137    bouyer 	 */
   1777  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
   1778  1.165   thorpej 	    WDSD_IBM | (xfer->c_drive << 4));
   1779  1.114    bouyer 	if ((wdc_c->flags & AT_XFDONE) != 0) {
   1780  1.114    bouyer 		/*
   1781  1.114    bouyer 		 * We have completed a data xfer. The drive should now be
   1782  1.114    bouyer 		 * in its initial state
   1783  1.114    bouyer 		 */
   1784  1.114    bouyer 		if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
   1785  1.137    bouyer 		    wdc_c->r_st_bmask, (irq == 0)  ? wdc_c->timeout : 0,
   1786  1.137    bouyer 		    wflags) ==  WDCWAIT_TOUT) {
   1787  1.114    bouyer 			if (irq && (xfer->c_flags & C_TIMEOU) == 0)
   1788  1.114    bouyer 				return 0; /* IRQ was not for us */
   1789  1.114    bouyer 			wdc_c->flags |= AT_TIMEOU;
   1790  1.114    bouyer 		}
   1791  1.131   mycroft 		goto out;
   1792  1.114    bouyer 	}
   1793   1.31    bouyer 	if (wdcwait(chp, wdc_c->r_st_pmask, wdc_c->r_st_pmask,
   1794  1.137    bouyer 	     (irq == 0)  ? wdc_c->timeout : 0, wflags) == WDCWAIT_TOUT) {
   1795   1.66    bouyer 		if (irq && (xfer->c_flags & C_TIMEOU) == 0)
   1796   1.63    bouyer 			return 0; /* IRQ was not for us */
   1797   1.63    bouyer 		wdc_c->flags |= AT_TIMEOU;
   1798  1.131   mycroft 		goto out;
   1799    1.2    bouyer 	}
   1800  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_IRQACK)
   1801  1.169   thorpej 		wdc->irqack(chp);
   1802   1.31    bouyer 	if (wdc_c->flags & AT_READ) {
   1803  1.131   mycroft 		if ((chp->ch_status & WDCS_DRQ) == 0) {
   1804  1.131   mycroft 			wdc_c->flags |= AT_TIMEOU;
   1805  1.131   mycroft 			goto out;
   1806  1.131   mycroft 		}
   1807  1.165   thorpej 		if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_CAP32) {
   1808   1.31    bouyer 			bus_space_read_multi_4(chp->data32iot, chp->data32ioh,
   1809   1.31    bouyer 			    0, (u_int32_t*)data, bcount >> 2);
   1810   1.31    bouyer 			data += bcount & 0xfffffffc;
   1811   1.31    bouyer 			bcount = bcount & 0x03;
   1812   1.31    bouyer 		}
   1813   1.31    bouyer 		if (bcount > 0)
   1814  1.157      fvdl 			bus_space_read_multi_2(chp->cmd_iot,
   1815  1.157      fvdl 			    chp->cmd_iohs[wd_data], 0,
   1816  1.157      fvdl 			    (u_int16_t *)data, bcount >> 1);
   1817  1.114    bouyer 		/* at this point the drive should be in its initial state */
   1818  1.114    bouyer 		wdc_c->flags |= AT_XFDONE;
   1819  1.137    bouyer 		/* XXX should read status register here ? */
   1820  1.131   mycroft 	} else if (wdc_c->flags & AT_WRITE) {
   1821  1.131   mycroft 		if ((chp->ch_status & WDCS_DRQ) == 0) {
   1822  1.114    bouyer 			wdc_c->flags |= AT_TIMEOU;
   1823  1.131   mycroft 			goto out;
   1824  1.131   mycroft 		}
   1825  1.165   thorpej 		if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_CAP32) {
   1826   1.31    bouyer 			bus_space_write_multi_4(chp->data32iot, chp->data32ioh,
   1827   1.31    bouyer 			    0, (u_int32_t*)data, bcount >> 2);
   1828   1.31    bouyer 			data += bcount & 0xfffffffc;
   1829   1.31    bouyer 			bcount = bcount & 0x03;
   1830   1.31    bouyer 		}
   1831   1.31    bouyer 		if (bcount > 0)
   1832  1.157      fvdl 			bus_space_write_multi_2(chp->cmd_iot,
   1833  1.157      fvdl 			    chp->cmd_iohs[wd_data], 0,
   1834  1.157      fvdl 			    (u_int16_t *)data, bcount >> 1);
   1835  1.114    bouyer 		wdc_c->flags |= AT_XFDONE;
   1836  1.114    bouyer 		if ((wdc_c->flags & AT_POLL) == 0) {
   1837  1.114    bouyer 			chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
   1838  1.114    bouyer 			callout_reset(&chp->ch_callout,
   1839  1.114    bouyer 			    wdc_c->timeout / 1000 * hz, wdctimeout, chp);
   1840  1.114    bouyer 			return 1;
   1841  1.114    bouyer 		} else {
   1842  1.114    bouyer 			goto again;
   1843  1.114    bouyer 		}
   1844    1.2    bouyer 	}
   1845  1.163   thorpej  out:
   1846   1.31    bouyer 	__wdccommand_done(chp, xfer);
   1847   1.31    bouyer 	return 1;
   1848    1.2    bouyer }
   1849    1.2    bouyer 
   1850  1.167   thorpej static void
   1851  1.168   thorpej __wdccommand_done(struct wdc_channel *chp, struct ata_xfer *xfer)
   1852    1.2    bouyer {
   1853  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1854  1.165   thorpej 	struct wdc_command *wdc_c = xfer->c_cmd;
   1855    1.2    bouyer 
   1856   1.34    bouyer 	WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d\n",
   1857  1.169   thorpej 	    wdc->sc_dev.dv_xname, chp->ch_channel, xfer->c_drive),
   1858  1.165   thorpej 	    DEBUG_FUNCS);
   1859   1.70    bouyer 
   1860   1.70    bouyer 
   1861   1.31    bouyer 	if (chp->ch_status & WDCS_DWF)
   1862   1.31    bouyer 		wdc_c->flags |= AT_DF;
   1863   1.31    bouyer 	if (chp->ch_status & WDCS_ERR) {
   1864   1.31    bouyer 		wdc_c->flags |= AT_ERROR;
   1865   1.31    bouyer 		wdc_c->r_error = chp->ch_error;
   1866   1.31    bouyer 	}
   1867   1.80     enami 	if ((wdc_c->flags & AT_READREG) != 0 &&
   1868  1.169   thorpej 	    (wdc->sc_dev.dv_flags & DVF_ACTIVE) != 0 &&
   1869   1.75     enami 	    (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
   1870  1.157      fvdl 		wdc_c->r_head = bus_space_read_1(chp->cmd_iot,
   1871  1.157      fvdl 		    chp->cmd_iohs[wd_sdh], 0);
   1872  1.179   mycroft 		wdc_c->r_count = bus_space_read_1(chp->cmd_iot,
   1873  1.179   mycroft 		    chp->cmd_iohs[wd_seccnt], 0);
   1874  1.179   mycroft 		wdc_c->r_sector = bus_space_read_1(chp->cmd_iot,
   1875  1.179   mycroft 		    chp->cmd_iohs[wd_sector], 0);
   1876  1.179   mycroft 		wdc_c->r_cyl |= bus_space_read_1(chp->cmd_iot,
   1877  1.179   mycroft 		    chp->cmd_iohs[wd_cyl_lo], 0);
   1878  1.157      fvdl 		wdc_c->r_cyl = bus_space_read_1(chp->cmd_iot,
   1879  1.157      fvdl 		    chp->cmd_iohs[wd_cyl_hi], 0) << 8;
   1880  1.157      fvdl 		wdc_c->r_error = bus_space_read_1(chp->cmd_iot,
   1881  1.157      fvdl 		    chp->cmd_iohs[wd_error], 0);
   1882  1.178   thorpej 		wdc_c->r_features = bus_space_read_1(chp->cmd_iot,
   1883  1.178   thorpej 		    chp->cmd_iohs[wd_features], 0);
   1884  1.135    bouyer 	}
   1885  1.182    bouyer 	__wdccommand_done_end(chp, xfer);
   1886  1.182    bouyer }
   1887  1.137    bouyer 
   1888  1.182    bouyer static void
   1889  1.182    bouyer __wdccommand_done_end(struct wdc_channel *chp, struct ata_xfer *xfer)
   1890  1.182    bouyer {
   1891  1.182    bouyer 	struct wdc_command *wdc_c = xfer->c_cmd;
   1892  1.182    bouyer 
   1893  1.182    bouyer 	callout_stop(&chp->ch_callout);
   1894  1.182    bouyer 	wdc_c->flags |= AT_DONE;
   1895  1.135    bouyer 	if (wdc_c->flags & AT_POLL) {
   1896  1.135    bouyer 		/* enable interrupts */
   1897  1.135    bouyer 		bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
   1898  1.135    bouyer 		    WDCTL_4BIT);
   1899  1.173    bouyer 		delay(10); /* some drives need a little delay here */
   1900   1.46      kenh 	}
   1901   1.31    bouyer 	wdc_free_xfer(chp, xfer);
   1902   1.71    bouyer 	if (wdc_c->flags & AT_WAIT)
   1903   1.71    bouyer 		wakeup(wdc_c);
   1904   1.71    bouyer 	else if (wdc_c->callback)
   1905   1.71    bouyer 		wdc_c->callback(wdc_c->callback_arg);
   1906   1.45  drochner 	wdcstart(chp);
   1907   1.31    bouyer 	return;
   1908    1.2    bouyer }
   1909    1.2    bouyer 
   1910  1.182    bouyer static void
   1911  1.182    bouyer __wdccommand_kill_xfer(struct wdc_channel *chp, struct ata_xfer *xfer,
   1912  1.182    bouyer     int reason)
   1913  1.182    bouyer {
   1914  1.182    bouyer 	struct wdc_command *wdc_c = xfer->c_cmd;
   1915  1.182    bouyer 
   1916  1.182    bouyer 	switch (reason) {
   1917  1.182    bouyer 	case KILL_GONE:
   1918  1.182    bouyer 		wdc_c->flags |= AT_GONE;
   1919  1.182    bouyer 		break;
   1920  1.182    bouyer 	case KILL_RESET:
   1921  1.182    bouyer 		wdc_c->flags |= AT_RESET;
   1922  1.182    bouyer 		break;
   1923  1.182    bouyer 	default:
   1924  1.182    bouyer 		printf("__wdccommand_kill_xfer: unknown reason %d\n",
   1925  1.182    bouyer 		    reason);
   1926  1.182    bouyer 		panic("__wdccommand_kill_xfer");
   1927  1.182    bouyer 	}
   1928  1.182    bouyer 	__wdccommand_done_end(chp, xfer);
   1929  1.182    bouyer 
   1930  1.182    bouyer }
   1931  1.182    bouyer 
   1932    1.2    bouyer /*
   1933   1.31    bouyer  * Send a command. The drive should be ready.
   1934    1.2    bouyer  * Assumes interrupts are blocked.
   1935    1.2    bouyer  */
   1936   1.31    bouyer void
   1937  1.168   thorpej wdccommand(struct wdc_channel *chp, u_int8_t drive, u_int8_t command,
   1938  1.163   thorpej     u_int16_t cylin, u_int8_t head, u_int8_t sector, u_int8_t count,
   1939  1.178   thorpej     u_int8_t features)
   1940   1.31    bouyer {
   1941  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1942  1.163   thorpej 
   1943   1.31    bouyer 	WDCDEBUG_PRINT(("wdccommand %s:%d:%d: command=0x%x cylin=%d head=%d "
   1944  1.178   thorpej 	    "sector=%d count=%d features=%d\n", wdc->sc_dev.dv_xname,
   1945  1.169   thorpej 	    chp->ch_channel, drive, command, cylin, head, sector, count,
   1946  1.178   thorpej 	    features), DEBUG_FUNCS);
   1947   1.31    bouyer 
   1948  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_SELECT)
   1949  1.169   thorpej 		wdc->select(chp,drive);
   1950  1.107       dbj 
   1951   1.31    bouyer 	/* Select drive, head, and addressing mode. */
   1952  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
   1953   1.31    bouyer 	    WDSD_IBM | (drive << 4) | head);
   1954  1.177   thorpej 	/* Load parameters into the wd_features register. */
   1955  1.177   thorpej 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_features], 0,
   1956  1.178   thorpej 	    features);
   1957  1.179   mycroft 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_seccnt], 0, count);
   1958  1.179   mycroft 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sector], 0, sector);
   1959  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_cyl_lo], 0, cylin);
   1960  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_cyl_hi],
   1961  1.157      fvdl 	    0, cylin >> 8);
   1962  1.108  christos 
   1963  1.108  christos 	/* Send command. */
   1964  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_command], 0, command);
   1965  1.108  christos 	return;
   1966  1.108  christos }
   1967  1.108  christos 
   1968  1.108  christos /*
   1969  1.108  christos  * Send a 48-bit addressing command. The drive should be ready.
   1970  1.108  christos  * Assumes interrupts are blocked.
   1971  1.108  christos  */
   1972  1.108  christos void
   1973  1.168   thorpej wdccommandext(struct wdc_channel *chp, u_int8_t drive, u_int8_t command,
   1974  1.163   thorpej     u_int64_t blkno, u_int16_t count)
   1975  1.108  christos {
   1976  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   1977  1.163   thorpej 
   1978  1.108  christos 	WDCDEBUG_PRINT(("wdccommandext %s:%d:%d: command=0x%x blkno=%d "
   1979  1.169   thorpej 	    "count=%d\n", wdc->sc_dev.dv_xname,
   1980  1.169   thorpej 	    chp->ch_channel, drive, command, (u_int32_t) blkno, count),
   1981  1.108  christos 	    DEBUG_FUNCS);
   1982  1.108  christos 
   1983  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_SELECT)
   1984  1.169   thorpej 		wdc->select(chp,drive);
   1985  1.108  christos 
   1986  1.108  christos 	/* Select drive, head, and addressing mode. */
   1987  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
   1988  1.108  christos 	    (drive << 4) | WDSD_LBA);
   1989  1.108  christos 
   1990  1.108  christos 	/* previous */
   1991  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_features], 0, 0);
   1992  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_seccnt],
   1993  1.157      fvdl 	    0, count >> 8);
   1994  1.179   mycroft 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_lba_lo],
   1995  1.179   mycroft 	    0, blkno >> 24);
   1996  1.179   mycroft 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_lba_mi],
   1997  1.179   mycroft 	    0, blkno >> 32);
   1998  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_lba_hi],
   1999  1.157      fvdl 	    0, blkno >> 40);
   2000  1.108  christos 
   2001  1.108  christos 	/* current */
   2002  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_features], 0, 0);
   2003  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_seccnt], 0, count);
   2004  1.179   mycroft 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_lba_lo], 0, blkno);
   2005  1.179   mycroft 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_lba_mi],
   2006  1.179   mycroft 	    0, blkno >> 8);
   2007  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_lba_hi],
   2008  1.157      fvdl 	    0, blkno >> 16);
   2009    1.2    bouyer 
   2010   1.31    bouyer 	/* Send command. */
   2011  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_command], 0, command);
   2012   1.31    bouyer 	return;
   2013    1.2    bouyer }
   2014    1.2    bouyer 
   2015    1.2    bouyer /*
   2016   1.31    bouyer  * Simplified version of wdccommand().  Unbusy/ready/drq must be
   2017   1.31    bouyer  * tested by the caller.
   2018    1.2    bouyer  */
   2019   1.31    bouyer void
   2020  1.168   thorpej wdccommandshort(struct wdc_channel *chp, int drive, int command)
   2021    1.2    bouyer {
   2022  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   2023    1.2    bouyer 
   2024   1.31    bouyer 	WDCDEBUG_PRINT(("wdccommandshort %s:%d:%d command 0x%x\n",
   2025  1.169   thorpej 	    wdc->sc_dev.dv_xname, chp->ch_channel, drive, command),
   2026   1.31    bouyer 	    DEBUG_FUNCS);
   2027  1.107       dbj 
   2028  1.169   thorpej 	if (wdc->cap & WDC_CAPABILITY_SELECT)
   2029  1.169   thorpej 		wdc->select(chp,drive);
   2030    1.2    bouyer 
   2031   1.31    bouyer 	/* Select drive. */
   2032  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
   2033   1.31    bouyer 	    WDSD_IBM | (drive << 4));
   2034    1.2    bouyer 
   2035  1.157      fvdl 	bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_command], 0, command);
   2036   1.31    bouyer }
   2037    1.2    bouyer 
   2038   1.31    bouyer /* Add a command to the queue and start controller. Must be called at splbio */
   2039    1.2    bouyer void
   2040  1.168   thorpej wdc_exec_xfer(struct wdc_channel *chp, struct ata_xfer *xfer)
   2041    1.2    bouyer {
   2042  1.163   thorpej 
   2043   1.33    bouyer 	WDCDEBUG_PRINT(("wdc_exec_xfer %p channel %d drive %d\n", xfer,
   2044  1.169   thorpej 	    chp->ch_channel, xfer->c_drive), DEBUG_XFERS);
   2045    1.2    bouyer 
   2046   1.31    bouyer 	/* complete xfer setup */
   2047  1.165   thorpej 	xfer->c_chp = chp;
   2048    1.2    bouyer 
   2049    1.2    bouyer 	/* insert at the end of command list */
   2050  1.165   thorpej 	TAILQ_INSERT_TAIL(&chp->ch_queue->queue_xfer, xfer, c_xferchain);
   2051   1.31    bouyer 	WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
   2052   1.33    bouyer 	    chp->ch_flags), DEBUG_XFERS);
   2053   1.45  drochner 	wdcstart(chp);
   2054   1.31    bouyer }
   2055    1.2    bouyer 
   2056  1.165   thorpej struct ata_xfer *
   2057  1.163   thorpej wdc_get_xfer(int flags)
   2058    1.2    bouyer {
   2059  1.165   thorpej 	struct ata_xfer *xfer;
   2060   1.72    bouyer 	int s;
   2061    1.2    bouyer 
   2062   1.72    bouyer 	s = splbio();
   2063   1.71    bouyer 	xfer = pool_get(&wdc_xfer_pool,
   2064   1.71    bouyer 	    ((flags & WDC_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK));
   2065   1.72    bouyer 	splx(s);
   2066   1.99       chs 	if (xfer != NULL) {
   2067  1.165   thorpej 		memset(xfer, 0, sizeof(struct ata_xfer));
   2068   1.99       chs 	}
   2069    1.2    bouyer 	return xfer;
   2070    1.2    bouyer }
   2071    1.2    bouyer 
   2072    1.2    bouyer void
   2073  1.168   thorpej wdc_free_xfer(struct wdc_channel *chp, struct ata_xfer *xfer)
   2074    1.2    bouyer {
   2075  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   2076    1.2    bouyer 	int s;
   2077    1.2    bouyer 
   2078   1.31    bouyer 	if (wdc->cap & WDC_CAPABILITY_HWLOCK)
   2079   1.31    bouyer 		(*wdc->free_hw)(chp);
   2080    1.2    bouyer 	s = splbio();
   2081   1.31    bouyer 	chp->ch_flags &= ~WDCF_ACTIVE;
   2082  1.165   thorpej 	TAILQ_REMOVE(&chp->ch_queue->queue_xfer, xfer, c_xferchain);
   2083   1.72    bouyer 	pool_put(&wdc_xfer_pool, xfer);
   2084    1.2    bouyer 	splx(s);
   2085   1.75     enami }
   2086   1.75     enami 
   2087   1.75     enami /*
   2088  1.168   thorpej  * Kill off all pending xfers for a wdc_channel.
   2089   1.75     enami  *
   2090   1.75     enami  * Must be called at splbio().
   2091   1.75     enami  */
   2092   1.75     enami void
   2093  1.168   thorpej wdc_kill_pending(struct wdc_channel *chp)
   2094   1.75     enami {
   2095  1.165   thorpej 	struct ata_xfer *xfer;
   2096   1.75     enami 
   2097  1.165   thorpej 	while ((xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer)) != NULL) {
   2098  1.165   thorpej 		chp = xfer->c_chp;
   2099  1.182    bouyer 		(*xfer->c_kill_xfer)(chp, xfer, KILL_GONE);
   2100   1.75     enami 	}
   2101    1.2    bouyer }
   2102    1.2    bouyer 
   2103   1.31    bouyer static void
   2104  1.168   thorpej __wdcerror(struct wdc_channel *chp, char *msg)
   2105    1.2    bouyer {
   2106  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   2107  1.165   thorpej 	struct ata_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->queue_xfer);
   2108   1.88       mrg 
   2109    1.2    bouyer 	if (xfer == NULL)
   2110  1.169   thorpej 		printf("%s:%d: %s\n", wdc->sc_dev.dv_xname, chp->ch_channel,
   2111   1.31    bouyer 		    msg);
   2112    1.2    bouyer 	else
   2113  1.169   thorpej 		printf("%s:%d:%d: %s\n", wdc->sc_dev.dv_xname,
   2114  1.169   thorpej 		    chp->ch_channel, xfer->c_drive, msg);
   2115    1.2    bouyer }
   2116    1.2    bouyer 
   2117    1.2    bouyer /*
   2118    1.2    bouyer  * the bit bucket
   2119    1.2    bouyer  */
   2120    1.2    bouyer void
   2121  1.168   thorpej wdcbit_bucket(struct wdc_channel *chp, int size)
   2122    1.2    bouyer {
   2123    1.2    bouyer 
   2124   1.12       cgd 	for (; size >= 2; size -= 2)
   2125  1.157      fvdl 		(void)bus_space_read_2(chp->cmd_iot, chp->cmd_iohs[wd_data], 0);
   2126   1.12       cgd 	if (size)
   2127  1.157      fvdl 		(void)bus_space_read_1(chp->cmd_iot, chp->cmd_iohs[wd_data], 0);
   2128   1.44   thorpej }
   2129   1.44   thorpej 
   2130   1.44   thorpej int
   2131  1.168   thorpej wdc_addref(struct wdc_channel *chp)
   2132   1.44   thorpej {
   2133  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   2134   1.96    bouyer 	struct scsipi_adapter *adapt = &wdc->sc_atapi_adapter._generic;
   2135   1.44   thorpej 	int s, error = 0;
   2136   1.44   thorpej 
   2137   1.44   thorpej 	s = splbio();
   2138   1.96    bouyer 	if (adapt->adapt_refcnt++ == 0 &&
   2139   1.96    bouyer 	    adapt->adapt_enable != NULL) {
   2140   1.96    bouyer 		error = (*adapt->adapt_enable)(&wdc->sc_dev, 1);
   2141   1.44   thorpej 		if (error)
   2142   1.96    bouyer 			adapt->adapt_refcnt--;
   2143   1.44   thorpej 	}
   2144   1.44   thorpej 	splx(s);
   2145   1.44   thorpej 	return (error);
   2146   1.44   thorpej }
   2147   1.44   thorpej 
   2148   1.44   thorpej void
   2149  1.168   thorpej wdc_delref(struct wdc_channel *chp)
   2150   1.44   thorpej {
   2151  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   2152   1.96    bouyer 	struct scsipi_adapter *adapt = &wdc->sc_atapi_adapter._generic;
   2153   1.44   thorpej 	int s;
   2154   1.44   thorpej 
   2155   1.44   thorpej 	s = splbio();
   2156   1.96    bouyer 	if (adapt->adapt_refcnt-- == 1 &&
   2157   1.96    bouyer 	    adapt->adapt_enable != NULL)
   2158   1.96    bouyer 		(void) (*adapt->adapt_enable)(&wdc->sc_dev, 0);
   2159   1.44   thorpej 	splx(s);
   2160   1.93  wrstuden }
   2161   1.93  wrstuden 
   2162   1.93  wrstuden void
   2163  1.168   thorpej wdc_print_modes(struct wdc_channel *chp)
   2164   1.93  wrstuden {
   2165  1.169   thorpej 	struct wdc_softc *wdc = chp->ch_wdc;
   2166   1.93  wrstuden 	int drive;
   2167   1.93  wrstuden 	struct ata_drive_datas *drvp;
   2168   1.93  wrstuden 
   2169   1.93  wrstuden 	for (drive = 0; drive < 2; drive++) {
   2170   1.93  wrstuden 		drvp = &chp->ch_drive[drive];
   2171   1.93  wrstuden 		if ((drvp->drive_flags & DRIVE) == 0)
   2172   1.93  wrstuden 			continue;
   2173  1.123   thorpej 		aprint_normal("%s(%s:%d:%d): using PIO mode %d",
   2174   1.93  wrstuden 			drvp->drv_softc->dv_xname,
   2175  1.169   thorpej 			wdc->sc_dev.dv_xname,
   2176  1.169   thorpej 			chp->ch_channel, drive, drvp->PIO_mode);
   2177   1.93  wrstuden 		if (drvp->drive_flags & DRIVE_DMA)
   2178  1.123   thorpej 			aprint_normal(", DMA mode %d", drvp->DMA_mode);
   2179   1.93  wrstuden 		if (drvp->drive_flags & DRIVE_UDMA) {
   2180  1.123   thorpej 			aprint_normal(", Ultra-DMA mode %d", drvp->UDMA_mode);
   2181   1.93  wrstuden 			if (drvp->UDMA_mode == 2)
   2182  1.123   thorpej 				aprint_normal(" (Ultra/33)");
   2183   1.93  wrstuden 			else if (drvp->UDMA_mode == 4)
   2184  1.123   thorpej 				aprint_normal(" (Ultra/66)");
   2185   1.93  wrstuden 			else if (drvp->UDMA_mode == 5)
   2186  1.123   thorpej 				aprint_normal(" (Ultra/100)");
   2187  1.123   thorpej 			else if (drvp->UDMA_mode == 6)
   2188  1.123   thorpej 				aprint_normal(" (Ultra/133)");
   2189   1.93  wrstuden 		}
   2190   1.93  wrstuden 		if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA))
   2191  1.123   thorpej 			aprint_normal(" (using DMA data transfers)");
   2192  1.123   thorpej 		aprint_normal("\n");
   2193   1.93  wrstuden 	}
   2194    1.2    bouyer }
   2195