LCOV - code coverage report
Current view: top level - dev/ic - wdc.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 840 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 52 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: wdc.c,v 1.134 2017/12/30 23:08:29 guenther Exp $      */
       2             : /*      $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $  */
       3             : /*
       4             :  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  * 1. Redistributions of source code must retain the above copyright
      10             :  *    notice, this list of conditions and the following disclaimer.
      11             :  * 2. Redistributions in binary form must reproduce the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer in the
      13             :  *    documentation and/or other materials provided with the distribution.
      14             :  *
      15             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      16             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      17             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      18             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      19             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      20             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      21             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      22             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      23             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      24             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      25             :  */
      26             : 
      27             : /*-
      28             :  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      29             :  * All rights reserved.
      30             :  *
      31             :  * This code is derived from software contributed to The NetBSD Foundation
      32             :  * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
      33             :  *
      34             :  * Redistribution and use in source and binary forms, with or without
      35             :  * modification, are permitted provided that the following conditions
      36             :  * are met:
      37             :  * 1. Redistributions of source code must retain the above copyright
      38             :  *    notice, this list of conditions and the following disclaimer.
      39             :  * 2. Redistributions in binary form must reproduce the above copyright
      40             :  *    notice, this list of conditions and the following disclaimer in the
      41             :  *    documentation and/or other materials provided with the distribution.
      42             :  *
      43             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      44             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      45             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      46             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      47             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      48             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      49             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      50             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      51             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      52             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      53             :  * POSSIBILITY OF SUCH DAMAGE.
      54             :  */
      55             : 
      56             : #include <sys/param.h>
      57             : #include <sys/systm.h>
      58             : #include <sys/kernel.h>
      59             : #include <sys/conf.h>
      60             : #include <sys/buf.h>
      61             : #include <sys/device.h>
      62             : #include <sys/malloc.h>
      63             : #include <sys/syslog.h>
      64             : #include <sys/disk.h>
      65             : #include <sys/pool.h>
      66             : 
      67             : #include <machine/intr.h>
      68             : #include <machine/bus.h>
      69             : 
      70             : #include <dev/ata/atavar.h>
      71             : #include <dev/ata/atareg.h>
      72             : #include <dev/ic/wdcreg.h>
      73             : #include <dev/ic/wdcvar.h>
      74             : #include <dev/ic/wdcevent.h>
      75             : 
      76             : #include <scsi/scsi_all.h>
      77             : #include <scsi/scsiconf.h>
      78             : 
      79             : #define WDCDELAY  100 /* 100 microseconds */
      80             : #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
      81             : #if 0
      82             : /* If you enable this, it will report any delays more than WDCDELAY * N long. */
      83             : #define WDCNDELAY_DEBUG 50
      84             : #endif /* 0 */
      85             : 
      86             : struct pool wdc_xfer_pool;
      87             : struct scsi_iopool wdc_xfer_iopool;
      88             : 
      89             : void *  wdc_xfer_get(void *);
      90             : void    wdc_xfer_put(void *, void *);
      91             : 
      92             : void  __wdcerror(struct channel_softc *, char *);
      93             : int   __wdcwait_reset(struct channel_softc *, int);
      94             : void  __wdccommand_done(struct channel_softc *, struct wdc_xfer *);
      95             : void  __wdccommand_start(struct channel_softc *, struct wdc_xfer *);
      96             : int   __wdccommand_intr(struct channel_softc *, struct wdc_xfer *, int);
      97             : int   wdprint(void *, const char *);
      98             : void  wdc_kill_pending(struct channel_softc *);
      99             : 
     100             : #define DEBUG_INTR    0x01
     101             : #define DEBUG_XFERS   0x02
     102             : #define DEBUG_STATUS  0x04
     103             : #define DEBUG_FUNCS   0x08
     104             : #define DEBUG_PROBE   0x10
     105             : #define DEBUG_STATUSX 0x20
     106             : #define DEBUG_SDRIVE  0x40
     107             : #define DEBUG_DETACH  0x80
     108             : 
     109             : #ifdef WDCDEBUG
     110             : #ifndef WDCDEBUG_MASK
     111             : #define WDCDEBUG_MASK 0x00
     112             : #endif
     113             : int wdcdebug_mask = WDCDEBUG_MASK;
     114             : int wdc_nxfer = 0;
     115             : #define WDCDEBUG_PRINT(args, level) do {        \
     116             :         if ((wdcdebug_mask & (level)) != 0) \
     117             :                 printf args;                    \
     118             : } while (0)
     119             : #else
     120             : #define WDCDEBUG_PRINT(args, level)
     121             : #endif /* WDCDEBUG */
     122             : 
     123             : int at_poll = AT_POLL;
     124             : 
     125             : int wdc_floating_bus(struct channel_softc *, int);
     126             : int wdc_preata_drive(struct channel_softc *, int);
     127             : int wdc_ata_present(struct channel_softc *, int);
     128             : 
     129             : struct cfdriver wdc_cd = {
     130             :         NULL, "wdc", DV_DULL
     131             : };
     132             : 
     133             : struct channel_softc_vtbl wdc_default_vtbl = {
     134             :         wdc_default_read_reg,
     135             :         wdc_default_write_reg,
     136             :         wdc_default_lba48_write_reg,
     137             :         wdc_default_read_raw_multi_2,
     138             :         wdc_default_write_raw_multi_2,
     139             :         wdc_default_read_raw_multi_4,
     140             :         wdc_default_write_raw_multi_4
     141             : };
     142             : 
     143             : #ifdef WDCDEBUG
     144             : static char *wdc_log_buf = NULL;
     145             : static unsigned int wdc_tail = 0;
     146             : static unsigned int wdc_head = 0;
     147             : static unsigned int wdc_log_cap = 16 * 1024;
     148             : static int chp_idx = 1;
     149             : 
     150             : void
     151             : wdc_log(struct channel_softc *chp, enum wdcevent_type type,
     152             :     unsigned int size, char val[])
     153             : {
     154             :         unsigned int request_size;
     155             :         char *ptr;
     156             :         int log_size;
     157             :         unsigned int head = wdc_head;
     158             :         unsigned int tail = wdc_tail;
     159             : 
     160             : #ifdef DIAGNOSTIC
     161             :         if (head < 0 || head > wdc_log_cap ||
     162             :             tail < 0 || tail > wdc_log_cap) {
     163             :                 printf ("wdc_log: head %x wdc_tail %x\n", head,
     164             :                     tail);
     165             :                 return;
     166             :         }
     167             : 
     168             :         if (size > wdc_log_cap / 2) {
     169             :                 printf ("wdc_log: type %d size %x\n", type, size);
     170             :                 return;
     171             :         }
     172             : #endif
     173             : 
     174             :         if (wdc_log_buf == NULL) {
     175             :                 wdc_log_buf = malloc(wdc_log_cap, M_DEVBUF, M_NOWAIT);
     176             :                 if (wdc_log_buf == NULL)
     177             :                         return;
     178             :         }
     179             :         if (chp->ch_log_idx == 0)
     180             :                 chp->ch_log_idx = chp_idx++;
     181             : 
     182             :         request_size = size + 2;
     183             : 
     184             :         /* Check how many bytes are left */
     185             :         log_size = head - tail;
     186             :         if (log_size < 0) log_size += wdc_log_cap;
     187             : 
     188             :         if (log_size + request_size >= wdc_log_cap) {
     189             :                 int nb = 0; 
     190             :                 int rec_size;
     191             : 
     192             :                 while (nb <= (request_size * 2)) {
     193             :                         if (wdc_log_buf[tail] == 0)
     194             :                                 rec_size = 1;
     195             :                         else
     196             :                                 rec_size = (wdc_log_buf[tail + 1] & 0x1f) + 2;
     197             :                         tail = (tail + rec_size) % wdc_log_cap;
     198             :                         nb += rec_size;
     199             :                 }
     200             :         }
     201             : 
     202             :         /* Avoid wrapping in the middle of a request */
     203             :         if (head + request_size >= wdc_log_cap) {
     204             :                 memset(&wdc_log_buf[head], 0, wdc_log_cap - head);
     205             :                 head = 0;
     206             :         }
     207             : 
     208             :         ptr = &wdc_log_buf[head];
     209             :         *ptr++ = type & 0xff;
     210             :         *ptr++ = ((chp->ch_log_idx & 0x7) << 5) | (size & 0x1f);
     211             :         memcpy(ptr, val, size);
     212             : 
     213             :         wdc_head = (head + request_size) % wdc_log_cap;
     214             :         wdc_tail = tail;
     215             : }
     216             : 
     217             : char *wdc_get_log(unsigned int *, unsigned int *);
     218             : 
     219             : char *
     220             : wdc_get_log(unsigned int * size, unsigned int *left)
     221             : {
     222             :         int  log_size;
     223             :         char *retbuf = NULL;
     224             :         int  nb, tocopy;
     225             :         int  s;
     226             :         unsigned int head = wdc_head;
     227             :         unsigned int tail = wdc_tail;
     228             : 
     229             :         s = splbio();
     230             : 
     231             :         log_size = (head - tail);
     232             :         if (left != NULL)
     233             :                 *left = 0;
     234             : 
     235             :         if (log_size < 0)
     236             :                 log_size += wdc_log_cap;
     237             : 
     238             :         tocopy = log_size;
     239             :         if ((u_int)tocopy > *size)
     240             :                 tocopy = *size;
     241             : 
     242             :         if (wdc_log_buf == NULL) {
     243             :                 *size = 0;
     244             :                 *left = 0;
     245             :                 goto out;
     246             :         }
     247             : 
     248             : #ifdef DIAGNOSTIC
     249             :         if (head < 0 || head > wdc_log_cap ||
     250             :             tail < 0 || tail > wdc_log_cap) {
     251             :                 printf ("wdc_log: head %x tail %x\n", head,
     252             :                     tail);
     253             :                 *size = 0;
     254             :                 *left = 0;
     255             :                 goto out;
     256             :         }
     257             : #endif
     258             : 
     259             :         retbuf = malloc(tocopy, M_TEMP, M_NOWAIT);
     260             :         if (retbuf == NULL) {
     261             :                 *size = 0;
     262             :                 *left = log_size;
     263             :                 goto out;
     264             :         }
     265             : 
     266             :         nb = 0;
     267             :         for (;;) {
     268             :                 int rec_size;
     269             : 
     270             :                 if (wdc_log_buf[tail] == 0)
     271             :                         rec_size = 1;
     272             :                 else
     273             :                         rec_size = (wdc_log_buf[tail + 1] & 0x1f) + 2;
     274             : 
     275             :                 if ((nb + rec_size) >= tocopy)
     276             :                         break;
     277             : 
     278             :                 memcpy(&retbuf[nb], &wdc_log_buf[tail], rec_size);
     279             :                 tail = (tail + rec_size) % wdc_log_cap;
     280             :                 nb += rec_size;
     281             :         }
     282             : 
     283             :         wdc_tail = tail;
     284             :         *size = nb;
     285             :         *left = log_size - nb;
     286             : 
     287             :  out:
     288             :         splx(s);
     289             :         return (retbuf);
     290             : }
     291             : #endif /* WDCDEBUG */
     292             : 
     293             : u_int8_t
     294           0 : wdc_default_read_reg(struct channel_softc *chp, enum wdc_regs reg)
     295             : {
     296             : #ifdef DIAGNOSTIC
     297           0 :         if (reg & _WDC_WRONLY) {
     298           0 :                 printf ("wdc_default_read_reg: reading from a write-only register %d\n", reg);
     299           0 :         }
     300             : #endif /* DIAGNOSTIC */
     301             : 
     302           0 :         if (reg & _WDC_AUX)
     303           0 :                 return (bus_space_read_1(chp->ctl_iot, chp->ctl_ioh,
     304             :                     reg & _WDC_REGMASK));
     305             :         else
     306           0 :                 return (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
     307             :                     reg & _WDC_REGMASK));
     308           0 : }
     309             : 
     310             : void
     311           0 : wdc_default_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val)
     312             : {
     313             : #ifdef DIAGNOSTIC
     314           0 :         if (reg & _WDC_RDONLY) {
     315           0 :                 printf ("wdc_default_write_reg: writing to a read-only register %d\n", reg);
     316           0 :         }
     317             : #endif /* DIAGNOSTIC */
     318             : 
     319           0 :         if (reg & _WDC_AUX)
     320           0 :                 bus_space_write_1(chp->ctl_iot, chp->ctl_ioh,
     321             :                     reg & _WDC_REGMASK, val);
     322             :         else
     323           0 :                 bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
     324             :                     reg & _WDC_REGMASK, val);
     325           0 : }
     326             : 
     327             : void
     328           0 : wdc_default_lba48_write_reg(struct channel_softc *chp, enum wdc_regs reg,
     329             :     u_int16_t val)
     330             : {
     331             :         /* All registers are two byte deep FIFOs. */
     332           0 :         CHP_WRITE_REG(chp, reg, val >> 8);
     333           0 :         CHP_WRITE_REG(chp, reg, val);
     334           0 : }
     335             : 
     336             : void
     337           0 : wdc_default_read_raw_multi_2(struct channel_softc *chp, void *data,
     338             :     unsigned int nbytes)
     339             : {
     340           0 :         if (data == NULL) {
     341             :                 unsigned int i;
     342             : 
     343           0 :                 for (i = 0; i < nbytes; i += 2) {
     344           0 :                         bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, 0);
     345             :                 }
     346             : 
     347             :                 return;
     348             :         }
     349             : 
     350           0 :         bus_space_read_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
     351             :             data, nbytes);
     352           0 : }
     353             : 
     354             : 
     355             : void
     356           0 : wdc_default_write_raw_multi_2(struct channel_softc *chp, void *data,
     357             :     unsigned int nbytes)
     358             : {
     359           0 :         if (data == NULL) {
     360             :                 unsigned int i;
     361             : 
     362           0 :                 for (i = 0; i < nbytes; i += 2) {
     363           0 :                         bus_space_write_2(chp->cmd_iot, chp->cmd_ioh, 0, 0);
     364             :                 }
     365             : 
     366             :                 return;
     367             :         }
     368             : 
     369           0 :         bus_space_write_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
     370             :             data, nbytes);
     371           0 : }
     372             : 
     373             : 
     374             : void
     375           0 : wdc_default_write_raw_multi_4(struct channel_softc *chp, void *data,
     376             :     unsigned int nbytes)
     377             : {
     378           0 :         if (data == NULL) {
     379             :                 unsigned int i;
     380             : 
     381           0 :                 for (i = 0; i < nbytes; i += 4) {
     382           0 :                         bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, 0, 0);
     383             :                 }
     384             : 
     385             :                 return;
     386             :         }
     387             : 
     388           0 :         bus_space_write_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
     389             :             data, nbytes);
     390           0 : }
     391             : 
     392             : 
     393             : void
     394           0 : wdc_default_read_raw_multi_4(struct channel_softc *chp, void *data,
     395             :     unsigned int nbytes)
     396             : {
     397           0 :         if (data == NULL) {
     398             :                 unsigned int i;
     399             : 
     400           0 :                 for (i = 0; i < nbytes; i += 4) {
     401           0 :                         bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, 0);
     402             :                 }
     403             : 
     404             :                 return;
     405             :         }
     406             : 
     407           0 :         bus_space_read_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
     408             :             data, nbytes);
     409           0 : }
     410             : 
     411             : int
     412           0 : wdprint(void *aux, const char *pnp)
     413             : {
     414           0 :         struct ata_atapi_attach *aa_link = aux;
     415           0 :         if (pnp)
     416           0 :                 printf("drive at %s", pnp);
     417           0 :         printf(" channel %d drive %d", aa_link->aa_channel,
     418           0 :             aa_link->aa_drv_data->drive);
     419           0 :         return (UNCONF);
     420             : }
     421             : 
     422             : void
     423           0 : wdc_disable_intr(struct channel_softc *chp)
     424             : {
     425           0 :         CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_IDS);
     426           0 : }
     427             : 
     428             : void
     429           0 : wdc_enable_intr(struct channel_softc *chp)
     430             : {
     431           0 :         CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
     432           0 : }
     433             : 
     434             : void
     435           0 : wdc_set_drive(struct channel_softc *chp, int drive)
     436             : {
     437           0 :         CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_IBM);
     438             :         WDC_LOG_SET_DRIVE(chp, drive);
     439           0 : }
     440             : 
     441             : int
     442           0 : wdc_floating_bus(struct channel_softc *chp, int drive)
     443             : {
     444             :         u_int8_t cumulative_status, status;
     445             :         int      iter;
     446             : 
     447           0 :         wdc_set_drive(chp, drive);
     448           0 :         delay(10);
     449             : 
     450             :         /* Stolen from Phoenix BIOS Drive Autotyping document */
     451             :         cumulative_status = 0;
     452           0 :         for (iter = 0; iter < 100; iter++) {
     453           0 :                 CHP_WRITE_REG(chp, wdr_seccnt, 0x7f);
     454           0 :                 delay (1);
     455             : 
     456           0 :                 status = CHP_READ_REG(chp, wdr_status);
     457             : 
     458             :                 /* The other bits are meaningless if BSY is set */
     459           0 :                 if (status & WDCS_BSY)
     460             :                         continue;
     461             : 
     462           0 :                 cumulative_status |= status;
     463             : 
     464             : #define BAD_BIT_COMBO  (WDCS_DRDY | WDCS_DSC | WDCS_DRQ | WDCS_ERR)
     465           0 :                 if ((cumulative_status & BAD_BIT_COMBO) == BAD_BIT_COMBO)
     466           0 :                         return 1;
     467             :         }
     468             : 
     469             : 
     470           0 :         return 0;
     471           0 : }
     472             : 
     473             : int
     474           0 : wdc_preata_drive(struct channel_softc *chp, int drive)
     475             : {
     476           0 :         if (wdc_floating_bus(chp, drive)) {
     477             :                 WDCDEBUG_PRINT(("%s:%d:%d: floating bus detected\n",
     478             :                     chp->wdc->sc_dev.dv_xname,
     479             :                     chp->channel, drive), DEBUG_PROBE);
     480           0 :                 return 0;
     481             :         }
     482             : 
     483           0 :         wdc_set_drive(chp, drive);
     484           0 :         delay(100);
     485           0 :         if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY, 10000) != 0) {
     486             :                 WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
     487             :                     chp->wdc->sc_dev.dv_xname,
     488             :                     chp->channel, drive), DEBUG_PROBE);
     489           0 :                 return 0;
     490             :         }
     491             : 
     492           0 :         CHP_WRITE_REG(chp, wdr_command, WDCC_RECAL);
     493             :         WDC_LOG_ATA_CMDSHORT(chp, WDCC_RECAL);
     494           0 :         if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY, 10000) != 0) {
     495             :                 WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
     496             :                     chp->wdc->sc_dev.dv_xname,
     497             :                     chp->channel, drive), DEBUG_PROBE);
     498           0 :                 return 0;
     499             :         }
     500             : 
     501           0 :         return 1;
     502           0 : }
     503             : 
     504             : int
     505           0 : wdc_ata_present(struct channel_softc *chp, int drive)
     506             : {
     507             :         int time_to_done;
     508             :         int retry_cnt = 0;
     509             : 
     510           0 :         wdc_set_drive(chp, drive);
     511           0 :         delay(10);
     512             : 
     513             : retry:
     514             :         /*
     515             :            You're actually supposed to wait up to 10 seconds
     516             :            for DRDY. However, as a practical matter, most
     517             :            drives assert DRDY very quickly after dropping BSY.
     518             : 
     519             :            The 10 seconds wait is sub-optimal because, according
     520             :            to the ATA standard, the master should reply with 00
     521             :            for any reads to a non-existent slave.
     522             :         */
     523           0 :         time_to_done = wdc_wait_for_status(chp,
     524             :             (WDCS_DRDY | WDCS_DSC | WDCS_DRQ),
     525             :             (WDCS_DRDY | WDCS_DSC), 1000);
     526           0 :         if (time_to_done == -1) {
     527           0 :                 if (retry_cnt == 0 && chp->ch_status == 0x00) {
     528             :                         /* At least one flash card needs to be kicked */
     529           0 :                         wdccommandshort(chp, drive, WDCC_CHECK_PWR);
     530           0 :                         retry_cnt++;
     531           0 :                         goto retry;
     532             :                 }
     533             :                 WDCDEBUG_PRINT(("%s:%d:%d: DRDY test timed out with status"
     534             :                     " %02x\n",
     535             :                     chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
     536             :                     chp->channel, drive, chp->ch_status),
     537             :                     DEBUG_PROBE);
     538           0 :                 return 0;
     539             :         }
     540             : 
     541           0 :         if ((chp->ch_status & 0xfc) != (WDCS_DRDY | WDCS_DSC)) {
     542             :                 WDCDEBUG_PRINT(("%s:%d:%d: status test for 0x50 failed with"
     543             :                     " %02x\n",
     544             :                     chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
     545             :                     chp->channel, drive, chp->ch_status),
     546             :                     DEBUG_PROBE);
     547             : 
     548           0 :                 return 0;
     549             :         }
     550             : 
     551             :         WDCDEBUG_PRINT(("%s:%d:%d: waiting for ready %d msec\n",
     552             :             chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
     553             :             chp->channel, drive, time_to_done), DEBUG_PROBE);
     554             : 
     555             :         /*
     556             :          * Test register writability
     557             :          */
     558           0 :         CHP_WRITE_REG(chp, wdr_cyl_lo, 0xaa);
     559           0 :         CHP_WRITE_REG(chp, wdr_cyl_hi, 0x55);
     560           0 :         CHP_WRITE_REG(chp, wdr_seccnt, 0xff);
     561           0 :         DELAY(10);
     562             : 
     563           0 :         if (CHP_READ_REG(chp, wdr_cyl_lo) != 0xaa &&
     564           0 :             CHP_READ_REG(chp, wdr_cyl_hi) != 0x55) {
     565             :                 WDCDEBUG_PRINT(("%s:%d:%d: register writability failed\n",
     566             :                     chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
     567             :                     chp->channel, drive), DEBUG_PROBE);
     568           0 :                 return 0;
     569             :         }
     570             : 
     571           0 :         return 1;
     572           0 : }
     573             : 
     574             : 
     575             : /*
     576             :  * Test to see controller with at least one attached drive is there.
     577             :  * Returns a bit for each possible drive found (0x01 for drive 0,
     578             :  * 0x02 for drive 1).
     579             :  * Logic:
     580             :  * - If a status register is at 0x7f or 0xff, assume there is no drive here
     581             :  *   (ISA has pull-up resistors).  Similarly if the status register has
     582             :  *   the value we last wrote to the bus (for IDE interfaces without pullups).
     583             :  *   If no drive at all -> return.
     584             :  * - reset the controller, wait for it to complete (may take up to 31s !).
     585             :  *   If timeout -> return.
     586             :  * - test ATA/ATAPI signatures. If at last one drive found -> return.
     587             :  * - try an ATA command on the master.
     588             :  */
     589             : 
     590             : int
     591           0 : wdcprobe(struct channel_softc *chp)
     592             : {
     593             :         u_int8_t st0, st1, sc, sn, cl, ch;
     594             :         u_int8_t ret_value = 0x03;
     595             :         u_int8_t drive;
     596             : #ifdef WDCDEBUG
     597             :         int savedmask = wdcdebug_mask;
     598             : #endif
     599             : 
     600           0 :         if (chp->_vtbl == 0) {
     601           0 :                 int s = splbio();
     602           0 :                 chp->_vtbl = &wdc_default_vtbl;
     603           0 :                 splx(s);
     604           0 :         }
     605             : 
     606             : #ifdef WDCDEBUG
     607             :         if ((chp->ch_flags & WDCF_VERBOSE_PROBE) ||
     608             :             (chp->wdc &&
     609             :             (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)))
     610             :                 wdcdebug_mask |= DEBUG_PROBE;
     611             : #endif /* WDCDEBUG */
     612             : 
     613           0 :         if (chp->wdc == NULL ||
     614           0 :             (chp->wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
     615             :                 /* Sample the statuses of drive 0 and 1 into st0 and st1 */
     616           0 :                 wdc_set_drive(chp, 0);
     617           0 :                 delay(10);
     618           0 :                 st0 = CHP_READ_REG(chp, wdr_status);
     619             :                 WDC_LOG_STATUS(chp, st0);
     620           0 :                 wdc_set_drive(chp, 1);
     621           0 :                 delay(10);
     622           0 :                 st1 = CHP_READ_REG(chp, wdr_status);
     623             :                 WDC_LOG_STATUS(chp, st1);
     624             : 
     625             :                 WDCDEBUG_PRINT(("%s:%d: before reset, st0=0x%b, st1=0x%b\n",
     626             :                     chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
     627             :                     chp->channel, st0, WDCS_BITS, st1, WDCS_BITS),
     628             :                     DEBUG_PROBE);
     629             : 
     630           0 :                 if (st0 == 0xff || st0 == WDSD_IBM)
     631           0 :                         ret_value &= ~0x01;
     632           0 :                 if (st1 == 0xff || st1 == (WDSD_IBM | 0x10))
     633           0 :                         ret_value &= ~0x02;
     634           0 :                 if (ret_value == 0)
     635           0 :                         return 0;
     636             :         }
     637             : 
     638             :         /* reset the channel */
     639           0 :         wdc_do_reset(chp);
     640             : 
     641           0 :         ret_value = __wdcwait_reset(chp, ret_value);
     642             :         WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
     643             :             chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
     644             :             ret_value), DEBUG_PROBE);
     645             : 
     646           0 :         if (ret_value == 0)
     647           0 :                 return 0;
     648             : 
     649           0 :         if (chp->wdc && (chp->wdc->quirks & WDC_QUIRK_NOATAPI))
     650             :                 goto noatapi;
     651             : 
     652             :         /*
     653             :          * Use signatures to find potential ATAPI drives
     654             :          */
     655           0 :         for (drive = 0; drive < 2; drive++) {
     656           0 :                 if ((ret_value & (0x01 << drive)) == 0)
     657             :                         continue;
     658           0 :                 wdc_set_drive(chp, drive);
     659           0 :                 delay(10);
     660             :                 /* Save registers contents */
     661           0 :                 st0 = CHP_READ_REG(chp, wdr_status);
     662           0 :                 sc = CHP_READ_REG(chp, wdr_seccnt);
     663           0 :                 sn = CHP_READ_REG(chp, wdr_sector);
     664           0 :                 cl = CHP_READ_REG(chp, wdr_cyl_lo);
     665           0 :                 ch = CHP_READ_REG(chp, wdr_cyl_hi);
     666             :                 WDC_LOG_REG(chp, wdr_cyl_lo, (ch << 8) | cl);
     667             : 
     668             :                 WDCDEBUG_PRINT(("%s:%d:%d: after reset, st=0x%b, sc=0x%x"
     669             :                     " sn=0x%x cl=0x%x ch=0x%x\n",
     670             :                     chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
     671             :                     chp->channel, drive, st0, WDCS_BITS, sc, sn, cl, ch),
     672             :                     DEBUG_PROBE);
     673             :                 /*
     674             :                  * This is a simplification of the test in the ATAPI
     675             :                  * spec since not all drives seem to set the other regs
     676             :                  * correctly.
     677             :                  */
     678           0 :                 if (cl == 0x14 && ch == 0xeb)
     679           0 :                         chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
     680             :         }
     681             : 
     682             : noatapi:
     683           0 :         if (chp->wdc && (chp->wdc->quirks & WDC_QUIRK_NOATA))
     684             :                 goto noata;
     685             : 
     686             :         /*
     687             :          * Detect ATA drives by poking around the registers
     688             :          */
     689           0 :         for (drive = 0; drive < 2; drive++) {
     690           0 :                 if ((ret_value & (0x01 << drive)) == 0)
     691             :                         continue;
     692           0 :                 if (chp->ch_drive[drive].drive_flags & DRIVE_ATAPI)
     693             :                         continue;
     694             : 
     695           0 :                 wdc_disable_intr(chp);
     696             :                 /* ATA detect */
     697           0 :                 if (wdc_ata_present(chp, drive)) {
     698           0 :                         chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
     699           0 :                         if (chp->wdc == NULL ||
     700           0 :                             (chp->wdc->cap & WDC_CAPABILITY_PREATA) != 0)
     701           0 :                                 chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
     702             :                 } else {
     703           0 :                         ret_value &= ~(1 << drive);
     704             :                 }
     705           0 :                 wdc_enable_intr(chp);
     706           0 :         }
     707             : 
     708             : noata:
     709             : 
     710             : #ifdef WDCDEBUG
     711             :         wdcdebug_mask = savedmask;
     712             : #endif
     713           0 :         return (ret_value);
     714           0 : }
     715             : 
     716             : struct channel_queue *
     717           0 : wdc_alloc_queue(void)
     718             : {
     719             :         static int inited = 0;
     720             :         struct channel_queue *queue;
     721             : 
     722             :         /* Initialize global data. */
     723           0 :         if (inited == 0) {
     724             :                 /* Initialize the wdc_xfer pool. */
     725           0 :                 pool_init(&wdc_xfer_pool, sizeof(struct wdc_xfer), 0, IPL_BIO,
     726             :                     0, "wdcxfer", NULL);
     727           0 :                 scsi_iopool_init(&wdc_xfer_iopool, NULL,
     728             :                     wdc_xfer_get, wdc_xfer_put);
     729           0 :                 inited = 1;
     730           0 :         }
     731             : 
     732           0 :         queue = malloc(sizeof(*queue), M_DEVBUF, M_NOWAIT);
     733           0 :         if (queue != NULL) {
     734           0 :                 TAILQ_INIT(&queue->sc_xfer);
     735           0 :         }
     736           0 :         return (queue);
     737             : }
     738             : 
     739             : void
     740           0 : wdc_free_queue(struct channel_queue *queue)
     741             : {
     742           0 :         free(queue, M_DEVBUF, sizeof(*queue));
     743           0 : }
     744             : 
     745             : void
     746           0 : wdcattach(struct channel_softc *chp)
     747             : {
     748             :         int i;
     749           0 :         struct ata_atapi_attach aa_link;
     750             : #ifdef WDCDEBUG
     751             :         int    savedmask = wdcdebug_mask;
     752             : #endif
     753             : 
     754           0 :         if (!cold)
     755           0 :                 at_poll = AT_WAIT;
     756             : 
     757           0 :         if (chp->wdc->reset == NULL)
     758           0 :                 chp->wdc->reset = wdc_do_reset;
     759             : 
     760           0 :         timeout_set(&chp->ch_timo, wdctimeout, chp);
     761             : 
     762           0 :         if (!chp->_vtbl)
     763           0 :                 chp->_vtbl = &wdc_default_vtbl;
     764             : 
     765           0 :         for (i = 0; i < 2; i++) {
     766           0 :                 chp->ch_drive[i].chnl_softc = chp;
     767           0 :                 chp->ch_drive[i].drive = i;
     768             :         }
     769             : 
     770           0 :         if (chp->wdc->drv_probe != NULL) {
     771           0 :                 chp->wdc->drv_probe(chp);
     772           0 :         } else {
     773           0 :                 if (wdcprobe(chp) == 0)
     774             :                         /* If no drives, abort attach here. */
     775           0 :                         return;
     776             :         }
     777             : 
     778             :         /* ATAPI drives need settling time. Give them 250ms */
     779           0 :         if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
     780           0 :             (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
     781           0 :                 delay(250 * 1000);
     782           0 :         }
     783             : 
     784             : #ifdef WDCDEBUG
     785             :         if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
     786             :                 wdcdebug_mask |= DEBUG_PROBE;
     787             : 
     788             :         if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
     789             :             (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
     790             :                 wdcdebug_mask = DEBUG_PROBE;
     791             :         }
     792             : #endif /* WDCDEBUG */
     793             : 
     794           0 :         for (i = 0; i < 2; i++) {
     795           0 :                 struct ata_drive_datas *drvp = &chp->ch_drive[i];
     796             : 
     797             :                 /* If controller can't do 16bit flag the drives as 32bit */
     798           0 :                 if ((chp->wdc->cap &
     799           0 :                     (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
     800             :                     WDC_CAPABILITY_DATA32)
     801           0 :                         drvp->drive_flags |= DRIVE_CAP32;
     802             : 
     803           0 :                 if ((drvp->drive_flags & DRIVE) == 0)
     804           0 :                         continue;
     805             : 
     806           0 :                 if (i == 1 && ((chp->ch_drive[0].drive_flags & DRIVE) == 0))
     807           0 :                         chp->ch_flags |= WDCF_ONESLAVE;
     808             :                 /*
     809             :                  * Wait a bit, some devices are weird just after a reset.
     810             :                  * Then issue a IDENTIFY command, to try to detect slave ghost.
     811             :                  */
     812           0 :                 delay(5000);
     813           0 :                 if (ata_get_params(&chp->ch_drive[i], at_poll, &drvp->id) ==
     814             :                     CMD_OK) {
     815             :                         /* If IDENTIFY succeeded, this is not an OLD ctrl */
     816           0 :                         drvp->drive_flags &= ~DRIVE_OLD;
     817           0 :                 } else {
     818           0 :                         bzero(&drvp->id, sizeof(struct ataparams));
     819           0 :                         drvp->drive_flags &=
     820             :                             ~(DRIVE_ATA | DRIVE_ATAPI);
     821             :                         WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed\n",
     822             :                             chp->wdc->sc_dev.dv_xname,
     823             :                             chp->channel, i), DEBUG_PROBE);
     824             : 
     825           0 :                         if ((drvp->drive_flags & DRIVE_OLD) &&
     826           0 :                             !wdc_preata_drive(chp, i))
     827           0 :                                 drvp->drive_flags &= ~DRIVE_OLD;
     828             :                 }
     829           0 :         }
     830             : 
     831             :         WDCDEBUG_PRINT(("wdcattach: ch_drive_flags 0x%x 0x%x\n",
     832             :             chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
     833             :             DEBUG_PROBE);
     834             : 
     835             :         /* If no drives, abort here */
     836           0 :         if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
     837           0 :             (chp->ch_drive[1].drive_flags & DRIVE) == 0)
     838             :                 goto exit;
     839             : 
     840           0 :         for (i = 0; i < 2; i++) {
     841           0 :                 if ((chp->ch_drive[i].drive_flags & DRIVE) == 0) {
     842             :                         continue;
     843             :                 }
     844           0 :                 bzero(&aa_link, sizeof(struct ata_atapi_attach));
     845           0 :                 if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI)
     846           0 :                         aa_link.aa_type = T_ATAPI;
     847             :                 else
     848           0 :                         aa_link.aa_type = T_ATA;
     849           0 :                 aa_link.aa_channel = chp->channel;
     850           0 :                 aa_link.aa_openings = 1;
     851           0 :                 aa_link.aa_drv_data = &chp->ch_drive[i];
     852           0 :                 config_found(&chp->wdc->sc_dev, (void *)&aa_link, wdprint);
     853           0 :         }
     854             : 
     855             :         /*
     856             :          * reset drive_flags for unattached devices, reset state for attached
     857             :          *  ones
     858             :          */
     859           0 :         for (i = 0; i < 2; i++) {
     860           0 :                 if (chp->ch_drive[i].drive_name[0] == 0)
     861           0 :                         chp->ch_drive[i].drive_flags = 0;
     862             :         }
     863             : 
     864             : exit:
     865             : #ifdef WDCDEBUG
     866             :         wdcdebug_mask = savedmask;
     867             : #endif
     868           0 :         return; /* for the ``exit'' label above */
     869           0 : }
     870             : 
     871             : /*
     872             :  * Start I/O on a controller, for the given channel.
     873             :  * The first xfer may be not for our channel if the channel queues
     874             :  * are shared.
     875             :  */
     876             : void
     877           0 : wdcstart(struct channel_softc *chp)
     878             : {
     879             :         struct wdc_xfer *xfer;
     880             : 
     881           0 :         splassert(IPL_BIO);
     882             : 
     883             :         /* is there a xfer ? */
     884           0 :         if ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) == NULL) {
     885           0 :                 return;
     886             :         }
     887             : 
     888             :         /* adjust chp, in case we have a shared queue */
     889           0 :         chp = xfer->chp;
     890             : 
     891           0 :         if ((chp->ch_flags & WDCF_ACTIVE) != 0 ) {
     892           0 :                 return; /* channel already active */
     893             :         }
     894             : #ifdef DIAGNOSTIC
     895           0 :         if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0)
     896           0 :                 panic("wdcstart: channel waiting for irq");
     897             : #endif /* DIAGNOSTIC */
     898             : 
     899             :         WDCDEBUG_PRINT(("wdcstart: xfer %p channel %d drive %d\n", xfer,
     900             :             chp->channel, xfer->drive), DEBUG_XFERS);
     901           0 :         chp->ch_flags |= WDCF_ACTIVE;
     902           0 :         if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_RESET) {
     903           0 :                 chp->ch_drive[xfer->drive].drive_flags &= ~DRIVE_RESET;
     904           0 :                 chp->ch_drive[xfer->drive].state = 0;
     905           0 :         }
     906           0 :         xfer->c_start(chp, xfer);
     907           0 : }
     908             : 
     909             : int
     910           0 : wdcdetach(struct channel_softc *chp, int flags)
     911             : {
     912             :         int s, rv;
     913             : 
     914           0 :         s = splbio();
     915           0 :         chp->dying = 1;
     916             : 
     917           0 :         wdc_kill_pending(chp);
     918           0 :         timeout_del(&chp->ch_timo);
     919             : 
     920           0 :         rv = config_detach_children((struct device *)chp->wdc, flags);
     921           0 :         splx(s);
     922             : 
     923           0 :         return (rv);
     924             : }
     925             : 
     926             : /*
     927             :  * Interrupt routine for the controller.  Acknowledge the interrupt, check for
     928             :  * errors on the current operation, mark it done if necessary, and start the
     929             :  * next request.  Also check for a partially done transfer, and continue with
     930             :  * the next chunk if so.
     931             :  */
     932             : int
     933           0 : wdcintr(void *arg)
     934             : {
     935           0 :         struct channel_softc *chp = arg;
     936             :         struct wdc_xfer *xfer;
     937             :         u_int8_t st = 0;
     938             :         int ret = 0;
     939             : 
     940           0 :         if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
     941             :                 /* Acknowledge interrupt by reading status */
     942           0 :                 if (chp->_vtbl == 0)
     943           0 :                         st = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
     944             :                             wdr_status & _WDC_REGMASK);
     945             :                 else
     946           0 :                         st = CHP_READ_REG(chp, wdr_status);
     947           0 :                 if (st == 0xff)
     948           0 :                         return (-1);
     949             : 
     950             :                 WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
     951           0 :                 return ret;
     952             :         }
     953             : 
     954             :         WDCDEBUG_PRINT(("wdcintr\n"), DEBUG_INTR);
     955           0 :         xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
     956           0 :         if (chp->ch_flags & WDCF_DMA_WAIT) {
     957           0 :                 chp->wdc->dma_status =
     958           0 :                     (*chp->wdc->dma_finish)(chp->wdc->dma_arg, chp->channel,
     959           0 :                     xfer->drive, 0);
     960           0 :                 if (chp->wdc->dma_status == 0xff)
     961           0 :                         return (-1);
     962           0 :                 if (chp->wdc->dma_status & WDC_DMAST_NOIRQ) {
     963             :                         /* IRQ not for us, not detected by DMA engine */
     964           0 :                         return 0;
     965             :                 }
     966           0 :                 chp->ch_flags &= ~WDCF_DMA_WAIT;
     967           0 :         }
     968             :                 
     969           0 :         chp->ch_flags &= ~WDCF_IRQ_WAIT;
     970           0 :         ret = xfer->c_intr(chp, xfer, 1);
     971           0 :         if (ret == 0)   /* irq was not for us, still waiting for irq */
     972           0 :                 chp->ch_flags |= WDCF_IRQ_WAIT;
     973           0 :         return (ret);
     974           0 : }
     975             : 
     976             : /* Put all disk in RESET state */
     977             : void
     978           0 : wdc_reset_channel(struct ata_drive_datas *drvp, int nowait)
     979             : {
     980           0 :         struct channel_softc *chp = drvp->chnl_softc;
     981             :         int drive;
     982             : 
     983             :         WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",
     984             :             chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
     985             :             DEBUG_FUNCS);
     986           0 :         (void) wdcreset(chp, nowait ? NOWAIT : VERBOSE);
     987           0 :         for (drive = 0; drive < 2; drive++) {
     988           0 :                 chp->ch_drive[drive].state = 0;
     989             :         }
     990           0 : }
     991             : 
     992             : int
     993           0 : wdcreset(struct channel_softc *chp, int flags)
     994             : {
     995             :         int drv_mask1, drv_mask2;
     996             : 
     997           0 :         if (!chp->_vtbl)
     998           0 :                 chp->_vtbl = &wdc_default_vtbl;
     999             : 
    1000           0 :         chp->wdc->reset(chp);
    1001             : 
    1002           0 :         if (flags & NOWAIT)
    1003           0 :                 return 0;
    1004             : 
    1005           0 :         drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00;
    1006           0 :         drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
    1007           0 :         drv_mask2 = __wdcwait_reset(chp, drv_mask1);
    1008             : 
    1009           0 :         if ((flags & VERBOSE) && drv_mask2 != drv_mask1) {
    1010           0 :                 printf("%s channel %d: reset failed for",
    1011           0 :                     chp->wdc->sc_dev.dv_xname, chp->channel);
    1012           0 :                 if ((drv_mask1 & 0x01) != 0 && (drv_mask2 & 0x01) == 0)
    1013           0 :                         printf(" drive 0");
    1014           0 :                 if ((drv_mask1 & 0x02) != 0 && (drv_mask2 & 0x02) == 0)
    1015           0 :                         printf(" drive 1");
    1016           0 :                 printf("\n");
    1017           0 :         }
    1018             : 
    1019           0 :         return (drv_mask1 != drv_mask2) ? 1 : 0;
    1020           0 : }
    1021             : 
    1022             : void
    1023           0 : wdc_do_reset(struct channel_softc *chp)
    1024             : {
    1025           0 :         wdc_set_drive(chp, 0);
    1026           0 :         DELAY(10);
    1027           0 :         CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT | WDCTL_RST);
    1028           0 :         delay(10000);
    1029           0 :         CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
    1030           0 :         delay(10000);
    1031           0 : }
    1032             : 
    1033             : int
    1034           0 : __wdcwait_reset(struct channel_softc *chp, int drv_mask)
    1035             : {
    1036             :         int timeout;
    1037             :         u_int8_t st0, er0, st1, er1;
    1038             : 
    1039             :         /* wait for BSY to deassert */
    1040           0 :         for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) {
    1041           0 :                 wdc_set_drive(chp, 0);
    1042           0 :                 delay(10);
    1043           0 :                 st0 = CHP_READ_REG(chp, wdr_status);
    1044           0 :                 er0 = CHP_READ_REG(chp, wdr_error);
    1045           0 :                 wdc_set_drive(chp, 1);
    1046           0 :                 delay(10);
    1047           0 :                 st1 = CHP_READ_REG(chp, wdr_status);
    1048           0 :                 er1 = CHP_READ_REG(chp, wdr_error);
    1049             : 
    1050           0 :                 if ((drv_mask & 0x01) == 0) {
    1051             :                         /* no master */
    1052           0 :                         if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
    1053             :                                 /* No master, slave is ready, it's done */
    1054             :                                 goto end;
    1055             :                         }
    1056           0 :                 } else if ((drv_mask & 0x02) == 0) {
    1057             :                         /* no slave */
    1058           0 :                         if ((drv_mask & 0x01) != 0 && (st0 & WDCS_BSY) == 0) {
    1059             :                                 /* No slave, master is ready, it's done */
    1060             :                                 goto end;
    1061             :                         }
    1062             :                 } else {
    1063             :                         /* Wait for both master and slave to be ready */
    1064           0 :                         if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
    1065             :                                 goto end;
    1066             :                         }
    1067             :                 }
    1068           0 :                 delay(WDCDELAY);
    1069             :         }
    1070             :         /* Reset timed out. Maybe it's because drv_mask was not right */
    1071           0 :         if (st0 & WDCS_BSY)
    1072           0 :                 drv_mask &= ~0x01;
    1073           0 :         if (st1 & WDCS_BSY)
    1074           0 :                 drv_mask &= ~0x02;
    1075             : end:
    1076             :         WDCDEBUG_PRINT(("%s:%d: wdcwait_reset() end, st0=0x%b, er0=0x%x, "
    1077             :             "st1=0x%b, er1=0x%x, reset time=%d msec\n",
    1078             :             chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
    1079             :             st0, WDCS_BITS, er0, st1, WDCS_BITS, er1,
    1080             :             timeout * WDCDELAY / 1000), DEBUG_PROBE);
    1081             : 
    1082           0 :         return drv_mask;
    1083             : }
    1084             : 
    1085             : /*
    1086             :  * Wait for a drive to be !BSY, and have mask in its status register.
    1087             :  * return -1 for a timeout after "timeout" ms.
    1088             :  */
    1089             : int
    1090           0 : wdc_wait_for_status(struct channel_softc *chp, int mask, int bits, int timeout)
    1091             : {
    1092             :         u_char status;
    1093             :         int time = 0;
    1094             : 
    1095             :         WDCDEBUG_PRINT(("wdcwait %s:%d\n", chp->wdc ?chp->wdc->sc_dev.dv_xname
    1096             :             :"none", chp->channel), DEBUG_STATUS);
    1097           0 :         chp->ch_error = 0;
    1098             : 
    1099           0 :         timeout = timeout * 1000 / WDCDELAY; /* delay uses microseconds */
    1100             : 
    1101           0 :         for (;;) {
    1102           0 :                 chp->ch_status = status = CHP_READ_REG(chp, wdr_status);
    1103             :                 WDC_LOG_STATUS(chp, chp->ch_status);
    1104             : 
    1105           0 :                 if (status == 0xff) {
    1106           0 :                         if ((chp->ch_flags & WDCF_ONESLAVE)) {
    1107           0 :                                 wdc_set_drive(chp, 1);
    1108           0 :                                 chp->ch_status = status =
    1109           0 :                                     CHP_READ_REG(chp, wdr_status);
    1110             :                                 WDC_LOG_STATUS(chp, chp->ch_status);
    1111           0 :                         }
    1112             :                 }
    1113           0 :                 if ((status & WDCS_BSY) == 0 && (status & mask) == bits)
    1114             :                         break;
    1115           0 :                 if (++time > timeout) {
    1116             :                         WDCDEBUG_PRINT(("wdcwait: timeout, status 0x%b "
    1117             :                             "error 0x%x\n", status, WDCS_BITS,
    1118             :                             CHP_READ_REG(chp, wdr_error)),
    1119             :                             DEBUG_STATUSX | DEBUG_STATUS);
    1120           0 :                         return -1;
    1121             :                 }
    1122           0 :                 delay(WDCDELAY);
    1123             :         }
    1124           0 :         if (status & WDCS_ERR) {
    1125           0 :                 chp->ch_error = CHP_READ_REG(chp, wdr_error);
    1126             :                 WDC_LOG_ERROR(chp, chp->ch_error);
    1127             : 
    1128             :                 WDCDEBUG_PRINT(("wdcwait: error %x\n", chp->ch_error),
    1129             :                                DEBUG_STATUSX | DEBUG_STATUS);
    1130           0 :         }
    1131             : 
    1132             : #ifdef WDCNDELAY_DEBUG
    1133             :         /* After autoconfig, there should be no long delays. */
    1134             :         if (!cold && time > WDCNDELAY_DEBUG) {
    1135             :                 struct wdc_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
    1136             :                 if (xfer == NULL)
    1137             :                         printf("%s channel %d: warning: busy-wait took %dus\n",
    1138             :                             chp->wdc->sc_dev.dv_xname, chp->channel,
    1139             :                             WDCDELAY * time);
    1140             :                 else
    1141             :                         printf("%s:%d:%d: warning: busy-wait took %dus\n",
    1142             :                             chp->wdc->sc_dev.dv_xname, chp->channel,
    1143             :                             xfer->drive,
    1144             :                             WDCDELAY * time);
    1145             :         }
    1146             : #endif /* WDCNDELAY_DEBUG */
    1147           0 :         return time;
    1148           0 : }
    1149             : 
    1150             : /*
    1151             :  * Busy-wait for DMA to complete
    1152             :  */
    1153             : int
    1154           0 : wdc_dmawait(struct channel_softc *chp, struct wdc_xfer *xfer, int timeout)
    1155             : {
    1156             :         int time;
    1157           0 :         for (time = 0; time < timeout * 1000 / WDCDELAY; time++) {
    1158           0 :                 chp->wdc->dma_status =
    1159           0 :                     (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
    1160             :                     chp->channel, xfer->drive, 0);
    1161           0 :                 if ((chp->wdc->dma_status & WDC_DMAST_NOIRQ) == 0)
    1162           0 :                         return 0;
    1163           0 :                 if (chp->wdc->dma_status == 0xff) {
    1164           0 :                         chp->dying = 1;
    1165           0 :                         return -1;
    1166             :                 }
    1167           0 :                 delay(WDCDELAY);
    1168             :         }
    1169             :         /* timeout, force a DMA halt */
    1170           0 :         chp->wdc->dma_status = (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
    1171             :             chp->channel, xfer->drive, 1);
    1172           0 :         return 1;
    1173           0 : }
    1174             : 
    1175             : void
    1176           0 : wdctimeout(void *arg)
    1177             : {
    1178           0 :         struct channel_softc *chp = (struct channel_softc *)arg;
    1179             :         struct wdc_xfer *xfer;
    1180             :         int s;
    1181             : 
    1182             :         WDCDEBUG_PRINT(("wdctimeout\n"), DEBUG_FUNCS);
    1183             : 
    1184           0 :         s = splbio();
    1185           0 :         xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
    1186             : 
    1187             :         /* Did we lose a race with the interrupt? */
    1188           0 :         if (xfer == NULL ||
    1189           0 :             !timeout_triggered(&chp->ch_timo)) {
    1190           0 :                 splx(s);
    1191           0 :                 return;
    1192             :         }
    1193           0 :         if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0) {
    1194           0 :                 __wdcerror(chp, "timeout");
    1195           0 :                 printf("\ttype: %s\n", (xfer->c_flags & C_ATAPI) ?
    1196             :                     "atapi":"ata");
    1197           0 :                 printf("\tc_bcount: %d\n", xfer->c_bcount);
    1198           0 :                 printf("\tc_skip: %d\n", xfer->c_skip);
    1199           0 :                 if (chp->ch_flags & WDCF_DMA_WAIT) {
    1200           0 :                         chp->wdc->dma_status =
    1201           0 :                             (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
    1202           0 :                             chp->channel, xfer->drive, 1);
    1203           0 :                         chp->ch_flags &= ~WDCF_DMA_WAIT;
    1204           0 :                 }
    1205             :                 /*
    1206             :                  * Call the interrupt routine. If we just missed and interrupt,
    1207             :                  * it will do what's needed. Else, it will take the needed
    1208             :                  * action (reset the device).
    1209             :                  */
    1210           0 :                 xfer->c_flags |= C_TIMEOU;
    1211           0 :                 chp->ch_flags &= ~WDCF_IRQ_WAIT;
    1212           0 :                 xfer->c_intr(chp, xfer, 1);
    1213           0 :         } else
    1214           0 :                 __wdcerror(chp, "missing untimeout");
    1215           0 :         splx(s);
    1216           0 : }
    1217             : 
    1218             : /*
    1219             :  * Probe drive's capabilities, for use by the controller later.
    1220             :  * Assumes drvp points to an existing drive.
    1221             :  * XXX this should be a controller-indep function
    1222             :  */
    1223             : void
    1224           0 : wdc_probe_caps(struct ata_drive_datas *drvp, struct ataparams *params)
    1225             : {
    1226           0 :         struct channel_softc *chp = drvp->chnl_softc;
    1227           0 :         struct wdc_softc *wdc = chp->wdc;
    1228             :         int i, valid_mode_found;
    1229           0 :         int cf_flags = drvp->cf_flags;
    1230             : 
    1231           0 :         if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
    1232             :             (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
    1233           0 :                 struct ataparams params2;
    1234             : 
    1235             :                 /*
    1236             :                  * Controller claims 16 and 32 bit transfers.
    1237             :                  * Re-do an IDENTIFY with 32-bit transfers,
    1238             :                  * and compare results.
    1239             :                  */
    1240           0 :                 drvp->drive_flags |= DRIVE_CAP32;
    1241           0 :                 ata_get_params(drvp, at_poll, &params2);
    1242           0 :                 if (bcmp(params, &params2, sizeof(struct ataparams)) != 0) {
    1243             :                         /* Not good. fall back to 16bits */
    1244           0 :                         drvp->drive_flags &= ~DRIVE_CAP32;
    1245           0 :                 }
    1246           0 :         }
    1247             : #if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
    1248             :         if (params->atap_ata_major > 0x01 &&
    1249             :             params->atap_ata_major != 0xffff) {
    1250             :                 for (i = 14; i > 0; i--) {
    1251             :                         if (params->atap_ata_major & (1 << i)) {
    1252             :                                 printf("%sATA version %d\n", sep, i);
    1253             :                                 drvp->ata_vers = i;
    1254             :                                 break;
    1255             :                         }
    1256             :                 }
    1257             :         } else
    1258             : #endif /* 0 */
    1259             :         /* Use PIO mode 3 as a default value for ATAPI devices */
    1260           0 :         if (drvp->drive_flags & DRIVE_ATAPI)
    1261           0 :                 drvp->PIO_mode = 3;
    1262             : 
    1263             :         WDCDEBUG_PRINT(("wdc_probe_caps: wdc_cap 0x%x cf_flags 0x%x\n",
    1264             :             wdc->cap, cf_flags), DEBUG_PROBE);
    1265             : 
    1266             :         valid_mode_found = 0;
    1267             : 
    1268             :         WDCDEBUG_PRINT(("%s: atap_oldpiotiming=%d\n", __func__,
    1269             :             params->atap_oldpiotiming), DEBUG_PROBE);
    1270             :         /*
    1271             :          * ATA-4 compliant devices contain PIO mode
    1272             :          * number in atap_oldpiotiming.
    1273             :          */
    1274           0 :         if (params->atap_oldpiotiming <= 2) {
    1275           0 :                 drvp->PIO_cap = params->atap_oldpiotiming;
    1276             :                 valid_mode_found = 1;
    1277           0 :                 drvp->drive_flags |= DRIVE_MODE;
    1278           0 :         } else if (params->atap_oldpiotiming > 180) {
    1279             :                 /*
    1280             :                  * ATA-2 compliant devices contain cycle
    1281             :                  * time in atap_oldpiotiming.
    1282             :                  * A device with a cycle time of 180ns
    1283             :                  * or less is at least PIO mode 3 and
    1284             :                  * should be reporting that in
    1285             :                  * atap_piomode_supp, so ignore it here.
    1286             :                  */
    1287           0 :                 if (params->atap_oldpiotiming <= 240) {
    1288           0 :                         drvp->PIO_cap = 2;
    1289           0 :                 } else {
    1290           0 :                         drvp->PIO_cap = 1;
    1291             :                 }
    1292             :                 valid_mode_found = 1;
    1293           0 :                 drvp->drive_flags |= DRIVE_MODE;
    1294           0 :         }
    1295           0 :         if (valid_mode_found)
    1296           0 :                 drvp->PIO_mode = drvp->PIO_cap;
    1297             : 
    1298             :         WDCDEBUG_PRINT(("%s: atap_extensions=0x%x, atap_piomode_supp=0x%x, "
    1299             :             "atap_dmamode_supp=0x%x, atap_udmamode_supp=0x%x\n",
    1300             :             __func__, params->atap_extensions, params->atap_piomode_supp,
    1301             :             params->atap_dmamode_supp, params->atap_udmamode_supp),
    1302             :             DEBUG_PROBE);
    1303             : 
    1304             :         /*
    1305             :          * It's not in the specs, but it seems that some drive
    1306             :          * returns 0xffff in atap_extensions when this field is invalid
    1307             :          */
    1308           0 :         if (params->atap_extensions != 0xffff &&
    1309           0 :             (params->atap_extensions & WDC_EXT_MODES)) {
    1310             :                 /*
    1311             :                  * XXX some drives report something wrong here (they claim to
    1312             :                  * support PIO mode 8 !). As mode is coded on 3 bits in
    1313             :                  * SET FEATURE, limit it to 7 (so limit i to 4).
    1314             :                  * If higher mode than 7 is found, abort.
    1315             :                  */
    1316           0 :                 for (i = 7; i >= 0; i--) {
    1317           0 :                         if ((params->atap_piomode_supp & (1 << i)) == 0)
    1318             :                                 continue;
    1319           0 :                         if (i > 4)
    1320           0 :                                 return;
    1321             : 
    1322             :                         valid_mode_found = 1;
    1323             : 
    1324           0 :                         if ((wdc->cap & WDC_CAPABILITY_MODE) == 0) {
    1325           0 :                                 drvp->PIO_cap = i + 3;
    1326           0 :                                 continue;
    1327             :                         }
    1328             : 
    1329             :                         /*
    1330             :                          * See if mode is accepted.
    1331             :                          * If the controller can't set its PIO mode,
    1332             :                          * assume the BIOS set it up correctly
    1333             :                          */
    1334           0 :                         if (ata_set_mode(drvp, 0x08 | (i + 3),
    1335           0 :                             at_poll) != CMD_OK)
    1336             :                                 continue;
    1337             : 
    1338             :                         /*
    1339             :                          * If controller's driver can't set its PIO mode,
    1340             :                          * set the highest one the controller supports
    1341             :                          */
    1342           0 :                         if (wdc->PIO_cap >= i + 3) {
    1343           0 :                                 drvp->PIO_mode = i + 3;
    1344           0 :                                 drvp->PIO_cap = i + 3;
    1345           0 :                                 break;
    1346             :                         }
    1347             :                 }
    1348           0 :                 if (!valid_mode_found) {
    1349             :                         /*
    1350             :                          * We didn't find a valid PIO mode.
    1351             :                          * Assume the values returned for DMA are buggy too
    1352             :                          */
    1353           0 :                         return;
    1354             :                 }
    1355           0 :                 drvp->drive_flags |= DRIVE_MODE;
    1356             : 
    1357             :                 /* Some controllers don't support ATAPI DMA */
    1358           0 :                 if ((drvp->drive_flags & DRIVE_ATAPI) &&
    1359           0 :                     (wdc->cap & WDC_CAPABILITY_NO_ATAPI_DMA))
    1360           0 :                         return;
    1361             : 
    1362             :                 valid_mode_found = 0;
    1363           0 :                 for (i = 7; i >= 0; i--) {
    1364           0 :                         if ((params->atap_dmamode_supp & (1 << i)) == 0)
    1365             :                                 continue;
    1366           0 :                         if ((wdc->cap & WDC_CAPABILITY_DMA) &&
    1367           0 :                             (wdc->cap & WDC_CAPABILITY_MODE))
    1368           0 :                                 if (ata_set_mode(drvp, 0x20 | i, at_poll)
    1369           0 :                                     != CMD_OK)
    1370             :                                         continue;
    1371             : 
    1372             :                         valid_mode_found = 1;
    1373             : 
    1374           0 :                         if (wdc->cap & WDC_CAPABILITY_DMA) {
    1375           0 :                                 if ((wdc->cap & WDC_CAPABILITY_MODE) &&
    1376           0 :                                     wdc->DMA_cap < i)
    1377             :                                         continue;
    1378           0 :                                 drvp->DMA_mode = i;
    1379           0 :                                 drvp->DMA_cap = i;
    1380           0 :                                 drvp->drive_flags |= DRIVE_DMA;
    1381           0 :                         }
    1382             :                         break;
    1383             :                 }
    1384           0 :                 if (params->atap_extensions & WDC_EXT_UDMA_MODES) {
    1385           0 :                         for (i = 7; i >= 0; i--) {
    1386           0 :                                 if ((params->atap_udmamode_supp & (1 << i))
    1387           0 :                                     == 0)
    1388             :                                         continue;
    1389           0 :                                 if ((wdc->cap & WDC_CAPABILITY_MODE) &&
    1390           0 :                                     (wdc->cap & WDC_CAPABILITY_UDMA))
    1391           0 :                                         if (ata_set_mode(drvp, 0x40 | i,
    1392           0 :                                             at_poll) != CMD_OK)
    1393             :                                                 continue;
    1394           0 :                                 if (wdc->cap & WDC_CAPABILITY_UDMA) {
    1395           0 :                                         if ((wdc->cap & WDC_CAPABILITY_MODE) &&
    1396           0 :                                             wdc->UDMA_cap < i)
    1397             :                                                 continue;
    1398           0 :                                         drvp->UDMA_mode = i;
    1399           0 :                                         drvp->UDMA_cap = i;
    1400           0 :                                         drvp->drive_flags |= DRIVE_UDMA;
    1401           0 :                                 }
    1402             :                                 break;
    1403             :                         }
    1404             :                 }
    1405             :         }
    1406             : 
    1407             :         /* Try to guess ATA version here, if it didn't get reported */
    1408           0 :         if (drvp->ata_vers == 0) {
    1409           0 :                 if (drvp->drive_flags & DRIVE_UDMA)
    1410           0 :                         drvp->ata_vers = 4; /* should be at last ATA-4 */
    1411           0 :                 else if (drvp->PIO_cap > 2)
    1412           0 :                         drvp->ata_vers = 2; /* should be at last ATA-2 */
    1413             :         }
    1414           0 :         if (cf_flags & ATA_CONFIG_PIO_SET) {
    1415           0 :                 drvp->PIO_mode =
    1416           0 :                     (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
    1417           0 :                 drvp->drive_flags |= DRIVE_MODE;
    1418           0 :         }
    1419           0 :         if ((wdc->cap & WDC_CAPABILITY_DMA) == 0) {
    1420             :                 /* don't care about DMA modes */
    1421           0 :                 return;
    1422             :         }
    1423           0 :         if (cf_flags & ATA_CONFIG_DMA_SET) {
    1424           0 :                 if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
    1425             :                     ATA_CONFIG_DMA_DISABLE) {
    1426           0 :                         drvp->drive_flags &= ~DRIVE_DMA;
    1427           0 :                 } else {
    1428           0 :                         drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >>
    1429             :                             ATA_CONFIG_DMA_OFF;
    1430           0 :                         drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
    1431             :                 }
    1432             :         }
    1433           0 :         if ((wdc->cap & WDC_CAPABILITY_UDMA) == 0) {
    1434             :                 /* don't care about UDMA modes */
    1435           0 :                 return;
    1436             :         }
    1437           0 :         if (cf_flags & ATA_CONFIG_UDMA_SET) {
    1438           0 :                 if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
    1439             :                     ATA_CONFIG_UDMA_DISABLE) {
    1440           0 :                         drvp->drive_flags &= ~DRIVE_UDMA;
    1441           0 :                 } else {
    1442           0 :                         drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >>
    1443             :                             ATA_CONFIG_UDMA_OFF;
    1444           0 :                         drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
    1445             :                 }
    1446             :         }
    1447           0 : }
    1448             : 
    1449             : void
    1450           0 : wdc_output_bytes(struct ata_drive_datas *drvp, void *bytes, unsigned int buflen)
    1451             : {
    1452           0 :         struct channel_softc *chp = drvp->chnl_softc;
    1453             :         unsigned int off = 0;
    1454             :         unsigned int len = buflen, roundlen;
    1455             : 
    1456           0 :         if (drvp->drive_flags & DRIVE_CAP32) {
    1457           0 :                 roundlen = len & ~3;
    1458             : 
    1459           0 :                 CHP_WRITE_RAW_MULTI_4(chp,
    1460             :                     (void *)((u_int8_t *)bytes + off), roundlen);
    1461             : 
    1462             :                 off += roundlen;
    1463           0 :                 len -= roundlen;
    1464           0 :         }
    1465             : 
    1466           0 :         if (len > 0) {
    1467           0 :                 roundlen = (len + 1) & ~0x1;
    1468             : 
    1469           0 :                 CHP_WRITE_RAW_MULTI_2(chp,
    1470             :                     (void *)((u_int8_t *)bytes + off), roundlen);
    1471           0 :         }
    1472           0 : }
    1473             : 
    1474             : void
    1475           0 : wdc_input_bytes(struct ata_drive_datas *drvp, void *bytes, unsigned int buflen)
    1476             : {
    1477           0 :         struct channel_softc *chp = drvp->chnl_softc;
    1478             :         unsigned int off = 0;
    1479             :         unsigned int len = buflen, roundlen;
    1480             : 
    1481           0 :         if (drvp->drive_flags & DRIVE_CAP32) {
    1482           0 :                 roundlen = len & ~3;
    1483             : 
    1484           0 :                 CHP_READ_RAW_MULTI_4(chp,
    1485             :                     (void *)((u_int8_t *)bytes + off), roundlen);
    1486             : 
    1487             :                 off += roundlen;
    1488           0 :                 len -= roundlen;
    1489           0 :         }
    1490             : 
    1491           0 :         if (len > 0) {
    1492           0 :                 roundlen = (len + 1) & ~0x1;
    1493             : 
    1494           0 :                 CHP_READ_RAW_MULTI_2(chp,
    1495             :                     (void *)((u_int8_t *)bytes + off), roundlen);
    1496           0 :         }
    1497           0 : }
    1498             : 
    1499             : void
    1500           0 : wdc_print_caps(struct ata_drive_datas *drvp)
    1501             : {
    1502             :         /* This is actually a lie until we fix the _probe_caps
    1503             :            algorithm. Don't print out lies */
    1504             : #if 0
    1505             :         printf("%s: can use ", drvp->drive_name);
    1506             : 
    1507             :         if (drvp->drive_flags & DRIVE_CAP32) {
    1508             :                 printf("32-bit");
    1509             :         } else
    1510             :                 printf("16-bit");
    1511             : 
    1512             :         printf(", PIO mode %d", drvp->PIO_cap);
    1513             : 
    1514             :         if (drvp->drive_flags & DRIVE_DMA) {
    1515             :                 printf(", DMA mode %d", drvp->DMA_cap);
    1516             :         }
    1517             : 
    1518             :         if (drvp->drive_flags & DRIVE_UDMA) {
    1519             :                 printf(", Ultra-DMA mode %d", drvp->UDMA_cap);
    1520             :         }
    1521             : 
    1522             :         printf("\n");
    1523             : #endif /* 0 */
    1524           0 : }
    1525             : 
    1526             : void
    1527           0 : wdc_print_current_modes(struct channel_softc *chp)
    1528             : {
    1529             :         int drive;
    1530             :         struct ata_drive_datas *drvp;
    1531             : 
    1532           0 :         for (drive = 0; drive < 2; drive++) {
    1533           0 :                 drvp = &chp->ch_drive[drive];
    1534           0 :                 if ((drvp->drive_flags & DRIVE) == 0)
    1535             :                         continue;
    1536             : 
    1537           0 :                 printf("%s(%s:%d:%d):",
    1538           0 :                     drvp->drive_name,
    1539           0 :                     chp->wdc->sc_dev.dv_xname, chp->channel, drive);
    1540             : 
    1541           0 :                 if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0 &&
    1542           0 :                     !(drvp->cf_flags & ATA_CONFIG_PIO_SET))
    1543           0 :                         printf(" using BIOS timings");
    1544             :                 else
    1545           0 :                         printf(" using PIO mode %d", drvp->PIO_mode);
    1546           0 :                 if (drvp->drive_flags & DRIVE_DMA)
    1547           0 :                         printf(", DMA mode %d", drvp->DMA_mode);
    1548           0 :                 if (drvp->drive_flags & DRIVE_UDMA)
    1549           0 :                         printf(", Ultra-DMA mode %d", drvp->UDMA_mode);
    1550           0 :                 printf("\n");
    1551           0 :         }
    1552           0 : }
    1553             : 
    1554             : /*
    1555             :  * downgrade the transfer mode of a drive after an error. return 1 if
    1556             :  * downgrade was possible, 0 otherwise.
    1557             :  */
    1558             : int
    1559           0 : wdc_downgrade_mode(struct ata_drive_datas *drvp)
    1560             : {
    1561           0 :         struct channel_softc *chp = drvp->chnl_softc;
    1562           0 :         struct wdc_softc *wdc = chp->wdc;
    1563           0 :         int cf_flags = drvp->cf_flags;
    1564             : 
    1565             :         /* if drive or controller don't know its mode, we can't do much */
    1566           0 :         if ((drvp->drive_flags & DRIVE_MODE) == 0 ||
    1567           0 :             (wdc->cap & WDC_CAPABILITY_MODE) == 0)
    1568           0 :                 return 0;
    1569             :         /* current drive mode was set by a config flag, let it this way */
    1570           0 :         if ((cf_flags & ATA_CONFIG_PIO_SET) ||
    1571           0 :             (cf_flags & ATA_CONFIG_DMA_SET) ||
    1572           0 :             (cf_flags & ATA_CONFIG_UDMA_SET))
    1573           0 :                 return 0;
    1574             : 
    1575             :         /*
    1576             :          * We'd ideally like to use an Ultra DMA mode since they have the
    1577             :          * protection of a CRC. So we try each Ultra DMA mode and see if
    1578             :          * we can find any working combo
    1579             :          */
    1580           0 :         if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode > 0) {
    1581           0 :                 drvp->UDMA_mode = drvp->UDMA_mode - 1;
    1582           0 :                 printf("%s: transfer error, downgrading to Ultra-DMA mode %d\n",
    1583           0 :                     drvp->drive_name, drvp->UDMA_mode);
    1584           0 :         } else  if ((drvp->drive_flags & DRIVE_UDMA) &&
    1585           0 :             (drvp->drive_flags & DRIVE_DMAERR) == 0) {
    1586             :                 /*
    1587             :                  * If we were using ultra-DMA, don't downgrade to
    1588             :                  * multiword DMA if we noticed a CRC error. It has
    1589             :                  * been noticed that CRC errors in ultra-DMA lead to
    1590             :                  * silent data corruption in multiword DMA.  Data
    1591             :                  * corruption is less likely to occur in PIO mode.
    1592             :                  */
    1593           0 :                 drvp->drive_flags &= ~DRIVE_UDMA;
    1594           0 :                 drvp->drive_flags |= DRIVE_DMA;
    1595           0 :                 drvp->DMA_mode = drvp->DMA_cap;
    1596           0 :                 printf("%s: transfer error, downgrading to DMA mode %d\n",
    1597           0 :                     drvp->drive_name, drvp->DMA_mode);
    1598           0 :         } else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
    1599           0 :                 drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
    1600           0 :                 drvp->PIO_mode = drvp->PIO_cap;
    1601           0 :                 printf("%s: transfer error, downgrading to PIO mode %d\n",
    1602           0 :                     drvp->drive_name, drvp->PIO_mode);
    1603             :         } else /* already using PIO, can't downgrade */
    1604           0 :                 return 0;
    1605             : 
    1606           0 :         wdc->set_modes(chp);
    1607             :         /* reset the channel, which will schedule all drives for setup */
    1608           0 :         wdc_reset_channel(drvp, 0);
    1609           0 :         return 1;
    1610           0 : }
    1611             : 
    1612             : int
    1613           0 : wdc_exec_command(struct ata_drive_datas *drvp, struct wdc_command *wdc_c)
    1614             : {
    1615           0 :         struct channel_softc *chp = drvp->chnl_softc;
    1616             :         struct wdc_xfer *xfer;
    1617             :         int s, ret;
    1618             : 
    1619             :         WDCDEBUG_PRINT(("wdc_exec_command %s:%d:%d\n",
    1620             :             chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
    1621             :             DEBUG_FUNCS);
    1622             : 
    1623             :         /* set up an xfer and queue. Wait for completion */
    1624           0 :         xfer = wdc_get_xfer(wdc_c->flags & AT_WAIT ? WDC_CANSLEEP :
    1625             :             WDC_NOSLEEP);
    1626           0 :         if (xfer == NULL) {
    1627           0 :                 return WDC_TRY_AGAIN;
    1628             :         }
    1629             : 
    1630           0 :         if (wdc_c->flags & AT_POLL)
    1631           0 :                 xfer->c_flags |= C_POLL;
    1632           0 :         xfer->drive = drvp->drive;
    1633           0 :         xfer->databuf = wdc_c->data;
    1634           0 :         xfer->c_bcount = wdc_c->bcount;
    1635           0 :         xfer->cmd = wdc_c;
    1636           0 :         xfer->c_start = __wdccommand_start;
    1637           0 :         xfer->c_intr = __wdccommand_intr;
    1638           0 :         xfer->c_kill_xfer = __wdccommand_done;
    1639             : 
    1640           0 :         s = splbio();
    1641           0 :         wdc_exec_xfer(chp, xfer);
    1642             : #ifdef DIAGNOSTIC
    1643           0 :         if ((wdc_c->flags & AT_POLL) != 0 &&
    1644           0 :             (wdc_c->flags & AT_DONE) == 0)
    1645           0 :                 panic("wdc_exec_command: polled command not done");
    1646             : #endif /* DIAGNOSTIC */
    1647           0 :         if (wdc_c->flags & AT_DONE) {
    1648             :                 ret = WDC_COMPLETE;
    1649           0 :         } else {
    1650           0 :                 if (wdc_c->flags & AT_WAIT) {
    1651             :                         WDCDEBUG_PRINT(("wdc_exec_command sleeping\n"),
    1652             :                                        DEBUG_FUNCS);
    1653             : 
    1654           0 :                         while ((wdc_c->flags & AT_DONE) == 0) {
    1655           0 :                                 tsleep(wdc_c, PRIBIO, "wdccmd", 0);
    1656             :                         }
    1657             :                         ret = WDC_COMPLETE;
    1658           0 :                 } else {
    1659             :                         ret = WDC_QUEUED;
    1660             :                 }
    1661             :         }
    1662           0 :         splx(s);
    1663           0 :         return ret;
    1664           0 : }
    1665             : 
    1666             : void
    1667           0 : __wdccommand_start(struct channel_softc *chp, struct wdc_xfer *xfer)
    1668             : {
    1669           0 :         int drive = xfer->drive;
    1670           0 :         struct wdc_command *wdc_c = xfer->cmd;
    1671             : 
    1672             :         WDCDEBUG_PRINT(("__wdccommand_start %s:%d:%d\n",
    1673             :             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
    1674             :             DEBUG_FUNCS);
    1675             : 
    1676             :         /*
    1677             :          * Disable interrupts if we're polling
    1678             :          */
    1679           0 :         if (xfer->c_flags & C_POLL) {
    1680           0 :                 wdc_disable_intr(chp);
    1681           0 :         }
    1682             : 
    1683           0 :         wdc_set_drive(chp, drive);
    1684           0 :         DELAY(1);
    1685             : 
    1686             :         /*
    1687             :          * For resets, we don't really care to make sure that
    1688             :          * the bus is free
    1689             :          */
    1690           0 :         if (wdc_c->r_command != ATAPI_SOFT_RESET) {
    1691           0 :                 if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
    1692           0 :                     wdc_c->r_st_bmask, wdc_c->timeout) != 0) {
    1693             :                         goto timeout;
    1694             :                 }
    1695             :         } else
    1696           0 :                 DELAY(10);
    1697             : 
    1698           0 :         wdccommand(chp, drive, wdc_c->r_command, wdc_c->r_cyl, wdc_c->r_head,
    1699           0 :             wdc_c->r_sector, wdc_c->r_count, wdc_c->r_features);
    1700             : 
    1701           0 :         if ((wdc_c->flags & AT_WRITE) == AT_WRITE) {
    1702             :                 /* wait at least 400ns before reading status register */
    1703           0 :                 DELAY(10);
    1704           0 :                 if (wait_for_unbusy(chp, wdc_c->timeout) != 0)
    1705             :                         goto timeout;
    1706             : 
    1707           0 :                 if ((chp->ch_status & (WDCS_DRQ | WDCS_ERR)) == WDCS_ERR) {
    1708           0 :                         __wdccommand_done(chp, xfer);
    1709           0 :                         return;
    1710             :                 }
    1711             : 
    1712           0 :                 if (wait_for_drq(chp, wdc_c->timeout) != 0)
    1713             :                         goto timeout;
    1714             : 
    1715           0 :                 wdc_output_bytes(&chp->ch_drive[drive],
    1716           0 :                     wdc_c->data, wdc_c->bcount);
    1717           0 :         }
    1718             : 
    1719           0 :         if ((wdc_c->flags & AT_POLL) == 0) {
    1720           0 :                 chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
    1721           0 :                 timeout_add_msec(&chp->ch_timo, wdc_c->timeout);
    1722           0 :                 return;
    1723             :         }
    1724             : 
    1725             :         /*
    1726             :          * Polled command. Wait for drive ready or drq. Done in intr().
    1727             :          * Wait for at last 400ns for status bit to be valid.
    1728             :          */
    1729           0 :         delay(10);
    1730           0 :         __wdccommand_intr(chp, xfer, 0);
    1731           0 :         return;
    1732             : 
    1733             : timeout:        
    1734           0 :         wdc_c->flags |= AT_TIMEOU;
    1735           0 :         __wdccommand_done(chp, xfer);
    1736           0 : }
    1737             : 
    1738             : int
    1739           0 : __wdccommand_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
    1740             : {
    1741           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
    1742           0 :         struct wdc_command *wdc_c = xfer->cmd;
    1743           0 :         int bcount = wdc_c->bcount;
    1744           0 :         char *data = wdc_c->data;
    1745             : 
    1746             :         WDCDEBUG_PRINT(("__wdccommand_intr %s:%d:%d\n",
    1747             :             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_INTR);
    1748           0 :         if (wdcwait(chp, wdc_c->r_st_pmask, wdc_c->r_st_pmask,
    1749             :             (irq == 0) ? wdc_c->timeout : 0)) {
    1750           0 :                 if (chp->dying) {
    1751           0 :                         __wdccommand_done(chp, xfer);
    1752           0 :                         return -1;
    1753             :                 }
    1754           0 :                 if (irq && (xfer->c_flags & C_TIMEOU) == 0)
    1755           0 :                         return 0; /* IRQ was not for us */
    1756           0 :                 wdc_c->flags |= AT_TIMEOU;
    1757           0 :                 goto out;
    1758             :         }
    1759           0 :         if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
    1760           0 :                 chp->wdc->irqack(chp);
    1761           0 :         if (wdc_c->flags & AT_READ) {
    1762           0 :                 if ((chp->ch_status & WDCS_DRQ) == 0) {
    1763           0 :                         wdc_c->flags |= AT_TIMEOU;
    1764           0 :                         goto out;
    1765             :                 }
    1766           0 :                 wdc_input_bytes(drvp, data, bcount);
    1767             :                 /* Should we wait for device to indicate idle? */
    1768           0 :         }
    1769             : out:
    1770           0 :         __wdccommand_done(chp, xfer);
    1771             :         WDCDEBUG_PRINT(("__wdccommand_intr returned\n"), DEBUG_INTR);
    1772           0 :         return 1;
    1773           0 : }
    1774             : 
    1775             : void
    1776           0 : __wdccommand_done(struct channel_softc *chp, struct wdc_xfer *xfer)
    1777             : {
    1778           0 :         struct wdc_command *wdc_c = xfer->cmd;
    1779             : 
    1780             :         WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d %02x\n",
    1781             :             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
    1782             :             chp->ch_status), DEBUG_FUNCS);
    1783           0 :         if (chp->dying)
    1784             :                 goto killit;
    1785           0 :         if (chp->ch_status & WDCS_DWF)
    1786           0 :                 wdc_c->flags |= AT_DF;
    1787           0 :         if (chp->ch_status & WDCS_ERR) {
    1788           0 :                 wdc_c->flags |= AT_ERROR;
    1789           0 :                 wdc_c->r_error = chp->ch_error;
    1790           0 :         }
    1791           0 :         wdc_c->flags |= AT_DONE;
    1792           0 :         if ((wdc_c->flags & AT_READREG) != 0 &&
    1793           0 :             (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
    1794           0 :                 wdc_c->r_head = CHP_READ_REG(chp, wdr_sdh);
    1795           0 :                 wdc_c->r_cyl = CHP_READ_REG(chp, wdr_cyl_hi) << 8;
    1796           0 :                 wdc_c->r_cyl |= CHP_READ_REG(chp, wdr_cyl_lo);
    1797           0 :                 wdc_c->r_sector = CHP_READ_REG(chp, wdr_sector);
    1798           0 :                 wdc_c->r_count = CHP_READ_REG(chp, wdr_seccnt);
    1799           0 :                 wdc_c->r_error = CHP_READ_REG(chp, wdr_error);
    1800           0 :                 wdc_c->r_features = wdc_c->r_error;
    1801           0 :         }
    1802             : 
    1803             : killit:
    1804           0 :         if (xfer->c_flags & C_POLL) {
    1805           0 :                 wdc_enable_intr(chp);
    1806           0 :         } else
    1807           0 :                 timeout_del(&chp->ch_timo);
    1808             : 
    1809           0 :         wdc_free_xfer(chp, xfer);
    1810             :         WDCDEBUG_PRINT(("__wdccommand_done before callback\n"), DEBUG_INTR);
    1811             : 
    1812           0 :         if (chp->dying)
    1813           0 :                 return;
    1814             : 
    1815           0 :         if (wdc_c->flags & AT_WAIT)
    1816           0 :                 wakeup(wdc_c);
    1817             :         else
    1818           0 :                 if (wdc_c->callback)
    1819           0 :                         wdc_c->callback(wdc_c->callback_arg);
    1820           0 :         wdcstart(chp);
    1821             :         WDCDEBUG_PRINT(("__wdccommand_done returned\n"), DEBUG_INTR);
    1822           0 : }
    1823             : 
    1824             : /*
    1825             :  * Send a command. The drive should be ready.
    1826             :  * Assumes interrupts are blocked.
    1827             :  */
    1828             : void
    1829           0 : wdccommand(struct channel_softc *chp, u_int8_t drive, u_int8_t command,
    1830             :     u_int16_t cylin, u_int8_t head, u_int8_t sector, u_int8_t count,
    1831             :     u_int8_t features)
    1832             : {
    1833             :         WDCDEBUG_PRINT(("wdccommand %s:%d:%d: command=0x%x cylin=%d head=%d "
    1834             :             "sector=%d count=%d features=%d\n", chp->wdc->sc_dev.dv_xname,
    1835             :             chp->channel, drive, command, cylin, head, sector, count, features),
    1836             :             DEBUG_FUNCS);
    1837             :         WDC_LOG_ATA_CMDLONG(chp, head, features, cylin, cylin >> 8, sector,
    1838             :             count, command);
    1839             : 
    1840             :         /* Select drive, head, and addressing mode. */
    1841           0 :         CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4) | head);
    1842             : 
    1843             :         /* Load parameters. */
    1844           0 :         CHP_WRITE_REG(chp, wdr_features, features);
    1845           0 :         CHP_WRITE_REG(chp, wdr_cyl_lo, cylin);
    1846           0 :         CHP_WRITE_REG(chp, wdr_cyl_hi, cylin >> 8);
    1847           0 :         CHP_WRITE_REG(chp, wdr_sector, sector);
    1848           0 :         CHP_WRITE_REG(chp, wdr_seccnt, count);
    1849             : 
    1850             :         /* Send command. */
    1851           0 :         CHP_WRITE_REG(chp, wdr_command, command);
    1852           0 : }
    1853             : 
    1854             : /*
    1855             :  * Send a 48-bit addressing command. The drive should be ready.
    1856             :  * Assumes interrupts are blocked.
    1857             :  */
    1858             : void
    1859           0 : wdccommandext(struct channel_softc *chp, u_int8_t drive, u_int8_t command,
    1860             :     u_int64_t blkno, u_int16_t count)
    1861             : {
    1862             :         WDCDEBUG_PRINT(("wdccommandext %s:%d:%d: command=0x%x blkno=%llu "
    1863             :             "count=%d\n", chp->wdc->sc_dev.dv_xname,
    1864             :             chp->channel, drive, command, blkno, count),
    1865             :             DEBUG_FUNCS);
    1866             :         WDC_LOG_ATA_CMDEXT(chp, blkno >> 40, blkno >> 16, blkno >> 32,
    1867             :             blkno >> 8, blkno >> 24, blkno, count >> 8, count, command);
    1868             : 
    1869             :         /* Select drive and LBA mode. */
    1870           0 :         CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_LBA);
    1871             : 
    1872             :         /* Load parameters. */
    1873           0 :         CHP_LBA48_WRITE_REG(chp, wdr_lba_hi,
    1874             :             ((blkno >> 32) & 0xff00) | ((blkno >> 16) & 0xff));
    1875           0 :         CHP_LBA48_WRITE_REG(chp, wdr_lba_mi,
    1876             :             ((blkno >> 24) & 0xff00) | ((blkno >> 8) & 0xff));
    1877           0 :         CHP_LBA48_WRITE_REG(chp, wdr_lba_lo,
    1878             :             ((blkno >> 16) & 0xff00) | (blkno & 0xff));
    1879           0 :         CHP_LBA48_WRITE_REG(chp, wdr_seccnt, count);
    1880             : 
    1881             :         /* Send command. */
    1882           0 :         CHP_WRITE_REG(chp, wdr_command, command);
    1883           0 : }
    1884             : 
    1885             : /*
    1886             :  * Simplified version of wdccommand().  Unbusy/ready/drq must be
    1887             :  * tested by the caller.
    1888             :  */
    1889             : void
    1890           0 : wdccommandshort(struct channel_softc *chp, int drive, int command)
    1891             : {
    1892             : 
    1893             :         WDCDEBUG_PRINT(("wdccommandshort %s:%d:%d command 0x%x\n",
    1894             :             chp->wdc->sc_dev.dv_xname, chp->channel, drive, command),
    1895             :             DEBUG_FUNCS);
    1896             :         WDC_LOG_ATA_CMDSHORT(chp, command);
    1897             : 
    1898             :         /* Select drive. */
    1899           0 :         CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4));
    1900           0 :         CHP_WRITE_REG(chp, wdr_command, command);
    1901           0 : }
    1902             : 
    1903             : /* Add a command to the queue and start controller. Must be called at splbio */
    1904             : 
    1905             : void
    1906           0 : wdc_exec_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
    1907             : {
    1908             :         WDCDEBUG_PRINT(("wdc_exec_xfer %p flags 0x%x channel %d drive %d\n",
    1909             :             xfer, xfer->c_flags, chp->channel, xfer->drive), DEBUG_XFERS);
    1910             : 
    1911             :         /* complete xfer setup */
    1912           0 :         xfer->chp = chp;
    1913             : 
    1914             :         /*
    1915             :          * If we are a polled command, and the list is not empty,
    1916             :          * we are doing a dump. Drop the list to allow the polled command
    1917             :          * to complete, we're going to reboot soon anyway.
    1918             :          */
    1919           0 :         if ((xfer->c_flags & C_POLL) != 0 &&
    1920           0 :             !TAILQ_EMPTY(&chp->ch_queue->sc_xfer)) {
    1921           0 :                 TAILQ_INIT(&chp->ch_queue->sc_xfer);
    1922           0 :         }
    1923             :         /* insert at the end of command list */
    1924           0 :         TAILQ_INSERT_TAIL(&chp->ch_queue->sc_xfer,xfer , c_xferchain);
    1925             :         WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
    1926             :             chp->ch_flags), DEBUG_XFERS);
    1927           0 :         wdcstart(chp);
    1928           0 : }
    1929             : 
    1930             : void *
    1931           0 : wdc_xfer_get(void *null)
    1932             : {
    1933           0 :         return (pool_get(&wdc_xfer_pool, PR_NOWAIT | PR_ZERO));
    1934             : }
    1935             : 
    1936             : void
    1937           0 : wdc_scrub_xfer(struct wdc_xfer *xfer)
    1938             : {
    1939           0 :         memset(xfer, 0, sizeof(*xfer));
    1940           0 :         xfer->c_flags = C_SCSIXFER;
    1941           0 : }
    1942             : 
    1943             : void
    1944           0 : wdc_xfer_put(void *null, void *xxfer)
    1945             : {
    1946           0 :         struct wdc_xfer *xfer = xxfer;
    1947             :         int put = 0;
    1948             :         int s;
    1949             : 
    1950           0 :         s = splbio();
    1951           0 :         if (ISSET(xfer->c_flags, C_SCSIXFER))
    1952           0 :                 CLR(xfer->c_flags, C_SCSIXFER);
    1953             :         else
    1954             :                 put = 1;
    1955           0 :         splx(s);
    1956             : 
    1957           0 :         if (put)
    1958           0 :                 pool_put(&wdc_xfer_pool, xfer);
    1959           0 : }
    1960             : 
    1961             : struct wdc_xfer *
    1962           0 : wdc_get_xfer(int flags)
    1963             : {
    1964           0 :         return (scsi_io_get(&wdc_xfer_iopool,
    1965           0 :             ISSET(flags, WDC_NOSLEEP) ? SCSI_NOSLEEP : 0));
    1966             : }
    1967             : 
    1968             : void
    1969           0 : wdc_free_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
    1970             : {
    1971             :         int put = 0;
    1972             :         int s;
    1973             : 
    1974           0 :         if (xfer->c_flags & C_PRIVATEXFER) {
    1975           0 :                 chp->ch_flags &= ~WDCF_ACTIVE;
    1976           0 :                 TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
    1977           0 :                 return;
    1978             :         }
    1979             : 
    1980           0 :         s = splbio();
    1981           0 :         chp->ch_flags &= ~WDCF_ACTIVE;
    1982           0 :         TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
    1983           0 :         if (ISSET(xfer->c_flags, C_SCSIXFER))
    1984           0 :                 CLR(xfer->c_flags, C_SCSIXFER);
    1985             :         else
    1986             :                 put = 1;
    1987           0 :         splx(s);
    1988             : 
    1989           0 :         if (put)
    1990           0 :                 scsi_io_put(&wdc_xfer_iopool, xfer);
    1991           0 : }
    1992             : 
    1993             : 
    1994             : /*
    1995             :  * Kill off all pending xfers for a channel_softc.
    1996             :  *
    1997             :  * Must be called at splbio().
    1998             :  */
    1999             : void
    2000           0 : wdc_kill_pending(struct channel_softc *chp)
    2001             : {
    2002             :         struct wdc_xfer *xfer;
    2003             : 
    2004           0 :         while ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) != NULL) {
    2005           0 :                 chp = xfer->chp;
    2006           0 :                 (*xfer->c_kill_xfer)(chp, xfer);
    2007             :         }
    2008           0 : }
    2009             : 
    2010             : void
    2011           0 : __wdcerror(struct channel_softc *chp, char *msg)
    2012             : {
    2013           0 :         struct wdc_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
    2014           0 :         if (xfer == NULL)
    2015           0 :                 printf("%s:%d: %s\n", chp->wdc->sc_dev.dv_xname, chp->channel,
    2016             :                     msg);
    2017             :         else
    2018           0 :                 printf("%s(%s:%d:%d): %s\n",
    2019           0 :                     chp->ch_drive[xfer->drive].drive_name,
    2020           0 :                     chp->wdc->sc_dev.dv_xname,
    2021           0 :                     chp->channel, xfer->drive, msg);
    2022           0 : }
    2023             : 
    2024             : /*
    2025             :  * the bit bucket
    2026             :  */
    2027             : void
    2028           0 : wdcbit_bucket(struct channel_softc *chp, int size)
    2029             : {
    2030           0 :         CHP_READ_RAW_MULTI_2(chp, NULL, size);
    2031           0 : }
    2032             : 
    2033             : 
    2034             : #include <sys/ataio.h>
    2035             : #include <sys/fcntl.h>
    2036             : 
    2037             : int wdc_ioc_ata_cmd(struct ata_drive_datas *, atareq_t *);
    2038             : 
    2039             : int
    2040           0 : wdc_ioc_ata_cmd(struct ata_drive_datas *drvp, atareq_t *atareq)
    2041             : {
    2042           0 :         struct wdc_command wdc_c;
    2043             :         int err = 0;
    2044             : 
    2045             :         /*
    2046             :          * Make sure a timeout was supplied in the ioctl request
    2047             :          */
    2048           0 :         if (atareq->timeout == 0)
    2049           0 :                 return (EINVAL);
    2050             : 
    2051           0 :         if (atareq->datalen > MAXPHYS)
    2052           0 :                 return (EINVAL);
    2053             : 
    2054           0 :         bzero(&wdc_c, sizeof(wdc_c));
    2055             : 
    2056           0 :         if (atareq->datalen > 0) {
    2057           0 :                 wdc_c.data = dma_alloc(atareq->datalen, PR_NOWAIT | PR_ZERO);
    2058           0 :                 if (wdc_c.data == NULL) {
    2059             :                         err = ENOMEM;
    2060           0 :                         goto err;
    2061             :                 }
    2062           0 :                 wdc_c.bcount = atareq->datalen;
    2063           0 :         }
    2064             : 
    2065           0 :         wdc_c.flags = AT_WAIT;
    2066           0 :         if (atareq->flags & ATACMD_READ)
    2067           0 :                 wdc_c.flags |= AT_READ;
    2068           0 :         if (atareq->flags & ATACMD_WRITE) {
    2069           0 :                 if (atareq->datalen > 0) {
    2070           0 :                         err = copyin(atareq->databuf, wdc_c.data,
    2071             :                             atareq->datalen);
    2072           0 :                         if (err != 0)
    2073             :                                 goto err;
    2074             :                 }
    2075           0 :                 wdc_c.flags |= AT_WRITE;
    2076           0 :         }
    2077           0 :         if (atareq->flags & ATACMD_READREG)
    2078           0 :                 wdc_c.flags |= AT_READREG;
    2079             : 
    2080           0 :         wdc_c.timeout = atareq->timeout;
    2081           0 :         wdc_c.r_command = atareq->command;
    2082           0 :         wdc_c.r_head = atareq->head & 0x0f;
    2083           0 :         wdc_c.r_cyl = atareq->cylinder;
    2084           0 :         wdc_c.r_sector = atareq->sec_num;
    2085           0 :         wdc_c.r_count = atareq->sec_count;
    2086           0 :         wdc_c.r_features = atareq->features;
    2087           0 :         if (drvp->drive_flags & DRIVE_ATAPI) {
    2088           0 :                 if (wdc_c.r_command == WDCC_IDENTIFY)
    2089           0 :                         wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
    2090             :         } else {
    2091           0 :                 wdc_c.r_st_bmask = WDCS_DRDY;
    2092           0 :                 wdc_c.r_st_pmask = WDCS_DRDY;
    2093             :         }
    2094             : 
    2095           0 :         if (wdc_exec_command(drvp, &wdc_c) != WDC_COMPLETE) {
    2096           0 :                 atareq->retsts = ATACMD_ERROR;
    2097           0 :                 goto copyout;
    2098             :         }
    2099             : 
    2100           0 :         if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
    2101           0 :                 if (wdc_c.flags & AT_ERROR) {
    2102           0 :                         atareq->retsts = ATACMD_ERROR;
    2103           0 :                         atareq->error = wdc_c.r_error;
    2104           0 :                 } else if (wdc_c.flags & AT_DF)
    2105           0 :                         atareq->retsts = ATACMD_DF;
    2106             :                 else
    2107           0 :                         atareq->retsts = ATACMD_TIMEOUT;
    2108             :         } else {
    2109           0 :                 atareq->retsts = ATACMD_OK;
    2110           0 :                 if (atareq->flags & ATACMD_READREG) {
    2111           0 :                         atareq->head = wdc_c.r_head;
    2112           0 :                         atareq->cylinder = wdc_c.r_cyl;
    2113           0 :                         atareq->sec_num = wdc_c.r_sector;
    2114           0 :                         atareq->sec_count = wdc_c.r_count;
    2115           0 :                         atareq->features = wdc_c.r_features;
    2116           0 :                         atareq->error = wdc_c.r_error;
    2117           0 :                 }
    2118             :         }
    2119             : 
    2120             : copyout:
    2121           0 :         if (atareq->datalen > 0 && atareq->flags & ATACMD_READ) {
    2122           0 :                 err = copyout(wdc_c.data, atareq->databuf, atareq->datalen);
    2123           0 :                 if (err != 0)
    2124             :                         goto err;
    2125             :         }
    2126             : 
    2127             : err:
    2128           0 :         if (wdc_c.data)
    2129           0 :                 dma_free(wdc_c.data, atareq->datalen);
    2130           0 :         return (err);
    2131           0 : }
    2132             : 
    2133             : int
    2134           0 : wdc_ioctl(struct ata_drive_datas *drvp, u_long xfer, caddr_t addr, int flag,
    2135             :     struct proc *p)
    2136             : {
    2137             :         int error = 0;
    2138             : 
    2139           0 :         switch (xfer) {
    2140             : #ifdef WDCDEBUG
    2141             :         case ATAIOGETTRACE: {
    2142             :                 atagettrace_t *agt = (atagettrace_t *)addr;
    2143             :                 unsigned int size = 0;
    2144             :                 char *log_to_copy;
    2145             : 
    2146             :                 size = agt->buf_size;
    2147             :                 if (size > 65536) {
    2148             :                         size = 65536;
    2149             :                 }
    2150             : 
    2151             :                 log_to_copy = wdc_get_log(&size, &agt->bytes_left);
    2152             : 
    2153             :                 if (log_to_copy != NULL) {
    2154             :                         error = copyout(log_to_copy, agt->buf, size);
    2155             :                         free(log_to_copy, M_TEMP, 0);
    2156             :                 }
    2157             : 
    2158             :                 agt->bytes_copied = size;
    2159             :                 break;
    2160             :         }
    2161             : #endif /* WDCDEBUG */
    2162             : 
    2163             :         case ATAIOCCOMMAND: {
    2164           0 :                 atareq_t *atareq = (atareq_t *)addr;
    2165             : 
    2166             :                 /*
    2167             :                  * Make sure this command is (relatively) safe first
    2168             :                  */
    2169           0 :                 if ((flag & FWRITE) == 0 && atareq->flags & ATACMD_WRITE)
    2170           0 :                         error = EPERM;
    2171             :                 else
    2172           0 :                         error = wdc_ioc_ata_cmd(drvp, atareq);
    2173             :                 break;
    2174             :         }
    2175             : 
    2176             :         default:
    2177             :                 error = ENOTTY;
    2178           0 :                 goto exit;
    2179           0 :         }
    2180             : 
    2181             : exit:
    2182           0 :         return (error);
    2183             : }

Generated by: LCOV version 1.13