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