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

          Line data    Source code
       1             : /*      $OpenBSD: atapiscsi.c,v 1.106 2017/12/30 20:46:59 guenther Exp $     */
       2             : 
       3             : /*
       4             :  * This code is derived from code with the copyright below.
       5             :  */
       6             : 
       7             : /*
       8             :  * Copyright (c) 1996, 1998 Manuel Bouyer.
       9             :  *
      10             :  * Redistribution and use in source and binary forms, with or without
      11             :  * modification, are permitted provided that the following conditions
      12             :  * are met:
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  * 2. Redistributions in binary form must reproduce the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer in the
      17             :  *    documentation and/or other materials provided with the distribution.
      18             :  *
      19             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      20             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      21             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      22             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      23             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      24             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      25             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      26             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      27             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      28             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      29             :  * SUCH DAMAGE.
      30             :  *
      31             :  */
      32             : 
      33             : 
      34             : #include <sys/param.h>
      35             : #include <sys/systm.h>
      36             : #include <sys/kernel.h>
      37             : #include <sys/device.h>
      38             : #include <sys/buf.h>
      39             : #include <sys/disklabel.h>
      40             : #include <sys/malloc.h>
      41             : #include <sys/reboot.h>
      42             : #include <sys/ioctl.h>
      43             : #include <sys/timeout.h>
      44             : #include <scsi/scsi_all.h>
      45             : #include <scsi/scsi_disk.h>
      46             : #include <scsi/scsi_tape.h>
      47             : #include <scsi/scsiconf.h>
      48             : 
      49             : #include <machine/bus.h>
      50             : #include <machine/cpu.h>
      51             : #include <machine/intr.h>
      52             : 
      53             : #include <dev/ata/atareg.h>
      54             : #include <dev/ata/atavar.h>
      55             : #include <dev/ic/wdcreg.h>
      56             : #include <dev/ic/wdcvar.h>
      57             : #include <dev/ic/wdcevent.h>
      58             : 
      59             : /* drive states stored in ata_drive_datas */
      60             : enum atapi_drive_states {
      61             :         ATAPI_RESET_BASE_STATE = 0,
      62             :         ATAPI_DEVICE_RESET_WAIT_STATE = 1,
      63             :         ATAPI_IDENTIFY_STATE = 2,
      64             :         ATAPI_IDENTIFY_WAIT_STATE = 3,
      65             :         ATAPI_PIOMODE_STATE = 4,
      66             :         ATAPI_PIOMODE_WAIT_STATE = 5,
      67             :         ATAPI_DMAMODE_STATE = 6,
      68             :         ATAPI_DMAMODE_WAIT_STATE = 7,
      69             :         ATAPI_READY_STATE = 8
      70             : };
      71             : 
      72             : #define DEBUG_INTR   0x01
      73             : #define DEBUG_XFERS  0x02
      74             : #define DEBUG_STATUS 0x04
      75             : #define DEBUG_FUNCS  0x08
      76             : #define DEBUG_PROBE  0x10
      77             : #define DEBUG_DSC    0x20
      78             : #define DEBUG_POLL   0x40
      79             : #define DEBUG_ERRORS 0x80   /* Debug error handling code */
      80             : 
      81             : #if defined(WDCDEBUG)
      82             : #ifndef WDCDEBUG_ATAPI_MASK
      83             : #define WDCDEBUG_ATAPI_MASK 0x00
      84             : #endif
      85             : int wdcdebug_atapi_mask = WDCDEBUG_ATAPI_MASK;
      86             : #define WDCDEBUG_PRINT(args, level) do {                \
      87             :         if ((wdcdebug_atapi_mask & (level)) != 0)   \
      88             :                 printf args;                            \
      89             : } while (0)
      90             : #else
      91             : #define WDCDEBUG_PRINT(args, level)
      92             : #endif
      93             : 
      94             : /* 10 ms, this is used only before sending a cmd.  */
      95             : #define ATAPI_DELAY 10
      96             : #define ATAPI_RESET_DELAY 1000
      97             : #define ATAPI_RESET_WAIT 2000
      98             : #define ATAPI_CTRL_WAIT 4000
      99             : 
     100             : /* When polling, let the exponential backoff max out at 1 second's interval. */
     101             : #define ATAPI_POLL_MAXTIC (hz)
     102             : 
     103             : void  wdc_atapi_start(struct channel_softc *,struct wdc_xfer *);
     104             : 
     105             : void  wdc_atapi_timer_handler(void *);
     106             : 
     107             : void  wdc_atapi_real_start(struct channel_softc *, struct wdc_xfer *,
     108             :     int, struct atapi_return_args *);
     109             : void  wdc_atapi_real_start_2(struct channel_softc *, struct wdc_xfer *,
     110             :     int, struct atapi_return_args *);
     111             : void  wdc_atapi_intr_command(struct channel_softc *, struct wdc_xfer *,
     112             :     int, struct atapi_return_args *);
     113             : void  wdc_atapi_intr_data(struct channel_softc *, struct wdc_xfer *,
     114             :     int, struct atapi_return_args *);
     115             : void  wdc_atapi_intr_complete(struct channel_softc *, struct wdc_xfer *,
     116             :     int, struct atapi_return_args *);
     117             : void  wdc_atapi_pio_intr(struct channel_softc *, struct wdc_xfer *,
     118             :     int, struct atapi_return_args *);
     119             : void  wdc_atapi_send_packet(struct channel_softc *, struct wdc_xfer *,
     120             :     int, struct atapi_return_args *);
     121             : void  wdc_atapi_ctrl(struct channel_softc *, struct wdc_xfer *,
     122             :     int, struct atapi_return_args *);
     123             : 
     124             : char  *wdc_atapi_in_data_phase(struct wdc_xfer *, int, int);
     125             : 
     126             : int   wdc_atapi_intr(struct channel_softc *, struct wdc_xfer *, int);
     127             : void  wdc_atapi_done(struct channel_softc *, struct wdc_xfer *,
     128             :         int, struct atapi_return_args *);
     129             : void  wdc_atapi_reset(struct channel_softc *, struct wdc_xfer *,
     130             :         int, struct atapi_return_args *);
     131             : void  wdc_atapi_reset_2(struct channel_softc *, struct wdc_xfer *,
     132             :         int, struct atapi_return_args *);
     133             : 
     134             : void  wdc_atapi_tape_done(struct channel_softc *, struct wdc_xfer *,
     135             :         int, struct atapi_return_args *);
     136             : #define MAX_SIZE MAXPHYS
     137             : 
     138             : struct atapiscsi_softc;
     139             : struct atapiscsi_xfer;
     140             : 
     141             : int     atapiscsi_match(struct device *, void *, void *);
     142             : void    atapiscsi_attach(struct device *, struct device *, void *);
     143             : int     atapiscsi_activate(struct device *, int);
     144             : int     atapiscsi_detach(struct device *, int);
     145             : int     atapi_to_scsi_sense(struct scsi_xfer *, u_int8_t);
     146             : 
     147             : enum atapi_state { as_none, as_data, as_completed };
     148             : 
     149             : struct atapiscsi_softc {
     150             :         struct device  sc_dev;
     151             :         struct  scsi_link  sc_adapterlink;
     152             :         struct channel_softc *chp;
     153             :         enum atapi_state protocol_phase;
     154             : 
     155             :         int drive;
     156             : };
     157             : 
     158             : void  wdc_atapi_minphys(struct buf *bp, struct scsi_link *sl);
     159             : int   wdc_atapi_ioctl(struct scsi_link *, u_long, caddr_t, int);
     160             : void  wdc_atapi_send_cmd(struct scsi_xfer *sc_xfer);
     161             : 
     162             : static struct scsi_adapter atapiscsi_switch =
     163             : {
     164             :         wdc_atapi_send_cmd,
     165             :         wdc_atapi_minphys,
     166             :         NULL,
     167             :         NULL,
     168             :         wdc_atapi_ioctl
     169             : };
     170             : 
     171             : /* Inital version shares bus_link structure so it can easily
     172             :    be "attached to current" wdc driver */
     173             : 
     174             : struct cfattach atapiscsi_ca = {
     175             :         sizeof(struct atapiscsi_softc), atapiscsi_match, atapiscsi_attach,
     176             :             atapiscsi_detach, atapiscsi_activate
     177             : };
     178             : 
     179             : struct cfdriver atapiscsi_cd = {
     180             :         NULL, "atapiscsi", DV_DULL
     181             : };
     182             : 
     183             : 
     184             : int
     185           0 : atapiscsi_match(struct device *parent, void *match, void *aux)
     186             : {
     187           0 :         struct ata_atapi_attach *aa_link = aux;
     188           0 :         struct cfdata *cf = match;
     189             : 
     190           0 :         if (aa_link == NULL)
     191           0 :                 return (0);
     192             : 
     193           0 :         if (aa_link->aa_type != T_ATAPI)
     194           0 :                 return (0);
     195             : 
     196           0 :         if (cf->cf_loc[0] != aa_link->aa_channel &&
     197           0 :             cf->cf_loc[0] != -1)
     198           0 :                 return (0);
     199             : 
     200           0 :         return (1);
     201           0 : }
     202             : 
     203             : void
     204           0 : atapiscsi_attach(struct device *parent, struct device *self, void *aux)
     205             : {
     206           0 :         struct atapiscsi_softc *as = (struct atapiscsi_softc *)self;
     207           0 :         struct ata_atapi_attach *aa_link = aux;
     208           0 :         struct scsibus_attach_args saa;
     209           0 :         struct ata_drive_datas *drvp = aa_link->aa_drv_data;
     210           0 :         struct channel_softc *chp = drvp->chnl_softc;
     211           0 :         struct ataparams *id = &drvp->id;
     212             :         struct device *child;
     213             : 
     214             :         extern struct scsi_iopool wdc_xfer_iopool;
     215             : 
     216           0 :         printf("\n");
     217             : 
     218             :         /* Initialize shared data. */
     219           0 :         scsi_init();
     220             : 
     221             : #ifdef WDCDEBUG
     222             :         if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
     223             :                 wdcdebug_atapi_mask |= DEBUG_PROBE;
     224             : #endif
     225             : 
     226           0 :         as->chp = chp;
     227           0 :         as->drive = drvp->drive;
     228           0 :         as->sc_adapterlink.adapter_softc = as;
     229           0 :         as->sc_adapterlink.adapter_target = 7;
     230           0 :         as->sc_adapterlink.adapter_buswidth = 2;
     231           0 :         as->sc_adapterlink.adapter = &atapiscsi_switch;
     232           0 :         as->sc_adapterlink.luns = 1;
     233           0 :         as->sc_adapterlink.openings = 1;
     234           0 :         as->sc_adapterlink.flags = SDEV_ATAPI;
     235           0 :         as->sc_adapterlink.pool = &wdc_xfer_iopool;
     236             : 
     237           0 :         strlcpy(drvp->drive_name, as->sc_dev.dv_xname,
     238             :             sizeof(drvp->drive_name));
     239           0 :         drvp->cf_flags = as->sc_dev.dv_cfdata->cf_flags;
     240             : 
     241           0 :         wdc_probe_caps(drvp, id);
     242             : 
     243             :         WDCDEBUG_PRINT(
     244             :                 ("general config %04x capabilities %04x ",
     245             :                     id->atap_config, id->atap_capabilities1),
     246             :                     DEBUG_PROBE);
     247             : 
     248             :         if ((NERRS_MAX - 2) > 0)
     249           0 :                 drvp->n_dmaerrs = NERRS_MAX - 2;
     250             :         else
     251             :                 drvp->n_dmaerrs = 0;
     252           0 :         drvp->drive_flags |= DRIVE_DEVICE_RESET;
     253             : 
     254             :         /* Tape drives do funny DSC stuff */
     255           0 :         if (ATAPI_CFG_TYPE(id->atap_config) ==
     256             :             ATAPI_CFG_TYPE_SEQUENTIAL)
     257           0 :                 drvp->atapi_cap |= ACAP_DSC;
     258             : 
     259           0 :         if ((id->atap_config & ATAPI_CFG_CMD_MASK) ==
     260             :             ATAPI_CFG_CMD_16)
     261           0 :                 drvp->atapi_cap |= ACAP_LEN;
     262             : 
     263           0 :         drvp->atapi_cap |=
     264           0 :             (id->atap_config & ATAPI_CFG_DRQ_MASK);
     265             : 
     266             :         WDCDEBUG_PRINT(("driver caps %04x\n", drvp->atapi_cap),
     267             :             DEBUG_PROBE);
     268             : 
     269           0 :         bzero(&saa, sizeof(saa));
     270           0 :         saa.saa_sc_link = &as->sc_adapterlink;
     271             : 
     272           0 :         child = config_found((struct device *)as, &saa, scsiprint);
     273             : 
     274           0 :         if (child != NULL) {
     275           0 :                 struct scsibus_softc *scsi = (struct scsibus_softc *)child;
     276           0 :                 struct scsi_link *link = scsi_get_link(scsi, 0, 0);
     277             : 
     278           0 :                 if (link) {
     279           0 :                         strlcpy(drvp->drive_name,
     280           0 :                             ((struct device *)(link->device_softc))->dv_xname,
     281             :                             sizeof(drvp->drive_name));
     282             : 
     283           0 :                         wdc_print_caps(drvp);
     284           0 :                 }
     285           0 :         }
     286             : 
     287             : #ifdef WDCDEBUG
     288             :         if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
     289             :                 wdcdebug_atapi_mask &= ~DEBUG_PROBE;
     290             : #endif
     291           0 : }
     292             : 
     293             : int
     294           0 : atapiscsi_activate(struct device *self, int act)
     295             : {
     296           0 :         struct atapiscsi_softc *as = (void *)self;
     297           0 :         struct channel_softc *chp = as->chp;
     298           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];
     299             : 
     300           0 :         switch (act) {
     301             :         case DVACT_SUSPEND:
     302             :                 break;
     303             :         case DVACT_RESUME:
     304             :                 /*
     305             :                  * Do two resets separated by a small delay. The
     306             :                  * first wakes the controller, the second resets
     307             :                  * the channel
     308             :                  */
     309           0 :                 wdc_disable_intr(chp);
     310           0 :                 wdc_reset_channel(drvp, 1);
     311           0 :                 delay(10000);
     312           0 :                 wdc_reset_channel(drvp, 0);
     313           0 :                 wdc_enable_intr(chp);
     314           0 :                 break;
     315             :         }
     316           0 :         return (0);
     317             : }
     318             : 
     319             : int
     320           0 : atapiscsi_detach(struct device *dev, int flags)
     321             : {
     322           0 :         return (config_detach_children(dev, flags));
     323             : }
     324             : 
     325             : void
     326           0 : wdc_atapi_send_cmd(struct scsi_xfer *sc_xfer)
     327             : {
     328           0 :         struct atapiscsi_softc *as = sc_xfer->sc_link->adapter_softc;
     329           0 :         struct channel_softc *chp = as->chp;
     330           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];
     331             :         struct wdc_xfer *xfer;
     332             :         int s;
     333             :         int idx;
     334             : 
     335             :         WDCDEBUG_PRINT(("wdc_atapi_send_cmd %s:%d:%d start\n",
     336             :             chp->wdc->sc_dev.dv_xname, chp->channel, as->drive), DEBUG_XFERS);
     337             : 
     338           0 :         if (sc_xfer->sc_link->target != 0) {
     339           0 :                 sc_xfer->error = XS_DRIVER_STUFFUP;
     340           0 :                 scsi_done(sc_xfer);
     341           0 :                 return;
     342             :         }
     343             : 
     344           0 :         xfer = sc_xfer->io;
     345           0 :         wdc_scrub_xfer(xfer);
     346           0 :         if (sc_xfer->flags & SCSI_POLL)
     347           0 :                 xfer->c_flags |= C_POLL;
     348           0 :         xfer->drive = as->drive;
     349           0 :         xfer->c_flags |= C_ATAPI;
     350           0 :         xfer->cmd = sc_xfer;
     351           0 :         xfer->databuf = sc_xfer->data;
     352           0 :         xfer->c_bcount = sc_xfer->datalen;
     353           0 :         xfer->c_start = wdc_atapi_start;
     354           0 :         xfer->c_intr = wdc_atapi_intr;
     355             : 
     356           0 :         timeout_set(&xfer->atapi_poll_to, wdc_atapi_timer_handler, chp);
     357             : 
     358             :         WDCDEBUG_PRINT(("wdc_atapi_send_cmd %s:%d:%d ",
     359             :             chp->wdc->sc_dev.dv_xname, chp->channel, as->drive),
     360             :             DEBUG_XFERS | DEBUG_ERRORS);
     361             : 
     362           0 :         for (idx = 0; idx < sc_xfer->cmdlen; idx++) {
     363             :                 WDCDEBUG_PRINT((" %02x",
     364             :                                    ((unsigned char *)sc_xfer->cmd)[idx]),
     365             :                     DEBUG_XFERS | DEBUG_ERRORS);
     366             :         }
     367             :         WDCDEBUG_PRINT(("\n"), DEBUG_XFERS | DEBUG_ERRORS);
     368             : 
     369           0 :         s = splbio();
     370             : 
     371           0 :         if (drvp->atapi_cap & ACAP_DSC) {
     372             :                 WDCDEBUG_PRINT(("about to send cmd 0x%x ",
     373             :                     sc_xfer->cmd->opcode), DEBUG_DSC);
     374           0 :                 switch (sc_xfer->cmd->opcode) {
     375             :                 case READ:
     376             :                 case WRITE:
     377           0 :                         xfer->c_flags |= C_MEDIA_ACCESS;
     378             : 
     379             :                         /* If we are not in buffer availability mode,
     380             :                            we limit the first request to 0 bytes, which
     381             :                            gets us into buffer availability mode without
     382             :                            holding the bus.  */
     383           0 :                         if (!(drvp->drive_flags & DRIVE_DSCBA)) {
     384           0 :                                 xfer->c_bcount = 0;
     385           0 :                                 xfer->transfer_len =
     386           0 :                                   _3btol(((struct scsi_rw_tape *)
     387           0 :                                           sc_xfer->cmd)->len);
     388           0 :                                 _lto3b(0,
     389           0 :                                     ((struct scsi_rw_tape *)
     390           0 :                                     sc_xfer->cmd)->len);
     391           0 :                                 xfer->c_done = wdc_atapi_tape_done;
     392             :                                 WDCDEBUG_PRINT(
     393             :                                     ("R/W in completion mode, do 0 blocks\n"),
     394             :                                     DEBUG_DSC);
     395           0 :                         } else
     396             :                                 WDCDEBUG_PRINT(("R/W %d blocks %d bytes\n",
     397             :                                     _3btol(((struct scsi_rw_tape *)
     398             :                                         sc_xfer->cmd)->len),
     399             :                                     sc_xfer->datalen),
     400             :                                     DEBUG_DSC);
     401             : 
     402             :                         /* DSC will change to buffer availability mode.
     403             :                            We reflect this in wdc_atapi_intr.  */
     404             :                         break;
     405             : 
     406             :                 case ERASE:             /* Media access commands */
     407             :                 case LOAD:
     408             :                 case REWIND:
     409             :                 case SPACE:
     410             :                 case WRITE_FILEMARKS:
     411             : #if 0
     412             :                 case LOCATE:
     413             :                 case READ_POSITION:
     414             : #endif
     415             : 
     416           0 :                         xfer->c_flags |= C_MEDIA_ACCESS;
     417           0 :                         break;
     418             : 
     419             :                 default:
     420             :                         WDCDEBUG_PRINT(("no media access\n"), DEBUG_DSC);
     421             :                 }
     422             :         }
     423             : 
     424           0 :         wdc_exec_xfer(chp, xfer);
     425           0 :         splx(s);
     426           0 : }
     427             : 
     428             : void
     429           0 : wdc_atapi_minphys (struct buf *bp, struct scsi_link *sl)
     430             : {
     431           0 :         if (bp->b_bcount > MAX_SIZE)
     432           0 :                 bp->b_bcount = MAX_SIZE;
     433           0 :         minphys(bp);
     434           0 : }
     435             : 
     436             : int
     437           0 : wdc_atapi_ioctl (struct scsi_link *sc_link, u_long cmd, caddr_t addr, int flag)
     438             : {
     439           0 :         struct atapiscsi_softc *as = sc_link->adapter_softc;
     440           0 :         struct channel_softc *chp = as->chp;
     441           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];
     442             : 
     443           0 :         if (sc_link->target != 0)
     444           0 :                 return ENOTTY;
     445             : 
     446           0 :         return (wdc_ioctl(drvp, cmd, addr, flag, curproc));
     447           0 : }
     448             : 
     449             : 
     450             : /*
     451             :  * Returns 1 if we experienced an ATA-level abort command
     452             :  *           (ABRT bit set but no additional sense)
     453             :  *         0 if normal command processing
     454             :  */
     455             : int
     456           0 : atapi_to_scsi_sense(struct scsi_xfer *xfer, u_int8_t flags)
     457             : {
     458           0 :         struct scsi_sense_data *sense = &xfer->sense;
     459             :         int ret = 0;
     460             : 
     461           0 :         xfer->error = XS_SHORTSENSE;
     462             : 
     463           0 :         sense->error_code = SSD_ERRCODE_VALID | SSD_ERRCODE_CURRENT;
     464           0 :         sense->flags = (flags >> 4);
     465             : 
     466             :         WDCDEBUG_PRINT(("Atapi error: %d ", (flags >> 4)), DEBUG_ERRORS);
     467             : 
     468           0 :         if ((flags & 4) && (sense->flags == 0)) {
     469           0 :                 sense->flags = SKEY_ABORTED_COMMAND;
     470             :                 WDCDEBUG_PRINT(("ABRT "), DEBUG_ERRORS);
     471             :                 ret = 1;
     472           0 :         }
     473             : 
     474           0 :         if (flags & 0x1) {
     475           0 :                 sense->flags |= SSD_ILI;
     476             :                 WDCDEBUG_PRINT(("ILI "), DEBUG_ERRORS);
     477           0 :         }
     478             : 
     479           0 :         if (flags & 0x2) {
     480           0 :                 sense->flags |= SSD_EOM;
     481             :                 WDCDEBUG_PRINT(("EOM "), DEBUG_ERRORS);
     482           0 :         }
     483             : 
     484             :         /* Media change requested */
     485             :         /* Let's ignore these in version 1 */
     486           0 :         if (flags & 0x8) {
     487             :                 WDCDEBUG_PRINT(("MCR "), DEBUG_ERRORS);
     488           0 :                 if (sense->flags == 0)
     489           0 :                         xfer->error = XS_NOERROR;
     490             :         }
     491             : 
     492             :         WDCDEBUG_PRINT(("\n"), DEBUG_ERRORS);
     493           0 :         return (ret);
     494             : }
     495             : 
     496             : int wdc_atapi_drive_selected(struct channel_softc *, int);
     497             : 
     498             : int
     499           0 : wdc_atapi_drive_selected(struct channel_softc *chp, int drive)
     500             : {
     501           0 :         u_int8_t reg = CHP_READ_REG(chp, wdr_sdh);
     502             : 
     503             :         WDC_LOG_REG(chp, wdr_sdh, reg);
     504             : 
     505           0 :         return ((reg & 0x10) == (drive << 4));
     506             : }
     507             : 
     508             : enum atapi_context {
     509             :         ctxt_process = 0,
     510             :         ctxt_timer = 1,
     511             :         ctxt_interrupt = 2
     512             : };
     513             : 
     514             : void wdc_atapi_the_machine(struct channel_softc *, struct wdc_xfer *,
     515             :     enum atapi_context);
     516             : 
     517             : void wdc_atapi_the_poll_machine(struct channel_softc *, struct wdc_xfer *);
     518             : 
     519             : void
     520           0 : wdc_atapi_start(struct channel_softc *chp, struct wdc_xfer *xfer)
     521             : {
     522           0 :         xfer->next = wdc_atapi_real_start;
     523             : 
     524           0 :         wdc_atapi_the_machine(chp, xfer, ctxt_process);
     525           0 : }
     526             : 
     527             : 
     528             : void
     529           0 : wdc_atapi_timer_handler(void *arg)
     530             : {
     531           0 :         struct channel_softc *chp = arg;
     532             :         struct wdc_xfer *xfer;
     533             :         int s;
     534             : 
     535           0 :         s = splbio();
     536           0 :         xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
     537           0 :         if (xfer == NULL ||
     538           0 :             !timeout_triggered(&xfer->atapi_poll_to)) {
     539           0 :                 splx(s);
     540           0 :                 return;
     541             :         }
     542           0 :         xfer->c_flags &= ~C_POLL_MACHINE;
     543           0 :         timeout_del(&xfer->atapi_poll_to);
     544           0 :         chp->ch_flags &= ~WDCF_IRQ_WAIT;
     545           0 :         wdc_atapi_the_machine(chp, xfer, ctxt_timer);
     546           0 :         splx(s);
     547           0 : }
     548             : 
     549             : 
     550             : int
     551           0 : wdc_atapi_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
     552             : {
     553           0 :         timeout_del(&chp->ch_timo);
     554             : 
     555             :         /* XXX we should consider an alternate signaling regime here */
     556           0 :         if (xfer->c_flags & C_TIMEOU) {
     557           0 :                 xfer->c_flags &= ~C_TIMEOU;
     558           0 :                 wdc_atapi_the_machine(chp, xfer, ctxt_timer);
     559           0 :                 return (0);
     560             :         }
     561             : 
     562           0 :         wdc_atapi_the_machine(chp, xfer, ctxt_interrupt);
     563             : 
     564           0 :         return (-1);
     565           0 : }
     566             : 
     567             : struct atapi_return_args {
     568             :         int timeout;
     569             :         int delay;
     570             :         int expect_irq;
     571             : };
     572             : 
     573             : #define ARGS_INIT {-1, 0, 0}
     574             : 
     575             : void
     576           0 : wdc_atapi_the_poll_machine(struct channel_softc *chp, struct wdc_xfer *xfer)
     577             : {
     578             :         int  idx = 0;
     579             :         int  current_timeout = 10;
     580             : 
     581             : 
     582           0 :         while (1) {
     583           0 :                 struct atapi_return_args retargs = ARGS_INIT;
     584           0 :                 idx++;
     585             : 
     586           0 :                 (xfer->next)(chp, xfer, (current_timeout * 1000 <= idx),
     587             :                     &retargs);
     588             : 
     589           0 :                 if (xfer->next == NULL) {
     590           0 :                         wdc_free_xfer(chp, xfer);
     591           0 :                         wdcstart(chp);
     592           0 :                         return;
     593             :                 }
     594             : 
     595           0 :                 if (retargs.timeout != -1) {
     596             :                         current_timeout = retargs.timeout;
     597             :                         idx = 0;
     598           0 :                 }
     599             : 
     600           0 :                 if (retargs.delay != 0) {
     601           0 :                         delay (1000 * retargs.delay);
     602           0 :                         idx += 1000 * retargs.delay;
     603           0 :                 }
     604             : 
     605           0 :                 DELAY(1);
     606           0 :         }
     607           0 : }
     608             : 
     609             : 
     610             : void
     611           0 : wdc_atapi_the_machine(struct channel_softc *chp, struct wdc_xfer *xfer,
     612             :     enum atapi_context ctxt)
     613             : {
     614             :         int idx = 0;
     615             :         extern int ticks;
     616           0 :         int timeout_delay = hz / 10;
     617             : 
     618           0 :         if (xfer->c_flags & C_POLL) {
     619           0 :                 wdc_disable_intr(chp);
     620             : 
     621           0 :                 if (ctxt != ctxt_process) {
     622           0 :                         if (ctxt == ctxt_interrupt)
     623           0 :                                 xfer->endticks = 1;
     624             : 
     625           0 :                         return;
     626             :                 }
     627             : 
     628           0 :                 wdc_atapi_the_poll_machine(chp, xfer);
     629           0 :                 return;
     630             :         }
     631             : 
     632             :         /* Don't go through more than 50 state machine steps
     633             :            before yielding. This tries to limit the amount of time
     634             :            spent at high SPL */
     635           0 :         for (idx = 0; idx < 50; idx++) {
     636           0 :                 struct atapi_return_args retargs = ARGS_INIT;
     637             : 
     638           0 :                 (xfer->next)(chp, xfer,
     639           0 :                     xfer->endticks && (ticks - xfer->endticks >= 0),
     640             :                     &retargs);
     641             : 
     642           0 :                 if (retargs.timeout != -1)
     643             :                         /*
     644             :                          * Add 1 tick to compensate for the fact that we
     645             :                          * can be just microseconds before the tick changes.
     646             :                          */
     647           0 :                         xfer->endticks =
     648           0 :                             max((retargs.timeout * hz) / 1000, 1) + 1 + ticks;
     649             : 
     650           0 :                 if (xfer->next == NULL) {
     651           0 :                         if (xfer->c_flags & C_POLL_MACHINE)
     652           0 :                                 timeout_del(&xfer->atapi_poll_to);
     653             : 
     654           0 :                         wdc_free_xfer(chp, xfer);
     655           0 :                         wdcstart(chp);
     656             : 
     657           0 :                         return;
     658             :                 }
     659             : 
     660           0 :                 if (retargs.expect_irq) {
     661             :                         int timeout_period;
     662           0 :                         chp->ch_flags |= WDCF_IRQ_WAIT;
     663           0 :                         timeout_period =  xfer->endticks - ticks;
     664           0 :                         if (timeout_period < 1)
     665             :                                 timeout_period = 1;
     666           0 :                         timeout_add(&chp->ch_timo, timeout_period);
     667             :                         return;
     668             :                 }
     669             : 
     670           0 :                 if (retargs.delay != 0) {
     671           0 :                         timeout_delay = max(retargs.delay * hz / 1000, 1);
     672           0 :                         break;
     673             :                 }
     674             : 
     675           0 :                 DELAY(1);
     676           0 :         }
     677             : 
     678           0 :         timeout_add(&xfer->atapi_poll_to, timeout_delay);
     679           0 :         xfer->c_flags |= C_POLL_MACHINE;
     680             : 
     681           0 :         return;
     682           0 : }
     683             : 
     684             : 
     685             : void wdc_atapi_update_status(struct channel_softc *);
     686             : 
     687             : void
     688           0 : wdc_atapi_update_status(struct channel_softc *chp)
     689             : {
     690           0 :         chp->ch_status = CHP_READ_REG(chp, wdr_status);
     691             : 
     692             :         WDC_LOG_STATUS(chp, chp->ch_status);
     693             : 
     694           0 :         if (chp->ch_status == 0xff && (chp->ch_flags & WDCF_ONESLAVE)) {
     695           0 :                 wdc_set_drive(chp, 1);
     696             : 
     697           0 :                 chp->ch_status = CHP_READ_REG(chp, wdr_status);
     698             :                 WDC_LOG_STATUS(chp, chp->ch_status);
     699           0 :         }
     700             : 
     701           0 :         if ((chp->ch_status & (WDCS_BSY | WDCS_ERR)) == WDCS_ERR) {
     702           0 :                 chp->ch_error = CHP_READ_REG(chp, wdr_error);
     703             :                 WDC_LOG_ERROR(chp, chp->ch_error);
     704           0 :         }
     705           0 : }
     706             : 
     707             : void
     708           0 : wdc_atapi_real_start(struct channel_softc *chp, struct wdc_xfer *xfer,
     709             :     int timeout, struct atapi_return_args *ret)
     710             : {
     711             : #ifdef WDCDEBUG
     712             :         struct scsi_xfer *sc_xfer = xfer->cmd;
     713             : #endif
     714           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
     715             : 
     716             :         /*
     717             :          * Only set the DMA flag if the transfer is reasonably large.
     718             :          * At least one older drive failed to complete a 4 byte DMA transfer.
     719             :          */
     720             : 
     721             :         /* Turn off DMA flag on REQUEST SENSE */
     722             : 
     723           0 :         if (!(xfer->c_flags & (C_POLL | C_SENSE | C_MEDIA_ACCESS)) &&
     724           0 :             (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
     725           0 :             (xfer->c_bcount > 100))
     726           0 :                 xfer->c_flags |= C_DMA;
     727             :         else
     728           0 :                 xfer->c_flags &= ~C_DMA;
     729             : 
     730             : 
     731           0 :         wdc_set_drive(chp, xfer->drive);
     732             : 
     733           0 :         DELAY(1);
     734             : 
     735           0 :         xfer->next = wdc_atapi_real_start_2;
     736           0 :         ret->timeout = ATAPI_DELAY;
     737             : 
     738             :         WDCDEBUG_PRINT(("wdc_atapi_start %s:%d:%d, scsi flags 0x%x, "
     739             :             "ATA flags 0x%x\n",
     740             :             chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive,
     741             :             sc_xfer->flags, xfer->c_flags), DEBUG_XFERS);
     742             : 
     743             : 
     744             :         return;
     745           0 : }
     746             : 
     747             : 
     748             : void
     749           0 : wdc_atapi_real_start_2(struct channel_softc *chp, struct wdc_xfer *xfer,
     750             :     int timeout, struct atapi_return_args *ret)
     751             : {
     752           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
     753           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
     754             : 
     755           0 :         if (timeout) {
     756           0 :                 printf("wdc_atapi_start: not ready, st = %02x\n",
     757           0 :                     chp->ch_status);
     758             : 
     759           0 :                 sc_xfer->error = XS_TIMEOUT;
     760           0 :                 xfer->next = wdc_atapi_reset;
     761           0 :                 return;
     762             :         } else {
     763           0 :                 wdc_atapi_update_status(chp);
     764             : 
     765           0 :                 if (chp->ch_status & (WDCS_BSY | WDCS_DRQ))
     766           0 :                         return;
     767             :         }
     768             : 
     769             :         /* Do control operations specially. */
     770           0 :         if (drvp->state < ATAPI_READY_STATE) {
     771           0 :                 xfer->next = wdc_atapi_ctrl;
     772           0 :                 return;
     773             :         }
     774             : 
     775           0 :         xfer->next = wdc_atapi_send_packet;
     776           0 :         return;
     777           0 : }
     778             : 
     779             : 
     780             : void
     781           0 : wdc_atapi_send_packet(struct channel_softc *chp, struct wdc_xfer *xfer,
     782             :     int timeout, struct atapi_return_args *ret)
     783             : {
     784           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
     785           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
     786             : 
     787             :         /*
     788             :          * Even with WDCS_ERR, the device should accept a command packet.
     789             :          * Limit length to what can be stuffed into the cylinder register
     790             :          * (16 bits).  Some CD-ROMs seem to interpret '0' as 65536,
     791             :          * but not all devices do that and it's not obvious from the
     792             :          * ATAPI spec that this behaviour should be expected.  If more
     793             :          * data is necessary, multiple data transfer phases will be done.
     794             :          */
     795             : 
     796           0 :         wdccommand(chp, xfer->drive, ATAPI_PKT_CMD,
     797           0 :             xfer->c_bcount <= 0xfffe ? xfer->c_bcount : 0xfffe,
     798             :             0, 0, 0,
     799           0 :             (xfer->c_flags & C_DMA) ? ATAPI_PKT_CMD_FTRE_DMA : 0);
     800             : 
     801           0 :         if (xfer->c_flags & C_DMA)
     802           0 :                 drvp->n_xfers++;
     803             : 
     804           0 :         DELAY(1);
     805             : 
     806           0 :         xfer->next = wdc_atapi_intr_command;
     807           0 :         ret->timeout = sc_xfer->timeout;
     808             : 
     809           0 :         if ((drvp->atapi_cap & ATAPI_CFG_DRQ_MASK) == ATAPI_CFG_IRQ_DRQ) {
     810             :                 /* We expect an IRQ to tell us of the next state */
     811           0 :                 ret->expect_irq = 1;
     812           0 :         }
     813             : 
     814             :         WDCDEBUG_PRINT(("wdc_atapi_send_packet %s:%d:%d command sent\n",
     815             :             chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive
     816             :             ), DEBUG_XFERS);
     817             :         return;
     818           0 : }
     819             : 
     820             : void
     821           0 : wdc_atapi_intr_command(struct channel_softc *chp, struct wdc_xfer *xfer,
     822             :     int timeout, struct atapi_return_args *ret)
     823             : {
     824           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
     825           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
     826           0 :         struct atapiscsi_softc *as = sc_xfer->sc_link->adapter_softc;
     827             :         int i;
     828           0 :         u_int8_t cmd[16];
     829             :         struct scsi_sense *cmd_reqsense;
     830           0 :         int cmdlen = (drvp->atapi_cap & ACAP_LEN) ? 16 : 12;
     831           0 :         int dma_flags = ((sc_xfer->flags & SCSI_DATA_IN) ||
     832           0 :             (xfer->c_flags & C_SENSE)) ?  WDC_DMA_READ : 0;
     833             : 
     834           0 :         wdc_atapi_update_status(chp);
     835             : 
     836           0 :         if ((chp->ch_status & WDCS_BSY) || !(chp->ch_status & WDCS_DRQ)) {
     837           0 :                 if (timeout)
     838             :                         goto timeout;
     839             : 
     840           0 :                 return;
     841             :         }
     842             : 
     843           0 :         if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
     844           0 :                 chp->wdc->irqack(chp);
     845             : 
     846           0 :         bzero(cmd, sizeof(cmd));
     847             : 
     848           0 :         if (xfer->c_flags & C_SENSE) {
     849           0 :                 cmd_reqsense = (struct scsi_sense *)&cmd[0];
     850           0 :                 cmd_reqsense->opcode = REQUEST_SENSE;
     851           0 :                 cmd_reqsense->length = xfer->c_bcount;
     852           0 :         } else
     853           0 :                 bcopy(sc_xfer->cmd, cmd, sc_xfer->cmdlen);
     854             : 
     855             :         WDC_LOG_ATAPI_CMD(chp, xfer->drive, xfer->c_flags,
     856             :             cmdlen, cmd);
     857             : 
     858           0 :         for (i = 0; i < 12; i++)
     859             :                 WDCDEBUG_PRINT(("%02x ", cmd[i]), DEBUG_INTR);
     860             :         WDCDEBUG_PRINT((": PHASE_CMDOUT\n"), DEBUG_INTR);
     861             : 
     862             :         /* Init the DMA channel if necessary */
     863           0 :         if (xfer->c_flags & C_DMA) {
     864           0 :                 if ((*chp->wdc->dma_init)(chp->wdc->dma_arg,
     865           0 :                     chp->channel, xfer->drive, xfer->databuf,
     866           0 :                     xfer->c_bcount, dma_flags) != 0) {
     867           0 :                         sc_xfer->error = XS_DRIVER_STUFFUP;
     868             : 
     869           0 :                         xfer->next = wdc_atapi_reset;
     870           0 :                         return;
     871             :                 }
     872             :         }
     873             : 
     874           0 :         wdc_output_bytes(drvp, cmd, cmdlen);
     875             : 
     876             :         /* Start the DMA channel if necessary */
     877           0 :         if (xfer->c_flags & C_DMA) {
     878           0 :                 (*chp->wdc->dma_start)(chp->wdc->dma_arg,
     879           0 :                     chp->channel, xfer->drive);
     880           0 :                 xfer->next = wdc_atapi_intr_complete;
     881           0 :         } else {
     882           0 :                 if (xfer->c_bcount == 0)
     883           0 :                         as->protocol_phase = as_completed;
     884             :                 else
     885           0 :                         as->protocol_phase = as_data;
     886             : 
     887           0 :                 xfer->next = wdc_atapi_pio_intr;
     888             :         }
     889             : 
     890           0 :         ret->expect_irq = 1;
     891             : 
     892             :         /* If we read/write to a tape we will get into buffer
     893             :            availability mode.  */
     894           0 :         if (drvp->atapi_cap & ACAP_DSC) {
     895           0 :                 if ((sc_xfer->cmd->opcode == READ ||
     896           0 :                        sc_xfer->cmd->opcode == WRITE)) {
     897           0 :                         drvp->drive_flags |= DRIVE_DSCBA;
     898             :                         WDCDEBUG_PRINT(("set DSCBA\n"), DEBUG_DSC);
     899           0 :                 } else if ((xfer->c_flags & C_MEDIA_ACCESS) &&
     900           0 :                     (drvp->drive_flags & DRIVE_DSCBA)) {
     901             :                         /* Clause 3.2.4 of QIC-157 D.
     902             : 
     903             :                            Any media access command other than read or
     904             :                            write will switch DSC back to completion
     905             :                            mode */
     906           0 :                         drvp->drive_flags &= ~DRIVE_DSCBA;
     907             :                         WDCDEBUG_PRINT(("clear DCSBA\n"), DEBUG_DSC);
     908           0 :                 }
     909             :         }
     910             : 
     911           0 :         return;
     912             : 
     913             :  timeout:
     914           0 :         printf ("%s:%d:%d: device timeout waiting to send SCSI packet\n",
     915           0 :             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive);
     916             : 
     917           0 :         sc_xfer->error = XS_TIMEOUT;
     918           0 :         xfer->next = wdc_atapi_reset;
     919           0 :         return;
     920           0 : }
     921             : 
     922             : 
     923             : char *
     924           0 : wdc_atapi_in_data_phase(struct wdc_xfer *xfer, int len, int ire)
     925             : {
     926           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
     927           0 :         struct atapiscsi_softc *as = sc_xfer->sc_link->adapter_softc;
     928             :         char *message;
     929             : 
     930           0 :         if (as->protocol_phase != as_data) {
     931             :                 message = "unexpected data phase";
     932           0 :                 goto unexpected_state;
     933             :         }
     934             : 
     935           0 :         if (ire & WDCI_CMD) {
     936             :                 message = "unexpectedly in command phase";
     937           0 :                 goto unexpected_state;
     938             :         }
     939             : 
     940           0 :         if (!(xfer->c_flags & C_SENSE)) {
     941           0 :                 if (!(sc_xfer->flags & (SCSI_DATA_IN | SCSI_DATA_OUT))) {
     942             :                         message = "data phase where none expected";
     943           0 :                         goto unexpected_state;
     944             :                 }
     945             : 
     946             :                 /* Make sure polarities match */
     947           0 :                 if (((ire & WDCI_IN) == WDCI_IN) ==
     948           0 :                     ((sc_xfer->flags & SCSI_DATA_OUT) == SCSI_DATA_OUT)) {
     949             :                         message = "data transfer direction disagreement";
     950           0 :                         goto unexpected_state;
     951             :                 }
     952             :         } else {
     953           0 :                 if (!(ire & WDCI_IN)) {
     954             :                         message = "data transfer direction disagreement during sense";
     955           0 :                         goto unexpected_state;
     956             :                 }
     957             :         }
     958             : 
     959           0 :         if (len == 0) {
     960             :                 message = "zero length transfer requested in data phase";
     961           0 :                 goto unexpected_state;
     962             :         }
     963             : 
     964             : 
     965           0 :         return (0);
     966             : 
     967             :  unexpected_state:
     968             : 
     969           0 :         return (message);
     970           0 : }
     971             : 
     972             : void
     973           0 : wdc_atapi_intr_data(struct channel_softc *chp, struct wdc_xfer *xfer,
     974             :     int timeout, struct atapi_return_args *ret)
     975             : {
     976           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
     977           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
     978             :         int len, ire;
     979             :         char *message;
     980             :         int tohost;
     981             : 
     982           0 :         len = (CHP_READ_REG(chp, wdr_cyl_hi) << 8) |
     983           0 :             CHP_READ_REG(chp, wdr_cyl_lo);
     984             :         WDC_LOG_REG(chp, wdr_cyl_lo, len);
     985             : 
     986           0 :         ire = CHP_READ_REG(chp, wdr_ireason);
     987             :         WDC_LOG_REG(chp, wdr_ireason, ire);
     988             : 
     989           0 :         if ((message = wdc_atapi_in_data_phase(xfer, len, ire))) {
     990             :                 /* The drive has dropped BSY before setting up the
     991             :                    registers correctly for DATA phase. This drive is
     992             :                    not compliant with ATA/ATAPI-4.
     993             : 
     994             :                    Give the drive 100ms to get its house in order
     995             :                    before we try again.  */
     996             :                 WDCDEBUG_PRINT(("wdc_atapi_intr: %s\n", message),
     997             :                     DEBUG_ERRORS);
     998             : 
     999           0 :                 if (!timeout) {
    1000           0 :                         ret->delay = 100;
    1001           0 :                         return;
    1002             :                 }
    1003             :         }
    1004             : 
    1005           0 :         tohost = ((sc_xfer->flags & SCSI_DATA_IN) != 0 ||
    1006           0 :             (xfer->c_flags & C_SENSE) != 0);
    1007             : 
    1008           0 :         if (xfer->c_bcount >= len) {
    1009             :                 WDCDEBUG_PRINT(("wdc_atapi_intr: c_bcount %d len %d "
    1010             :                     "st 0x%b err 0x%x "
    1011             :                     "ire 0x%x\n", xfer->c_bcount,
    1012             :                     len, chp->ch_status, WDCS_BITS, chp->ch_error, ire),
    1013             :                     DEBUG_INTR);
    1014             : 
    1015             :                 /* Common case */
    1016           0 :                 if (!tohost)
    1017           0 :                         wdc_output_bytes(drvp, (u_int8_t *)xfer->databuf +
    1018             :                             xfer->c_skip, len);
    1019             :                 else
    1020           0 :                         wdc_input_bytes(drvp, (u_int8_t *)xfer->databuf +
    1021             :                             xfer->c_skip, len);
    1022             : 
    1023           0 :                 xfer->c_skip += len;
    1024           0 :                 xfer->c_bcount -= len;
    1025           0 :         } else {
    1026             :                 /* Exceptional case - drive want to transfer more
    1027             :                    data than we have buffer for */
    1028           0 :                 if (!tohost) {
    1029             :                         /* Wouldn't it be better to just abort here rather
    1030             :                            than to write random stuff to drive? */
    1031           0 :                         printf("wdc_atapi_intr: warning: device requesting "
    1032             :                             "%d bytes, only %d left in buffer\n", len, xfer->c_bcount);
    1033             : 
    1034           0 :                         wdc_output_bytes(drvp, (u_int8_t *)xfer->databuf +
    1035           0 :                             xfer->c_skip, xfer->c_bcount);
    1036             : 
    1037           0 :                         CHP_WRITE_RAW_MULTI_2(chp, NULL,
    1038             :                             len - xfer->c_bcount);
    1039           0 :                 } else {
    1040           0 :                         printf("wdc_atapi_intr: warning: reading only "
    1041             :                             "%d of %d bytes\n", xfer->c_bcount, len);
    1042             : 
    1043           0 :                         wdc_input_bytes(drvp,
    1044           0 :                             (char *)xfer->databuf + xfer->c_skip,
    1045           0 :                             xfer->c_bcount);
    1046           0 :                         wdcbit_bucket(chp, len - xfer->c_bcount);
    1047             :                 }
    1048             : 
    1049           0 :                 xfer->c_skip += xfer->c_bcount;
    1050           0 :                 xfer->c_bcount = 0;
    1051             :         }
    1052             : 
    1053           0 :         ret->expect_irq = 1;
    1054           0 :         xfer->next = wdc_atapi_pio_intr;
    1055             : 
    1056           0 :         return;
    1057           0 : }
    1058             : 
    1059             : void
    1060           0 : wdc_atapi_intr_complete(struct channel_softc *chp, struct wdc_xfer *xfer,
    1061             :     int timeout, struct atapi_return_args *ret)
    1062             : {
    1063           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
    1064           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
    1065           0 :         struct atapiscsi_softc *as = sc_xfer->sc_link->adapter_softc;
    1066             : 
    1067             :         WDCDEBUG_PRINT(("PHASE_COMPLETED\n"), DEBUG_INTR);
    1068             : 
    1069           0 :         if (xfer->c_flags & C_DMA) {
    1070             :                 int retry;
    1071             : 
    1072           0 :                 if (timeout) {
    1073           0 :                         sc_xfer->error = XS_TIMEOUT;
    1074           0 :                         ata_dmaerr(drvp);
    1075             : 
    1076           0 :                         xfer->next = wdc_atapi_reset;
    1077           0 :                         return;
    1078             :                 }
    1079             : 
    1080           0 :                 for (retry = 5; retry > 0; retry--) {
    1081           0 :                         wdc_atapi_update_status(chp);
    1082           0 :                         if ((chp->ch_status & (WDCS_BSY | WDCS_DRQ)) == 0)
    1083             :                                 break;
    1084           0 :                         DELAY(5);
    1085             :                 }
    1086           0 :                 if (retry == 0) {
    1087           0 :                         ret->expect_irq = 1;
    1088           0 :                         return;
    1089             :                 }
    1090             : 
    1091           0 :                 chp->wdc->dma_status =
    1092           0 :                     (*chp->wdc->dma_finish)
    1093           0 :                     (chp->wdc->dma_arg, chp->channel,
    1094           0 :                         xfer->drive, 1);
    1095             : 
    1096           0 :                 if (chp->wdc->dma_status & WDC_DMAST_UNDER)
    1097           0 :                         xfer->c_bcount = 1;
    1098             :                 else
    1099           0 :                         xfer->c_bcount = 0;
    1100           0 :         }
    1101             : 
    1102           0 :         as->protocol_phase = as_none;
    1103             : 
    1104           0 :         if (xfer->c_flags & C_SENSE) {
    1105           0 :                 if (chp->ch_status & WDCS_ERR) {
    1106           0 :                         if (chp->ch_error & WDCE_ABRT) {
    1107             :                                 WDCDEBUG_PRINT(("wdc_atapi_intr: request_sense aborted, "
    1108             :                                                 "calling wdc_atapi_done()"
    1109             :                                         ), DEBUG_INTR);
    1110           0 :                                 xfer->next = wdc_atapi_done;
    1111           0 :                                 return;
    1112             :                         }
    1113             : 
    1114             :                         /*
    1115             :                          * request sense failed ! it's not supposed
    1116             :                          * to be possible
    1117             :                          */
    1118           0 :                         sc_xfer->error = XS_SHORTSENSE;
    1119           0 :                 } else if (xfer->c_bcount < sizeof(sc_xfer->sense)) {
    1120             :                         /* use the sense we just read */
    1121           0 :                         sc_xfer->error = XS_SENSE;
    1122           0 :                 } else {
    1123             :                         /*
    1124             :                          * command completed, but no data was read.
    1125             :                          * use the short sense we saved previously.
    1126             :                          */
    1127           0 :                         sc_xfer->error = XS_SHORTSENSE;
    1128             :                 }
    1129             :         } else {
    1130           0 :                 sc_xfer->resid = xfer->c_bcount;
    1131           0 :                 if (chp->ch_status & WDCS_ERR) {
    1132           0 :                         if (!atapi_to_scsi_sense(sc_xfer, chp->ch_error) &&
    1133           0 :                             (sc_xfer->sc_link->quirks &
    1134           0 :                              ADEV_NOSENSE) == 0) {
    1135             :                                 /*
    1136             :                                  * let the driver issue a
    1137             :                                  * 'request sense'
    1138             :                                  */
    1139           0 :                                 xfer->databuf = &sc_xfer->sense;
    1140           0 :                                 xfer->c_bcount = sizeof(sc_xfer->sense);
    1141           0 :                                 xfer->c_skip = 0;
    1142           0 :                                 xfer->c_done = NULL;
    1143           0 :                                 xfer->c_flags |= C_SENSE;
    1144           0 :                                 xfer->next = wdc_atapi_real_start;
    1145           0 :                                 return;
    1146             :                         }
    1147             :                 }
    1148             :         }
    1149             : 
    1150           0 :         if ((xfer->c_flags & C_DMA) &&
    1151           0 :             (chp->wdc->dma_status & ~WDC_DMAST_UNDER)) {
    1152           0 :                 ata_dmaerr(drvp);
    1153           0 :                 sc_xfer->error = XS_RESET;
    1154             : 
    1155           0 :                 xfer->next = wdc_atapi_reset;
    1156           0 :                 return;
    1157             :         }
    1158             : 
    1159             : 
    1160           0 :         if (xfer->c_bcount != 0) {
    1161             :                 WDCDEBUG_PRINT(("wdc_atapi_intr: bcount value is "
    1162             :                                 "%d after io\n", xfer->c_bcount), DEBUG_XFERS);
    1163             :         }
    1164             : #ifdef DIAGNOSTIC
    1165           0 :         if (xfer->c_bcount < 0) {
    1166           0 :                 printf("wdc_atapi_intr warning: bcount value "
    1167             :                        "is %d after io\n", xfer->c_bcount);
    1168           0 :         }
    1169             : #endif
    1170             : 
    1171             :         WDCDEBUG_PRINT(("wdc_atapi_intr: wdc_atapi_done() (end), error 0x%x "
    1172             :                         "\n", sc_xfer->error),
    1173             :                        DEBUG_INTR);
    1174             : 
    1175             : 
    1176           0 :         if (xfer->c_done)
    1177           0 :                 xfer->next = xfer->c_done;
    1178             :         else
    1179           0 :                 xfer->next = wdc_atapi_done;
    1180             : 
    1181           0 :         return;
    1182           0 : }
    1183             : 
    1184             : void
    1185           0 : wdc_atapi_pio_intr(struct channel_softc *chp, struct wdc_xfer *xfer,
    1186             :     int timeout, struct atapi_return_args *ret)
    1187             : {
    1188           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
    1189           0 :         struct atapiscsi_softc *as = sc_xfer->sc_link->adapter_softc;
    1190             :         u_int8_t ireason;
    1191             : 
    1192           0 :         wdc_atapi_update_status(chp);
    1193             : 
    1194           0 :         if (chp->ch_status & WDCS_BSY) {
    1195           0 :                 if (timeout)
    1196             :                         goto timeout;
    1197             : 
    1198           0 :                 return;
    1199             :         }
    1200             : 
    1201           0 :         if (!wdc_atapi_drive_selected(chp, xfer->drive)) {
    1202             :                 WDCDEBUG_PRINT(("wdc_atapi_intr_for_us: wrong drive selected\n"), DEBUG_INTR);
    1203           0 :                 wdc_set_drive(chp, xfer->drive);
    1204           0 :                 delay (1);
    1205             : 
    1206           0 :                 if (!timeout)
    1207           0 :                         return;
    1208             :         }
    1209             : 
    1210           0 :         if ((xfer->c_flags & C_MEDIA_ACCESS) &&
    1211           0 :             !(chp->ch_status & (WDCS_DSC | WDCS_DRQ))) {
    1212           0 :                 if (timeout)
    1213             :                         goto timeout;
    1214             : 
    1215           0 :                 ret->delay = 100;
    1216           0 :                 return;
    1217             :         }
    1218             : 
    1219           0 :         if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
    1220           0 :                 chp->wdc->irqack(chp);
    1221             : 
    1222           0 :         ireason = CHP_READ_REG(chp, wdr_ireason);
    1223             :         WDC_LOG_REG(chp, wdr_ireason, ireason);
    1224             : 
    1225             :         WDCDEBUG_PRINT(("Phase %d, (0x%b, 0x%x) ", as->protocol_phase,
    1226             :             chp->ch_status, WDCS_BITS, ireason), DEBUG_INTR );
    1227             : 
    1228           0 :         switch (as->protocol_phase) {
    1229             :         case as_data:
    1230           0 :                 if ((chp->ch_status & WDCS_DRQ) ||
    1231           0 :                     (ireason & 3) != 3) {
    1232           0 :                         if (timeout)
    1233             :                                 goto timeout;
    1234             : 
    1235           0 :                         wdc_atapi_intr_data(chp, xfer, timeout, ret);
    1236           0 :                         return;
    1237             :                 }
    1238             : 
    1239           0 :                 wdc_atapi_intr_complete(chp, xfer, timeout, ret);
    1240           0 :                 return;
    1241             : 
    1242             :         case as_completed:
    1243           0 :                 if ((chp->ch_status & WDCS_DRQ) ||
    1244           0 :                     (ireason & 3) != 3) {
    1245           0 :                         if (timeout)
    1246             :                                 goto timeout;
    1247             : 
    1248           0 :                         ret->delay = 100;
    1249           0 :                         return;
    1250             :                 }
    1251             : 
    1252           0 :                 wdc_atapi_intr_complete(chp, xfer, timeout, ret);
    1253           0 :                 return;
    1254             : 
    1255             :         default:
    1256           0 :                 printf ("atapiscsi: Shouldn't get here\n");
    1257           0 :                 sc_xfer->error = XS_DRIVER_STUFFUP;
    1258           0 :                 xfer->next = wdc_atapi_reset;
    1259           0 :                 return;
    1260             :         }
    1261             : 
    1262             :         return;
    1263             : timeout:
    1264           0 :         ireason = CHP_READ_REG(chp, wdr_ireason);
    1265             :         WDC_LOG_REG(chp, wdr_ireason, ireason);
    1266             : 
    1267           0 :         printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d, "
    1268             :             "status=0x%b, ireason=0x%x\n",
    1269           0 :             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
    1270           0 :             xfer->c_bcount, xfer->c_skip, chp->ch_status, WDCS_BITS, ireason);
    1271             : 
    1272           0 :         sc_xfer->error = XS_TIMEOUT;
    1273           0 :         xfer->next = wdc_atapi_reset;
    1274           0 :         return;
    1275           0 : }
    1276             : 
    1277             : void
    1278           0 : wdc_atapi_ctrl(struct channel_softc *chp, struct wdc_xfer *xfer,
    1279             :     int timeout, struct atapi_return_args *ret)
    1280             : {
    1281           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
    1282           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
    1283             :         char *errstring = NULL;
    1284             : 
    1285           0 :         wdc_atapi_update_status(chp);
    1286             : 
    1287           0 :         if (!timeout) {
    1288           0 :                 switch (drvp->state) {
    1289             :                 case ATAPI_IDENTIFY_WAIT_STATE:
    1290           0 :                         if (chp->ch_status & WDCS_BSY)
    1291           0 :                                 return;
    1292             :                         break;
    1293             :                 default:
    1294           0 :                         if (chp->ch_status & (WDCS_BSY | WDCS_DRQ))
    1295           0 :                                 return;
    1296             :                         break;
    1297             :                 }
    1298             :         }
    1299             : 
    1300           0 :         if (!wdc_atapi_drive_selected(chp, xfer->drive))
    1301             :         {
    1302           0 :                 wdc_set_drive(chp, xfer->drive);
    1303           0 :                 delay (1);
    1304           0 :         }
    1305             : 
    1306           0 :         if (timeout) {
    1307             :                 int trigger_timeout = 1;
    1308             : 
    1309           0 :                 switch (drvp->state) {
    1310             :                 case ATAPI_DEVICE_RESET_WAIT_STATE:
    1311             :                         errstring = "Device Reset Wait";
    1312           0 :                         drvp->drive_flags &= ~DRIVE_DEVICE_RESET;
    1313           0 :                         break;
    1314             : 
    1315             :                 case ATAPI_IDENTIFY_WAIT_STATE:
    1316             :                         errstring = "Identify";
    1317           0 :                         if (!(chp->ch_status & WDCS_BSY) &&
    1318           0 :                             (chp->ch_status & (WDCS_DRQ | WDCS_ERR)))
    1319           0 :                                 trigger_timeout = 0;
    1320             : 
    1321             :                         break;
    1322             : 
    1323             :                 case ATAPI_PIOMODE_STATE:
    1324             :                         errstring = "Post-Identify";
    1325           0 :                         if (!(chp->ch_status & (WDCS_BSY | WDCS_DRQ)))
    1326           0 :                                 trigger_timeout = 0;
    1327             :                         break;
    1328             : 
    1329             :                 case ATAPI_PIOMODE_WAIT_STATE:
    1330             :                         errstring = "PIOMODE";
    1331           0 :                         if (chp->ch_status & (WDCS_BSY | WDCS_DRQ))
    1332           0 :                                 drvp->drive_flags &= ~DRIVE_MODE;
    1333             :                         else
    1334             :                                 trigger_timeout = 0;
    1335             :                         break;
    1336             :                 case ATAPI_DMAMODE_WAIT_STATE:
    1337             :                         errstring = "dmamode";
    1338           0 :                         if (chp->ch_status & (WDCS_BSY | WDCS_DRQ))
    1339           0 :                                 drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
    1340             :                         else
    1341             :                                 trigger_timeout = 0;
    1342             :                         break;
    1343             : 
    1344             :                 default:
    1345             :                         errstring = "unknown state";
    1346           0 :                         break;
    1347             :                 }
    1348             : 
    1349           0 :                 if (trigger_timeout)
    1350           0 :                         goto timeout;
    1351           0 :         }
    1352             : 
    1353             :         WDCDEBUG_PRINT(("wdc_atapi_ctrl %s:%d:%d state %d\n",
    1354             :             chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive, drvp->state),
    1355             :             DEBUG_INTR | DEBUG_FUNCS);
    1356             : 
    1357           0 :         switch (drvp->state) {
    1358             :                 /* My ATAPI slave device likes to assert DASP-/PDIAG- until
    1359             :                    it is DEVICE RESET. This causes the LED to stay on.
    1360             : 
    1361             :                    There is a trade-off here. This drive will cause any
    1362             :                    play-back or seeks happening to be interrupted.
    1363             : 
    1364             :                    Note that the bus reset that triggered this state
    1365             :                    (which may have been caused by the other drive on
    1366             :                    the chain) need not interrupt this playback. It happens
    1367             :                    to on my Smart & Friendly CD burner.
    1368             : 
    1369             :                    - csapuntz@
    1370             :                 */
    1371             :         case ATAPI_RESET_BASE_STATE:
    1372           0 :                 if ((drvp->drive_flags & DRIVE_DEVICE_RESET) == 0) {
    1373           0 :                         drvp->state = ATAPI_IDENTIFY_STATE;
    1374           0 :                         break;
    1375             :                 }
    1376             : 
    1377           0 :                 wdccommandshort(chp, drvp->drive, ATAPI_DEVICE_RESET);
    1378           0 :                 drvp->state = ATAPI_DEVICE_RESET_WAIT_STATE;
    1379           0 :                 ret->delay = ATAPI_RESET_DELAY;
    1380           0 :                 ret->timeout = ATAPI_RESET_WAIT;
    1381           0 :                 break;
    1382             : 
    1383             :         case ATAPI_DEVICE_RESET_WAIT_STATE:
    1384             :                 /* FALLTHROUGH */
    1385             : 
    1386             :         case ATAPI_IDENTIFY_STATE:
    1387           0 :                 wdccommandshort(chp, drvp->drive, ATAPI_IDENTIFY_DEVICE);
    1388           0 :                 drvp->state = ATAPI_IDENTIFY_WAIT_STATE;
    1389           0 :                 ret->delay = 10;
    1390           0 :                 ret->timeout = ATAPI_RESET_WAIT;
    1391           0 :                 break;
    1392             : 
    1393             :         case ATAPI_IDENTIFY_WAIT_STATE: {
    1394             :                 int idx = 0;
    1395             : 
    1396           0 :                 while ((chp->ch_status & WDCS_DRQ) &&
    1397           0 :                     idx++ < 20) {
    1398           0 :                         wdcbit_bucket(chp, 512);
    1399             : 
    1400           0 :                         DELAY(1);
    1401           0 :                         wdc_atapi_update_status(chp);
    1402             :                 }
    1403             : 
    1404           0 :                 drvp->state = ATAPI_PIOMODE_STATE;
    1405             :                 /*
    1406             :                  * Note, we can't go directly to set PIO mode
    1407             :                  * because the drive is free to assert BSY
    1408             :                  * after the transfer
    1409             :                  */
    1410             :                 break;
    1411             :         }
    1412             : 
    1413             :         case ATAPI_PIOMODE_STATE:
    1414             :                 /* Don't try to set mode if controller can't be adjusted */
    1415           0 :                 if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
    1416             :                         goto ready;
    1417             :                 /* Also don't try if the drive didn't report its mode */
    1418           0 :                 if ((drvp->drive_flags & DRIVE_MODE) == 0)
    1419             :                         goto ready;
    1420             :                 /* SET FEATURES 0x08 is only for PIO mode > 2 */
    1421           0 :                 if (drvp->PIO_mode <= 2)
    1422             :                         goto ready;
    1423           0 :                 wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
    1424           0 :                     0x08 | drvp->PIO_mode, WDSF_SET_MODE);
    1425           0 :                 drvp->state = ATAPI_PIOMODE_WAIT_STATE;
    1426           0 :                 ret->timeout = ATAPI_CTRL_WAIT;
    1427           0 :                 ret->expect_irq = 1;
    1428           0 :                 break;
    1429             :         case ATAPI_PIOMODE_WAIT_STATE:
    1430           0 :                 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
    1431           0 :                         chp->wdc->irqack(chp);
    1432           0 :                 if (chp->ch_status & WDCS_ERR) {
    1433             :                         /* Downgrade straight to PIO mode 3 */
    1434           0 :                         drvp->PIO_mode = 3;
    1435           0 :                         chp->wdc->set_modes(chp);
    1436           0 :                 }
    1437             :         /* FALLTHROUGH */
    1438             : 
    1439             :         case ATAPI_DMAMODE_STATE:
    1440           0 :                 if (drvp->drive_flags & DRIVE_UDMA) {
    1441           0 :                         wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
    1442           0 :                             0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
    1443           0 :                 } else if (drvp->drive_flags & DRIVE_DMA) {
    1444           0 :                         wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
    1445           0 :                             0x20 | drvp->DMA_mode, WDSF_SET_MODE);
    1446             :                 } else {
    1447             :                         goto ready;
    1448             :                 }
    1449           0 :                 drvp->state = ATAPI_DMAMODE_WAIT_STATE;
    1450             : 
    1451           0 :                 ret->timeout = ATAPI_CTRL_WAIT;
    1452           0 :                 ret->expect_irq = 1;
    1453           0 :                 break;
    1454             : 
    1455             :         case ATAPI_DMAMODE_WAIT_STATE:
    1456           0 :                 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
    1457           0 :                         chp->wdc->irqack(chp);
    1458           0 :                 if (chp->ch_status & WDCS_ERR)
    1459           0 :                         drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
    1460             :         /* FALLTHROUGH */
    1461             : 
    1462             :         case ATAPI_READY_STATE:
    1463             :         ready:
    1464           0 :                 drvp->state = ATAPI_READY_STATE;
    1465           0 :                 xfer->next = wdc_atapi_real_start;
    1466           0 :                 break;
    1467             :         }
    1468           0 :         return;
    1469             : 
    1470             : timeout:
    1471           0 :         printf("%s:%d:%d: %s timed out\n",
    1472           0 :             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
    1473           0 :         sc_xfer->error = XS_TIMEOUT;
    1474           0 :         xfer->next = wdc_atapi_reset;
    1475           0 :         return;
    1476             : 
    1477           0 : }
    1478             : 
    1479             : void
    1480           0 : wdc_atapi_tape_done(struct channel_softc *chp, struct wdc_xfer *xfer,
    1481             :     int timeout, struct atapi_return_args *ret)
    1482             : {
    1483           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
    1484             : 
    1485           0 :         if (sc_xfer->error != XS_NOERROR) {
    1486           0 :                 xfer->next = wdc_atapi_done;
    1487           0 :                 return;
    1488             :         }
    1489             : 
    1490           0 :         _lto3b(xfer->transfer_len,
    1491           0 :             ((struct scsi_rw_tape *)
    1492           0 :                 sc_xfer->cmd)->len);
    1493             : 
    1494           0 :         xfer->c_bcount = sc_xfer->datalen;
    1495           0 :         xfer->c_done = NULL;
    1496           0 :         xfer->c_skip = 0;
    1497             : 
    1498           0 :         xfer->next = wdc_atapi_real_start;
    1499           0 :         return;
    1500           0 : }
    1501             : 
    1502             : 
    1503             : void
    1504           0 : wdc_atapi_done(struct channel_softc *chp, struct wdc_xfer *xfer,
    1505             :     int timeout, struct atapi_return_args *ret)
    1506             : {
    1507           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
    1508             : 
    1509             :         WDCDEBUG_PRINT(("wdc_atapi_done %s:%d:%d: flags 0x%x error 0x%x\n",
    1510             :             chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
    1511             :             (u_int)xfer->c_flags, sc_xfer->error), DEBUG_XFERS);
    1512             :         WDC_LOG_ATAPI_DONE(chp, xfer->drive, xfer->c_flags, sc_xfer->error);
    1513             : 
    1514           0 :         if (xfer->c_flags & C_POLL)
    1515           0 :                 wdc_enable_intr(chp);
    1516             : 
    1517           0 :         scsi_done(sc_xfer);
    1518             : 
    1519           0 :         xfer->next = NULL;
    1520             :         return;
    1521           0 : }
    1522             : 
    1523             : 
    1524             : void
    1525           0 : wdc_atapi_reset(struct channel_softc *chp, struct wdc_xfer *xfer,
    1526             :     int timeout, struct atapi_return_args *ret)
    1527             : {
    1528           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
    1529             : 
    1530           0 :         if (drvp->state == 0) {
    1531           0 :                 xfer->next = wdc_atapi_done;
    1532           0 :                 return;
    1533             :         }
    1534             : 
    1535             :         WDCDEBUG_PRINT(("wdc_atapi_reset\n"), DEBUG_XFERS);
    1536           0 :         wdccommandshort(chp, xfer->drive, ATAPI_SOFT_RESET);
    1537           0 :         drvp->state = ATAPI_IDENTIFY_STATE;
    1538             : 
    1539           0 :         drvp->n_resets++;
    1540             :         /* Some ATAPI devices need extra time to find their
    1541             :            brains after a reset
    1542             :          */
    1543           0 :         xfer->next = wdc_atapi_reset_2;
    1544           0 :         ret->delay = ATAPI_RESET_DELAY;
    1545           0 :         ret->timeout = ATAPI_RESET_WAIT;
    1546           0 :         return;
    1547           0 : }
    1548             : 
    1549             : void
    1550           0 : wdc_atapi_reset_2(struct channel_softc *chp, struct wdc_xfer *xfer,
    1551             :     int timeout, struct atapi_return_args *ret)
    1552             : {
    1553           0 :         struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
    1554           0 :         struct scsi_xfer *sc_xfer = xfer->cmd;
    1555             : 
    1556           0 :         if (timeout) {
    1557           0 :                 printf("%s:%d:%d: soft reset failed\n",
    1558           0 :                     chp->wdc->sc_dev.dv_xname, chp->channel,
    1559           0 :                     xfer->drive);
    1560           0 :                 sc_xfer->error = XS_SELTIMEOUT;
    1561           0 :                 wdc_reset_channel(drvp, 0);
    1562             : 
    1563           0 :                 xfer->next = wdc_atapi_done;
    1564           0 :                 return;
    1565             :         }
    1566             : 
    1567           0 :         wdc_atapi_update_status(chp);
    1568             : 
    1569           0 :         if (chp->ch_status & (WDCS_BSY | WDCS_DRQ)) {
    1570           0 :                 return;
    1571             :         }
    1572             : 
    1573           0 :         xfer->next = wdc_atapi_done;
    1574           0 :         return;
    1575           0 : }

Generated by: LCOV version 1.13