root/dev/atapiscsi/atapiscsi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. atapiscsi_match
  2. atapiscsi_attach
  3. atapiscsi_detach
  4. wdc_atapi_send_cmd
  5. wdc_atapi_minphys
  6. wdc_atapi_ioctl
  7. atapi_to_scsi_sense
  8. wdc_atapi_drive_selected
  9. wdc_atapi_start
  10. wdc_atapi_timer_handler
  11. wdc_atapi_intr
  12. wdc_atapi_the_poll_machine
  13. wdc_atapi_the_machine
  14. wdc_atapi_update_status
  15. wdc_atapi_real_start
  16. wdc_atapi_real_start_2
  17. wdc_atapi_send_packet
  18. wdc_atapi_intr_command
  19. wdc_atapi_in_data_phase
  20. wdc_atapi_intr_data
  21. wdc_atapi_intr_complete
  22. wdc_atapi_pio_intr
  23. wdc_atapi_ctrl
  24. wdc_atapi_tape_done
  25. wdc_atapi_done
  26. wdc_atapi_reset
  27. wdc_atapi_reset_2

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

/* [<][>][^][v][top][bottom][index][help] */