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/sili.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: sili.c,v 1.61 2022/04/09 20:10:26 naddy Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
    5  * Copyright (c) 2010 Conformal Systems LLC <info@conformal.com>
    6  * Copyright (c) 2010 Jonathan Matthew <jonathan@d14n.org>
    7  *
    8  * Permission to use, copy, modify, and distribute this software for any
    9  * purpose with or without fee is hereby granted, provided that the above
   10  * copyright notice and this permission notice appear in all copies.
   11  *
   12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   19  */
   20 
   21 #include <sys/param.h>
   22 #include <sys/systm.h>
   23 #include <sys/device.h>
   24 #include <sys/timeout.h>
   25 #include <sys/malloc.h>
   26 #include <sys/kernel.h>
   27 #include <sys/mutex.h>
   28 
   29 #include <machine/bus.h>
   30 
   31 #include <dev/ata/atascsi.h>
   32 #include <dev/ata/pmreg.h>
   33 
   34 #include <dev/ic/silireg.h>
   35 #include <dev/ic/silivar.h>
   36 
   37 /* use SILI_DEBUG for dmesg spam */
   38 #define NO_SILI_DEBUG
   39 
   40 #ifdef SILI_DEBUG
   41 #define SILI_D_VERBOSE          (1<<0)
   42 #define SILI_D_INTR             (1<<1)
   43 
   44 int silidebug = SILI_D_VERBOSE;
   45 
   46 #define DPRINTF(m, a...)        do { if ((m) & silidebug) printf(a); } while (0)
   47 #else
   48 #define DPRINTF(m, a...)
   49 #endif
   50 
   51 /* these can be used to simulate read and write errors on specific PMP ports */
   52 #undef SILI_ERROR_TEST
   53 int sili_error_pmp_ports = 0;           /* bitmask containing ports to fail*/
   54 int sili_error_test_inv_p = 500;        /* 1/P(error) */
   55 int sili_error_restart_type = SILI_PREG_PCS_PORTINIT; /* or _DEVRESET */
   56 
   57 struct cfdriver sili_cd = {
   58         NULL, "sili", DV_DULL
   59 };
   60 
   61 /* wrapper around dma memory */
   62 struct sili_dmamem {
   63         bus_dmamap_t            sdm_map;
   64         bus_dma_segment_t       sdm_seg;
   65         size_t                  sdm_size;
   66         caddr_t                 sdm_kva;
   67 };
   68 #define SILI_DMA_MAP(_sdm)      ((_sdm)->sdm_map)
   69 #define SILI_DMA_DVA(_sdm)      ((_sdm)->sdm_map->dm_segs[0].ds_addr)
   70 #define SILI_DMA_KVA(_sdm)      ((_sdm)->sdm_kva)
   71 
   72 struct sili_dmamem      *sili_dmamem_alloc(struct sili_softc *, bus_size_t,
   73                             bus_size_t);
   74 void                    sili_dmamem_free(struct sili_softc *,
   75                             struct sili_dmamem *);
   76 
   77 /* per port goo */
   78 struct sili_ccb;
   79 
   80 /* size of scratch space for use in error recovery. */
   81 #define SILI_SCRATCH_LEN        512     /* must be at least 1 sector */
   82 
   83 struct sili_port {
   84         struct sili_softc       *sp_sc;
   85         bus_space_handle_t      sp_ioh;
   86 
   87         struct sili_ccb         *sp_ccbs;
   88         struct sili_dmamem      *sp_cmds;
   89         struct sili_dmamem      *sp_scratch;
   90 
   91         TAILQ_HEAD(, sili_ccb)  sp_free_ccbs;
   92         struct mutex            sp_free_ccb_mtx;
   93 
   94         volatile u_int32_t      sp_active;
   95         TAILQ_HEAD(, sili_ccb)  sp_active_ccbs;
   96         TAILQ_HEAD(, sili_ccb)  sp_deferred_ccbs;
   97 
   98         int                     sp_port;
   99         int                     sp_pmp_ports;
  100         int                     sp_active_pmp_ports;
  101         int                     sp_pmp_error_recovery;  /* port bitmask */
  102         volatile u_int32_t      sp_err_active;          /* cmd bitmask */
  103         volatile u_int32_t      sp_err_cmds;            /* cmd bitmask */
  104 
  105 #ifdef SILI_DEBUG
  106         char                    sp_name[16];
  107 #define PORTNAME(_sp)   ((_sp)->sp_name)
  108 #else
  109 #define PORTNAME(_sp)   DEVNAME((_sp)->sp_sc)
  110 #endif
  111 };
  112 
  113 int                     sili_ports_alloc(struct sili_softc *);
  114 void                    sili_ports_free(struct sili_softc *);
  115 
  116 /* ccb shizz */
  117 
  118 /*
  119  * the dma memory for each command will be made up of a prb followed by
  120  * 7 sgts, this is a neat 512 bytes.
  121  */
  122 #define SILI_CMD_LEN            512
  123 
  124 /*
  125  * you can fit 22 sge's into 7 sgts and a prb:
  126  * there's 1 sgl in an atapi prb (two in the ata one, but we cant over
  127  * advertise), but that's needed for the chain element. you get three sges
  128  * per sgt cos you lose the 4th sge for the chaining, but you keep it in
  129  * the last sgt. so 3 x 6 + 4 is 22.
  130  */
  131 #define SILI_DMA_SEGS           22
  132 
  133 struct sili_ccb {
  134         struct ata_xfer         ccb_xa;
  135 
  136         void                    *ccb_cmd;
  137         u_int64_t               ccb_cmd_dva;
  138         bus_dmamap_t            ccb_dmamap;
  139 
  140         struct sili_port        *ccb_port;
  141 
  142         TAILQ_ENTRY(sili_ccb)   ccb_entry;
  143 };
  144 
  145 int                     sili_ccb_alloc(struct sili_port *);
  146 void                    sili_ccb_free(struct sili_port *);
  147 struct sili_ccb         *sili_get_ccb(struct sili_port *);
  148 void                    sili_put_ccb(struct sili_ccb *);
  149 
  150 /* bus space ops */
  151 u_int32_t               sili_read(struct sili_softc *, bus_size_t);
  152 void                    sili_write(struct sili_softc *, bus_size_t, u_int32_t);
  153 u_int32_t               sili_pread(struct sili_port *, bus_size_t);
  154 void                    sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
  155 int                     sili_pwait_eq(struct sili_port *, bus_size_t,
  156                             u_int32_t, u_int32_t, int);
  157 int                     sili_pwait_ne(struct sili_port *, bus_size_t,
  158                             u_int32_t, u_int32_t, int);
  159 
  160 /* command handling */
  161 void                    sili_post_direct(struct sili_port *, u_int,
  162                             void *, size_t buflen);
  163 void                    sili_post_indirect(struct sili_port *,
  164                             struct sili_ccb *);
  165 void                    sili_pread_fis(struct sili_port *, u_int,
  166                             struct ata_fis_d2h *);
  167 u_int32_t               sili_signature(struct sili_port *, u_int);
  168 u_int32_t               sili_port_softreset(struct sili_port *sp);
  169 int                     sili_load(struct sili_ccb *, struct sili_sge *, int);
  170 void                    sili_unload(struct sili_ccb *);
  171 int                     sili_poll(struct sili_ccb *, int, void (*)(void *));
  172 void                    sili_start(struct sili_port *, struct sili_ccb *);
  173 int                     sili_read_ncq_error(struct sili_port *, int *, int);
  174 int                     sili_pmp_port_start_error_recovery(struct sili_port *,
  175                             int);
  176 void                    sili_pmp_port_do_error_recovery(struct sili_port *,
  177                             int, u_int32_t *);
  178 void                    sili_port_clear_commands(struct sili_port *sp);
  179 
  180 /* pmp operations */
  181 int                     sili_pmp_read(struct sili_port *, int, int,
  182                             u_int32_t *);
  183 int                     sili_pmp_write(struct sili_port *, int, int, u_int32_t);
  184 int                     sili_pmp_phy_status(struct sili_port *, int,
  185                             u_int32_t *);
  186 int                     sili_pmp_identify(struct sili_port *, int *);
  187 
  188 /* port interrupt handler */
  189 u_int32_t               sili_port_intr(struct sili_port *, int);
  190 
  191 /* atascsi interface */
  192 int                     sili_ata_probe(void *, int, int);
  193 void                    sili_ata_free(void *, int, int);
  194 struct ata_xfer         *sili_ata_get_xfer(void *, int);
  195 void                    sili_ata_put_xfer(struct ata_xfer *);
  196 void                    sili_ata_cmd(struct ata_xfer *);
  197 int                     sili_pmp_portreset(struct sili_softc *, int, int);
  198 int                     sili_pmp_softreset(struct sili_softc *, int, int);
  199 
  200 #ifdef SILI_ERROR_TEST
  201 void                    sili_simulate_error(struct sili_ccb *ccb,
  202                             int *need_restart, int *err_port);
  203 #endif
  204 
  205 const struct atascsi_methods sili_atascsi_methods = {
  206         sili_ata_probe,
  207         sili_ata_free,
  208         sili_ata_get_xfer,
  209         sili_ata_put_xfer,
  210         sili_ata_cmd
  211 };
  212 
  213 /* completion paths */
  214 void                    sili_ata_cmd_done(struct sili_ccb *, int);
  215 void                    sili_ata_cmd_timeout(void *);
  216 void                    sili_dummy_done(struct ata_xfer *);
  217 
  218 void                    sili_pmp_op_timeout(void *);
  219 
  220 int
  221 sili_attach(struct sili_softc *sc)
  222 {
  223         struct atascsi_attach_args      aaa;
  224 
  225         printf("\n");
  226 
  227         if (sili_ports_alloc(sc) != 0) {
  228                 /* error already printed by sili_port_alloc */
  229                 return (1);
  230         }
  231 
  232         /* bounce the controller */
  233         sili_write(sc, SILI_REG_GC, SILI_REG_GC_GR);
  234         sili_write(sc, SILI_REG_GC, 0x0);
  235 
  236         bzero(&aaa, sizeof(aaa));
  237         aaa.aaa_cookie = sc;
  238         aaa.aaa_methods = &sili_atascsi_methods;
  239         aaa.aaa_minphys = NULL;
  240         aaa.aaa_nports = sc->sc_nports;
  241         aaa.aaa_ncmds = SILI_MAX_CMDS;
  242         aaa.aaa_capability = ASAA_CAP_NCQ | ASAA_CAP_PMP_NCQ;
  243 
  244         sc->sc_atascsi = atascsi_attach(&sc->sc_dev, &aaa);
  245 
  246         return (0);
  247 }
  248 
  249 int
  250 sili_detach(struct sili_softc *sc, int flags)
  251 {
  252         int                             rv;
  253 
  254         if (sc->sc_atascsi != NULL) {
  255                 rv = atascsi_detach(sc->sc_atascsi, flags);
  256                 if (rv != 0)
  257                         return (rv);
  258         }
  259 
  260         if (sc->sc_ports != NULL)
  261                 sili_ports_free(sc);
  262 
  263         return (0);
  264 }
  265 
  266 void
  267 sili_resume(struct sili_softc *sc)
  268 {
  269         int i, j;
  270 
  271         /* bounce the controller */
  272         sili_write(sc, SILI_REG_GC, SILI_REG_GC_GR);
  273         sili_write(sc, SILI_REG_GC, 0x0);
  274 
  275         for (i = 0; i < sc->sc_nports; i++) {
  276                 if (sili_ata_probe(sc, i, 0) == ATA_PORT_T_PM) {
  277                         struct sili_port *sp = &sc->sc_ports[i];
  278                         for (j = 0; j < sp->sp_pmp_ports; j++) {
  279                                 sili_ata_probe(sc, i, j);
  280                         }
  281                 }
  282         }
  283 }
  284 
  285 int
  286 sili_pmp_port_start_error_recovery(struct sili_port *sp, int err_port)
  287 {
  288         struct sili_ccb *ccb;
  289 
  290         sp->sp_pmp_error_recovery |= (1 << err_port);
  291 
  292         /* create a bitmask of active commands on non-error ports */
  293         sp->sp_err_active = 0;
  294         TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
  295                 int bit = (1 << ccb->ccb_xa.pmp_port);
  296                 if ((sp->sp_pmp_error_recovery & bit) == 0) {
  297                         DPRINTF(SILI_D_VERBOSE, "%s: slot %d active on port "
  298                             "%d\n", PORTNAME(sp), ccb->ccb_xa.tag,
  299                             ccb->ccb_xa.pmp_port);
  300                         sp->sp_err_active |= (1 << ccb->ccb_xa.tag);
  301                 }
  302         }
  303 
  304         if (sp->sp_err_active == 0) {
  305                 DPRINTF(SILI_D_VERBOSE, "%s: no other PMP ports active\n",
  306                     PORTNAME(sp));
  307                 sp->sp_pmp_error_recovery = 0;
  308                 return (0);
  309         }
  310 
  311         /* set port resume */
  312         sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_RESUME);
  313 
  314         DPRINTF(SILI_D_VERBOSE, "%s: beginning error recovery (port %d); "
  315             "error port mask %x, active slot mask %x\n", PORTNAME(sp), err_port,
  316             sp->sp_pmp_error_recovery, sp->sp_err_active);
  317         return (1);
  318 }
  319 
  320 void
  321 sili_port_clear_commands(struct sili_port *sp)
  322 {
  323         int port;
  324 
  325         DPRINTF(SILI_D_VERBOSE, "%s: clearing active commands\n",
  326             PORTNAME(sp));
  327 
  328         /* clear port resume */
  329         sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_RESUME);
  330         delay(10000);
  331 
  332         /* clear port status and port active for all ports */
  333         for (port = 0; port < 16; port++) {
  334                 sili_pwrite(sp, SILI_PREG_PMP_STATUS(port), 0);
  335                 sili_pwrite(sp, SILI_PREG_PMP_QACTIVE(port), 0);
  336         }
  337 }
  338 
  339 void
  340 sili_pmp_port_do_error_recovery(struct sili_port *sp, int slot,
  341     u_int32_t *need_restart)
  342 {
  343         if (sp->sp_pmp_error_recovery == 0) {
  344                 return;
  345         }
  346 
  347         /* have all outstanding commands finished yet? */
  348         if (sp->sp_err_active != 0) {
  349                 DPRINTF(SILI_D_VERBOSE, "%s: PMP error recovery still waiting "
  350                     "for %x\n", PORTNAME(sp), sp->sp_err_active);
  351                 *need_restart = 0;
  352                 return;
  353         }
  354 
  355         sili_port_clear_commands(sp);
  356 
  357         /* get the main error recovery code to reset the port and
  358          * resubmit commands.  it will also reset the error recovery flags.
  359          */
  360         *need_restart = SILI_PREG_PCS_PORTINIT;
  361         DPRINTF(SILI_D_VERBOSE, "%s: PMP error recovery complete\n",
  362             PORTNAME(sp));
  363 }
  364 
  365 #ifdef SILI_ERROR_TEST
  366 void
  367 sili_simulate_error(struct sili_ccb *ccb, int *need_restart, int *err_port)
  368 {
  369         struct sili_port *sp = ccb->ccb_port;
  370 
  371         if (*need_restart == 0 &&
  372             ((1 << ccb->ccb_xa.pmp_port) & sili_error_pmp_ports)) {
  373                 switch (ccb->ccb_xa.fis->command) {
  374                 case ATA_C_WRITE_FPDMA:
  375                 case ATA_C_READ_FPDMA:
  376                 case ATA_C_WRITEDMA_EXT:
  377                 case ATA_C_READDMA_EXT:
  378                 case ATA_C_WRITEDMA:
  379                 case ATA_C_READDMA:
  380                         if (arc4random_uniform(sili_error_test_inv_p) == 0) {
  381                                 printf("%s: faking error on slot %d\n",
  382                                     PORTNAME(sp), ccb->ccb_xa.tag);
  383                                 ccb->ccb_xa.state = ATA_S_ERROR;
  384                                 *need_restart = sili_error_restart_type;
  385                                 *err_port = ccb->ccb_xa.pmp_port;
  386 
  387                                 ccb->ccb_port->sp_err_cmds |=
  388                                     (1 << ccb->ccb_xa.tag);
  389                         }
  390                         break;
  391 
  392                 default:
  393                         /* leave other commands alone, we only want to mess
  394                          * with normal read/write ops
  395                          */
  396                         break;
  397                 }
  398         }
  399 }
  400 #endif
  401 
  402 u_int32_t
  403 sili_port_intr(struct sili_port *sp, int timeout_slot)
  404 {
  405         u_int32_t                       is, pss_saved, pss_masked;
  406         u_int32_t                       processed = 0, need_restart = 0;
  407         u_int32_t                       err_port = 0;
  408         int                             slot;
  409         struct sili_ccb                 *ccb;
  410 
  411         is = sili_pread(sp, SILI_PREG_IS);
  412         pss_saved = sili_pread(sp, SILI_PREG_PSS); /* reading acks CMDCOMP */
  413 
  414 #ifdef SILI_DEBUG
  415         if ((pss_saved & SILI_PREG_PSS_ALL_SLOTS) != sp->sp_active ||
  416             ((is >> 16) & ~SILI_PREG_IS_CMDCOMP)) {
  417                 DPRINTF(SILI_D_INTR, "%s: IS: 0x%08x (0x%b), PSS: %08x, "
  418                     "active: %08x\n", PORTNAME(sp), is, is >> 16, SILI_PFMT_IS,
  419                     pss_saved, sp->sp_active);
  420         }
  421 #endif
  422 
  423         /* Only interested in slot status bits. */
  424         pss_saved &= SILI_PREG_PSS_ALL_SLOTS;
  425 
  426         if (is & SILI_PREG_IS_CMDERR) {
  427                 int                     err_slot, err_code;
  428                 u_int32_t               sactive = 0;
  429 
  430                 sili_pwrite(sp, SILI_PREG_IS, SILI_PREG_IS_CMDERR);
  431                 err_slot = SILI_PREG_PCS_ACTIVE(sili_pread(sp, SILI_PREG_PCS));
  432                 err_code = sili_pread(sp, SILI_PREG_CE);
  433                 ccb = &sp->sp_ccbs[err_slot];
  434 
  435                 switch (err_code) {
  436                 case SILI_PREG_CE_DEVICEERROR:
  437                 case SILI_PREG_CE_DATAFISERROR:
  438                         /* Extract error from command slot in LRAM. */
  439                         sili_pread_fis(sp, err_slot, &ccb->ccb_xa.rfis);
  440                         err_port = ccb->ccb_xa.pmp_port;
  441                         break;
  442 
  443                 case SILI_PREG_CE_SDBERROR:
  444 
  445                         if (sp->sp_pmp_ports > 0) {
  446                                 /* get the PMP port number for the error */
  447                                 err_port = (sili_pread(sp, SILI_PREG_CONTEXT)
  448                                     >> SILI_PREG_CONTEXT_PMPORT_SHIFT) &
  449                                     SILI_PREG_CONTEXT_PMPORT_MASK;
  450                                 DPRINTF(SILI_D_VERBOSE, "%s: error port is "
  451                                     "%d\n", PORTNAME(sp), err_port);
  452 
  453                                 /* were there any NCQ commands active for
  454                                  * the port?
  455                                  */
  456                                 sactive = sili_pread(sp,
  457                                     SILI_PREG_PMP_QACTIVE(err_port));
  458                                 DPRINTF(SILI_D_VERBOSE, "%s: error SActive "
  459                                     "%x\n", PORTNAME(sp), sactive);
  460                                 if (sactive == 0)
  461                                         break;
  462                         } else {
  463                                 /* No NCQ commands active?  Treat as a normal
  464                                  * error.
  465                                  */
  466                                 sactive = sili_pread(sp, SILI_PREG_SACT);
  467                                 if (sactive == 0)
  468                                         break;
  469                         }
  470 
  471                         /* Extract real NCQ error slot & RFIS from
  472                          * log page.
  473                          */ 
  474                         if (!sili_read_ncq_error(sp, &err_slot, err_port)) {
  475                                 /* got real err_slot */
  476                                 DPRINTF(SILI_D_VERBOSE, "%s.%d: error slot "
  477                                     "%d\n", PORTNAME(sp), err_port, err_slot);
  478                                 ccb = &sp->sp_ccbs[err_slot];
  479                                 break;
  480                         }
  481                         DPRINTF(SILI_D_VERBOSE, "%s.%d: failed to get error "
  482                             "slot\n", PORTNAME(sp), err_port);
  483 
  484                         /* failed to get error or not NCQ */
  485 
  486                         /* FALLTHROUGH */
  487                 default:
  488                         /* All other error types are fatal. */
  489                         if (err_code != SILI_PREG_CE_SDBERROR) {
  490                                 err_port = (sili_pread(sp, SILI_PREG_CONTEXT)
  491                                     >> SILI_PREG_CONTEXT_PMPORT_SHIFT) &
  492                                     SILI_PREG_CONTEXT_PMPORT_MASK;
  493                         }
  494                         printf("%s.%d: fatal error (%d), aborting active slots "
  495                             "(%08x) and resetting device.\n", PORTNAME(sp),
  496                             err_port, err_code, pss_saved);
  497                         while (pss_saved) {
  498                                 slot = ffs(pss_saved) - 1;
  499                                 pss_saved &= ~(1 << slot);
  500 
  501                                 ccb = &sp->sp_ccbs[slot];
  502                                 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  503                                 ccb->ccb_xa.state = ATA_S_ERROR;
  504                         }
  505                         need_restart = SILI_PREG_PCS_DEVRESET;
  506                         goto fatal;
  507                 }
  508 
  509                 DPRINTF(SILI_D_VERBOSE, "%s.%d: %serror, code %d, slot %d, "
  510                     "active %08x\n", PORTNAME(sp), err_port,
  511                     sactive ? "NCQ " : "", err_code, err_slot, sp->sp_active);
  512 
  513                 /* Clear the failed command in saved PSS so cmd_done runs. */
  514                 pss_saved &= ~(1 << err_slot);
  515                 /* Track errored commands until we finish recovery */
  516                 sp->sp_err_cmds |= (1 << err_slot);
  517 
  518                 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  519                 ccb->ccb_xa.state = ATA_S_ERROR;
  520 
  521                 need_restart = SILI_PREG_PCS_PORTINIT;
  522         }
  523 fatal:
  524 
  525         /* Process command timeout request only if command is still active. */
  526         if (timeout_slot >= 0 && (pss_saved & (1 << timeout_slot))) {
  527                 DPRINTF(SILI_D_VERBOSE, "%s: timing out slot %d, active %08x\n",
  528                     PORTNAME(sp), timeout_slot, sp->sp_active);
  529 
  530                 /* Clear the failed command in saved PSS so cmd_done runs. */
  531                 pss_saved &= ~(1 << timeout_slot);
  532 
  533                 ccb = &sp->sp_ccbs[timeout_slot];
  534                 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  535                 ccb->ccb_xa.state = ATA_S_TIMEOUT;
  536 
  537                 /* Reinitialise the port and clear all active commands */
  538                 need_restart = SILI_PREG_PCS_PORTINIT;
  539 
  540                 err_port = ccb->ccb_xa.pmp_port;
  541                 sp->sp_err_cmds |= (1 << timeout_slot);
  542 
  543                 sili_port_clear_commands(sp);
  544         }
  545 
  546         /* Command slot is complete if its bit in PSS is 0 but 1 in active. */
  547         pss_masked = ~pss_saved & sp->sp_active;
  548         while (pss_masked) {
  549                 slot = ffs(pss_masked) - 1;
  550                 ccb = &sp->sp_ccbs[slot];
  551                 pss_masked &= ~(1 << slot);
  552 
  553                 /* copy the rfis into the ccb if we were asked for it */
  554                 if (ccb->ccb_xa.state == ATA_S_ONCHIP &&
  555                     ccb->ccb_xa.flags & ATA_F_GET_RFIS) {
  556                         sili_pread_fis(sp, slot, &ccb->ccb_xa.rfis);
  557                 }
  558 
  559 #ifdef SILI_ERROR_TEST
  560                 /* introduce random errors on reads and writes for testing */
  561                 sili_simulate_error(ccb, &need_restart, &err_port);
  562 #endif
  563 
  564                 DPRINTF(SILI_D_INTR, "%s: slot %d is complete%s%s\n",
  565                     PORTNAME(sp), slot, ccb->ccb_xa.state == ATA_S_ERROR ?
  566                     " (error)" : (ccb->ccb_xa.state == ATA_S_TIMEOUT ?
  567                     " (timeout)" : ""),
  568                     ccb->ccb_xa.flags & ATA_F_NCQ ? " (ncq)" : "");
  569 
  570                 sili_ata_cmd_done(ccb, need_restart);
  571 
  572                 processed |= 1 << slot;
  573 
  574                 sili_pmp_port_do_error_recovery(sp, slot, &need_restart);
  575         }
  576 
  577         if (need_restart) {
  578 
  579                 if (sp->sp_pmp_error_recovery) {
  580                         if (sp->sp_err_active != 0) {
  581                                 DPRINTF(SILI_D_VERBOSE, "%s: still waiting for "
  582                                     "non-error commands to finish; port mask "
  583                                     "%x, slot mask %x\n", PORTNAME(sp),
  584                                     sp->sp_pmp_error_recovery,
  585                                     sp->sp_err_active);
  586                                 return (processed);
  587                         }
  588                 } else if (timeout_slot < 0 && sp->sp_pmp_ports > 0) {
  589                         /* wait until all other commands have finished before
  590                          * attempting to reinit the port.
  591                          */
  592                         DPRINTF(SILI_D_VERBOSE, "%s: error on port with PMP "
  593                             "attached, error port %d\n", PORTNAME(sp),
  594                             err_port);
  595                         if (sili_pmp_port_start_error_recovery(sp, err_port)) {
  596                                 DPRINTF(SILI_D_VERBOSE, "%s: need to wait for "
  597                                     "other commands to finish\n", PORTNAME(sp));
  598                                 return (processed);
  599                         }
  600                 } else if (sp->sp_pmp_ports > 0) {
  601                         DPRINTF(SILI_D_VERBOSE, "%s: timeout on PMP port\n",
  602                             PORTNAME(sp));
  603                 } else {
  604                         DPRINTF(SILI_D_VERBOSE, "%s: error on non-PMP port\n",
  605                             PORTNAME(sp));
  606                 }
  607 
  608                 /* Re-enable transfers on port. */
  609                 sili_pwrite(sp, SILI_PREG_PCS, need_restart);
  610                 if (!sili_pwait_eq(sp, SILI_PREG_PCS, need_restart, 0, 5000)) {
  611                         printf("%s: port reset bit didn't clear after error\n",
  612                             PORTNAME(sp));
  613                 }
  614                 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
  615                     SILI_PREG_PCS_PORTRDY, 1000)) {
  616                         printf("%s: couldn't restart port after error\n",
  617                             PORTNAME(sp));
  618                 }
  619                 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_RESUME);
  620 
  621                 /* check that our active CCB list matches the restart mask */
  622                 pss_masked = pss_saved & ~(sp->sp_err_cmds);
  623                 DPRINTF(SILI_D_VERBOSE, "%s: restart mask %x\n",
  624                     PORTNAME(sp), pss_masked);
  625                 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
  626                         if (!(pss_masked & (1 << ccb->ccb_xa.tag))) {
  627                                 panic("sili_intr: slot %d not active in "
  628                                     "pss_masked: %08x, state %02x",
  629                                     ccb->ccb_xa.tag, pss_masked,
  630                                     ccb->ccb_xa.state);
  631                         }
  632                         pss_masked &= ~(1 << ccb->ccb_xa.tag);
  633                 }
  634                 if (pss_masked != 0) {
  635                         printf("%s: mask excluding active slots: %x\n",
  636                             PORTNAME(sp), pss_masked);
  637                 }
  638                 KASSERT(pss_masked == 0);
  639                 
  640                 /* if we had a timeout on a PMP port, do a portreset.
  641                  * exclude the control port here as there isn't a real
  642                  * device there to reset.
  643                  */
  644                 if (timeout_slot >= 0 && sp->sp_pmp_ports > 0 &&
  645                     err_port != 15) {
  646 
  647                         DPRINTF(SILI_D_VERBOSE,
  648                             "%s.%d: doing portreset after timeout\n",
  649                             PORTNAME(sp), err_port);
  650                         sili_pmp_portreset(sp->sp_sc, sp->sp_port, err_port);
  651 
  652                         /* wait a bit to let the port settle down */
  653                         delay(2000000);
  654                 }
  655 
  656                 /* if we sent a device reset to a PMP, we need to reset the
  657                  * devices behind it too.
  658                  */
  659                 if (need_restart == SILI_PREG_PCS_DEVRESET &&
  660                     sp->sp_pmp_ports > 0) {
  661                         int port_type;
  662                         int i;
  663 
  664                         port_type = sili_port_softreset(sp);
  665                         if (port_type != ATA_PORT_T_PM) {
  666                                 /* device disappeared or changed type? */
  667                                 printf("%s: expected to find a port multiplier,"
  668                                     " got %d\n", PORTNAME(sp), port_type);
  669                         }
  670 
  671                         /* and now portreset all active ports */
  672                         for (i = 0; i < sp->sp_pmp_ports; i++) {
  673                                 struct sili_softc *sc = sp->sp_sc;
  674 
  675                                 if ((sp->sp_active_pmp_ports & (1 << i)) == 0)
  676                                         continue;
  677 
  678                                 if (sili_pmp_portreset(sc, sp->sp_port, i)) {
  679                                         printf("%s.%d: failed to portreset "
  680                                             "after error\n", PORTNAME(sp), i);
  681                                 }
  682                         }
  683                 }
  684 
  685                 /* Restart CCBs in the order they were originally queued. */
  686                 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
  687                         DPRINTF(SILI_D_VERBOSE, "%s: restarting slot %d "
  688                             "after error, state %02x\n", PORTNAME(sp),
  689                             ccb->ccb_xa.tag, ccb->ccb_xa.state);
  690                         KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
  691                         sili_post_indirect(sp, ccb);
  692                 }
  693                 sp->sp_err_cmds = 0;
  694                 sp->sp_pmp_error_recovery = 0;
  695                 
  696                 /*
  697                  * Finally, run atascsi completion for any finished CCBs.  If
  698                  * we had run these during cmd_done above, any ccbs that their
  699                  * completion generated would have been activated out of order.
  700                  */
  701                 while ((ccb = TAILQ_FIRST(&sp->sp_deferred_ccbs)) != NULL) {
  702                         TAILQ_REMOVE(&sp->sp_deferred_ccbs, ccb, ccb_entry);
  703 
  704                         DPRINTF(SILI_D_VERBOSE, "%s: running deferred "
  705                             "completion for slot %d, state %02x\n",
  706                             PORTNAME(sp), ccb->ccb_xa.tag, ccb->ccb_xa.state);
  707                         KASSERT(ccb->ccb_xa.state == ATA_S_COMPLETE ||
  708                             ccb->ccb_xa.state == ATA_S_ERROR ||
  709                             ccb->ccb_xa.state == ATA_S_TIMEOUT);
  710                         ata_complete(&ccb->ccb_xa);
  711                 }
  712         }
  713 
  714         return (processed);
  715 }
  716 
  717 int
  718 sili_intr(void *arg)
  719 {
  720         struct sili_softc               *sc = arg;
  721         u_int32_t                       is;
  722         int                             port;
  723 
  724         /* If the card has gone away, this will return 0xffffffff. */
  725         is = sili_read(sc, SILI_REG_GIS);
  726         if (is == 0 || is == 0xffffffff)
  727                 return (0);
  728         sili_write(sc, SILI_REG_GIS, is);
  729         DPRINTF(SILI_D_INTR, "sili_intr, GIS: %08x\n", is);
  730 
  731         while (is & SILI_REG_GIS_PIS_MASK) {
  732                 port = ffs(is) - 1;
  733                 sili_port_intr(&sc->sc_ports[port], -1);
  734                 is &= ~(1 << port);
  735         }
  736 
  737         return (1);
  738 }
  739 
  740 int
  741 sili_ports_alloc(struct sili_softc *sc)
  742 {
  743         struct sili_port                *sp;
  744         int                             i;
  745 
  746         sc->sc_ports = mallocarray(sc->sc_nports, sizeof(struct sili_port),
  747             M_DEVBUF, M_WAITOK | M_ZERO);
  748 
  749         for (i = 0; i < sc->sc_nports; i++) {
  750                 sp = &sc->sc_ports[i];
  751 
  752                 sp->sp_sc = sc;
  753                 sp->sp_port = i;
  754 #ifdef SILI_DEBUG
  755                 snprintf(sp->sp_name, sizeof(sp->sp_name), "%s.%d",
  756                     DEVNAME(sc), i);
  757 #endif
  758                 if (bus_space_subregion(sc->sc_iot_port, sc->sc_ioh_port,
  759                     SILI_PORT_OFFSET(i), SILI_PORT_SIZE, &sp->sp_ioh) != 0) {
  760                         printf("%s: unable to create register window "
  761                             "for port %d\n", DEVNAME(sc), i);
  762                         goto freeports;
  763                 }
  764         }
  765 
  766         return (0);
  767 
  768 freeports:
  769         /* bus_space(9) says subregions dont have to be freed */
  770         free(sc->sc_ports, M_DEVBUF, sc->sc_nports * sizeof(struct sili_port));
  771         sc->sc_ports = NULL;
  772         return (1);
  773 }
  774 
  775 void
  776 sili_ports_free(struct sili_softc *sc)
  777 {
  778         struct sili_port                *sp;
  779         int                             i;
  780 
  781         for (i = 0; i < sc->sc_nports; i++) {
  782                 sp = &sc->sc_ports[i];
  783 
  784                 if (sp->sp_ccbs != NULL)
  785                         sili_ccb_free(sp);
  786         }
  787 
  788         /* bus_space(9) says subregions dont have to be freed */
  789         free(sc->sc_ports, M_DEVBUF, sc->sc_nports * sizeof(struct sili_port));
  790         sc->sc_ports = NULL;
  791 }
  792 
  793 int
  794 sili_ccb_alloc(struct sili_port *sp)
  795 {
  796         struct sili_softc               *sc = sp->sp_sc;
  797         struct sili_ccb                 *ccb;
  798         struct sili_prb                 *prb;
  799         int                             i;
  800 
  801         TAILQ_INIT(&sp->sp_free_ccbs);
  802         mtx_init(&sp->sp_free_ccb_mtx, IPL_BIO);
  803         TAILQ_INIT(&sp->sp_active_ccbs);
  804         TAILQ_INIT(&sp->sp_deferred_ccbs);
  805 
  806         sp->sp_ccbs = mallocarray(SILI_MAX_CMDS, sizeof(struct sili_ccb),
  807             M_DEVBUF, M_WAITOK);
  808         sp->sp_cmds = sili_dmamem_alloc(sc, SILI_CMD_LEN * SILI_MAX_CMDS,
  809             SILI_PRB_ALIGN);
  810         if (sp->sp_cmds == NULL)
  811                 goto free_ccbs;
  812         sp->sp_scratch = sili_dmamem_alloc(sc, SILI_SCRATCH_LEN, PAGE_SIZE);
  813         if (sp->sp_scratch == NULL)
  814                 goto free_cmds;
  815 
  816         bzero(sp->sp_ccbs, sizeof(struct sili_ccb) * SILI_MAX_CMDS);
  817 
  818         for (i = 0; i < SILI_MAX_CMDS; i++) {
  819                 ccb = &sp->sp_ccbs[i];
  820                 ccb->ccb_port = sp;
  821                 ccb->ccb_cmd = SILI_DMA_KVA(sp->sp_cmds) + i * SILI_CMD_LEN;
  822                 ccb->ccb_cmd_dva = SILI_DMA_DVA(sp->sp_cmds) + i * SILI_CMD_LEN;
  823                 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, SILI_DMA_SEGS,
  824                     MAXPHYS, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
  825                     &ccb->ccb_dmamap) != 0)
  826                         goto free_scratch;
  827 
  828                 prb = ccb->ccb_cmd;
  829                 ccb->ccb_xa.fis = (struct ata_fis_h2d *)&prb->fis;
  830                 ccb->ccb_xa.packetcmd = ((struct sili_prb_packet *)prb)->cdb;
  831                 ccb->ccb_xa.tag = i;
  832                 ccb->ccb_xa.state = ATA_S_COMPLETE;
  833 
  834                 sili_put_ccb(ccb);
  835         }
  836 
  837         return (0);
  838 
  839 free_scratch:
  840         sili_dmamem_free(sc, sp->sp_scratch);
  841 free_cmds:
  842         sili_dmamem_free(sc, sp->sp_cmds);
  843 free_ccbs:
  844         sili_ccb_free(sp);
  845         return (1);
  846 }
  847 
  848 void
  849 sili_ccb_free(struct sili_port *sp)
  850 {
  851         struct sili_softc               *sc = sp->sp_sc;
  852         struct sili_ccb                 *ccb;
  853 
  854         while ((ccb = sili_get_ccb(sp)) != NULL)
  855                 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
  856 
  857         free(sp->sp_ccbs, M_DEVBUF, 0);
  858         sp->sp_ccbs = NULL;
  859 }
  860 
  861 struct sili_ccb *
  862 sili_get_ccb(struct sili_port *sp)
  863 {
  864         struct sili_ccb                 *ccb;
  865 
  866         /*
  867          * Don't allow new commands to start while doing PMP error
  868          * recovery
  869          */
  870         if (sp->sp_pmp_error_recovery != 0) {
  871                 return (NULL);
  872         }
  873 
  874         mtx_enter(&sp->sp_free_ccb_mtx);
  875         ccb = TAILQ_FIRST(&sp->sp_free_ccbs);
  876         if (ccb != NULL) {
  877                 KASSERT(ccb->ccb_xa.state == ATA_S_PUT);
  878                 TAILQ_REMOVE(&sp->sp_free_ccbs, ccb, ccb_entry);
  879                 ccb->ccb_xa.state = ATA_S_SETUP;
  880         }
  881         mtx_leave(&sp->sp_free_ccb_mtx);
  882 
  883         return (ccb);
  884 }
  885 
  886 void
  887 sili_put_ccb(struct sili_ccb *ccb)
  888 {
  889         struct sili_port                *sp = ccb->ccb_port;
  890 
  891 #ifdef DIAGNOSTIC
  892         if (ccb->ccb_xa.state != ATA_S_COMPLETE &&
  893             ccb->ccb_xa.state != ATA_S_TIMEOUT &&
  894             ccb->ccb_xa.state != ATA_S_ERROR) {
  895                 printf("%s: invalid ata_xfer state %02x in sili_put_ccb, "
  896                     "slot %d\n", PORTNAME(sp), ccb->ccb_xa.state,
  897                     ccb->ccb_xa.tag);
  898         }
  899 #endif
  900 
  901         ccb->ccb_xa.state = ATA_S_PUT;
  902         mtx_enter(&sp->sp_free_ccb_mtx);
  903         TAILQ_INSERT_TAIL(&sp->sp_free_ccbs, ccb, ccb_entry);
  904         mtx_leave(&sp->sp_free_ccb_mtx);
  905 }
  906 
  907 struct sili_dmamem *
  908 sili_dmamem_alloc(struct sili_softc *sc, bus_size_t size, bus_size_t align)
  909 {
  910         struct sili_dmamem              *sdm;
  911         int                             nsegs;
  912 
  913         sdm = malloc(sizeof(*sdm), M_DEVBUF, M_WAITOK | M_ZERO);
  914         sdm->sdm_size = size;
  915 
  916         if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
  917             BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &sdm->sdm_map) != 0)
  918                 goto sdmfree;
  919 
  920         if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &sdm->sdm_seg,
  921             1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
  922                 goto destroy;
  923 
  924         if (bus_dmamem_map(sc->sc_dmat, &sdm->sdm_seg, nsegs, size,
  925             &sdm->sdm_kva, BUS_DMA_NOWAIT) != 0)
  926                 goto free;
  927 
  928         if (bus_dmamap_load(sc->sc_dmat, sdm->sdm_map, sdm->sdm_kva, size,
  929             NULL, BUS_DMA_NOWAIT) != 0)
  930                 goto unmap;
  931 
  932         return (sdm);
  933 
  934 unmap:
  935         bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, size);
  936 free:
  937         bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
  938 destroy:
  939         bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
  940 sdmfree:
  941         free(sdm, M_DEVBUF, sizeof *sdm);
  942 
  943         return (NULL);
  944 }
  945 
  946 void
  947 sili_dmamem_free(struct sili_softc *sc, struct sili_dmamem *sdm)
  948 {
  949         bus_dmamap_unload(sc->sc_dmat, sdm->sdm_map);
  950         bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, sdm->sdm_size);
  951         bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
  952         bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
  953         free(sdm, M_DEVBUF, sizeof *sdm);
  954 }
  955 
  956 u_int32_t
  957 sili_read(struct sili_softc *sc, bus_size_t r)
  958 {
  959         u_int32_t                       rv;
  960 
  961         bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
  962             BUS_SPACE_BARRIER_READ);
  963         rv = bus_space_read_4(sc->sc_iot_global, sc->sc_ioh_global, r);
  964 
  965         return (rv);
  966 }
  967 
  968 void
  969 sili_write(struct sili_softc *sc, bus_size_t r, u_int32_t v)
  970 {
  971         bus_space_write_4(sc->sc_iot_global, sc->sc_ioh_global, r, v);
  972         bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
  973             BUS_SPACE_BARRIER_WRITE);
  974 }
  975 
  976 u_int32_t
  977 sili_pread(struct sili_port *sp, bus_size_t r)
  978 {
  979         u_int32_t                       rv;
  980 
  981         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
  982             BUS_SPACE_BARRIER_READ);
  983         rv = bus_space_read_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r);
  984 
  985         return (rv);
  986 }
  987 
  988 void
  989 sili_pwrite(struct sili_port *sp, bus_size_t r, u_int32_t v)
  990 {
  991         bus_space_write_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, v);
  992         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
  993             BUS_SPACE_BARRIER_WRITE);
  994 }
  995 
  996 int
  997 sili_pwait_eq(struct sili_port *sp, bus_size_t r, u_int32_t mask,
  998     u_int32_t value, int timeout)
  999 {
 1000         while ((sili_pread(sp, r) & mask) != value) {
 1001                 if (timeout == 0)
 1002                         return (0);
 1003 
 1004                 delay(1000);
 1005                 timeout--;
 1006         }
 1007 
 1008         return (1);
 1009 }
 1010 
 1011 int
 1012 sili_pwait_ne(struct sili_port *sp, bus_size_t r, u_int32_t mask,
 1013     u_int32_t value, int timeout)
 1014 {
 1015         while ((sili_pread(sp, r) & mask) == value) {
 1016                 if (timeout == 0)
 1017                         return (0);
 1018 
 1019                 delay(1000);
 1020                 timeout--;
 1021         }
 1022 
 1023         return (1);
 1024 }
 1025 
 1026 void
 1027 sili_post_direct(struct sili_port *sp, u_int slot, void *buf, size_t buflen)
 1028 {
 1029         bus_size_t                      r = SILI_PREG_SLOT(slot);
 1030 
 1031 #ifdef DIAGNOSTIC
 1032         if (buflen != 64 && buflen != 128)
 1033                 panic("sili_pcopy: buflen of %lu is not 64 or 128", buflen);
 1034 #endif
 1035 
 1036         bus_space_write_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
 1037             buf, buflen);
 1038         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, buflen,
 1039             BUS_SPACE_BARRIER_WRITE);
 1040 
 1041         sili_pwrite(sp, SILI_PREG_FIFO, slot);
 1042 }
 1043 
 1044 void
 1045 sili_pread_fis(struct sili_port *sp, u_int slot, struct ata_fis_d2h *fis)
 1046 {
 1047         bus_size_t                      r = SILI_PREG_SLOT(slot) + 8;
 1048 
 1049         bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
 1050             sizeof(struct ata_fis_d2h), BUS_SPACE_BARRIER_READ);
 1051         bus_space_read_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
 1052             fis, sizeof(struct ata_fis_d2h));
 1053 }
 1054 
 1055 void
 1056 sili_post_indirect(struct sili_port *sp, struct sili_ccb *ccb)
 1057 {
 1058         sili_pwrite(sp, SILI_PREG_CAR_LO(ccb->ccb_xa.tag),
 1059             (u_int32_t)ccb->ccb_cmd_dva);
 1060         sili_pwrite(sp, SILI_PREG_CAR_HI(ccb->ccb_xa.tag),
 1061             (u_int32_t)(ccb->ccb_cmd_dva >> 32));
 1062 }
 1063 
 1064 u_int32_t
 1065 sili_signature(struct sili_port *sp, u_int slot)
 1066 {
 1067         u_int32_t                       sig_hi, sig_lo;
 1068 
 1069         sig_hi = sili_pread(sp, SILI_PREG_SIG_HI(slot));
 1070         sig_hi <<= SILI_PREG_SIG_HI_SHIFT;
 1071         sig_lo = sili_pread(sp, SILI_PREG_SIG_LO(slot));
 1072         sig_lo &= SILI_PREG_SIG_LO_MASK;
 1073 
 1074         return (sig_hi | sig_lo);
 1075 }
 1076 
 1077 void
 1078 sili_dummy_done(struct ata_xfer *xa)
 1079 {
 1080 }
 1081 
 1082 int
 1083 sili_pmp_portreset(struct sili_softc *sc, int port, int pmp_port)
 1084 {
 1085         struct sili_port        *sp;
 1086         u_int32_t               data;
 1087         int                     loop;
 1088 
 1089         sp = &sc->sc_ports[port];
 1090         DPRINTF(SILI_D_VERBOSE, "%s: resetting pmp port %d\n", PORTNAME(sp),
 1091             pmp_port);
 1092 
 1093         if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1))
 1094                 goto err;
 1095         if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SCTL,
 1096             SATA_PM_SCTL_IPM_DISABLED))
 1097                 goto err;
 1098         delay(10000);
 1099 
 1100         /* enable PHY by writing 1 then 0 to Scontrol DET field, using
 1101          * Write Port Multiplier commands
 1102          */
 1103         data = SATA_PM_SCTL_IPM_DISABLED | SATA_PM_SCTL_DET_INIT |
 1104             SATA_PM_SCTL_SPD_ANY;
 1105         if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SCTL, data))
 1106                 goto err;
 1107         delay(100000);
 1108         
 1109         if (sili_pmp_phy_status(sp, pmp_port, &data)) {
 1110                 printf("%s: cannot clear phy status for PMP probe\n",
 1111                         PORTNAME(sp));
 1112                 goto err;
 1113         }
 1114         
 1115         sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
 1116         data = SATA_PM_SCTL_IPM_DISABLED | SATA_PM_SCTL_DET_NONE;
 1117         if (sili_pmp_write(sp, pmp_port, SATA_PMREG_SCTL, data))
 1118                 goto err;
 1119         delay(100000);
 1120         
 1121         /* wait for PHYRDY by polling SStatus */
 1122         for (loop = 3; loop; loop--) {
 1123                 if (sili_pmp_read(sp, pmp_port, SATA_PMREG_SSTS, &data))
 1124                         goto err;
 1125                 if (data & SATA_PM_SSTS_DET)
 1126                         break;
 1127                 delay(100000);
 1128         }
 1129         if (loop == 0) {
 1130                 DPRINTF(SILI_D_VERBOSE, "%s.%d: port appears to be unplugged\n",
 1131                     PORTNAME(sp), pmp_port);
 1132                 goto err;
 1133         }
 1134         
 1135         /* give it a bit more time to complete negotiation */
 1136         for (loop = 30; loop; loop--) {
 1137                 if (sili_pmp_read(sp, pmp_port, SATA_PMREG_SSTS, &data))
 1138                         goto err;
 1139                 if ((data & SATA_PM_SSTS_DET) == SATA_PM_SSTS_DET_DEV)
 1140                         break;
 1141                 delay(10000);
 1142         }
 1143         if (loop == 0) {
 1144                 printf("%s.%d: device may be powered down\n", PORTNAME(sp),
 1145                     pmp_port);
 1146                 goto err;
 1147         }
 1148 
 1149         DPRINTF(SILI_D_VERBOSE, "%s.%d: device detected; SStatus=%08x\n",
 1150             PORTNAME(sp), pmp_port, data);
 1151 
 1152         /* clear the X-bit and all other error bits in Serror (PCSR[1]) */
 1153         sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
 1154         return (0);
 1155 
 1156 err:
 1157         DPRINTF(SILI_D_VERBOSE, "%s.%d: port reset failed\n", PORTNAME(sp),
 1158             pmp_port);
 1159         sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
 1160         return (1);
 1161 }
 1162 
 1163 void
 1164 sili_pmp_op_timeout(void *cookie)
 1165 {
 1166         struct sili_ccb *ccb = cookie;
 1167         struct sili_port *sp = ccb->ccb_port;
 1168         int s;
 1169 
 1170         switch (ccb->ccb_xa.state) {
 1171         case ATA_S_PENDING:
 1172                 TAILQ_REMOVE(&sp->sp_active_ccbs, ccb, ccb_entry);
 1173                 ccb->ccb_xa.state = ATA_S_TIMEOUT;
 1174                 break;
 1175         case ATA_S_ONCHIP:
 1176                 KASSERT(sp->sp_active == (1 << ccb->ccb_xa.tag));
 1177                 s = splbio();
 1178                 sili_port_intr(sp, ccb->ccb_xa.tag);
 1179                 splx(s);
 1180                 break;
 1181         case ATA_S_ERROR:
 1182                 /* don't do anything? */
 1183                 break;
 1184         default:
 1185                 panic("%s: sili_pmp_op_timeout: ccb in bad state %d",
 1186                       PORTNAME(sp), ccb->ccb_xa.state);
 1187         }
 1188 }
 1189 
 1190 int
 1191 sili_pmp_softreset(struct sili_softc *sc, int port, int pmp_port)
 1192 {
 1193         struct sili_ccb         *ccb;
 1194         struct sili_prb         *prb;
 1195         struct sili_port        *sp;
 1196         struct ata_fis_h2d      *fis;
 1197         u_int32_t               data;
 1198         u_int32_t               signature;
 1199 
 1200         sp = &sc->sc_ports[port];
 1201 
 1202         ccb = sili_get_ccb(sp);
 1203         if (ccb == NULL) {
 1204                 printf("%s: sili_pmp_softreset NULL ccb!\n", PORTNAME(sp));
 1205                 return (-1);
 1206         }
 1207 
 1208         ccb->ccb_xa.flags = ATA_F_POLL | ATA_F_GET_RFIS;
 1209         ccb->ccb_xa.complete = sili_dummy_done;
 1210         ccb->ccb_xa.pmp_port = pmp_port;
 1211         
 1212         prb = ccb->ccb_cmd;
 1213         bzero(prb, sizeof(*prb));
 1214         fis = (struct ata_fis_h2d *)&prb->fis;
 1215         fis->flags = pmp_port;
 1216         prb->control = SILI_PRB_SOFT_RESET;
 1217 
 1218         ccb->ccb_xa.state = ATA_S_PENDING;
 1219 
 1220         if (sili_poll(ccb, 8000, sili_pmp_op_timeout) != 0) {
 1221                 DPRINTF(SILI_D_VERBOSE, "%s.%d: softreset FIS failed\n",
 1222                     PORTNAME(sp), pmp_port);
 1223 
 1224                 sili_put_ccb(ccb);
 1225                 /* don't return a valid device type here so the caller knows
 1226                  * it can retry if it wants to
 1227                  */
 1228                 return (-1);
 1229         }
 1230 
 1231         signature = ccb->ccb_xa.rfis.sector_count |
 1232             (ccb->ccb_xa.rfis.lba_low << 8) |
 1233             (ccb->ccb_xa.rfis.lba_mid << 16) |
 1234             (ccb->ccb_xa.rfis.lba_high << 24);
 1235         DPRINTF(SILI_D_VERBOSE, "%s.%d: signature: %08x\n", PORTNAME(sp),
 1236             pmp_port, signature);
 1237 
 1238         sili_put_ccb(ccb);
 1239 
 1240         /* clear phy status and error bits */
 1241         if (sili_pmp_phy_status(sp, pmp_port, &data)) {
 1242                 printf("%s.%d: cannot clear phy status after softreset\n",
 1243                        PORTNAME(sp), pmp_port);
 1244         }
 1245         sili_pmp_write(sp, pmp_port, SATA_PMREG_SERR, -1);
 1246 
 1247         /* classify the device based on its signature */
 1248         switch (signature) {
 1249         case SATA_SIGNATURE_DISK:
 1250                 return (ATA_PORT_T_DISK);
 1251         case SATA_SIGNATURE_ATAPI:
 1252                 return (ATA_PORT_T_ATAPI);
 1253         case SATA_SIGNATURE_PORT_MULTIPLIER:
 1254                 return (ATA_PORT_T_NONE);
 1255         default:
 1256                 return (ATA_PORT_T_NONE);
 1257         }
 1258 }
 1259 
 1260 u_int32_t
 1261 sili_port_softreset(struct sili_port *sp)
 1262 {
 1263         struct sili_prb_softreset       sreset;
 1264         u_int32_t                       signature;
 1265 
 1266         bzero(&sreset, sizeof(sreset));
 1267         sreset.control = htole16(SILI_PRB_SOFT_RESET | SILI_PRB_INTERRUPT_MASK);
 1268         sreset.fis[1] = SATA_PMP_CONTROL_PORT;
 1269 
 1270         /* we use slot 0 */
 1271         sili_post_direct(sp, 0, &sreset, sizeof(sreset));
 1272         if (!sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000)) {
 1273                 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for soft "
 1274                     "reset\n", PORTNAME(sp));
 1275                 return (ATA_PORT_T_NONE);
 1276         }
 1277 
 1278         /* Read device signature from command slot. */
 1279         signature = sili_signature(sp, 0);
 1280 
 1281         DPRINTF(SILI_D_VERBOSE, "%s: signature 0x%08x\n", PORTNAME(sp),
 1282             signature);
 1283 
 1284         switch (signature) {
 1285         case SATA_SIGNATURE_DISK:
 1286                 return (ATA_PORT_T_DISK);
 1287         case SATA_SIGNATURE_ATAPI:
 1288                 return (ATA_PORT_T_ATAPI);
 1289         case SATA_SIGNATURE_PORT_MULTIPLIER:
 1290                 return (ATA_PORT_T_PM);
 1291         default:
 1292                 return (ATA_PORT_T_NONE);
 1293         }
 1294 }
 1295 
 1296 int
 1297 sili_ata_probe(void *xsc, int port, int lun)
 1298 {
 1299         struct sili_softc               *sc = xsc;
 1300         struct sili_port                *sp = &sc->sc_ports[port];
 1301         int                             port_type;
 1302 
 1303         /* handle pmp port probes */
 1304         if (lun != 0) {
 1305                 int i;
 1306                 int rc;
 1307                 int pmp_port = lun - 1;
 1308 
 1309                 if (lun > sp->sp_pmp_ports)
 1310                         return (ATA_PORT_T_NONE);
 1311 
 1312                 for (i = 0; i < 2; i++) {
 1313                         if (sili_pmp_portreset(sc, port, pmp_port)) {
 1314                                 continue;
 1315                         }
 1316 
 1317                         /* small delay between attempts to allow error
 1318                          * conditions to settle down.  this doesn't seem
 1319                          * to affect portreset operations, just
 1320                          * commands sent to the device.
 1321                          */
 1322                         if (i != 0) {
 1323                                 delay(5000000);
 1324                         }
 1325 
 1326                         rc = sili_pmp_softreset(sc, port, pmp_port);
 1327                         switch (rc) {
 1328                         case -1:
 1329                                 /* possibly try again */
 1330                                 break;
 1331                         case ATA_PORT_T_DISK:
 1332                         case ATA_PORT_T_ATAPI:
 1333                                 /* mark this port as active */
 1334                                 sp->sp_active_pmp_ports |= (1 << pmp_port);
 1335                         default:
 1336                                 return (rc);
 1337                         }
 1338                 }
 1339                 DPRINTF(SILI_D_VERBOSE, "%s.%d: probe failed\n", PORTNAME(sp),
 1340                     pmp_port);
 1341                 return (ATA_PORT_T_NONE);
 1342         }
 1343 
 1344         sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRESET);
 1345         delay(10000);
 1346         sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_PORTRESET);
 1347 
 1348         sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTINIT);
 1349         if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
 1350             SILI_PREG_PCS_PORTRDY, 1000)) {
 1351                 printf("%s: couldn't initialize port\n", PORTNAME(sp));
 1352                 return (ATA_PORT_T_NONE);
 1353         }
 1354 
 1355         sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_A32B);
 1356 
 1357         if (!sili_pwait_eq(sp, SILI_PREG_SSTS, SATA_SStatus_DET,
 1358             SATA_SStatus_DET_DEV, 2000)) {
 1359                 DPRINTF(SILI_D_VERBOSE, "%s: unattached\n", PORTNAME(sp));
 1360                 return (ATA_PORT_T_NONE);
 1361         }
 1362 
 1363         DPRINTF(SILI_D_VERBOSE, "%s: SSTS 0x%08x\n", PORTNAME(sp),
 1364             sili_pread(sp, SILI_PREG_SSTS));
 1365 
 1366         port_type = sili_port_softreset(sp);
 1367         if (port_type == ATA_PORT_T_NONE)
 1368                 return (port_type);
 1369 
 1370         /* allocate port resources */
 1371         if (sili_ccb_alloc(sp) != 0)
 1372                 return (ATA_PORT_T_NONE);
 1373 
 1374         /* do PMP probe now that we can talk to the device */
 1375         if (port_type == ATA_PORT_T_PM) {
 1376                 int i;
 1377 
 1378                 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PMEN);
 1379 
 1380                 if (sili_pmp_identify(sp, &sp->sp_pmp_ports)) {
 1381                         return (ATA_PORT_T_NONE);
 1382                 }
 1383 
 1384                 /* reset all the PMP ports to wake devices up */
 1385                 for (i = 0; i < sp->sp_pmp_ports; i++) {
 1386                         sili_pmp_portreset(sp->sp_sc, sp->sp_port, i);
 1387                 }
 1388         }
 1389 
 1390         /* enable port interrupts */
 1391         sili_write(sc, SILI_REG_GC, sili_read(sc, SILI_REG_GC) | 1 << port);
 1392         sili_pwrite(sp, SILI_PREG_IES, SILI_PREG_IE_CMDERR |
 1393             SILI_PREG_IE_CMDCOMP);
 1394 
 1395         return (port_type);
 1396 }
 1397 
 1398 void
 1399 sili_ata_free(void *xsc, int port, int lun)
 1400 {
 1401         struct sili_softc               *sc = xsc;
 1402         struct sili_port                *sp = &sc->sc_ports[port];
 1403 
 1404         if (lun == 0) {
 1405                 if (sp->sp_ccbs != NULL)
 1406                         sili_ccb_free(sp);
 1407 
 1408                 /* XXX we should do more here */
 1409         }
 1410 }
 1411 
 1412 void
 1413 sili_ata_cmd(struct ata_xfer *xa)
 1414 {
 1415         struct sili_ccb                 *ccb = (struct sili_ccb *)xa;
 1416         struct sili_port                *sp = ccb->ccb_port;
 1417         struct sili_softc               *sc = sp->sp_sc;
 1418         struct sili_prb_ata             *ata;
 1419         struct sili_prb_packet          *atapi;
 1420         struct sili_sge                 *sgl;
 1421         int                             sgllen;
 1422         int                             s;
 1423 
 1424         KASSERT(xa->state == ATA_S_SETUP || xa->state == ATA_S_TIMEOUT);
 1425 
 1426         if (xa->flags & ATA_F_PACKET) {
 1427                 atapi = ccb->ccb_cmd;
 1428 
 1429                 if (xa->flags & ATA_F_WRITE)
 1430                         atapi->control = htole16(SILI_PRB_PACKET_WRITE);
 1431                 else
 1432                         atapi->control = htole16(SILI_PRB_PACKET_READ);
 1433 
 1434                 sgl = atapi->sgl;
 1435                 sgllen = nitems(atapi->sgl);
 1436         } else {
 1437                 ata = ccb->ccb_cmd;
 1438 
 1439                 ata->control = 0;
 1440 
 1441                 sgl = ata->sgl;
 1442                 sgllen = nitems(ata->sgl);
 1443         }
 1444 
 1445         if (sili_load(ccb, sgl, sgllen) != 0)
 1446                 goto failcmd;
 1447 
 1448         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
 1449             xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_PREWRITE);
 1450 
 1451         timeout_set(&xa->stimeout, sili_ata_cmd_timeout, ccb);
 1452 
 1453         xa->state = ATA_S_PENDING;
 1454 
 1455         if (xa->flags & ATA_F_POLL)
 1456                 sili_poll(ccb, xa->timeout, sili_ata_cmd_timeout);
 1457         else {
 1458                 s = splbio();
 1459                 timeout_add_msec(&xa->stimeout, xa->timeout);
 1460                 sili_start(sp, ccb);
 1461                 splx(s);
 1462         }
 1463 
 1464         return;
 1465 
 1466 failcmd:
 1467         s = splbio();
 1468         xa->state = ATA_S_ERROR;
 1469         ata_complete(xa);
 1470         splx(s);
 1471 }
 1472 
 1473 void
 1474 sili_ata_cmd_done(struct sili_ccb *ccb, int defer_completion)
 1475 {
 1476         struct sili_port                *sp = ccb->ccb_port;
 1477         struct sili_softc               *sc = sp->sp_sc;
 1478         struct ata_xfer                 *xa = &ccb->ccb_xa;
 1479 
 1480         splassert(IPL_BIO);
 1481 
 1482         timeout_del(&xa->stimeout);
 1483 
 1484         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
 1485             xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_POSTWRITE);
 1486 
 1487         sili_unload(ccb);
 1488 
 1489         TAILQ_REMOVE(&sp->sp_active_ccbs, ccb, ccb_entry);
 1490         sp->sp_active &= ~(1 << xa->tag);
 1491         if (sp->sp_err_active & (1 << xa->tag)) {
 1492                 sp->sp_err_active &= ~(1 << xa->tag);
 1493                 DPRINTF(SILI_D_VERBOSE, "%s: slot %d complete, error mask now "
 1494                     "%x\n", PORTNAME(sp), xa->tag, sp->sp_err_active);
 1495         }
 1496 
 1497         if (xa->state == ATA_S_ONCHIP)
 1498                 xa->state = ATA_S_COMPLETE;
 1499 #ifdef DIAGNOSTIC
 1500         else if (xa->state != ATA_S_ERROR && xa->state != ATA_S_TIMEOUT)
 1501                 printf("%s: invalid ata_xfer state %02x in sili_ata_cmd_done, "
 1502                     "slot %d\n", PORTNAME(sp), xa->state, xa->tag);
 1503 #endif
 1504         if (defer_completion)
 1505                 TAILQ_INSERT_TAIL(&sp->sp_deferred_ccbs, ccb, ccb_entry);
 1506         else if (xa->state == ATA_S_COMPLETE)
 1507                 ata_complete(xa);
 1508 #ifdef DIAGNOSTIC
 1509         else
 1510                 printf("%s: completion not deferred, but xa->state is %02x?\n",
 1511                     PORTNAME(sp), xa->state);
 1512 #endif
 1513 }
 1514 
 1515 void
 1516 sili_ata_cmd_timeout(void *xccb)
 1517 {
 1518         struct sili_ccb                 *ccb = xccb;
 1519         struct sili_port                *sp = ccb->ccb_port;
 1520         int                             s;
 1521 
 1522         s = splbio();
 1523         sili_port_intr(sp, ccb->ccb_xa.tag);
 1524         splx(s);
 1525 }
 1526 
 1527 int
 1528 sili_load(struct sili_ccb *ccb, struct sili_sge *sgl, int sgllen)
 1529 {
 1530         struct sili_port                *sp = ccb->ccb_port;
 1531         struct sili_softc               *sc = sp->sp_sc;
 1532         struct ata_xfer                 *xa = &ccb->ccb_xa;
 1533         struct sili_sge                 *nsge = sgl, *ce = NULL;
 1534         bus_dmamap_t                    dmap = ccb->ccb_dmamap;
 1535         u_int64_t                       addr;
 1536         int                             error;
 1537         int                             i;
 1538 
 1539         if (xa->datalen == 0)
 1540                 return (0);
 1541 
 1542         error = bus_dmamap_load(sc->sc_dmat, dmap, xa->data, xa->datalen, NULL,
 1543             (xa->flags & ATA_F_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
 1544         if (error != 0) {
 1545                 printf("%s: error %d loading dmamap\n", PORTNAME(sp), error);
 1546                 return (1);
 1547         }
 1548 
 1549         if (dmap->dm_nsegs > sgllen)
 1550                 ce = &sgl[sgllen - 1];
 1551 
 1552         for (i = 0; i < dmap->dm_nsegs; i++) {
 1553                 if (nsge == ce) {
 1554                         nsge++;
 1555 
 1556                         addr = ccb->ccb_cmd_dva;
 1557                         addr += ((u_int8_t *)nsge - (u_int8_t *)ccb->ccb_cmd);
 1558 
 1559                         ce->addr_lo = htole32((u_int32_t)addr);
 1560                         ce->addr_hi = htole32((u_int32_t)(addr >> 32));
 1561                         ce->flags = htole32(SILI_SGE_LNK);
 1562 
 1563                         if ((dmap->dm_nsegs - i) > SILI_SGT_SGLLEN)
 1564                                 ce += SILI_SGT_SGLLEN;
 1565                         else
 1566                                 ce = NULL;
 1567                 }
 1568 
 1569                 sgl = nsge;
 1570 
 1571                 addr = dmap->dm_segs[i].ds_addr;
 1572                 sgl->addr_lo = htole32((u_int32_t)addr);
 1573                 sgl->addr_hi = htole32((u_int32_t)(addr >> 32));
 1574                 sgl->data_count = htole32(dmap->dm_segs[i].ds_len);
 1575                 sgl->flags = 0;
 1576 
 1577                 nsge++;
 1578         }
 1579         sgl->flags |= htole32(SILI_SGE_TRM);
 1580 
 1581         bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
 1582             (xa->flags & ATA_F_READ) ? BUS_DMASYNC_PREREAD :
 1583             BUS_DMASYNC_PREWRITE);
 1584 
 1585         return (0);
 1586 }
 1587 
 1588 void
 1589 sili_unload(struct sili_ccb *ccb)
 1590 {
 1591         struct sili_port                *sp = ccb->ccb_port;
 1592         struct sili_softc               *sc = sp->sp_sc;
 1593         struct ata_xfer                 *xa = &ccb->ccb_xa;
 1594         bus_dmamap_t                    dmap = ccb->ccb_dmamap;
 1595 
 1596         if (xa->datalen == 0)
 1597                 return;
 1598 
 1599         bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
 1600             (xa->flags & ATA_F_READ) ? BUS_DMASYNC_POSTREAD :
 1601             BUS_DMASYNC_POSTWRITE);
 1602         bus_dmamap_unload(sc->sc_dmat, dmap);
 1603 
 1604         if (xa->flags & ATA_F_READ)
 1605                 xa->resid = xa->datalen - sili_pread(sp,
 1606                     SILI_PREG_RX_COUNT(xa->tag));
 1607         else
 1608                 xa->resid = 0;
 1609 }
 1610 
 1611 int
 1612 sili_poll(struct sili_ccb *ccb, int timeout, void (*timeout_fn)(void *))
 1613 {
 1614         struct sili_port                *sp = ccb->ccb_port;
 1615         int                             s;
 1616 
 1617         s = splbio();
 1618         sili_start(sp, ccb);
 1619         do {
 1620                 if (sili_port_intr(sp, -1) & (1 << ccb->ccb_xa.tag)) {
 1621                         splx(s);
 1622                         return (ccb->ccb_xa.state != ATA_S_COMPLETE);
 1623                 }
 1624 
 1625                 delay(1000);
 1626         } while (--timeout > 0);
 1627 
 1628         /* Run timeout while at splbio, otherwise sili_intr could interfere. */
 1629         if (timeout_fn != NULL)
 1630                 timeout_fn(ccb);
 1631 
 1632         splx(s);
 1633 
 1634         return (1);
 1635 }
 1636 
 1637 void
 1638 sili_start(struct sili_port *sp, struct sili_ccb *ccb)
 1639 {
 1640         int                             slot = ccb->ccb_xa.tag;
 1641 
 1642         splassert(IPL_BIO);
 1643         KASSERT(ccb->ccb_xa.state == ATA_S_PENDING);
 1644         KASSERT(sp->sp_pmp_error_recovery == 0);
 1645 
 1646         TAILQ_INSERT_TAIL(&sp->sp_active_ccbs, ccb, ccb_entry);
 1647         sp->sp_active |= 1 << slot;
 1648         ccb->ccb_xa.state = ATA_S_ONCHIP;
 1649 
 1650         sili_post_indirect(sp, ccb);
 1651 }
 1652 
 1653 int
 1654 sili_read_ncq_error(struct sili_port *sp, int *err_slotp, int pmp_port)
 1655 {
 1656         struct sili_softc               *sc = sp->sp_sc;
 1657         struct sili_prb_ata             read_10h;
 1658         u_int64_t                       addr;
 1659         struct ata_fis_h2d              *fis;
 1660         struct ata_log_page_10h         *log;
 1661         struct sili_ccb                 *ccb;
 1662         int                             rc;
 1663 
 1664         sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTINIT);
 1665         if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
 1666             SILI_PREG_PCS_PORTRDY, 1000)) {
 1667                 printf("%s: couldn't ready port during log page read\n",
 1668                     PORTNAME(sp));
 1669                 return (1);
 1670         }
 1671 
 1672         /* READ LOG EXT 10h into scratch space */
 1673         bzero(&read_10h, sizeof(read_10h));
 1674         read_10h.control = htole16(SILI_PRB_INTERRUPT_MASK);
 1675 
 1676         addr = SILI_DMA_DVA(sp->sp_scratch);
 1677         read_10h.sgl[0].addr_lo = htole32((u_int32_t)addr);
 1678         read_10h.sgl[0].addr_hi = htole32((u_int32_t)(addr >> 32));
 1679         read_10h.sgl[0].data_count = htole32(512);
 1680         read_10h.sgl[0].flags = htole32(SILI_SGE_TRM);
 1681 
 1682         fis = (struct ata_fis_h2d *)read_10h.fis;
 1683         fis->type = ATA_FIS_TYPE_H2D;
 1684         fis->flags = ATA_H2D_FLAGS_CMD | pmp_port;
 1685         fis->command = ATA_C_READ_LOG_EXT;
 1686         fis->lba_low = 0x10;            /* queued error log page (10h) */
 1687         fis->sector_count = 1;          /* number of sectors (1) */
 1688         fis->sector_count_exp = 0;
 1689         fis->lba_mid = 0;               /* starting offset */
 1690         fis->lba_mid_exp = 0;
 1691         fis->device = 0;
 1692 
 1693         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
 1694             512, BUS_DMASYNC_PREREAD);
 1695 
 1696         /* issue read and poll for completion */
 1697         sili_post_direct(sp, 0, &read_10h, sizeof(read_10h));
 1698         rc = sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000);
 1699 
 1700         bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
 1701             512, BUS_DMASYNC_POSTREAD);
 1702 
 1703         if (!rc) {
 1704                 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for log "
 1705                     "page read\n", PORTNAME(sp));
 1706                 return (1);
 1707         }
 1708 
 1709         /* Extract failed register set and tags from the scratch space. */
 1710         log = (struct ata_log_page_10h *)SILI_DMA_KVA(sp->sp_scratch);
 1711         if (ISSET(log->err_regs.type, ATA_LOG_10H_TYPE_NOTQUEUED)) {
 1712                 /* Not queued bit was set - wasn't an NCQ error? */
 1713                 printf("%s: read NCQ error page, but not an NCQ error?\n",
 1714                     PORTNAME(sp));
 1715                 return (1);
 1716         }
 1717 
 1718         /* Copy back the log record as a D2H register FIS. */
 1719         *err_slotp = log->err_regs.type & ATA_LOG_10H_TYPE_TAG_MASK;
 1720 
 1721         ccb = &sp->sp_ccbs[*err_slotp];
 1722         memcpy(&ccb->ccb_xa.rfis, &log->err_regs, sizeof(struct ata_fis_d2h));
 1723         ccb->ccb_xa.rfis.type = ATA_FIS_TYPE_D2H;
 1724         ccb->ccb_xa.rfis.flags = 0;
 1725 
 1726         return (0);
 1727 }
 1728 
 1729 struct ata_xfer *
 1730 sili_ata_get_xfer(void *xsc, int port)
 1731 {
 1732         struct sili_softc               *sc = xsc;
 1733         struct sili_port                *sp = &sc->sc_ports[port];
 1734         struct sili_ccb                 *ccb;
 1735 
 1736         ccb = sili_get_ccb(sp);
 1737         if (ccb == NULL) {
 1738                 printf("%s: sili_ata_get_xfer NULL ccb!\n", PORTNAME(sp));
 1739                 return (NULL);
 1740         }
 1741 
 1742         bzero(ccb->ccb_cmd, SILI_CMD_LEN);
 1743 
 1744         return ((struct ata_xfer *)ccb);
 1745 }
 1746 
 1747 void
 1748 sili_ata_put_xfer(struct ata_xfer *xa)
 1749 {
 1750         struct sili_ccb                 *ccb = (struct sili_ccb *)xa;
 1751 
 1752         sili_put_ccb(ccb);
 1753 }
 1754 
 1755 /* PMP register ops */
 1756 int
 1757 sili_pmp_read(struct sili_port *sp, int target, int which, u_int32_t *datap)
 1758 {
 1759         struct sili_ccb *ccb;
 1760         struct sili_prb *prb;
 1761         struct ata_fis_h2d *fis;
 1762         int error;
 1763 
 1764         ccb = sili_get_ccb(sp);
 1765         if (ccb == NULL) {
 1766                 printf("%s: sili_pmp_read NULL ccb!\n", PORTNAME(sp));
 1767                 return (1);
 1768         }
 1769         ccb->ccb_xa.flags = ATA_F_POLL | ATA_F_GET_RFIS;
 1770         ccb->ccb_xa.complete = sili_dummy_done;
 1771         ccb->ccb_xa.pmp_port = SATA_PMP_CONTROL_PORT;
 1772         ccb->ccb_xa.state = ATA_S_PENDING;
 1773         
 1774         prb = ccb->ccb_cmd;
 1775         bzero(prb, sizeof(*prb));
 1776         fis = (struct ata_fis_h2d *)&prb->fis;
 1777         fis->type = ATA_FIS_TYPE_H2D;
 1778         fis->flags = ATA_H2D_FLAGS_CMD | SATA_PMP_CONTROL_PORT;
 1779         fis->command = ATA_C_READ_PM;
 1780         fis->features = which;
 1781         fis->device = target | ATA_H2D_DEVICE_LBA;
 1782         fis->control = ATA_FIS_CONTROL_4BIT;
 1783 
 1784         if (sili_poll(ccb, 1000, sili_pmp_op_timeout) != 0) {
 1785                 printf("sili_pmp_read(%d, %d) failed\n", target, which);
 1786                 error = 1;
 1787         } else {
 1788                 *datap = ccb->ccb_xa.rfis.sector_count |
 1789                     (ccb->ccb_xa.rfis.lba_low << 8) |
 1790                     (ccb->ccb_xa.rfis.lba_mid << 16) |
 1791                     (ccb->ccb_xa.rfis.lba_high << 24);
 1792                 error = 0;
 1793         }
 1794         sili_put_ccb(ccb);
 1795         return (error);
 1796 }
 1797 
 1798 int
 1799 sili_pmp_write(struct sili_port *sp, int target, int which, u_int32_t data)
 1800 {
 1801         struct sili_ccb *ccb;
 1802         struct sili_prb *prb;
 1803         struct ata_fis_h2d *fis;
 1804         int error;
 1805 
 1806         ccb = sili_get_ccb(sp);
 1807         if (ccb == NULL) {
 1808                 printf("%s: sili_pmp_write NULL ccb!\n", PORTNAME(sp));
 1809                 return (1);
 1810         }
 1811         ccb->ccb_xa.complete = sili_dummy_done;
 1812         ccb->ccb_xa.flags = ATA_F_POLL;
 1813         ccb->ccb_xa.pmp_port = SATA_PMP_CONTROL_PORT;
 1814         ccb->ccb_xa.state = ATA_S_PENDING;
 1815 
 1816         prb = ccb->ccb_cmd;
 1817         bzero(prb, sizeof(*prb));
 1818         fis = (struct ata_fis_h2d *)&prb->fis;
 1819         fis->type = ATA_FIS_TYPE_H2D;
 1820         fis->flags = ATA_H2D_FLAGS_CMD | SATA_PMP_CONTROL_PORT;
 1821         fis->command = ATA_C_WRITE_PM;
 1822         fis->features = which;
 1823         fis->device = target | ATA_H2D_DEVICE_LBA;
 1824         fis->sector_count = (u_int8_t)data;
 1825         fis->lba_low = (u_int8_t)(data >> 8);
 1826         fis->lba_mid = (u_int8_t)(data >> 16);
 1827         fis->lba_high = (u_int8_t)(data >> 24);
 1828         fis->control = ATA_FIS_CONTROL_4BIT;
 1829 
 1830         error = sili_poll(ccb, 1000, sili_pmp_op_timeout);
 1831         sili_put_ccb(ccb);
 1832         return (error);
 1833 }
 1834 
 1835 int
 1836 sili_pmp_phy_status(struct sili_port *sp, int target, u_int32_t *datap)
 1837 {
 1838         int error;
 1839 
 1840         error = sili_pmp_read(sp, target, SATA_PMREG_SSTS, datap);
 1841         if (error == 0)
 1842                 error = sili_pmp_write(sp, target, SATA_PMREG_SERR, -1);
 1843         if (error)
 1844                 *datap = 0;
 1845 
 1846         return (error);
 1847 }
 1848 
 1849 int
 1850 sili_pmp_identify(struct sili_port *sp, int *ret_nports)
 1851 {
 1852         u_int32_t chipid;
 1853         u_int32_t rev;
 1854         u_int32_t nports;
 1855         u_int32_t features;
 1856         u_int32_t enabled;
 1857 
 1858         if (sili_pmp_read(sp, 15, 0, &chipid) ||
 1859             sili_pmp_read(sp, 15, 1, &rev) ||
 1860             sili_pmp_read(sp, 15, 2, &nports) ||
 1861             sili_pmp_read(sp, 15, SATA_PMREG_FEA, &features) ||
 1862             sili_pmp_read(sp, 15, SATA_PMREG_FEAEN, &enabled)) {
 1863                 printf("%s: port multiplier identification failed\n",
 1864                     PORTNAME(sp));
 1865                 return (1);
 1866         }
 1867 
 1868         nports &= 0x0F;
 1869 
 1870         /* ignore SEMB port on SiI3726 port multiplier chips */
 1871         if (chipid == 0x37261095) {
 1872                 nports--;
 1873         }
 1874 
 1875         printf("%s: port multiplier found: chip=%08x rev=0x%b nports=%d, "
 1876             "features: 0x%b, enabled: 0x%b\n", PORTNAME(sp), chipid, rev,
 1877             SATA_PFMT_PM_REV, nports, features, SATA_PFMT_PM_FEA, enabled,
 1878             SATA_PFMT_PM_FEA);
 1879 
 1880         *ret_nports = nports;
 1881         return (0);
 1882 }

Cache object: 1f17af90f914bb508a2caa324a6eca16


[ 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.