The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/siisata.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: siisata.c,v 1.2.4.5 2009/09/28 00:24:52 snj Exp $ */
    2 
    3 /* from ahcisata_core.c */
    4 
    5 /*
    6  * Copyright (c) 2006 Manuel Bouyer.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Manuel Bouyer.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  *
   33  */
   34 
   35 /* from atapi_wdc.c */
   36 
   37 /*
   38  * Copyright (c) 1998, 2001 Manuel Bouyer.
   39  *
   40  * Redistribution and use in source and binary forms, with or without
   41  * modification, are permitted provided that the following conditions
   42  * are met:
   43  * 1. Redistributions of source code must retain the above copyright
   44  *    notice, this list of conditions and the following disclaimer.
   45  * 2. Redistributions in binary form must reproduce the above copyright
   46  *    notice, this list of conditions and the following disclaimer in the
   47  *    documentation and/or other materials provided with the distribution.
   48  * 3. All advertising materials mentioning features or use of this software
   49  *    must display the following acknowledgement:
   50  *      This product includes software developed by Manuel Bouyer.
   51  * 4. The name of the author may not be used to endorse or promote products
   52  *    derived from this software without specific prior written permission.
   53  *
   54  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   55  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   56  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   57  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   58  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   60  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   61  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   63  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   64  */
   65 
   66 /*-
   67  * Copyright (c) 2007, 2008, 2009 Jonathan A. Kollasch.
   68  * All rights reserved.
   69  *
   70  * Redistribution and use in source and binary forms, with or without
   71  * modification, are permitted provided that the following conditions
   72  * are met:
   73  * 1. Redistributions of source code must retain the above copyright
   74  *    notice, this list of conditions and the following disclaimer.
   75  * 2. Redistributions in binary form must reproduce the above copyright
   76  *    notice, this list of conditions and the following disclaimer in the
   77  *    documentation and/or other materials provided with the distribution.
   78  *
   79  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   80  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   81  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   82  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   83  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   84  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   85  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   86  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   87  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   88  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   89  *
   90  */
   91 
   92 #include <sys/types.h>
   93 #include <sys/malloc.h>
   94 #include <sys/param.h>
   95 #include <sys/kernel.h>
   96 #include <sys/systm.h>
   97 #include <sys/syslog.h>
   98 #include <sys/disklabel.h>
   99 #include <sys/buf.h>
  100 
  101 #include <uvm/uvm_extern.h>
  102 
  103 #include <dev/ata/atareg.h>
  104 #include <dev/ata/satavar.h>
  105 #include <dev/ata/satareg.h>
  106 #include <dev/ata/satafisvar.h>
  107 #include <dev/ic/siisatavar.h>
  108 #include <dev/ic/wdcreg.h>
  109 
  110 #include <dev/scsipi/scsi_all.h> /* for SCSI status */
  111 
  112 #include "atapibus.h"
  113 
  114 #ifdef SIISATA_DEBUG
  115 #if 0
  116 int siisata_debug_mask = 0xffff;
  117 #else
  118 int siisata_debug_mask = 0;
  119 #endif
  120 #endif
  121 
  122 #define ATA_DELAY 10000         /* 10s for a drive I/O */
  123 
  124 static void siisata_attach_port(struct siisata_softc *, int);
  125 static void siisata_intr_port(struct siisata_channel *);
  126 
  127 void siisata_probe_drive(struct ata_channel *);
  128 void siisata_setup_channel(struct ata_channel *);
  129 
  130 int siisata_ata_bio(struct ata_drive_datas *, struct ata_bio *);
  131 void siisata_reset_drive(struct ata_drive_datas *, int);
  132 void siisata_reset_channel(struct ata_channel *, int);
  133 int siisata_ata_addref(struct ata_drive_datas *);
  134 void siisata_ata_delref(struct ata_drive_datas *);
  135 void siisata_killpending(struct ata_drive_datas *);
  136 
  137 void siisata_cmd_start(struct ata_channel *, struct ata_xfer *);
  138 int siisata_cmd_complete(struct ata_channel *, struct ata_xfer *, int);
  139 void siisata_cmd_done(struct ata_channel *, struct ata_xfer *, int);
  140 void siisata_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
  141 
  142 void siisata_bio_start(struct ata_channel *, struct ata_xfer *);
  143 int siisata_bio_complete(struct ata_channel *, struct ata_xfer *, int);
  144 void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
  145 int siisata_exec_command(struct ata_drive_datas *, struct ata_command *);
  146 
  147 void siisata_timeout(void *);
  148 
  149 static void siisata_reinit_port(struct ata_channel *);
  150 static void siisata_device_reset(struct ata_channel *);
  151 static void siisata_activate_prb(struct siisata_channel *, int);
  152 static void siisata_deactivate_prb(struct siisata_channel *, int);
  153 static int siisata_dma_setup(struct ata_channel *chp, int slot,
  154     void *data, size_t, int);
  155 
  156 #if NATAPIBUS > 0
  157 void siisata_atapibus_attach(struct atabus_softc *);
  158 void siisata_atapi_probe_device(struct atapibus_softc *, int);
  159 void siisata_atapi_minphys(struct buf *);
  160 void siisata_atapi_start(struct ata_channel *,struct ata_xfer *);
  161 int siisata_atapi_complete(struct ata_channel *, struct ata_xfer *, int);
  162 void siisata_atapi_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
  163 void siisata_atapi_done(struct ata_channel *, struct ata_xfer *, int);
  164 void siisata_atapi_scsipi_request(struct scsipi_channel *,
  165     scsipi_adapter_req_t, void *);
  166 void siisata_atapi_kill_pending(struct scsipi_periph *);
  167 #endif /* NATAPIBUS */
  168 
  169 const struct ata_bustype siisata_ata_bustype = {
  170         SCSIPI_BUSTYPE_ATA,
  171         siisata_ata_bio,
  172         siisata_reset_drive,
  173         siisata_reset_channel,
  174         siisata_exec_command,
  175         ata_get_params,
  176         siisata_ata_addref,
  177         siisata_ata_delref,
  178         siisata_killpending
  179 };
  180 
  181 #if NATAPIBUS > 0
  182 static const struct scsipi_bustype siisata_atapi_bustype = {
  183         SCSIPI_BUSTYPE_ATAPI,
  184         atapi_scsipi_cmd,
  185         atapi_interpret_sense,
  186         atapi_print_addr,
  187         siisata_atapi_kill_pending
  188 };
  189 #endif /* NATAPIBUS */
  190 
  191 
  192 void
  193 siisata_attach(struct siisata_softc *sc)
  194 {
  195         int i;
  196 
  197         SIISATA_DEBUG_PRINT(("%s: %s: GR_GC: 0x%08x\n",
  198             SIISATANAME(sc), __func__, GRREAD(sc, GR_GC)), DEBUG_FUNCS);
  199 
  200         sc->sc_atac.atac_cap = ATAC_CAP_DMA | ATAC_CAP_UDMA;
  201         sc->sc_atac.atac_pio_cap = 4;
  202         sc->sc_atac.atac_dma_cap = 2;
  203         sc->sc_atac.atac_udma_cap = 6;
  204         sc->sc_atac.atac_channels = sc->sc_chanarray;
  205         sc->sc_atac.atac_probe = siisata_probe_drive;
  206         sc->sc_atac.atac_bustype_ata = &siisata_ata_bustype;
  207         sc->sc_atac.atac_set_modes = siisata_setup_channel;
  208 #if NATAPIBUS > 0
  209         sc->sc_atac.atac_atapibus_attach = siisata_atapibus_attach;
  210 #endif  
  211 
  212         /* come out of reset state */
  213         GRWRITE(sc, GR_GC, 0);
  214 
  215         for (i = 0; i < sc->sc_atac.atac_nchannels; i++) {
  216                 siisata_attach_port(sc, i);
  217         }
  218 
  219         SIISATA_DEBUG_PRINT(("%s: %s: GR_GC: 0x%08x\n",
  220             SIISATANAME(sc), __func__, GRREAD(sc, GR_GC)),
  221             DEBUG_FUNCS);
  222         return;
  223 }
  224 
  225 static void
  226 siisata_init_port(struct siisata_softc *sc, int port)
  227 {
  228         struct siisata_channel *schp;
  229         struct ata_channel *chp;
  230 
  231         schp = &sc->sc_channels[port];
  232         chp = (struct ata_channel *)schp;
  233 
  234         /* come out of reset, 64-bit activation */
  235         PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC),
  236             PR_PC_32BA | PR_PC_PORT_RESET);
  237         /* initialize port */
  238         siisata_reinit_port(chp);
  239         /* clear any interrupts */
  240         PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff);
  241         /* enable CmdErrr+CmdCmpl interrupting */
  242         PRWRITE(sc, PRX(chp->ch_channel, PRO_PIES),
  243             PR_PIS_CMDERRR | PR_PIS_CMDCMPL);
  244         /* enable port interrupt */
  245         GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel));
  246 }
  247 
  248 static void
  249 siisata_attach_port(struct siisata_softc *sc, int port)
  250 {
  251         int j;
  252         bus_dma_segment_t seg;
  253         int dmasize;
  254         int error;
  255         int rseg;
  256         void *prbp;
  257         struct siisata_channel *schp;
  258         struct ata_channel *chp;
  259 
  260         schp = &sc->sc_channels[port];
  261         chp = (struct ata_channel *)schp;
  262         sc->sc_chanarray[port] = chp;
  263         chp->ch_channel = port;
  264         chp->ch_atac = &sc->sc_atac;
  265         chp->ch_queue = malloc(sizeof(struct ata_queue),
  266                                M_DEVBUF, M_NOWAIT);
  267         if (chp->ch_queue == NULL) {
  268                 aprint_error_dev(sc->sc_atac.atac_dev,
  269                     "port %d: can't allocate memory "
  270                     "for command queue\n", chp->ch_channel);
  271                 return;
  272         }
  273 
  274         dmasize = SIISATA_CMD_SIZE * SIISATA_MAX_SLOTS;
  275 
  276         SIISATA_DEBUG_PRINT(("%s: %s: dmasize: %d\n", SIISATANAME(sc),
  277             __func__, dmasize), DEBUG_FUNCS);
  278 
  279         error = bus_dmamem_alloc(sc->sc_dmat, dmasize, PAGE_SIZE, 0,
  280             &seg, 1, &rseg, BUS_DMA_NOWAIT);
  281         if (error) {
  282                 aprint_error_dev(sc->sc_atac.atac_dev,
  283                     "unable to allocate PRB table memory, "
  284                     "error=%d\n", error);
  285                 return;
  286         }
  287 
  288         error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, dmasize,
  289             &prbp, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
  290         if (error) {
  291                 aprint_error_dev(sc->sc_atac.atac_dev,
  292                     "unable to map PRB table memory, "
  293                     "error=%d\n", error);
  294                 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
  295                 return;
  296         }
  297 
  298         error = bus_dmamap_create(sc->sc_dmat, dmasize, 1, dmasize, 0,
  299             BUS_DMA_NOWAIT, &schp->sch_prbd);
  300         if (error) {
  301                 aprint_error_dev(sc->sc_atac.atac_dev,
  302                     "unable to create PRB table map, "
  303                     "error=%d\n", error);
  304                 bus_dmamem_unmap(sc->sc_dmat, prbp, dmasize);
  305                 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
  306                 return;
  307         }
  308 
  309         error = bus_dmamap_load(sc->sc_dmat, schp->sch_prbd,
  310             prbp, dmasize, NULL, BUS_DMA_NOWAIT);
  311         if (error) {
  312                 aprint_error_dev(sc->sc_atac.atac_dev,
  313                     "unable to load PRB table map, "
  314                     "error=%d\n", error);
  315                 bus_dmamap_destroy(sc->sc_dmat, schp->sch_prbd);
  316                 bus_dmamem_unmap(sc->sc_dmat, prbp, dmasize);
  317                 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
  318                 return;
  319         }
  320 
  321         for (j = 0; j < SIISATA_MAX_SLOTS; j++) {
  322                 schp->sch_prb[j] = (struct siisata_prb *)
  323                     ((char *)prbp + SIISATA_CMD_SIZE * j);
  324                 schp->sch_bus_prb[j] =
  325                     schp->sch_prbd->dm_segs[0].ds_addr +
  326                     SIISATA_CMD_SIZE * j;
  327                 error = bus_dmamap_create(sc->sc_dmat, MAXPHYS,
  328                     SIISATA_NSGE, MAXPHYS, 0,
  329                     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
  330                     &schp->sch_datad[j]);
  331                 if (error) {
  332                         aprint_error_dev(sc->sc_atac.atac_dev,
  333                             "couldn't create xfer DMA map, error=%d\n",
  334                             error);
  335                         return;
  336                 }
  337         }
  338 
  339         chp->ch_ndrive = 1;
  340         if (bus_space_subregion(sc->sc_prt, sc->sc_prh,
  341             PRX(chp->ch_channel, PRO_SSTATUS), 4, &schp->sch_sstatus) != 0) {
  342                 aprint_error_dev(sc->sc_atac.atac_dev,
  343                     "couldn't map port %d SStatus regs\n",
  344                     chp->ch_channel);
  345                 return;
  346         }
  347         if (bus_space_subregion(sc->sc_prt, sc->sc_prh,
  348             PRX(chp->ch_channel, PRO_SCONTROL), 4, &schp->sch_scontrol) != 0) {
  349                 aprint_error_dev(sc->sc_atac.atac_dev,
  350                     "couldn't map port %d SControl regs\n",
  351                     chp->ch_channel);
  352                 return;
  353         }
  354         if (bus_space_subregion(sc->sc_prt, sc->sc_prh,
  355             PRX(chp->ch_channel, PRO_SERROR), 4, &schp->sch_serror) != 0) {
  356                 aprint_error_dev(sc->sc_atac.atac_dev,
  357                     "couldn't map port %d SError regs\n",
  358                     chp->ch_channel);
  359                 return;
  360         }
  361 
  362         siisata_init_port(sc, port);
  363 
  364         ata_channel_attach(chp);
  365 
  366         return;
  367 }
  368 
  369 int
  370 siisata_detach(struct siisata_softc *sc, int flags)
  371 {
  372         struct atac_softc *atac = &sc->sc_atac;
  373         struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic;
  374         struct siisata_channel *schp;
  375         struct ata_channel *chp;
  376         bus_dmamap_t dmam;
  377         int i, j, error;
  378 
  379         for (i = 0; i < sc->sc_atac.atac_nchannels; i++) {
  380                 schp = &sc->sc_channels[i];
  381                 chp = sc->sc_chanarray[i];
  382 
  383                 if (chp->atabus == NULL)
  384                         continue;
  385                 if ((error = config_detach(chp->atabus, flags)) != 0)
  386                         return error;
  387 
  388                 for (j = 0; j < SIISATA_MAX_SLOTS; j++)
  389                         bus_dmamap_destroy(sc->sc_dmat, schp->sch_datad[j]);
  390 
  391                 dmam = schp->sch_prbd;
  392                 bus_dmamap_unload(sc->sc_dmat, dmam);
  393                 bus_dmamap_destroy(sc->sc_dmat, dmam);
  394                 bus_dmamem_unmap(sc->sc_dmat, schp->sch_prb[0],
  395                     dmam->dm_mapsize);
  396                 bus_dmamem_free(sc->sc_dmat, dmam->dm_segs, dmam->dm_nsegs);
  397 
  398                 free(chp->ch_queue, M_DEVBUF);
  399                 chp->atabus = NULL;
  400         }
  401 
  402         if (adapt->adapt_refcnt != 0)
  403                 return EBUSY;
  404 
  405         /* leave the chip in reset */
  406         GRWRITE(sc, GR_GC, GR_GC_GLBLRST);
  407 
  408         return 0;
  409 }
  410 
  411 void
  412 siisata_resume(struct siisata_softc *sc)
  413 {
  414         int i;
  415 
  416         /* come out of reset state */
  417         GRWRITE(sc, GR_GC, 0);
  418 
  419         for (i = 0; i < sc->sc_atac.atac_nchannels; i++) {
  420                 siisata_init_port(sc, i);
  421         }
  422         
  423 }
  424 
  425 int
  426 siisata_intr(void *v)
  427 {
  428         struct siisata_softc *sc = v;
  429         uint32_t is;
  430         int i, r = 0;
  431         while ((is = GRREAD(sc, GR_GIS))) {
  432                 SIISATA_DEBUG_PRINT(("%s: %s: GR_GIS: 0x%08x\n",
  433                     SIISATANAME(sc), __func__, is), DEBUG_INTR);
  434                 r = 1;
  435                 for (i = 0; i < sc->sc_atac.atac_nchannels; i++)
  436                         if (is & GR_GIS_PXIS(i))
  437                                 siisata_intr_port(&sc->sc_channels[i]);
  438         }
  439         return r;
  440 }
  441 
  442 static void
  443 siisata_intr_port(struct siisata_channel *schp)
  444 {
  445         struct siisata_softc *sc;
  446         struct ata_channel *chp;
  447         struct ata_xfer *xfer;
  448         int slot;
  449         uint32_t pss, pis;
  450         uint32_t prbfis;
  451 
  452         sc = (struct siisata_softc *)schp->ata_channel.ch_atac;
  453         chp = &schp->ata_channel;
  454         xfer = chp->ch_queue->active_xfer;
  455         slot = SIISATA_NON_NCQ_SLOT;
  456 
  457         SIISATA_DEBUG_PRINT(("%s: %s port %d\n",
  458             SIISATANAME(sc), __func__, chp->ch_channel), DEBUG_INTR);
  459 
  460         pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS));
  461 
  462         if (pis & PR_PIS_CMDCMPL) {
  463                 /* get slot status, clearing completion interrupt */
  464                 pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS));
  465                 /* is this expected? */
  466                 /* XXX improve */
  467                 if ((schp->sch_active_slots & __BIT(slot)) == 0) {
  468                         log(LOG_WARNING, "%s: unexpected command "
  469                             "completion on port %d\n",
  470                             SIISATANAME(sc), chp->ch_channel);
  471                         return;
  472                 } 
  473         } else if (pis & PR_PIS_CMDERRR) {
  474                 uint32_t ec;
  475 
  476                 /* emulate a CRC error by default */
  477                 chp->ch_status = WDCS_ERR;
  478                 chp->ch_error = WDCE_CRC;
  479 
  480                 ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE));
  481                 if (ec <= PR_PCE_DATAFISERROR) {
  482                         if (ec == PR_PCE_DEVICEERROR) {
  483                                 /* read in specific information about error */
  484                                 prbfis = bus_space_read_stream_4(
  485                                     sc->sc_prt, sc->sc_prh,
  486                                     PRSX(chp->ch_channel, slot, PRSO_FIS));
  487                                 /* set ch_status and ch_error */
  488                                 satafis_rdh_parse(chp, (uint8_t *)&prbfis);
  489                         }
  490                         siisata_reinit_port(chp);
  491                 } else {
  492                         /* okay, we have a "Fatal Error" */
  493                         siisata_device_reset(chp);
  494                 }
  495         }
  496 
  497         /* clear some (ok, all) ints */
  498         PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff);
  499 
  500         KASSERT(xfer != NULL);
  501         KASSERT(xfer->c_intr != NULL);
  502         xfer->c_intr(chp, xfer, slot);
  503 
  504         return;
  505 }
  506 
  507 void
  508 siisata_reset_drive(struct ata_drive_datas *drvp, int flags)
  509 {
  510         struct ata_channel *chp = drvp->chnl_softc;
  511         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
  512         struct siisata_channel *schp = (struct siisata_channel *)chp;
  513         struct siisata_prb *prb;
  514         int slot = SIISATA_NON_NCQ_SLOT;
  515         int i;
  516 
  517         /* wait for ready */
  518         while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY))
  519                 DELAY(10);
  520 
  521         prb = schp->sch_prb[slot];
  522         memset(prb, 0, sizeof(struct siisata_prb));
  523         prb->prb_control =
  524             htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK);
  525 
  526         siisata_activate_prb(schp, slot);
  527 
  528         for(i = 0; i < 31000; i++) {
  529                 if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) &
  530                     PR_PXSS(slot))
  531                         DELAY(1000);
  532                 else
  533                         break;
  534         }
  535 
  536         siisata_deactivate_prb(schp, slot);
  537 
  538         log(LOG_DEBUG, "%s: port %d: ch_status %x ch_error %x\n",
  539             __func__, chp->ch_channel, chp->ch_status, chp->ch_error);
  540 
  541 #if 1
  542         /* attempt to downgrade signaling in event of CRC error */
  543         /* XXX should be part of the MI (S)ATA subsystem */
  544         if (chp->ch_status == 0x51 && chp->ch_error == 0x84) {
  545                 bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0,
  546                     SControl_IPM_NONE | SControl_SPD_G1 | SControl_DET_INIT);
  547                 DELAY(10);
  548                 bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0,
  549                     SControl_IPM_NONE | SControl_SPD_G1);
  550                 DELAY(10);
  551                 for (;;) {
  552                         if ((bus_space_read_4(sc->sc_prt, schp->sch_sstatus, 0)
  553                             & SStatus_DET_mask) == SStatus_DET_DEV)
  554                                 break;
  555                         DELAY(10);
  556                 }
  557         }
  558 #endif
  559 
  560 #if 1
  561         chp->ch_status = 0;
  562         chp->ch_error = 0;
  563 #endif
  564 
  565         return;
  566 }
  567 
  568 void
  569 siisata_reset_channel(struct ata_channel *chp, int flags)
  570 {
  571         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
  572         struct siisata_channel *schp = (struct siisata_channel *)chp;
  573 
  574         SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__),
  575             DEBUG_FUNCS);
  576 
  577         if (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol,
  578             schp->sch_sstatus) != SStatus_DET_DEV) {
  579                 log(LOG_CRIT, "%s port %d: reset failed\n",
  580                     SIISATANAME(sc), chp->ch_channel);
  581                 /* XXX and then ? */
  582         }
  583         /* wait for ready */
  584         while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY))
  585                 DELAY(10);
  586         PRWRITE(sc, PRX(chp->ch_channel, PRO_SERROR),
  587             PRREAD(sc, PRX(chp->ch_channel, PRO_SERROR)));
  588         if (chp->ch_queue->active_xfer) {
  589                 chp->ch_queue->active_xfer->c_kill_xfer(chp,
  590                     chp->ch_queue->active_xfer, KILL_RESET);
  591         }
  592 
  593         return;
  594 }
  595 
  596 int
  597 siisata_ata_addref(struct ata_drive_datas *drvp)
  598 {
  599         return 0;
  600 }
  601 
  602 void
  603 siisata_ata_delref(struct ata_drive_datas *drvp)
  604 {
  605         return;
  606 }
  607 
  608 void
  609 siisata_killpending(struct ata_drive_datas *drvp)
  610 {
  611         return;
  612 }
  613 
  614 void
  615 siisata_probe_drive(struct ata_channel *chp)
  616 {
  617         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
  618         struct siisata_channel *schp = (struct siisata_channel *)chp;
  619         int i;
  620         int s;
  621         uint32_t sig;
  622         int slot = SIISATA_NON_NCQ_SLOT;
  623         struct siisata_prb *prb;
  624 
  625         SIISATA_DEBUG_PRINT(("%s: %s: port %d start\n", SIISATANAME(sc),
  626             __func__, chp->ch_channel), DEBUG_FUNCS);
  627 
  628         /* XXX This should be done by other code. */
  629         for (i = 0; i < chp->ch_ndrive; i++) {
  630                 chp->ch_drive[i].chnl_softc = chp;
  631                 chp->ch_drive[i].drive = i;
  632         }
  633 
  634         switch (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol,
  635                 schp->sch_sstatus)) {
  636         case SStatus_DET_DEV:
  637                 /* wait for ready */
  638                 while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS))
  639                     & PR_PS_PORT_READY))
  640                         DELAY(10);
  641 
  642                 prb = schp->sch_prb[slot];
  643                 memset(prb, 0, sizeof(struct siisata_prb));
  644                 prb->prb_control =
  645                     htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK);
  646 
  647                 siisata_activate_prb(schp, slot);
  648 
  649                 for(i = 0; i < 31000; i++) {
  650                         if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) &
  651                             PR_PXSS(slot))
  652                                 DELAY(1000);
  653                         else
  654                                 break;
  655                 }
  656 
  657                 siisata_deactivate_prb(schp, slot);
  658 
  659                 /* read the signature out of the FIS */
  660                 sig = 0;
  661                 sig |= (PRREAD(sc, PRSX(chp->ch_channel, slot,
  662                     PRSO_FIS+0x4)) & 0x00ffffff) << 8;
  663                 sig |= PRREAD(sc, PRSX(chp->ch_channel, slot,
  664                     PRSO_FIS+0xc)) & 0xff;
  665 
  666                 SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc),
  667                     __func__, sig), DEBUG_PROBE);
  668 
  669                 /* some ATAPI devices have bogus lower two bytes, sigh */
  670                 if ((sig & 0xffff0000) == 0xeb140000) {
  671                         sig &= 0xffff0000;
  672                         sig |= 0x00000101;
  673                 }
  674 
  675                 s = splbio();
  676                 switch (sig) {
  677                 case 0xeb140101:
  678                         chp->ch_drive[0].drive_flags |= DRIVE_ATAPI;
  679                         break;
  680                 case 0x00000101:
  681                         chp->ch_drive[0].drive_flags |= DRIVE_ATA;
  682                         break;
  683                 default:
  684                         chp->ch_drive[0].drive_flags |= DRIVE_ATA;
  685                         aprint_verbose_dev(sc->sc_atac.atac_dev,
  686                             "Unrecognized signature 0x%08x on port %d. "
  687                             "Assuming it's a disk.\n", sig, chp->ch_channel);
  688                         break;
  689                 }
  690                 splx(s);
  691                 break;
  692         default:
  693                 break;
  694         }
  695 
  696         SIISATA_DEBUG_PRINT(("%s: %s: port %d done\n", SIISATANAME(sc),
  697             __func__, chp->ch_channel), DEBUG_PROBE);
  698         return;
  699 }
  700 
  701 void
  702 siisata_setup_channel(struct ata_channel *chp)
  703 {
  704         return;
  705 }
  706 
  707 int
  708 siisata_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c)
  709 {
  710         struct ata_channel *chp = drvp->chnl_softc;
  711         struct ata_xfer *xfer;
  712         int ret;
  713         int s;
  714 
  715         SIISATA_DEBUG_PRINT(("%s: %s begins\n",
  716             SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__),
  717             DEBUG_FUNCS);
  718 
  719         xfer = ata_get_xfer(ata_c->flags & AT_WAIT ?
  720             ATAXF_CANSLEEP : ATAXF_NOSLEEP);
  721         if (xfer == NULL)
  722                 return ATACMD_TRY_AGAIN;
  723         if (ata_c->flags & AT_POLL)
  724                 xfer->c_flags |= C_POLL;
  725         if (ata_c->flags & AT_WAIT)
  726                 xfer->c_flags |= C_WAIT;
  727         xfer->c_drive = drvp->drive;
  728         xfer->c_databuf = ata_c->data;
  729         xfer->c_bcount = ata_c->bcount;
  730         xfer->c_cmd = ata_c;
  731         xfer->c_start = siisata_cmd_start;
  732         xfer->c_intr = siisata_cmd_complete;
  733         xfer->c_kill_xfer = siisata_cmd_kill_xfer;
  734         s = splbio();
  735         ata_exec_xfer(chp, xfer);
  736 #ifdef DIAGNOSTIC
  737         if ((ata_c->flags & AT_POLL) != 0 &&
  738             (ata_c->flags & AT_DONE) == 0)
  739                 panic("%s: polled command not done", __func__);
  740 #endif
  741         if (ata_c->flags & AT_DONE) {
  742                 ret = ATACMD_COMPLETE;
  743         } else {
  744                 if (ata_c->flags & AT_WAIT) {
  745                         while ((ata_c->flags & AT_DONE) == 0) {
  746                                 SIISATA_DEBUG_PRINT(("%s: %s: sleeping\n",
  747                                     SIISATANAME(
  748                                     (struct siisata_softc *)chp->ch_atac),
  749                                     __func__), DEBUG_FUNCS);
  750                                 tsleep(ata_c, PRIBIO, "siicmd", 0);
  751                         }
  752                         ret = ATACMD_COMPLETE;
  753                 } else {
  754                         ret = ATACMD_QUEUED;
  755                 }
  756         }
  757         splx(s);
  758         SIISATA_DEBUG_PRINT( ("%s: %s ends\n",
  759             SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__),
  760             DEBUG_FUNCS);
  761         return ret;
  762 }
  763 
  764 void
  765 siisata_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer)
  766 {
  767         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
  768         struct siisata_channel *schp = (struct siisata_channel *)chp;
  769         struct ata_command *ata_c = xfer->c_cmd;
  770         int slot = SIISATA_NON_NCQ_SLOT;
  771         struct siisata_prb *prb;
  772         int i;
  773 
  774         SIISATA_DEBUG_PRINT(("%s: %s port %d, slot %d\n",
  775             SIISATANAME(sc), __func__, chp->ch_channel, slot), DEBUG_FUNCS);
  776 
  777         chp->ch_status = 0;
  778         chp->ch_error = 0;
  779 
  780         prb = schp->sch_prb[slot];
  781         memset(prb, 0, sizeof(struct siisata_prb));
  782 
  783         satafis_rhd_construct_cmd(ata_c, prb->prb_fis);
  784 
  785         memset(prb->prb_atapi, 0, sizeof(prb->prb_atapi));
  786 
  787         if (siisata_dma_setup(chp, slot,
  788             (ata_c->flags & (AT_READ | AT_WRITE)) ? ata_c->data : NULL,
  789             ata_c->bcount,
  790             (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) { 
  791                 ata_c->flags |= AT_DF;
  792                 siisata_cmd_complete(chp, xfer, slot);
  793                 return;
  794         }
  795 
  796         if (xfer->c_flags & C_POLL) {
  797                 /* polled command, disable interrupts */
  798                 prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK);
  799         }
  800 
  801         /* go for it */
  802         siisata_activate_prb(schp, slot);
  803 
  804         if ((ata_c->flags & AT_POLL) == 0) {
  805                 chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
  806                 callout_reset(&chp->ch_callout, mstohz(ata_c->timeout),
  807                     siisata_timeout, chp);
  808                 goto out;
  809         }
  810 
  811         /*
  812          * polled command
  813          */
  814         for (i = 0; i < ata_c->timeout / 10; i++) {
  815                 if (ata_c->flags & AT_DONE)
  816                         break;
  817                 siisata_intr_port(schp);
  818                 DELAY(1000);
  819         }
  820 
  821         if ((ata_c->flags & AT_DONE) == 0) {
  822                 ata_c->flags |= AT_TIMEOU;
  823                 siisata_cmd_complete(chp, xfer, slot);
  824         }
  825 
  826         /* reenable interrupts */
  827         GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel));
  828 out:
  829         SIISATA_DEBUG_PRINT(
  830             ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS);
  831         return;
  832 }
  833 
  834 void
  835 siisata_cmd_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer,
  836     int reason)
  837 {
  838         int slot = SIISATA_NON_NCQ_SLOT;
  839 
  840         struct ata_command *ata_c = xfer->c_cmd;
  841         switch (reason) {
  842         case KILL_GONE:
  843                 ata_c->flags |= AT_GONE;
  844                 break;
  845         case KILL_RESET:
  846                 ata_c->flags |= AT_RESET;
  847                 break;
  848         default:
  849                 panic("%s: port %d: unknown reason %d",
  850                    __func__, chp->ch_channel, reason);
  851         }
  852         siisata_cmd_done(chp, xfer, slot);
  853 }
  854 
  855 int
  856 siisata_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int slot)
  857 {
  858         struct ata_command *ata_c = xfer->c_cmd;
  859 #ifdef SIISATA_DEBUG
  860         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
  861 #endif
  862         
  863         SIISATA_DEBUG_PRINT(
  864             ("%s: %s\n", SIISATANAME(sc), __func__), DEBUG_FUNCS);
  865 
  866         chp->ch_flags &= ~ATACH_IRQ_WAIT;
  867         if (xfer->c_flags & C_TIMEOU)
  868                 ata_c->flags |= AT_TIMEOU;
  869         else
  870                 callout_stop(&chp->ch_callout);
  871 
  872         if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) {
  873                 siisata_cmd_kill_xfer(chp, xfer, KILL_GONE);
  874                 chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN;
  875                 wakeup(&chp->ch_queue->active_xfer);
  876                 return 0;
  877         }
  878 
  879         chp->ch_queue->active_xfer = NULL;
  880 
  881         {
  882                 ata_c->r_head = 0;
  883                 ata_c->r_count = 0;
  884                 ata_c->r_sector = 0;
  885                 ata_c->r_cyl = 0;
  886                 if (chp->ch_status & WDCS_BSY) {
  887                         ata_c->flags |= AT_TIMEOU;
  888                 } else if (chp->ch_status & WDCS_ERR) {
  889                         ata_c->r_error = chp->ch_error;
  890                         ata_c->flags |= AT_ERROR;
  891                 }
  892         }
  893         siisata_cmd_done(chp, xfer, slot);
  894         return 0;
  895 }
  896 
  897 void
  898 siisata_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer, int slot)
  899 {
  900         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
  901         struct siisata_channel *schp = (struct siisata_channel *)chp;
  902         struct ata_command *ata_c = xfer->c_cmd;
  903         int i;
  904         uint16_t *idwordbuf;
  905 
  906         SIISATA_DEBUG_PRINT(
  907             ("%s: %s.\n", SIISATANAME(sc), __func__), DEBUG_FUNCS);
  908 
  909         siisata_deactivate_prb(schp, slot);
  910 
  911         if (ata_c->flags & (AT_READ | AT_WRITE)) {
  912                 bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0,
  913                     schp->sch_datad[slot]->dm_mapsize,
  914                     (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD :
  915                     BUS_DMASYNC_POSTWRITE);
  916                 bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]);
  917         }
  918 
  919         idwordbuf = xfer->c_databuf;
  920 
  921         /* correct the endianess of IDENTIFY data */
  922         if (ata_c->r_command == WDCC_IDENTIFY ||
  923             ata_c->r_command == ATAPI_IDENTIFY_DEVICE) {
  924                 for (i = 0; i < (xfer->c_bcount / sizeof(*idwordbuf)); i++) {
  925                         idwordbuf[i] = le16toh(idwordbuf[i]);
  926                 }
  927         }
  928 
  929         ata_c->flags |= AT_DONE;
  930         if (PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC)))
  931                 ata_c->flags |= AT_XFDONE;
  932 
  933         ata_free_xfer(chp, xfer);
  934         if (ata_c->flags & AT_WAIT)
  935                 wakeup(ata_c);
  936         else if (ata_c->callback)
  937                 ata_c->callback(ata_c->callback_arg);
  938         atastart(chp);
  939         return;
  940 }
  941 
  942 int
  943 siisata_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
  944 {
  945         struct ata_channel *chp = drvp->chnl_softc;
  946         struct ata_xfer *xfer;
  947 
  948         SIISATA_DEBUG_PRINT( ("%s: %s.\n",
  949             SIISATANAME((struct siisata_softc *)chp->ch_atac),
  950             __func__), DEBUG_FUNCS);
  951 
  952         xfer = ata_get_xfer(ATAXF_NOSLEEP);
  953         if (xfer == NULL)
  954                 return ATACMD_TRY_AGAIN;
  955         if (ata_bio->flags & ATA_POLL)
  956                 xfer->c_flags |= C_POLL;
  957         xfer->c_drive = drvp->drive;
  958         xfer->c_cmd = ata_bio;
  959         xfer->c_databuf = ata_bio->databuf;
  960         xfer->c_bcount = ata_bio->bcount;
  961         xfer->c_start = siisata_bio_start;
  962         xfer->c_intr = siisata_bio_complete;
  963         xfer->c_kill_xfer = siisata_bio_kill_xfer;
  964         ata_exec_xfer(chp, xfer);
  965         return (ata_bio->flags & ATA_ITSDONE) ?
  966             ATACMD_COMPLETE : ATACMD_QUEUED;
  967 }
  968 
  969 void
  970 siisata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer)
  971 {
  972         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
  973         struct siisata_channel *schp = (struct siisata_channel *)chp;
  974         struct siisata_prb *prb;
  975         struct ata_bio *ata_bio = xfer->c_cmd;
  976         int slot = SIISATA_NON_NCQ_SLOT;
  977         int i;
  978 
  979         SIISATA_DEBUG_PRINT(
  980             ("%s: %s port %d, slot %d\n",
  981             SIISATANAME(sc), __func__, chp->ch_channel, slot),
  982             DEBUG_FUNCS);
  983 
  984         chp->ch_status = 0;
  985         chp->ch_error = 0;
  986 
  987         prb = schp->sch_prb[slot];
  988         memset(prb, 0, sizeof(struct siisata_prb));
  989 
  990         satafis_rhd_construct_bio(xfer, prb->prb_fis);
  991 
  992         memset(prb->prb_atapi, 0, sizeof(prb->prb_atapi));
  993 
  994         if (siisata_dma_setup(chp, slot, ata_bio->databuf, ata_bio->bcount,
  995             (ata_bio->flags & ATA_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
  996                 ata_bio->error = ERR_DMA;
  997                 ata_bio->r_error = 0;
  998                 siisata_bio_complete(chp, xfer, slot);
  999                 return;
 1000         }
 1001 
 1002         if (xfer->c_flags & C_POLL) {
 1003                 /* polled command, disable interrupts */
 1004                 prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK);
 1005         }
 1006 
 1007         siisata_activate_prb(schp, slot);
 1008 
 1009         if ((ata_bio->flags & ATA_POLL) == 0) {
 1010                 chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
 1011                 callout_reset(&chp->ch_callout, mstohz(ATA_DELAY),
 1012                     siisata_timeout, chp);
 1013                 goto out;
 1014         }
 1015 
 1016         /*
 1017          * polled command
 1018          */
 1019         for (i = 0; i < ATA_DELAY / 10; i++) {
 1020                 if (ata_bio->flags & ATA_ITSDONE)
 1021                         break;
 1022                 siisata_intr_port(schp);
 1023                 DELAY(1000);
 1024         }
 1025 
 1026         GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel));
 1027 out:
 1028         SIISATA_DEBUG_PRINT(
 1029             ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS);
 1030         return;
 1031 }
 1032 
 1033 void
 1034 siisata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer,
 1035     int reason)
 1036 {
 1037         struct siisata_channel *schp = (struct siisata_channel *)chp;
 1038         struct ata_bio *ata_bio = xfer->c_cmd;
 1039         int drive = xfer->c_drive;
 1040         int slot = SIISATA_NON_NCQ_SLOT;
 1041 
 1042         SIISATA_DEBUG_PRINT(("%s: %s: port %d\n",
 1043             SIISATANAME((struct siisata_softc *)chp->ch_atac),
 1044             __func__, chp->ch_channel), DEBUG_FUNCS);
 1045 
 1046         siisata_deactivate_prb(schp, slot);
 1047 
 1048         ata_free_xfer(chp, xfer);
 1049         ata_bio->flags |= ATA_ITSDONE;
 1050         switch (reason) {
 1051         case KILL_GONE:
 1052                 ata_bio->error = ERR_NODEV;
 1053                 break;
 1054         case KILL_RESET:
 1055                 ata_bio->error = ERR_RESET;
 1056                 break;
 1057         default:
 1058                 panic("%s: port %d: unknown reason %d",
 1059                    __func__, chp->ch_channel, reason);
 1060         }
 1061         ata_bio->r_error = WDCE_ABRT;
 1062         (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc);
 1063 }
 1064 
 1065 int
 1066 siisata_bio_complete(struct ata_channel *chp, struct ata_xfer *xfer, int slot)
 1067 {
 1068         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 1069         struct siisata_channel *schp = (struct siisata_channel *)chp;
 1070         struct ata_bio *ata_bio = xfer->c_cmd;
 1071         int drive = xfer->c_drive;
 1072 
 1073         schp->sch_active_slots &= ~__BIT(slot);
 1074         chp->ch_flags &= ~ATACH_IRQ_WAIT;
 1075         if (xfer->c_flags & C_TIMEOU) {
 1076                 ata_bio->error = TIMEOUT;
 1077         } else {
 1078                 callout_stop(&chp->ch_callout);
 1079                 ata_bio->error = NOERROR;
 1080         }
 1081 
 1082         chp->ch_queue->active_xfer = NULL;
 1083 
 1084         bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0,
 1085             schp->sch_datad[slot]->dm_mapsize,
 1086             (ata_bio->flags & ATA_READ) ? BUS_DMASYNC_POSTREAD :
 1087             BUS_DMASYNC_POSTWRITE);
 1088         bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]);
 1089 
 1090         if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) {
 1091                 siisata_bio_kill_xfer(chp, xfer, KILL_GONE);
 1092                 chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN;
 1093                 wakeup(&chp->ch_queue->active_xfer);
 1094                 return 0;
 1095         }
 1096         ata_free_xfer(chp, xfer);
 1097         ata_bio->flags |= ATA_ITSDONE;
 1098         if (chp->ch_status & WDCS_DWF) {
 1099                 ata_bio->error = ERR_DF;
 1100         } else if (chp->ch_status & WDCS_ERR) {
 1101                 ata_bio->error = ERROR;
 1102                 ata_bio->r_error = chp->ch_error;
 1103         } else if (chp->ch_status & WDCS_CORR)
 1104                 ata_bio->flags |= ATA_CORR;
 1105 
 1106         SIISATA_DEBUG_PRINT(("%s: %s bcount: %ld", SIISATANAME(sc),
 1107             __func__, ata_bio->bcount), DEBUG_XFERS); 
 1108         if (ata_bio->error == NOERROR) {
 1109                 if (ata_bio->flags & ATA_READ)
 1110                         ata_bio->bcount -=
 1111                             PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC));
 1112                 else
 1113                         ata_bio->bcount = 0;
 1114         }
 1115         SIISATA_DEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS); 
 1116         if (ata_bio->flags & ATA_POLL)
 1117                 return 1;
 1118         (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc);
 1119         atastart(chp);
 1120         return 0;
 1121 }
 1122 
 1123 void
 1124 siisata_timeout(void *v)
 1125 {
 1126         struct ata_channel *chp = (struct ata_channel *)v;
 1127         struct ata_xfer *xfer = chp->ch_queue->active_xfer;
 1128         int slot = SIISATA_NON_NCQ_SLOT;
 1129         int s = splbio();
 1130         SIISATA_DEBUG_PRINT(("%s: %p\n", __func__, xfer), DEBUG_INTR);
 1131         if ((chp->ch_flags & ATACH_IRQ_WAIT) != 0) {
 1132                 xfer->c_flags |= C_TIMEOU;
 1133                 xfer->c_intr(chp, xfer, slot);
 1134         }
 1135         splx(s);
 1136 }
 1137 
 1138 static int
 1139 siisata_dma_setup(struct ata_channel *chp, int slot, void *data,
 1140     size_t count, int op)
 1141 {
 1142 
 1143         int error, seg;
 1144         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 1145         struct siisata_channel *schp = (struct siisata_channel *)chp;
 1146 
 1147         struct siisata_prb *prbp;
 1148 
 1149         prbp = schp->sch_prb[slot];
 1150 
 1151         if (data == NULL) {
 1152                 goto end;
 1153         }
 1154 
 1155         error = bus_dmamap_load(sc->sc_dmat, schp->sch_datad[slot],
 1156             data, count, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | op);
 1157         if (error) {
 1158                 log(LOG_ERR, "%s port %d: "
 1159                     "failed to load xfer in slot %d: error %d\n",
 1160                     SIISATANAME(sc), chp->ch_channel, slot, error);
 1161                 return error;
 1162         }
 1163 
 1164         bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0,
 1165             schp->sch_datad[slot]->dm_mapsize,
 1166             (op == BUS_DMA_READ) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 1167 
 1168         /* make sure it's clean */
 1169         memset(prbp->prb_sge, 0, SIISATA_NSGE * sizeof(struct siisata_prb));
 1170 
 1171         SIISATA_DEBUG_PRINT(("%s: %d segs, %ld count\n", __func__,
 1172             schp->sch_datad[slot]->dm_nsegs, (long unsigned int) count),
 1173             DEBUG_FUNCS | DEBUG_DEBUG);
 1174 
 1175         for (seg = 0; seg < schp->sch_datad[slot]->dm_nsegs; seg++) {
 1176                 prbp->prb_sge[seg].sge_da =
 1177                     htole64(schp->sch_datad[slot]->dm_segs[seg].ds_addr);
 1178                 prbp->prb_sge[seg].sge_dc =
 1179                     htole32(schp->sch_datad[slot]->dm_segs[seg].ds_len);
 1180                 prbp->prb_sge[seg].sge_flags = htole32(0);
 1181         }
 1182         prbp->prb_sge[seg - 1].sge_flags |= htole32(SGE_FLAG_TRM);
 1183 end:
 1184         return 0;
 1185 }
 1186 
 1187 static void
 1188 siisata_activate_prb(struct siisata_channel *schp, int slot)
 1189 {
 1190         struct siisata_softc *sc;
 1191         bus_size_t offset;
 1192         uint64_t pprb;
 1193 
 1194         sc = (struct siisata_softc *)schp->ata_channel.ch_atac;
 1195 
 1196         KASSERTMSG(((schp->sch_active_slots & __BIT(slot)) == __BIT(slot)),
 1197             ("%s: trying to activate active slot %d", SIISATANAME(sc), slot));
 1198 
 1199         SIISATA_PRB_SYNC(sc, schp, slot, BUS_DMASYNC_PREWRITE);
 1200         /* keep track of what's going on */
 1201         schp->sch_active_slots |= __BIT(slot);
 1202 
 1203         offset = PRO_CARX(schp->ata_channel.ch_channel, slot);
 1204 
 1205         pprb = schp->sch_bus_prb[slot];
 1206 
 1207         PRWRITE(sc, offset + 0, pprb >>  0);
 1208         PRWRITE(sc, offset + 4, pprb >> 32);
 1209 }
 1210 
 1211 static void
 1212 siisata_deactivate_prb(struct siisata_channel *schp, int slot)
 1213 {
 1214         struct siisata_softc *sc;
 1215         
 1216         sc = (struct siisata_softc *)schp->ata_channel.ch_atac;
 1217 
 1218         KASSERTMSG(((schp->sch_active_slots & __BIT(slot)) == 0),
 1219             ("%s: trying to deactivate inactive slot %d", SIISATANAME(sc),
 1220             slot));
 1221 
 1222         schp->sch_active_slots &= ~__BIT(slot); /* mark free */
 1223         SIISATA_PRB_SYNC(sc, schp, slot, BUS_DMASYNC_POSTWRITE);
 1224 }
 1225 
 1226 static void
 1227 siisata_reinit_port(struct ata_channel *chp)
 1228 {
 1229         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 1230 
 1231         PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), PR_PC_PORT_INITIALIZE);
 1232         while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY))
 1233                 DELAY(10);
 1234 }
 1235 
 1236 static void
 1237 siisata_device_reset(struct ata_channel *chp)
 1238 {
 1239         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 1240 
 1241         PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), PR_PC_DEVICE_RESET);
 1242         while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY))
 1243                 DELAY(10);
 1244 }
 1245 
 1246 
 1247 #if NATAPIBUS > 0
 1248 void
 1249 siisata_atapibus_attach(struct atabus_softc *ata_sc)
 1250 {
 1251         struct ata_channel *chp = ata_sc->sc_chan;
 1252         struct atac_softc *atac = chp->ch_atac;
 1253         struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic;
 1254         struct scsipi_channel *chan = &chp->ch_atapi_channel;
 1255 
 1256         /*
 1257          * Fill in the scsipi_adapter.
 1258          */
 1259         adapt->adapt_dev = atac->atac_dev;
 1260         adapt->adapt_nchannels = atac->atac_nchannels;
 1261         adapt->adapt_request = siisata_atapi_scsipi_request;
 1262         adapt->adapt_minphys = siisata_atapi_minphys;
 1263         atac->atac_atapi_adapter.atapi_probe_device =
 1264             siisata_atapi_probe_device;
 1265 
 1266         /*
 1267          * Fill in the scsipi_channel.
 1268          */
 1269         memset(chan, 0, sizeof(*chan));
 1270         chan->chan_adapter = adapt;
 1271         chan->chan_bustype = &siisata_atapi_bustype;
 1272         chan->chan_channel = chp->ch_channel;
 1273         chan->chan_flags = SCSIPI_CHAN_OPENINGS;
 1274         chan->chan_openings = 1;
 1275         chan->chan_max_periph = 1;
 1276         chan->chan_ntargets = 1;
 1277         chan->chan_nluns = 1;
 1278 
 1279         chp->atapibus = config_found_ia(ata_sc->sc_dev, "atapi", chan,
 1280             atapiprint);
 1281 }
 1282 
 1283 void
 1284 siisata_atapi_minphys(struct buf *bp)
 1285 {
 1286         if (bp->b_bcount > MAXPHYS)
 1287                 bp->b_bcount = MAXPHYS;
 1288         minphys(bp);
 1289 }
 1290 
 1291 /*
 1292  * Kill off all pending xfers for a periph.
 1293  *
 1294  * Must be called at splbio().
 1295  */
 1296 void
 1297 siisata_atapi_kill_pending(struct scsipi_periph *periph)
 1298 {
 1299         struct atac_softc *atac =
 1300             device_private(periph->periph_channel->chan_adapter->adapt_dev);
 1301         struct ata_channel *chp =
 1302             atac->atac_channels[periph->periph_channel->chan_channel];
 1303 
 1304         ata_kill_pending(&chp->ch_drive[periph->periph_target]);
 1305 }
 1306 
 1307 void
 1308 siisata_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer,
 1309     int reason)
 1310 {
 1311         struct scsipi_xfer *sc_xfer = xfer->c_cmd;
 1312 
 1313         /* remove this command from xfer queue */
 1314         switch (reason) {
 1315         case KILL_GONE:
 1316                 sc_xfer->error = XS_DRIVER_STUFFUP;
 1317                 break;
 1318         case KILL_RESET:
 1319                 sc_xfer->error = XS_RESET;
 1320                 break;
 1321         default:
 1322                 panic("%s: port %d: unknown reason %d",
 1323                    __func__, chp->ch_channel, reason);
 1324         }
 1325         ata_free_xfer(chp, xfer);
 1326         scsipi_done(sc_xfer);
 1327 }
 1328 
 1329 void
 1330 siisata_atapi_probe_device(struct atapibus_softc *sc, int target)
 1331 {
 1332         struct scsipi_channel *chan = sc->sc_channel;
 1333         struct scsipi_periph *periph;
 1334         struct ataparams ids;
 1335         struct ataparams *id = &ids;
 1336         struct siisata_softc *siic =
 1337             device_private(chan->chan_adapter->adapt_dev);
 1338         struct atac_softc *atac = &siic->sc_atac;
 1339         struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
 1340         struct ata_drive_datas *drvp = &chp->ch_drive[target];
 1341         struct scsipibus_attach_args sa;
 1342         char serial_number[21], model[41], firmware_revision[9];
 1343         int s;
 1344 
 1345         /* skip if already attached */
 1346         if (scsipi_lookup_periph(chan, target, 0) != NULL)
 1347                 return;
 1348 
 1349         /* if no ATAPI device detected at attach time, skip */
 1350         if ((drvp->drive_flags & DRIVE_ATAPI) == 0) {
 1351                 SIISATA_DEBUG_PRINT(("%s: drive %d "
 1352                     "not present\n", __func__, target), DEBUG_PROBE);
 1353                 return;
 1354         }
 1355 
 1356         /* Some ATAPI devices need a bit more time after software reset. */
 1357         DELAY(5000);
 1358         if (ata_get_params(drvp, AT_WAIT, id) == 0) {
 1359 #ifdef ATAPI_DEBUG_PROBE
 1360                 log(LOG_DEBUG, "%s drive %d: cmdsz 0x%x drqtype 0x%x\n",
 1361                     device_xname(sc->sc_dev), target,
 1362                     id->atap_config & ATAPI_CFG_CMD_MASK,
 1363                     id->atap_config & ATAPI_CFG_DRQ_MASK);
 1364 #endif
 1365                 periph = scsipi_alloc_periph(M_NOWAIT);
 1366                 if (periph == NULL) {
 1367                         aprint_error_dev(sc->sc_dev,
 1368                             "%s: unable to allocate periph for "
 1369                             "channel %d drive %d\n", __func__,
 1370                             chp->ch_channel, target);
 1371                         return;
 1372                 }
 1373                 periph->periph_dev = NULL;
 1374                 periph->periph_channel = chan;
 1375                 periph->periph_switch = &atapi_probe_periphsw;
 1376                 periph->periph_target = target;
 1377                 periph->periph_lun = 0;
 1378                 periph->periph_quirks = PQUIRK_ONLYBIG;
 1379 
 1380 #ifdef SCSIPI_DEBUG
 1381                 if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_ATAPI &&
 1382                     SCSIPI_DEBUG_TARGET == target)
 1383                         periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS;
 1384 #endif
 1385                 periph->periph_type = ATAPI_CFG_TYPE(id->atap_config);
 1386                 if (id->atap_config & ATAPI_CFG_REMOV)
 1387                         periph->periph_flags |= PERIPH_REMOVABLE;
 1388                 if (periph->periph_type == T_SEQUENTIAL) {
 1389                         s = splbio();
 1390                         drvp->drive_flags |= DRIVE_ATAPIST;
 1391                         splx(s);
 1392                 }
 1393 
 1394                 sa.sa_periph = periph;
 1395                 sa.sa_inqbuf.type = ATAPI_CFG_TYPE(id->atap_config);
 1396                 sa.sa_inqbuf.removable = id->atap_config & ATAPI_CFG_REMOV ?
 1397                     T_REMOV : T_FIXED;
 1398                 scsipi_strvis((u_char *)model, 40, id->atap_model, 40);
 1399                 scsipi_strvis((u_char *)serial_number, 20,
 1400                     id->atap_serial, 20);
 1401                 scsipi_strvis((u_char *)firmware_revision, 8,
 1402                     id->atap_revision, 8);
 1403                 sa.sa_inqbuf.vendor = model;
 1404                 sa.sa_inqbuf.product = serial_number;
 1405                 sa.sa_inqbuf.revision = firmware_revision;
 1406 
 1407                 /*
 1408                  * Determine the operating mode capabilities of the device.
 1409                  */
 1410                 if ((id->atap_config & ATAPI_CFG_CMD_MASK)
 1411                     == ATAPI_CFG_CMD_16) {
 1412                         periph->periph_cap |= PERIPH_CAP_CMD16;
 1413                 
 1414                         /* configure port for packet length */
 1415                         PRWRITE(siic, PRX(chp->ch_channel, PRO_PCS),
 1416                             PR_PC_PACKET_LENGTH);
 1417                 } else {
 1418                         PRWRITE(siic, PRX(chp->ch_channel, PRO_PCC),
 1419                             PR_PC_PACKET_LENGTH);
 1420                 }
 1421 
 1422                 /* XXX This is gross. */
 1423                 periph->periph_cap |= (id->atap_config & ATAPI_CFG_DRQ_MASK);
 1424 
 1425                 drvp->drv_softc = atapi_probe_device(sc, target, periph, &sa);
 1426 
 1427                 if (drvp->drv_softc)
 1428                         ata_probe_caps(drvp);
 1429                 else {
 1430                         s = splbio();
 1431                         drvp->drive_flags &= ~DRIVE_ATAPI;
 1432                         splx(s);
 1433                 }
 1434         } else {
 1435                 SIISATA_DEBUG_PRINT(("%s: ATAPI_IDENTIFY_DEVICE "
 1436                     "failed for drive %s:%d:%d: error 0x%x\n",
 1437                     __func__, SIISATANAME(siic), chp->ch_channel, target,
 1438                     chp->ch_error), DEBUG_PROBE);
 1439                 s = splbio();
 1440                 drvp->drive_flags &= ~DRIVE_ATAPI;
 1441                 splx(s);
 1442         }
 1443 }
 1444 
 1445 void
 1446 siisata_atapi_scsipi_request(struct scsipi_channel *chan,
 1447     scsipi_adapter_req_t req, void *arg)
 1448 {
 1449         struct scsipi_adapter *adapt = chan->chan_adapter;
 1450         struct scsipi_periph *periph;
 1451         struct scsipi_xfer *sc_xfer;
 1452         struct siisata_softc *sc = device_private(adapt->adapt_dev);
 1453         struct atac_softc *atac = &sc->sc_atac;
 1454         struct ata_xfer *xfer;
 1455         int channel = chan->chan_channel;
 1456         int drive, s;
 1457 
 1458         switch (req) {
 1459         case ADAPTER_REQ_RUN_XFER:
 1460                 sc_xfer = arg;
 1461                 periph = sc_xfer->xs_periph;
 1462                 drive = periph->periph_target;
 1463 
 1464                 SIISATA_DEBUG_PRINT(("%s: %s:%d:%d\n", __func__,
 1465                     device_xname(atac->atac_dev), channel, drive),
 1466                     DEBUG_XFERS);
 1467 
 1468                 if (!device_is_active(atac->atac_dev)) {
 1469                         sc_xfer->error = XS_DRIVER_STUFFUP;
 1470                         scsipi_done(sc_xfer);
 1471                         return;
 1472                 }
 1473                 xfer = ata_get_xfer(ATAXF_NOSLEEP);
 1474                 if (xfer == NULL) {
 1475                         sc_xfer->error = XS_RESOURCE_SHORTAGE;
 1476                         scsipi_done(sc_xfer);
 1477                         return;
 1478                 }
 1479 
 1480                 if (sc_xfer->xs_control & XS_CTL_POLL)
 1481                         xfer->c_flags |= C_POLL;
 1482                 xfer->c_drive = drive;
 1483                 xfer->c_flags |= C_ATAPI;
 1484                 xfer->c_cmd = sc_xfer;
 1485                 xfer->c_databuf = sc_xfer->data;
 1486                 xfer->c_bcount = sc_xfer->datalen;
 1487                 xfer->c_start = siisata_atapi_start;
 1488                 xfer->c_intr = siisata_atapi_complete;
 1489                 xfer->c_kill_xfer = siisata_atapi_kill_xfer;
 1490                 xfer->c_dscpoll = 0;
 1491                 s = splbio();
 1492                 ata_exec_xfer(atac->atac_channels[channel], xfer);
 1493 #ifdef DIAGNOSTIC
 1494                 if ((sc_xfer->xs_control & XS_CTL_POLL) != 0 &&
 1495                     (sc_xfer->xs_status & XS_STS_DONE) == 0)
 1496                         panic("%s: polled command not done", __func__);
 1497 #endif
 1498                 splx(s);
 1499                 return;
 1500 
 1501         default:
 1502                 /* Not supported, nothing to do. */
 1503                 ;
 1504         }
 1505 }
 1506 
 1507 void
 1508 siisata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer)
 1509 {
 1510         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 1511         struct siisata_channel *schp = (struct siisata_channel *)chp;
 1512         struct siisata_prb *prbp;
 1513 
 1514         struct scsipi_xfer *sc_xfer = xfer->c_cmd;
 1515 
 1516         int slot = SIISATA_NON_NCQ_SLOT;
 1517         int i;
 1518 
 1519         SIISATA_DEBUG_PRINT( ("%s: %s:%d:%d, scsi flags 0x%x\n", __func__,
 1520             SIISATANAME(sc), chp->ch_channel,
 1521             chp->ch_drive[xfer->c_drive].drive, sc_xfer->xs_control),
 1522             DEBUG_XFERS);
 1523 
 1524         chp->ch_status = 0;
 1525         chp->ch_error = 0;
 1526 
 1527         prbp = schp->sch_prb[slot];
 1528         memset(prbp, 0, sizeof(struct siisata_prb));
 1529 
 1530 
 1531         /* fill in direction for ATAPI command */
 1532         if ((sc_xfer->xs_control & XS_CTL_DATA_IN))
 1533                 prbp->prb_control |= htole16(PRB_CF_PACKET_READ);
 1534         if ((sc_xfer->xs_control & XS_CTL_DATA_OUT))
 1535                 prbp->prb_control |= htole16(PRB_CF_PACKET_WRITE);
 1536 
 1537         satafis_rhd_construct_atapi(xfer, prbp->prb_fis);
 1538 
 1539         /* copy over ATAPI command */
 1540         memcpy(prbp->prb_atapi, sc_xfer->cmd, sc_xfer->cmdlen);
 1541 
 1542         if (siisata_dma_setup(chp, slot,
 1543                 (sc_xfer->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) ?
 1544                 xfer->c_databuf : NULL,
 1545                 xfer->c_bcount,
 1546                 (sc_xfer->xs_control & XS_CTL_DATA_IN) ?
 1547                 BUS_DMA_READ : BUS_DMA_WRITE)
 1548         )
 1549                 panic("%s", __func__);
 1550 
 1551         if (xfer->c_flags & C_POLL) {
 1552                 /* polled command, disable interrupts */
 1553                 prbp->prb_control = htole16(PRB_CF_INTERRUPT_MASK);
 1554         }
 1555 
 1556         siisata_activate_prb(schp, slot);
 1557 
 1558         if ((xfer->c_flags & C_POLL) == 0) {
 1559                 chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */
 1560                 callout_reset(&chp->ch_callout, mstohz(sc_xfer->timeout),
 1561                     siisata_timeout, chp);
 1562                 goto out;
 1563         }
 1564 
 1565         /*
 1566          * polled command
 1567          */
 1568         for (i = 0; i < ATA_DELAY / 10; i++) {
 1569                 if (sc_xfer->xs_status & XS_STS_DONE)
 1570                         break;
 1571                 siisata_intr_port(schp);
 1572                 DELAY(1000);
 1573         }
 1574         if ((sc_xfer->xs_status & XS_STS_DONE) == 0) {
 1575                 sc_xfer->error = XS_TIMEOUT;
 1576                 siisata_atapi_complete(chp, xfer, slot);
 1577         }
 1578         /* reenable interrupts */
 1579         GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel));
 1580 out:
 1581         SIISATA_DEBUG_PRINT(
 1582             ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS);
 1583         return;
 1584 }
 1585 
 1586 int
 1587 siisata_atapi_complete(struct ata_channel *chp, struct ata_xfer *xfer,
 1588     int slot)
 1589 {
 1590         struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 1591         struct siisata_channel *schp = (struct siisata_channel *)chp;
 1592         struct scsipi_xfer *sc_xfer = xfer->c_cmd;
 1593 
 1594         SIISATA_DEBUG_PRINT(
 1595             ("%s: %s()\n", SIISATANAME(sc), __func__), DEBUG_INTR);
 1596 
 1597         /* this comamnd is not active any more */
 1598         schp->sch_active_slots &= ~__BIT(slot);
 1599         chp->ch_flags &= ~ATACH_IRQ_WAIT;
 1600         if (xfer->c_flags & C_TIMEOU) {
 1601                 sc_xfer->error = XS_TIMEOUT;
 1602         } else {
 1603                 callout_stop(&chp->ch_callout);
 1604                 sc_xfer->error = XS_NOERROR;
 1605         }
 1606 
 1607         bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0,
 1608             schp->sch_datad[slot]->dm_mapsize,
 1609             (sc_xfer->xs_control & XS_CTL_DATA_IN) ?
 1610             BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
 1611         bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]);
 1612 
 1613         if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) {
 1614                 siisata_atapi_kill_xfer(chp, xfer, KILL_GONE);
 1615                 chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN;
 1616                 wakeup(&chp->ch_queue->active_xfer);
 1617                 return 0; /* XXX verify */
 1618         }
 1619 
 1620         chp->ch_queue->active_xfer = NULL;
 1621         ata_free_xfer(chp, xfer);
 1622 
 1623         sc_xfer->resid = sc_xfer->datalen;
 1624         sc_xfer->resid -= PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC));
 1625         SIISATA_DEBUG_PRINT(("%s: %s datalen %d resid %d\n", SIISATANAME(sc),
 1626             __func__, sc_xfer->datalen, sc_xfer->resid), DEBUG_XFERS); 
 1627         if ((chp->ch_status & WDCS_ERR) &&
 1628             ((sc_xfer->xs_control & XS_CTL_REQSENSE) == 0 ||
 1629             sc_xfer->resid == sc_xfer->datalen)) {
 1630                 sc_xfer->error = XS_SHORTSENSE;
 1631                 sc_xfer->sense.atapi_sense = chp->ch_error;
 1632                 if ((sc_xfer->xs_periph->periph_quirks &
 1633                     PQUIRK_NOSENSE) == 0) {
 1634                         /* request sense */
 1635                         sc_xfer->error = XS_BUSY;
 1636                         sc_xfer->status = SCSI_CHECK;
 1637                 }
 1638         }
 1639         scsipi_done(sc_xfer);
 1640         atastart(chp);
 1641         return 0; /* XXX verify */
 1642 }
 1643 
 1644 #endif /* NATAPIBUS */

Cache object: 1d4c3f169f757f8ad02bcc720ea8d2c9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.