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