root/dev/ic/sili.c

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

DEFINITIONS

This source file includes following definitions.
  1. sili_attach
  2. sili_detach
  3. sili_port_intr
  4. sili_intr
  5. sili_ports_alloc
  6. sili_ports_free
  7. sili_ccb_alloc
  8. sili_ccb_free
  9. sili_get_ccb
  10. sili_put_ccb
  11. sili_dmamem_alloc
  12. sili_dmamem_free
  13. sili_read
  14. sili_write
  15. sili_pread
  16. sili_pwrite
  17. sili_pwait_eq
  18. sili_pwait_ne
  19. sili_post_direct
  20. sili_pread_fis
  21. sili_post_indirect
  22. sili_signature
  23. sili_ata_probe
  24. sili_ata_cmd
  25. sili_ata_cmd_done
  26. sili_ata_cmd_timeout
  27. sili_load
  28. sili_unload
  29. sili_poll
  30. sili_start
  31. sili_read_ncq_error
  32. sili_ata_get_xfer
  33. sili_ata_put_xfer

    1 /*      $OpenBSD: sili.c,v 1.33 2007/04/22 00:06:51 dlg Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include <sys/param.h>
   20 #include <sys/systm.h>
   21 #include <sys/buf.h>
   22 #include <sys/device.h>
   23 #include <sys/proc.h>
   24 #include <sys/malloc.h>
   25 #include <sys/kernel.h>
   26 
   27 #include <machine/bus.h>
   28 
   29 #include <dev/ata/atascsi.h>
   30 
   31 #include <dev/ic/silireg.h>
   32 #include <dev/ic/silivar.h>
   33 
   34 /* use SILI_DEBUG for dmesg spam */
   35 #define NO_SILI_DEBUG
   36 
   37 #ifdef SILI_DEBUG
   38 #define SILI_D_VERBOSE          (1<<0)
   39 #define SILI_D_INTR             (1<<1)
   40 
   41 int silidebug = SILI_D_VERBOSE;
   42 
   43 #define DPRINTF(m, a...)        do { if ((m) & silidebug) printf(a); } while (0)
   44 #else
   45 #define DPRINTF(m, a...)
   46 #endif
   47 
   48 struct cfdriver sili_cd = {
   49         NULL, "sili", DV_DULL
   50 };
   51 
   52 /* wrapper around dma memory */
   53 struct sili_dmamem {
   54         bus_dmamap_t            sdm_map;
   55         bus_dma_segment_t       sdm_seg;
   56         size_t                  sdm_size;
   57         caddr_t                 sdm_kva;
   58 };
   59 #define SILI_DMA_MAP(_sdm)      ((_sdm)->sdm_map)
   60 #define SILI_DMA_DVA(_sdm)      ((_sdm)->sdm_map->dm_segs[0].ds_addr)
   61 #define SILI_DMA_KVA(_sdm)      ((void *)(_sdm)->sdm_kva)
   62 
   63 struct sili_dmamem      *sili_dmamem_alloc(struct sili_softc *, bus_size_t,
   64                             bus_size_t);
   65 void                    sili_dmamem_free(struct sili_softc *,
   66                             struct sili_dmamem *);
   67 
   68 /* per port goo */
   69 struct sili_ccb;
   70 
   71 /* size of scratch space for use in error recovery. */
   72 #define SILI_SCRATCH_LEN        512     /* must be at least 1 sector */
   73 
   74 struct sili_port {
   75         struct sili_softc       *sp_sc;
   76         bus_space_handle_t      sp_ioh;
   77 
   78         struct sili_ccb         *sp_ccbs;
   79         struct sili_dmamem      *sp_cmds;
   80         struct sili_dmamem      *sp_scratch;
   81 
   82         TAILQ_HEAD(, sili_ccb)  sp_free_ccbs;
   83 
   84         volatile u_int32_t      sp_active;
   85         TAILQ_HEAD(, sili_ccb)  sp_active_ccbs;
   86         TAILQ_HEAD(, sili_ccb)  sp_deferred_ccbs;
   87 
   88 #ifdef SILI_DEBUG
   89         char                    sp_name[16];
   90 #define PORTNAME(_sp)   ((_sp)->sp_name)
   91 #else
   92 #define PORTNAME(_sp)   DEVNAME((_sp)->sp_sc)
   93 #endif
   94 };
   95 
   96 int                     sili_ports_alloc(struct sili_softc *);
   97 void                    sili_ports_free(struct sili_softc *);
   98 
   99 /* ccb shizz */
  100 
  101 /*
  102  * the dma memory for each command will be made up of a prb followed by
  103  * 7 sgts, this is a neat 512 bytes.
  104  */
  105 #define SILI_CMD_LEN            512
  106 
  107 /*
  108  * you can fit 22 sge's into 7 sgts and a prb:
  109  * there's 1 sgl in an atapi prb (two in the ata one, but we cant over
  110  * advertise), but that's needed for the chain element. you get three sges
  111  * per sgt cos you lose the 4th sge for the chaining, but you keep it in
  112  * the last sgt. so 3 x 6 + 4 is 22.
  113  */
  114 #define SILI_DMA_SEGS           22
  115 
  116 struct sili_ccb {
  117         struct ata_xfer         ccb_xa;
  118 
  119         void                    *ccb_cmd;
  120         u_int64_t               ccb_cmd_dva;
  121         bus_dmamap_t            ccb_dmamap;
  122 
  123         struct sili_port        *ccb_port;
  124 
  125         TAILQ_ENTRY(sili_ccb)   ccb_entry;
  126 };
  127 
  128 int                     sili_ccb_alloc(struct sili_port *);
  129 void                    sili_ccb_free(struct sili_port *);
  130 struct sili_ccb         *sili_get_ccb(struct sili_port *);
  131 void                    sili_put_ccb(struct sili_ccb *);
  132 
  133 /* bus space ops */
  134 u_int32_t               sili_read(struct sili_softc *, bus_size_t);
  135 void                    sili_write(struct sili_softc *, bus_size_t, u_int32_t);
  136 u_int32_t               sili_pread(struct sili_port *, bus_size_t);
  137 void                    sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
  138 int                     sili_pwait_eq(struct sili_port *, bus_size_t,
  139                             u_int32_t, u_int32_t, int);
  140 int                     sili_pwait_ne(struct sili_port *, bus_size_t,
  141                             u_int32_t, u_int32_t, int);
  142 
  143 /* command handling */
  144 void                    sili_post_direct(struct sili_port *, u_int,
  145                             void *, size_t buflen);
  146 void                    sili_post_indirect(struct sili_port *,
  147                             struct sili_ccb *);
  148 void                    sili_pread_fis(struct sili_port *, u_int,
  149                             struct ata_fis_d2h *);
  150 u_int32_t               sili_signature(struct sili_port *, u_int);
  151 int                     sili_load(struct sili_ccb *, struct sili_sge *, int);
  152 void                    sili_unload(struct sili_ccb *);
  153 int                     sili_poll(struct sili_ccb *, int, void (*)(void *));
  154 void                    sili_start(struct sili_port *, struct sili_ccb *);
  155 int                     sili_read_ncq_error(struct sili_port *, int *);
  156 
  157 /* port interrupt handler */
  158 u_int32_t               sili_port_intr(struct sili_port *, int);
  159 
  160 /* atascsi interface */
  161 int                     sili_ata_probe(void *, int);
  162 struct ata_xfer         *sili_ata_get_xfer(void *, int);
  163 void                    sili_ata_put_xfer(struct ata_xfer *);
  164 int                     sili_ata_cmd(struct ata_xfer *);
  165 
  166 struct atascsi_methods sili_atascsi_methods = {
  167         sili_ata_probe,
  168         sili_ata_get_xfer,
  169         sili_ata_cmd
  170 };
  171 
  172 /* completion paths */
  173 void                    sili_ata_cmd_done(struct sili_ccb *, int);
  174 void                    sili_ata_cmd_timeout(void *);
  175 
  176 int
  177 sili_attach(struct sili_softc *sc)
  178 {
  179         struct atascsi_attach_args      aaa;
  180 
  181         printf("\n");
  182 
  183         if (sili_ports_alloc(sc) != 0) {
  184                 /* error already printed by sili_port_alloc */
  185                 return (1);
  186         }
  187 
  188         /* bounce the controller */
  189         sili_write(sc, SILI_REG_GC, SILI_REG_GC_GR);
  190         sili_write(sc, SILI_REG_GC, 0x0);
  191 
  192         bzero(&aaa, sizeof(aaa));
  193         aaa.aaa_cookie = sc;
  194         aaa.aaa_methods = &sili_atascsi_methods;
  195         aaa.aaa_minphys = minphys;
  196         aaa.aaa_nports = sc->sc_nports;
  197         aaa.aaa_ncmds = SILI_MAX_CMDS;
  198         aaa.aaa_capability = ASAA_CAP_NCQ;
  199 
  200         sc->sc_atascsi = atascsi_attach(&sc->sc_dev, &aaa);
  201 
  202         return (0);
  203 }
  204 
  205 int
  206 sili_detach(struct sili_softc *sc, int flags)
  207 {
  208         return (0);
  209 }
  210 
  211 u_int32_t
  212 sili_port_intr(struct sili_port *sp, int timeout_slot)
  213 {
  214         u_int32_t                       is, pss_saved, pss_masked;
  215         u_int32_t                       processed = 0, need_restart = 0;
  216         int                             slot;
  217         struct sili_ccb                 *ccb;
  218 
  219         is = sili_pread(sp, SILI_PREG_IS);
  220         pss_saved = sili_pread(sp, SILI_PREG_PSS); /* reading acks CMDCOMP */
  221 
  222 #ifdef SILI_DEBUG
  223         if ((pss_saved & SILI_PREG_PSS_ALL_SLOTS) != sp->sp_active ||
  224             ((is >> 16) & ~SILI_PREG_IS_CMDCOMP)) {
  225                 DPRINTF(SILI_D_INTR, "%s: IS: 0x%08x (0x%b), PSS: %08x, "
  226                     "active: %08x\n", PORTNAME(sp), is, is >> 16, SILI_PFMT_IS,
  227                     pss_saved, sp->sp_active);
  228         }
  229 #endif
  230 
  231         /* Only interested in slot status bits. */
  232         pss_saved &= SILI_PREG_PSS_ALL_SLOTS;
  233 
  234         if (is & SILI_PREG_IS_CMDERR) {
  235                 int                     err_slot, err_code;
  236                 u_int32_t               sactive = 0;
  237 
  238                 sili_pwrite(sp, SILI_PREG_IS, SILI_PREG_IS_CMDERR);
  239                 err_slot = SILI_PREG_PCS_ACTIVE(sili_pread(sp, SILI_PREG_PCS));
  240                 err_code = sili_pread(sp, SILI_PREG_CE);
  241                 ccb = &sp->sp_ccbs[err_slot];
  242 
  243                 switch (err_code) {
  244                 case SILI_PREG_CE_DEVICEERROR:
  245                 case SILI_PREG_CE_DATAFISERROR:
  246                         /* Extract error from command slot in LRAM. */
  247                         sili_pread_fis(sp, err_slot, &ccb->ccb_xa.rfis);
  248                         break;
  249 
  250                 case SILI_PREG_CE_SDBERROR:
  251                         /* No NCQ commands active?  Treat as a normal error. */
  252                         sactive = sili_pread(sp, SILI_PREG_SACT);/* XXX Pmult */
  253                         if (sactive == 0)
  254                                 break;
  255 
  256                         /* Extract real NCQ error slot & RFIS from log page. */
  257                         if (!sili_read_ncq_error(sp, &err_slot)) {
  258                                 /* got real err_slot */
  259                                 ccb = &sp->sp_ccbs[err_slot];
  260                                 break;
  261                         }
  262 
  263                         /* failed to get error or not NCQ */
  264 
  265                         /* FALLTHROUGH */
  266                 default:
  267                         /* All other error types are fatal. */
  268                         printf("%s: fatal error (%d), aborting active slots "
  269                             "(%08x) and resetting device.\n", PORTNAME(sp),
  270                             err_code, pss_saved);
  271                         while (pss_saved) {
  272                                 slot = ffs(pss_saved) - 1;
  273                                 pss_saved &= ~(1 << slot);
  274 
  275                                 ccb = &sp->sp_ccbs[slot];
  276                                 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  277                                 ccb->ccb_xa.state = ATA_S_ERROR;
  278                         }
  279                         need_restart = SILI_PREG_PCS_DEVRESET;
  280                         goto fatal;
  281                 }
  282 
  283                 DPRINTF(SILI_D_VERBOSE, "%s: %serror, code %d, slot %d, "
  284                     "active %08x\n", PORTNAME(sp), sactive ? "NCQ " : "",
  285                     err_code, err_slot, sp->sp_active);
  286 
  287                 /* Clear the failed commmand in saved PSS so cmd_done runs. */
  288                 pss_saved &= ~(1 << err_slot);
  289 
  290                 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  291                 ccb->ccb_xa.state = ATA_S_ERROR;
  292 
  293                 need_restart = SILI_PREG_PCS_PORTINIT;
  294         }
  295 fatal:
  296 
  297         /* Process command timeout request only if command is still active. */
  298         if (timeout_slot >= 0 && (pss_saved & (1 << timeout_slot))) {
  299                 DPRINTF(SILI_D_VERBOSE, "%s: timing out slot %d, active %08x\n",
  300                     PORTNAME(sp), timeout_slot, sp->sp_active);
  301 
  302                 /* Clear the failed commmand in saved PSS so cmd_done runs. */
  303                 pss_saved &= ~(1 << timeout_slot);
  304 
  305                 ccb = &sp->sp_ccbs[timeout_slot];
  306                 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  307                 ccb->ccb_xa.state = ATA_S_TIMEOUT;
  308 
  309                 /* Reset device to abort all commands (including this one). */
  310                 need_restart = SILI_PREG_PCS_DEVRESET;
  311         }
  312 
  313         /* Command slot is complete if its bit in PSS is 0 but 1 in active. */
  314         pss_masked = ~pss_saved & sp->sp_active;
  315         while (pss_masked) {
  316                 slot = ffs(pss_masked) - 1;
  317                 ccb = &sp->sp_ccbs[slot];
  318                 pss_masked &= ~(1 << slot);
  319 
  320                 DPRINTF(SILI_D_INTR, "%s: slot %d is complete%s\n",
  321                     PORTNAME(sp), slot, ccb->ccb_xa.state == ATA_S_ERROR ?
  322                     " (error)" : (ccb->ccb_xa.state == ATA_S_TIMEOUT ?
  323                     " (timeout)" : ""));
  324 
  325                 sili_ata_cmd_done(ccb, need_restart);
  326 
  327                 processed |= 1 << slot;
  328         }
  329 
  330         if (need_restart) {
  331                 /* Re-enable transfers on port. */
  332                 sili_pwrite(sp, SILI_PREG_PCS, need_restart);
  333                 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
  334                     SILI_PREG_PCS_PORTRDY, 1000)) {
  335                         printf("%s: couldn't restart port after error\n",
  336                             PORTNAME(sp));
  337                 }
  338 
  339                 /* Restart CCBs in the order they were originally queued. */
  340                 pss_masked = pss_saved;
  341                 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
  342                         DPRINTF(SILI_D_VERBOSE, "%s: restarting slot %d "
  343                             "after error, state %02x\n", PORTNAME(sp),
  344                             ccb->ccb_xa.tag, ccb->ccb_xa.state);
  345                         if (!(pss_masked & (1 << ccb->ccb_xa.tag))) {
  346                                 panic("sili_intr: slot %d not active in "
  347                                     "pss_masked: %08x, state %02x",
  348                                     ccb->ccb_xa.tag, pss_masked,
  349                                     ccb->ccb_xa.state);
  350                         }
  351                         pss_masked &= ~(1 << ccb->ccb_xa.tag);
  352 
  353                         KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  354                         sili_post_indirect(sp, ccb);
  355                 }
  356                 KASSERT(pss_masked == 0);
  357 
  358                 /*
  359                  * Finally, run atascsi completion for any finished CCBs.  If
  360                  * we had run these during cmd_done above, any ccbs that their
  361                  * completion generated would have been activated out of order.
  362                  */
  363                 while ((ccb = TAILQ_FIRST(&sp->sp_deferred_ccbs)) != NULL) {
  364                         TAILQ_REMOVE(&sp->sp_deferred_ccbs, ccb, ccb_entry);
  365 
  366                         KASSERT(ccb->ccb_xa.state == ATA_S_COMPLETE ||
  367                             ccb->ccb_xa.state == ATA_S_ERROR ||
  368                             ccb->ccb_xa.state == ATA_S_TIMEOUT);
  369                         ccb->ccb_xa.complete(&ccb->ccb_xa);
  370                 }
  371         }
  372 
  373         return (processed);
  374 }
  375 
  376 int
  377 sili_intr(void *arg)
  378 {
  379         struct sili_softc               *sc = arg;
  380         u_int32_t                       is;
  381         int                             port;
  382 
  383         is = sili_read(sc, SILI_REG_GIS);
  384         if (is == 0)
  385                 return (0);
  386         sili_write(sc, SILI_REG_GIS, is);
  387         DPRINTF(SILI_D_INTR, "sili_intr, GIS: %08x\n", is);
  388 
  389         while (is & SILI_REG_GIS_PIS_MASK) {
  390                 port = ffs(is) - 1;
  391                 sili_port_intr(&sc->sc_ports[port], -1);
  392                 is &= ~(1 << port);
  393         }
  394 
  395         return (1);
  396 }
  397 
  398 int
  399 sili_ports_alloc(struct sili_softc *sc)
  400 {
  401         struct sili_port                *sp;
  402         int                             i;
  403 
  404         sc->sc_ports = malloc(sizeof(struct sili_port) * sc->sc_nports,
  405             M_DEVBUF, M_WAITOK);
  406         bzero(sc->sc_ports, sizeof(struct sili_port) * sc->sc_nports);
  407 
  408         for (i = 0; i < sc->sc_nports; i++) {
  409                 sp = &sc->sc_ports[i];
  410 
  411                 sp->sp_sc = sc;
  412 #ifdef SILI_DEBUG
  413                 snprintf(sp->sp_name, sizeof(sp->sp_name), "%s.%d",
  414                     DEVNAME(sc), i);
  415 #endif
  416                 if (bus_space_subregion(sc->sc_iot_port, sc->sc_ioh_port,
  417                     SILI_PORT_OFFSET(i), SILI_PORT_SIZE, &sp->sp_ioh) != 0) {
  418                         printf("%s: unable to create register window "
  419                             "for port %d\n", DEVNAME(sc), i);
  420                         goto freeports;
  421                 }
  422         }
  423 
  424         return (0);
  425 
  426 freeports:
  427         /* bus_space(9) says subregions dont have to be freed */
  428         free(sp, M_DEVBUF);
  429         sc->sc_ports = NULL;
  430         return (1);
  431 }
  432 
  433 void
  434 sili_ports_free(struct sili_softc *sc)
  435 {
  436         struct sili_port                *sp;
  437         int                             i;
  438 
  439         for (i = 0; i < sc->sc_nports; i++) {
  440                 sp = &sc->sc_ports[i];
  441 
  442                 if (sp->sp_ccbs != NULL)
  443                         sili_ccb_free(sp);
  444         }
  445 
  446         /* bus_space(9) says subregions dont have to be freed */
  447         free(sc->sc_ports, M_DEVBUF);
  448         sc->sc_ports = NULL;
  449 }
  450 
  451 int
  452 sili_ccb_alloc(struct sili_port *sp)
  453 {
  454         struct sili_softc               *sc = sp->sp_sc;
  455         struct sili_ccb                 *ccb;
  456         struct sili_prb                 *prb;
  457         int                             i;
  458 
  459         TAILQ_INIT(&sp->sp_free_ccbs);
  460         TAILQ_INIT(&sp->sp_active_ccbs);
  461         TAILQ_INIT(&sp->sp_deferred_ccbs);
  462 
  463         sp->sp_ccbs = malloc(sizeof(struct sili_ccb) * SILI_MAX_CMDS,
  464             M_DEVBUF, M_WAITOK);
  465         sp->sp_cmds = sili_dmamem_alloc(sc, SILI_CMD_LEN * SILI_MAX_CMDS,
  466             SILI_PRB_ALIGN);
  467         if (sp->sp_cmds == NULL)
  468                 goto free_ccbs;
  469         sp->sp_scratch = sili_dmamem_alloc(sc, SILI_SCRATCH_LEN, PAGE_SIZE);
  470         if (sp->sp_scratch == NULL)
  471                 goto free_cmds;
  472 
  473         bzero(sp->sp_ccbs, sizeof(struct sili_ccb) * SILI_MAX_CMDS);
  474 
  475         for (i = 0; i < SILI_MAX_CMDS; i++) {
  476                 ccb = &sp->sp_ccbs[i];
  477                 ccb->ccb_port = sp;
  478                 ccb->ccb_cmd = SILI_DMA_KVA(sp->sp_cmds) + i * SILI_CMD_LEN;
  479                 ccb->ccb_cmd_dva = SILI_DMA_DVA(sp->sp_cmds) + i * SILI_CMD_LEN;
  480                 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, SILI_DMA_SEGS,
  481                     MAXPHYS, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
  482                     &ccb->ccb_dmamap) != 0)
  483                         goto free_scratch;
  484 
  485                 prb = ccb->ccb_cmd;
  486                 ccb->ccb_xa.fis = (struct ata_fis_h2d *)&prb->fis;
  487                 ccb->ccb_xa.packetcmd = ((struct sili_prb_packet *)prb)->cdb;
  488                 ccb->ccb_xa.tag = i;
  489                 ccb->ccb_xa.ata_put_xfer = sili_ata_put_xfer;
  490                 ccb->ccb_xa.state = ATA_S_COMPLETE;
  491 
  492                 sili_put_ccb(ccb);
  493         }
  494 
  495         return (0);
  496 
  497 free_scratch:
  498         sili_dmamem_free(sc, sp->sp_scratch);
  499 free_cmds:
  500         sili_dmamem_free(sc, sp->sp_cmds);
  501 free_ccbs:
  502         sili_ccb_free(sp);
  503         return (1);
  504 }
  505 
  506 void
  507 sili_ccb_free(struct sili_port *sp)
  508 {
  509         struct sili_softc               *sc = sp->sp_sc;
  510         struct sili_ccb                 *ccb;
  511 
  512         while ((ccb = sili_get_ccb(sp)) != NULL)
  513                 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
  514 
  515         free(sp->sp_ccbs, M_DEVBUF);
  516         sp->sp_ccbs = NULL;
  517 }
  518 
  519 struct sili_ccb *
  520 sili_get_ccb(struct sili_port *sp)
  521 {
  522         struct sili_ccb                 *ccb;
  523 
  524         ccb = TAILQ_FIRST(&sp->sp_free_ccbs);
  525         if (ccb != NULL) {
  526                 KASSERT(ccb->ccb_xa.state == ATA_S_PUT);
  527                 TAILQ_REMOVE(&sp->sp_free_ccbs, ccb, ccb_entry);
  528                 ccb->ccb_xa.state = ATA_S_SETUP;
  529         }
  530 
  531         return (ccb);
  532 }
  533 
  534 void
  535 sili_put_ccb(struct sili_ccb *ccb)
  536 {
  537         struct sili_port                *sp = ccb->ccb_port;
  538 
  539 #ifdef DIAGNOSTIC
  540         if (ccb->ccb_xa.state != ATA_S_COMPLETE &&
  541             ccb->ccb_xa.state != ATA_S_TIMEOUT &&
  542             ccb->ccb_xa.state != ATA_S_ERROR) {
  543                 printf("%s: invalid ata_xfer state %02x in sili_put_ccb, "
  544                     "slot %d\n", PORTNAME(sp), ccb->ccb_xa.state,
  545                     ccb->ccb_xa.tag);
  546         }
  547 #endif
  548 
  549         ccb->ccb_xa.state = ATA_S_PUT;
  550         TAILQ_INSERT_TAIL(&sp->sp_free_ccbs, ccb, ccb_entry);
  551 }
  552 
  553 struct sili_dmamem *
  554 sili_dmamem_alloc(struct sili_softc *sc, bus_size_t size, bus_size_t align)
  555 {
  556         struct sili_dmamem              *sdm;
  557         int                             nsegs;
  558 
  559         sdm = malloc(sizeof(struct sili_dmamem), M_DEVBUF, M_WAITOK);
  560         bzero(sdm, sizeof(struct sili_dmamem));
  561         sdm->sdm_size = size;
  562 
  563         if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
  564             BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &sdm->sdm_map) != 0)
  565                 goto sdmfree;
  566 
  567         if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &sdm->sdm_seg,
  568             1, &nsegs, BUS_DMA_NOWAIT) != 0)
  569                 goto destroy;
  570 
  571         if (bus_dmamem_map(sc->sc_dmat, &sdm->sdm_seg, nsegs, size,
  572             &sdm->sdm_kva, BUS_DMA_NOWAIT) != 0)
  573                 goto free;
  574 
  575         if (bus_dmamap_load(sc->sc_dmat, sdm->sdm_map, sdm->sdm_kva, size,
  576             NULL, BUS_DMA_NOWAIT) != 0)
  577                 goto unmap;
  578 
  579         bzero(sdm->sdm_kva, size);
  580 
  581         return (sdm);
  582 
  583 unmap:
  584         bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, size);
  585 free:
  586         bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
  587 destroy:
  588         bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
  589 sdmfree:
  590         free(sdm, M_DEVBUF);
  591 
  592         return (NULL);
  593 }
  594 
  595 void
  596 sili_dmamem_free(struct sili_softc *sc, struct sili_dmamem *sdm)
  597 {
  598         bus_dmamap_unload(sc->sc_dmat, sdm->sdm_map);
  599         bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, sdm->sdm_size);
  600         bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
  601         bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
  602         free(sdm, M_DEVBUF);
  603 }
  604 
  605 u_int32_t
  606 sili_read(struct sili_softc *sc, bus_size_t r)
  607 {
  608         u_int32_t                       rv;
  609 
  610         bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
  611             BUS_SPACE_BARRIER_READ);
  612         rv = bus_space_read_4(sc->sc_iot_global, sc->sc_ioh_global, r);
  613 
  614         return (rv);
  615 }
  616 
  617 void
  618 sili_write(struct sili_softc *sc, bus_size_t r, u_int32_t v)
  619 {
  620         bus_space_write_4(sc->sc_iot_global, sc->sc_ioh_global, r, v);
  621         bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
  622             BUS_SPACE_BARRIER_WRITE);
  623 }
  624 
  625 u_int32_t
  626 sili_pread(struct sili_port *sp, bus_size_t r)
  627 {
  628         u_int32_t                       rv;
  629 
  630         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
  631             BUS_SPACE_BARRIER_READ);
  632         rv = bus_space_read_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r);
  633 
  634         return (rv);
  635 }
  636 
  637 void
  638 sili_pwrite(struct sili_port *sp, bus_size_t r, u_int32_t v)
  639 {
  640         bus_space_write_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, v);
  641         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
  642             BUS_SPACE_BARRIER_WRITE);
  643 }
  644 
  645 int
  646 sili_pwait_eq(struct sili_port *sp, bus_size_t r, u_int32_t mask,
  647     u_int32_t value, int timeout)
  648 {
  649         while ((sili_pread(sp, r) & mask) != value) {
  650                 if (timeout == 0)
  651                         return (0);
  652 
  653                 delay(1000);
  654                 timeout--;
  655         }
  656 
  657         return (1);
  658 }
  659 
  660 int
  661 sili_pwait_ne(struct sili_port *sp, bus_size_t r, u_int32_t mask,
  662     u_int32_t value, int timeout)
  663 {
  664         while ((sili_pread(sp, r) & mask) == value) {
  665                 if (timeout == 0)
  666                         return (0);
  667 
  668                 delay(1000);
  669                 timeout--;
  670         }
  671 
  672         return (1);
  673 }
  674 
  675 void
  676 sili_post_direct(struct sili_port *sp, u_int slot, void *buf, size_t buflen)
  677 {
  678         bus_size_t                      r = SILI_PREG_SLOT(slot);
  679 
  680 #ifdef DIAGNOSTIC
  681         if (buflen != 64 && buflen != 128)
  682                 panic("sili_pcopy: buflen of %d is not 64 or 128", buflen);
  683 #endif
  684 
  685         bus_space_write_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
  686             buf, buflen);
  687         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, buflen,
  688             BUS_SPACE_BARRIER_WRITE);
  689 
  690         sili_pwrite(sp, SILI_PREG_FIFO, slot);
  691 }
  692 
  693 void
  694 sili_pread_fis(struct sili_port *sp, u_int slot, struct ata_fis_d2h *fis)
  695 {
  696         bus_size_t                      r = SILI_PREG_SLOT(slot) + 8;
  697 
  698         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
  699             sizeof(struct ata_fis_d2h), BUS_SPACE_BARRIER_READ);
  700         bus_space_read_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
  701             fis, sizeof(struct ata_fis_d2h));
  702 }
  703 
  704 void
  705 sili_post_indirect(struct sili_port *sp, struct sili_ccb *ccb)
  706 {
  707         sili_pwrite(sp, SILI_PREG_CAR_LO(ccb->ccb_xa.tag),
  708             (u_int32_t)ccb->ccb_cmd_dva);
  709         sili_pwrite(sp, SILI_PREG_CAR_HI(ccb->ccb_xa.tag),
  710             (u_int32_t)(ccb->ccb_cmd_dva >> 32));
  711 }
  712 
  713 u_int32_t
  714 sili_signature(struct sili_port *sp, u_int slot)
  715 {
  716         u_int32_t                       sig_hi, sig_lo;
  717 
  718         sig_hi = sili_pread(sp, SILI_PREG_SIG_HI(slot));
  719         sig_hi <<= SILI_PREG_SIG_HI_SHIFT;
  720         sig_lo = sili_pread(sp, SILI_PREG_SIG_LO(slot));
  721         sig_lo &= SILI_PREG_SIG_LO_MASK;
  722 
  723         return (sig_hi | sig_lo);
  724 }
  725 
  726 int
  727 sili_ata_probe(void *xsc, int port)
  728 {
  729         struct sili_softc               *sc = xsc;
  730         struct sili_port                *sp = &sc->sc_ports[port];
  731         struct sili_prb_softreset       sreset;
  732         u_int32_t                       signature;
  733         int                             port_type;
  734 
  735         sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_PORTRESET);
  736         sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_A32B);
  737 
  738         if (!sili_pwait_eq(sp, SILI_PREG_SSTS, SATA_SStatus_DET,
  739             SATA_SStatus_DET_DEV, 1000))
  740                 return (ATA_PORT_T_NONE);
  741 
  742         DPRINTF(SILI_D_VERBOSE, "%s: SSTS 0x%08x\n", PORTNAME(sp),
  743             sili_pread(sp, SILI_PREG_SSTS));
  744 
  745         bzero(&sreset, sizeof(sreset));
  746         sreset.control = htole16(SILI_PRB_SOFT_RESET | SILI_PRB_INTERRUPT_MASK);
  747         /* XXX sreset fis pmp field */
  748 
  749         /* we use slot 0 */
  750         sili_post_direct(sp, 0, &sreset, sizeof(sreset));
  751         if (!sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000)) {
  752                 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for soft "
  753                     "reset\n", PORTNAME(sp));
  754                 return (ATA_PORT_T_NONE);
  755         }
  756 
  757         /* Read device signature from command slot. */
  758         signature = sili_signature(sp, 0);
  759 
  760         DPRINTF(SILI_D_VERBOSE, "%s: signature 0x%08x\n", PORTNAME(sp),
  761             signature);
  762 
  763         switch (signature) {
  764         case SATA_SIGNATURE_DISK:
  765                 port_type = ATA_PORT_T_DISK;
  766                 break;
  767         case SATA_SIGNATURE_ATAPI:
  768                 port_type = ATA_PORT_T_ATAPI;
  769                 break;
  770         case SATA_SIGNATURE_PORT_MULTIPLIER:
  771         default:
  772                 return (ATA_PORT_T_NONE);
  773         }
  774 
  775         /* allocate port resources */
  776         if (sili_ccb_alloc(sp) != 0)
  777                 return (ATA_PORT_T_NONE);
  778 
  779         /* enable port interrupts */
  780         sili_write(sc, SILI_REG_GC, sili_read(sc, SILI_REG_GC) | 1 << port);
  781         sili_pwrite(sp, SILI_PREG_IES, SILI_PREG_IE_CMDERR |
  782             SILI_PREG_IE_CMDCOMP);
  783 
  784         return (port_type);
  785 }
  786 
  787 int
  788 sili_ata_cmd(struct ata_xfer *xa)
  789 {
  790         struct sili_ccb                 *ccb = (struct sili_ccb *)xa;
  791         struct sili_port                *sp = ccb->ccb_port;
  792         struct sili_softc               *sc = sp->sp_sc;
  793         struct sili_prb_ata             *ata;
  794         struct sili_prb_packet          *atapi;
  795         struct sili_sge                 *sgl;
  796         int                             sgllen;
  797         int                             s;
  798 
  799         KASSERT(xa->state == ATA_S_SETUP);
  800 
  801         if (xa->flags & ATA_F_PACKET) {
  802                 atapi = ccb->ccb_cmd;
  803 
  804                 if (xa->flags & ATA_F_WRITE)
  805                         atapi->control = htole16(SILI_PRB_PACKET_WRITE);
  806                 else
  807                         atapi->control = htole16(SILI_PRB_PACKET_READ);
  808 
  809                 sgl = atapi->sgl;
  810                 sgllen = sizeofa(atapi->sgl);
  811         } else {
  812                 ata = ccb->ccb_cmd;
  813 
  814                 ata->control = 0;
  815 
  816                 sgl = ata->sgl;
  817                 sgllen = sizeofa(ata->sgl);
  818         }
  819 
  820         if (sili_load(ccb, sgl, sgllen) != 0)
  821                 goto failcmd;
  822 
  823         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
  824             xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_PREWRITE);
  825 
  826         timeout_set(&xa->stimeout, sili_ata_cmd_timeout, ccb);
  827 
  828         xa->state = ATA_S_PENDING;
  829 
  830         if (xa->flags & ATA_F_POLL) {
  831                 sili_poll(ccb, xa->timeout, sili_ata_cmd_timeout);
  832                 return (ATA_COMPLETE);
  833         }
  834 
  835         timeout_add(&xa->stimeout, (xa->timeout * hz) / 1000);
  836 
  837         s = splbio();
  838         sili_start(sp, ccb);
  839         splx(s);
  840         return (ATA_QUEUED);
  841 
  842 failcmd:
  843         s = splbio();
  844         xa->state = ATA_S_ERROR;
  845         xa->complete(xa);
  846         splx(s);
  847         return (ATA_ERROR);
  848 }
  849 
  850 void
  851 sili_ata_cmd_done(struct sili_ccb *ccb, int defer_completion)
  852 {
  853         struct sili_port                *sp = ccb->ccb_port;
  854         struct sili_softc               *sc = sp->sp_sc;
  855         struct ata_xfer                 *xa = &ccb->ccb_xa;
  856 
  857         splassert(IPL_BIO);
  858 
  859         timeout_del(&xa->stimeout);
  860 
  861         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
  862             xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_POSTWRITE);
  863 
  864         sili_unload(ccb);
  865 
  866         TAILQ_REMOVE(&sp->sp_active_ccbs, ccb, ccb_entry);
  867         sp->sp_active &= ~(1 << xa->tag);
  868 
  869         if (xa->state == ATA_S_ONCHIP)
  870                 xa->state = ATA_S_COMPLETE;
  871 #ifdef DIAGNOSTIC
  872         else if (xa->state != ATA_S_ERROR && xa->state != ATA_S_TIMEOUT)
  873                 printf("%s: invalid ata_xfer state %02x in sili_ata_cmd_done, "
  874                     "slot %d\n", PORTNAME(sp), xa->state, xa->tag);
  875 #endif
  876         if (defer_completion)
  877                 TAILQ_INSERT_TAIL(&sp->sp_deferred_ccbs, ccb, ccb_entry);
  878         else if (xa->state == ATA_S_COMPLETE)
  879                 xa->complete(xa);
  880 #ifdef DIAGNOSTIC
  881         else
  882                 printf("%s: completion not deferred, but xa->state is %02x?\n",
  883                     PORTNAME(sp), xa->state);
  884 #endif
  885 }
  886 
  887 void
  888 sili_ata_cmd_timeout(void *xccb)
  889 {
  890         struct sili_ccb                 *ccb = xccb;
  891         struct sili_port                *sp = ccb->ccb_port;
  892         int                             s;
  893 
  894         s = splbio();
  895         sili_port_intr(sp, ccb->ccb_xa.tag);
  896         splx(s);
  897 }
  898 
  899 int
  900 sili_load(struct sili_ccb *ccb, struct sili_sge *sgl, int sgllen)
  901 {
  902         struct sili_port                *sp = ccb->ccb_port;
  903         struct sili_softc               *sc = sp->sp_sc;
  904         struct ata_xfer                 *xa = &ccb->ccb_xa;
  905         struct sili_sge                 *nsge = sgl, *ce = NULL;
  906         bus_dmamap_t                    dmap = ccb->ccb_dmamap;
  907         u_int64_t                       addr;
  908         int                             error;
  909         int                             i;
  910 
  911         if (xa->datalen == 0)
  912                 return (0);
  913 
  914         error = bus_dmamap_load(sc->sc_dmat, dmap, xa->data, xa->datalen, NULL,
  915             (xa->flags & ATA_F_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
  916         if (error != 0) {
  917                 printf("%s: error %d loading dmamap\n", PORTNAME(sp), error);
  918                 return (1);
  919         }
  920 
  921         if (dmap->dm_nsegs > sgllen)
  922                 ce = &sgl[sgllen - 1];
  923 
  924         for (i = 0; i < dmap->dm_nsegs; i++) {
  925                 if (nsge == ce) {
  926                         nsge++;
  927 
  928                         addr = ccb->ccb_cmd_dva;
  929                         addr += ((u_int8_t *)nsge - (u_int8_t *)ccb->ccb_cmd);
  930 
  931                         ce->addr_lo = htole32((u_int32_t)addr);
  932                         ce->addr_hi = htole32((u_int32_t)(addr >> 32));
  933                         ce->flags = htole32(SILI_SGE_LNK);
  934 
  935                         if ((dmap->dm_nsegs - i) > SILI_SGT_SGLLEN)
  936                                 ce += SILI_SGT_SGLLEN;
  937                         else
  938                                 ce = NULL;
  939                 }
  940 
  941                 sgl = nsge;
  942 
  943                 addr = dmap->dm_segs[i].ds_addr;
  944                 sgl->addr_lo = htole32((u_int32_t)addr);
  945                 sgl->addr_hi = htole32((u_int32_t)(addr >> 32));
  946                 sgl->data_count = htole32(dmap->dm_segs[i].ds_len);
  947                 sgl->flags = 0;
  948 
  949                 nsge++;
  950         }
  951         sgl->flags |= htole32(SILI_SGE_TRM);
  952 
  953         bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
  954             (xa->flags & ATA_F_READ) ? BUS_DMASYNC_PREREAD :
  955             BUS_DMASYNC_PREWRITE);
  956 
  957         return (0);
  958 }
  959 
  960 void
  961 sili_unload(struct sili_ccb *ccb)
  962 {
  963         struct sili_port                *sp = ccb->ccb_port;
  964         struct sili_softc               *sc = sp->sp_sc;
  965         struct ata_xfer                 *xa = &ccb->ccb_xa;
  966         bus_dmamap_t                    dmap = ccb->ccb_dmamap;
  967 
  968         if (xa->datalen == 0)
  969                 return;
  970 
  971         bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
  972             (xa->flags & ATA_F_READ) ? BUS_DMASYNC_POSTREAD :
  973             BUS_DMASYNC_POSTWRITE);
  974         bus_dmamap_unload(sc->sc_dmat, dmap);
  975 
  976         if (xa->flags & ATA_F_READ)
  977                 xa->resid = xa->datalen - sili_pread(sp,
  978                     SILI_PREG_RX_COUNT(xa->tag));
  979         else
  980                 xa->resid = 0;
  981 }
  982 
  983 int
  984 sili_poll(struct sili_ccb *ccb, int timeout, void (*timeout_fn)(void *))
  985 {
  986         struct sili_port                *sp = ccb->ccb_port;
  987         int                             s;
  988 
  989         s = splbio();
  990         sili_start(sp, ccb);
  991         do {
  992                 if (sili_port_intr(sp, -1) & (1 << ccb->ccb_xa.tag)) {
  993                         splx(s);
  994                         return (0);
  995                 }
  996 
  997                 delay(1000);
  998         } while (--timeout > 0);
  999 
 1000         /* Run timeout while at splbio, otherwise sili_intr could interfere. */
 1001         if (timeout_fn != NULL)
 1002                 timeout_fn(ccb);
 1003 
 1004         splx(s);
 1005 
 1006         return (1);
 1007 }
 1008 
 1009 void
 1010 sili_start(struct sili_port *sp, struct sili_ccb *ccb)
 1011 {
 1012         int                             slot = ccb->ccb_xa.tag;
 1013 
 1014         splassert(IPL_BIO);
 1015         KASSERT(ccb->ccb_xa.state == ATA_S_PENDING);
 1016 
 1017         TAILQ_INSERT_TAIL(&sp->sp_active_ccbs, ccb, ccb_entry);
 1018         sp->sp_active |= 1 << slot;
 1019         ccb->ccb_xa.state = ATA_S_ONCHIP;
 1020 
 1021         sili_post_indirect(sp, ccb);
 1022 }
 1023 
 1024 int
 1025 sili_read_ncq_error(struct sili_port *sp, int *err_slotp)
 1026 {
 1027         struct sili_softc               *sc = sp->sp_sc;
 1028         struct sili_prb_ata             read_10h;
 1029         u_int64_t                       addr;
 1030         struct ata_fis_h2d              *fis;
 1031         struct ata_log_page_10h         *log;
 1032         struct sili_ccb                 *ccb;
 1033         int                             rc;
 1034 
 1035         sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTINIT);
 1036         if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
 1037             SILI_PREG_PCS_PORTRDY, 1000)) {
 1038                 printf("%s: couldn't ready port during log page read\n",
 1039                     PORTNAME(sp));
 1040                 return (1);
 1041         }
 1042 
 1043         /* READ LOG EXT 10h into scratch space */
 1044         bzero(&read_10h, sizeof(read_10h));
 1045         read_10h.control = htole16(SILI_PRB_INTERRUPT_MASK);
 1046 
 1047         addr = SILI_DMA_DVA(sp->sp_scratch);
 1048         read_10h.sgl[0].addr_lo = htole32((u_int32_t)addr);
 1049         read_10h.sgl[0].addr_hi = htole32((u_int32_t)(addr >> 32));
 1050         read_10h.sgl[0].data_count = htole32(512);
 1051         read_10h.sgl[0].flags = htole32(SILI_SGE_TRM);
 1052 
 1053         fis = (struct ata_fis_h2d *)read_10h.fis;
 1054         fis->type = ATA_FIS_TYPE_H2D;
 1055         fis->flags = ATA_H2D_FLAGS_CMD; /* XXX fis pmp field */
 1056         fis->command = ATA_C_READ_LOG_EXT;
 1057         fis->lba_low = 0x10;            /* queued error log page (10h) */
 1058         fis->sector_count = 1;          /* number of sectors (1) */
 1059         fis->sector_count_exp = 0;
 1060         fis->lba_mid = 0;               /* starting offset */
 1061         fis->lba_mid_exp = 0;
 1062         fis->device = 0;
 1063 
 1064         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
 1065             512, BUS_DMASYNC_PREREAD);
 1066 
 1067         /* issue read and poll for completion */
 1068         sili_post_direct(sp, 0, &read_10h, sizeof(read_10h));
 1069         rc = sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000);
 1070 
 1071         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
 1072             512, BUS_DMASYNC_POSTREAD);
 1073 
 1074         if (!rc) {
 1075                 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for log "
 1076                     "page read\n", PORTNAME(sp));
 1077                 return (1);
 1078         }
 1079 
 1080         /* Extract failed register set and tags from the scratch space. */
 1081         log = (struct ata_log_page_10h *)SILI_DMA_KVA(sp->sp_scratch);
 1082         if (ISSET(log->err_regs.type, ATA_LOG_10H_TYPE_NOTQUEUED)) {
 1083                 /* Not queued bit was set - wasn't an NCQ error? */
 1084                 printf("%s: read NCQ error page, but not an NCQ error?\n",
 1085                     PORTNAME(sp));
 1086                 return (1);
 1087         }
 1088 
 1089         /* Copy back the log record as a D2H register FIS. */
 1090         *err_slotp = log->err_regs.type & ATA_LOG_10H_TYPE_TAG_MASK;
 1091 
 1092         ccb = &sp->sp_ccbs[*err_slotp];
 1093         memcpy(&ccb->ccb_xa.rfis, &log->err_regs, sizeof(struct ata_fis_d2h));
 1094         ccb->ccb_xa.rfis.type = ATA_FIS_TYPE_D2H;
 1095         ccb->ccb_xa.rfis.flags = 0;
 1096 
 1097         return (0);
 1098 }
 1099 
 1100 struct ata_xfer *
 1101 sili_ata_get_xfer(void *xsc, int port)
 1102 {
 1103         struct sili_softc               *sc = xsc;
 1104         struct sili_port                *sp = &sc->sc_ports[port];
 1105         struct sili_ccb                 *ccb;
 1106 
 1107         ccb = sili_get_ccb(sp);
 1108         if (ccb == NULL) {
 1109                 printf("sili_ata_get_xfer: NULL ccb\n");
 1110                 return (NULL);
 1111         }
 1112 
 1113         bzero(ccb->ccb_cmd, SILI_CMD_LEN);
 1114 
 1115         return ((struct ata_xfer *)ccb);
 1116 }
 1117 
 1118 void
 1119 sili_ata_put_xfer(struct ata_xfer *xa)
 1120 {
 1121         struct sili_ccb                 *ccb = (struct sili_ccb *)xa;
 1122 
 1123         sili_put_ccb(ccb);
 1124 }

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