[BACK]Return to ahci.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/ahci.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: ahci.c,v 1.128 2007/07/03 22:33:20 dlg Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2006 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/kernel.h>
        !            23: #include <sys/malloc.h>
        !            24: #include <sys/device.h>
        !            25: #include <sys/proc.h>
        !            26: #include <sys/queue.h>
        !            27:
        !            28: #include <machine/bus.h>
        !            29:
        !            30: #include <dev/pci/pcireg.h>
        !            31: #include <dev/pci/pcivar.h>
        !            32: #include <dev/pci/pcidevs.h>
        !            33:
        !            34: #include <dev/ata/atascsi.h>
        !            35:
        !            36: /* change to AHCI_DEBUG for dmesg spam */
        !            37: #define NO_AHCI_DEBUG
        !            38:
        !            39: #ifdef AHCI_DEBUG
        !            40: #define DPRINTF(m, f...) do { if ((ahcidebug & (m)) == (m)) printf(f); } \
        !            41:     while (0)
        !            42: #define AHCI_D_TIMEOUT         0x00
        !            43: #define AHCI_D_VERBOSE         0x01
        !            44: #define AHCI_D_INTR            0x02
        !            45: #define AHCI_D_XFER            0x08
        !            46: int ahcidebug = AHCI_D_VERBOSE;
        !            47: #else
        !            48: #define DPRINTF(m, f...)
        !            49: #endif
        !            50:
        !            51: #define AHCI_PCI_BAR           0x24
        !            52: #define AHCI_PCI_INTERFACE     0x01
        !            53:
        !            54: #define AHCI_REG_CAP           0x000 /* HBA Capabilities */
        !            55: #define  AHCI_REG_CAP_NP(_r)           (((_r) & 0x1f)+1) /* Number of Ports */
        !            56: #define  AHCI_REG_CAP_SXS              (1<<5) /* External SATA */
        !            57: #define  AHCI_REG_CAP_EMS              (1<<6) /* Enclosure Mgmt */
        !            58: #define  AHCI_REG_CAP_CCCS             (1<<7) /* Cmd Coalescing */
        !            59: #define  AHCI_REG_CAP_NCS(_r)          ((((_r) & 0x1f00)>>8)+1) /* NCmds*/
        !            60: #define  AHCI_REG_CAP_PSC              (1<<13) /* Partial State Capable */
        !            61: #define  AHCI_REG_CAP_SSC              (1<<14) /* Slumber State Capable */
        !            62: #define  AHCI_REG_CAP_PMD              (1<<15) /* PIO Multiple DRQ Block */
        !            63: #define  AHCI_REG_CAP_FBSS             (1<<16) /* FIS-Based Switching */
        !            64: #define  AHCI_REG_CAP_SPM              (1<<17) /* Port Multiplier */
        !            65: #define  AHCI_REG_CAP_SAM              (1<<18) /* AHCI Only mode */
        !            66: #define  AHCI_REG_CAP_SNZO             (1<<19) /* Non Zero DMA Offsets */
        !            67: #define  AHCI_REG_CAP_ISS              (0xf<<20) /* Interface Speed Support */
        !            68: #define  AHCI_REG_CAP_ISS_G1           (0x1<<20) /* Gen 1 (1.5 Gbps) */
        !            69: #define  AHCI_REG_CAP_ISS_G1_2         (0x2<<20) /* Gen 1 and 2 (3 Gbps) */
        !            70: #define  AHCI_REG_CAP_SCLO             (1<<24) /* Cmd List Override */
        !            71: #define  AHCI_REG_CAP_SAL              (1<<25) /* Activity LED */
        !            72: #define  AHCI_REG_CAP_SALP             (1<<26) /* Aggressive Link Pwr Mgmt */
        !            73: #define  AHCI_REG_CAP_SSS              (1<<27) /* Staggered Spinup */
        !            74: #define  AHCI_REG_CAP_SMPS             (1<<28) /* Mech Presence Switch */
        !            75: #define  AHCI_REG_CAP_SSNTF            (1<<29) /* SNotification Register */
        !            76: #define  AHCI_REG_CAP_SNCQ             (1<<30) /* Native Cmd Queuing */
        !            77: #define  AHCI_REG_CAP_S64A             (1<<31) /* 64bit Addressing */
        !            78: #define  AHCI_FMT_CAP          "\020" "\040S64A" "\037NCQ" "\036SSNTF" \
        !            79:                                    "\035SMPS" "\034SSS" "\033SALP" "\032SAL" \
        !            80:                                    "\031SCLO" "\024SNZO" "\023SAM" "\022SPM" \
        !            81:                                    "\021FBSS" "\020PMD" "\017SSC" "\016PSC" \
        !            82:                                    "\010CCCS" "\007EMS" "\006SXS"
        !            83: #define AHCI_REG_GHC           0x004 /* Global HBA Control */
        !            84: #define  AHCI_REG_GHC_HR               (1<<0) /* HBA Reset */
        !            85: #define  AHCI_REG_GHC_IE               (1<<1) /* Interrupt Enable */
        !            86: #define  AHCI_REG_GHC_MRSM             (1<<2) /* MSI Revert to Single Msg */
        !            87: #define  AHCI_REG_GHC_AE               (1<<31) /* AHCI Enable */
        !            88: #define AHCI_FMT_GHC           "\020" "\040AE" "\003MRSM" "\002IE" "\001HR"
        !            89: #define AHCI_REG_IS            0x008 /* Interrupt Status */
        !            90: #define AHCI_REG_PI            0x00c /* Ports Implemented */
        !            91: #define AHCI_REG_VS            0x010 /* AHCI Version */
        !            92: #define  AHCI_REG_VS_0_95              0x00000905 /* 0.95 */
        !            93: #define  AHCI_REG_VS_1_0               0x00010000 /* 1.0 */
        !            94: #define  AHCI_REG_VS_1_1               0x00010100 /* 1.1 */
        !            95: #define AHCI_REG_CCC_CTL       0x014 /* Coalescing Control */
        !            96: #define  AHCI_REG_CCC_CTL_INT(_r)      (((_r) & 0xf8) >> 3) /* CCC INT slot */
        !            97: #define AHCI_REG_CCC_PORTS     0x018 /* Coalescing Ports */
        !            98: #define AHCI_REG_EM_LOC                0x01c /* Enclosure Mgmt Location */
        !            99: #define AHCI_REG_EM_CTL                0x020 /* Enclosure Mgmt Control */
        !           100:
        !           101: #define AHCI_PORT_REGION(_p)   (0x100 + ((_p) * 0x80))
        !           102: #define AHCI_PORT_SIZE         0x80
        !           103:
        !           104: #define AHCI_PREG_CLB          0x00 /* Cmd List Base Addr */
        !           105: #define AHCI_PREG_CLBU         0x04 /* Cmd List Base Hi Addr */
        !           106: #define AHCI_PREG_FB           0x08 /* FIS Base Addr */
        !           107: #define AHCI_PREG_FBU          0x0c /* FIS Base Hi Addr */
        !           108: #define AHCI_PREG_IS           0x10 /* Interrupt Status */
        !           109: #define  AHCI_PREG_IS_DHRS             (1<<0) /* Device to Host FIS */
        !           110: #define  AHCI_PREG_IS_PSS              (1<<1) /* PIO Setup FIS */
        !           111: #define  AHCI_PREG_IS_DSS              (1<<2) /* DMA Setup FIS */
        !           112: #define  AHCI_PREG_IS_SDBS             (1<<3) /* Set Device Bits FIS */
        !           113: #define  AHCI_PREG_IS_UFS              (1<<4) /* Unknown FIS */
        !           114: #define  AHCI_PREG_IS_DPS              (1<<5) /* Descriptor Processed */
        !           115: #define  AHCI_PREG_IS_PCS              (1<<6) /* Port Change */
        !           116: #define  AHCI_PREG_IS_DMPS             (1<<7) /* Device Mechanical Presence */
        !           117: #define  AHCI_PREG_IS_PRCS             (1<<22) /* PhyRdy Change */
        !           118: #define  AHCI_PREG_IS_IPMS             (1<<23) /* Incorrect Port Multiplier */
        !           119: #define  AHCI_PREG_IS_OFS              (1<<24) /* Overflow */
        !           120: #define  AHCI_PREG_IS_INFS             (1<<26) /* Interface Non-fatal Error */
        !           121: #define  AHCI_PREG_IS_IFS              (1<<27) /* Interface Fatal Error */
        !           122: #define  AHCI_PREG_IS_HBDS             (1<<28) /* Host Bus Data Error */
        !           123: #define  AHCI_PREG_IS_HBFS             (1<<29) /* Host Bus Fatal Error */
        !           124: #define  AHCI_PREG_IS_TFES             (1<<30) /* Task File Error */
        !           125: #define  AHCI_PREG_IS_CPDS             (1<<31) /* Cold Presence Detect */
        !           126: #define AHCI_PFMT_IS           "\20" "\040CPDS" "\037TFES" "\036HBFS" \
        !           127:                                    "\035HBDS" "\034IFS" "\033INFS" "\031OFS" \
        !           128:                                    "\030IPMS" "\027PRCS" "\010DMPS" "\006DPS" \
        !           129:                                    "\007PCS" "\005UFS" "\004SDBS" "\003DSS" \
        !           130:                                    "\002PSS" "\001DHRS"
        !           131: #define AHCI_PREG_IE           0x14 /* Interrupt Enable */
        !           132: #define  AHCI_PREG_IE_DHRE             (1<<0) /* Device to Host FIS */
        !           133: #define  AHCI_PREG_IE_PSE              (1<<1) /* PIO Setup FIS */
        !           134: #define  AHCI_PREG_IE_DSE              (1<<2) /* DMA Setup FIS */
        !           135: #define  AHCI_PREG_IE_SDBE             (1<<3) /* Set Device Bits FIS */
        !           136: #define  AHCI_PREG_IE_UFE              (1<<4) /* Unknown FIS */
        !           137: #define  AHCI_PREG_IE_DPE              (1<<5) /* Descriptor Processed */
        !           138: #define  AHCI_PREG_IE_PCE              (1<<6) /* Port Change */
        !           139: #define  AHCI_PREG_IE_DMPE             (1<<7) /* Device Mechanical Presence */
        !           140: #define  AHCI_PREG_IE_PRCE             (1<<22) /* PhyRdy Change */
        !           141: #define  AHCI_PREG_IE_IPME             (1<<23) /* Incorrect Port Multiplier */
        !           142: #define  AHCI_PREG_IE_OFE              (1<<24) /* Overflow */
        !           143: #define  AHCI_PREG_IE_INFE             (1<<26) /* Interface Non-fatal Error */
        !           144: #define  AHCI_PREG_IE_IFE              (1<<27) /* Interface Fatal Error */
        !           145: #define  AHCI_PREG_IE_HBDE             (1<<28) /* Host Bus Data Error */
        !           146: #define  AHCI_PREG_IE_HBFE             (1<<29) /* Host Bus Fatal Error */
        !           147: #define  AHCI_PREG_IE_TFEE             (1<<30) /* Task File Error */
        !           148: #define  AHCI_PREG_IE_CPDE             (1<<31) /* Cold Presence Detect */
        !           149: #define AHCI_PFMT_IE           "\20" "\040CPDE" "\037TFEE" "\036HBFE" \
        !           150:                                    "\035HBDE" "\034IFE" "\033INFE" "\031OFE" \
        !           151:                                    "\030IPME" "\027PRCE" "\010DMPE" "\007PCE" \
        !           152:                                    "\006DPE" "\005UFE" "\004SDBE" "\003DSE" \
        !           153:                                    "\002PSE" "\001DHRE"
        !           154: #define AHCI_PREG_CMD          0x18 /* Command and Status */
        !           155: #define  AHCI_PREG_CMD_ST              (1<<0) /* Start */
        !           156: #define  AHCI_PREG_CMD_SUD             (1<<1) /* Spin Up Device */
        !           157: #define  AHCI_PREG_CMD_POD             (1<<2) /* Power On Device */
        !           158: #define  AHCI_PREG_CMD_CLO             (1<<3) /* Command List Override */
        !           159: #define  AHCI_PREG_CMD_FRE             (1<<4) /* FIS Receive Enable */
        !           160: #define  AHCI_PREG_CMD_CCS(_r)         (((_r) >> 8) & 0x1f) /* Curr CmdSlot# */
        !           161: #define  AHCI_PREG_CMD_MPSS            (1<<13) /* Mech Presence State */
        !           162: #define  AHCI_PREG_CMD_FR              (1<<14) /* FIS Receive Running */
        !           163: #define  AHCI_PREG_CMD_CR              (1<<15) /* Command List Running */
        !           164: #define  AHCI_PREG_CMD_CPS             (1<<16) /* Cold Presence State */
        !           165: #define  AHCI_PREG_CMD_PMA             (1<<17) /* Port Multiplier Attached */
        !           166: #define  AHCI_PREG_CMD_HPCP            (1<<18) /* Hot Plug Capable */
        !           167: #define  AHCI_PREG_CMD_MPSP            (1<<19) /* Mech Presence Switch */
        !           168: #define  AHCI_PREG_CMD_CPD             (1<<20) /* Cold Presence Detection */
        !           169: #define  AHCI_PREG_CMD_ESP             (1<<21) /* External SATA Port */
        !           170: #define  AHCI_PREG_CMD_ATAPI           (1<<24) /* Device is ATAPI */
        !           171: #define  AHCI_PREG_CMD_DLAE            (1<<25) /* Drv LED on ATAPI Enable */
        !           172: #define  AHCI_PREG_CMD_ALPE            (1<<26) /* Aggro Pwr Mgmt Enable */
        !           173: #define  AHCI_PREG_CMD_ASP             (1<<27) /* Aggro Slumber/Partial */
        !           174: #define  AHCI_PREG_CMD_ICC             0xf0000000 /* Interface Comm Ctrl */
        !           175: #define  AHCI_PREG_CMD_ICC_SLUMBER     0x60000000
        !           176: #define  AHCI_PREG_CMD_ICC_PARTIAL     0x20000000
        !           177: #define  AHCI_PREG_CMD_ICC_ACTIVE      0x10000000
        !           178: #define  AHCI_PREG_CMD_ICC_IDLE                0x00000000
        !           179: #define  AHCI_PFMT_CMD         "\020" "\034ASP" "\033ALPE" "\032DLAE" \
        !           180:                                    "\031ATAPI" "\026ESP" "\025CPD" "\024MPSP" \
        !           181:                                    "\023HPCP" "\022PMA" "\021CPS" "\020CR" \
        !           182:                                    "\017FR" "\016MPSS" "\005FRE" "\004CLO" \
        !           183:                                    "\003POD" "\002SUD" "\001ST"
        !           184: #define AHCI_PREG_TFD          0x20 /* Task File Data*/
        !           185: #define  AHCI_PREG_TFD_STS             0xff
        !           186: #define  AHCI_PREG_TFD_STS_ERR         (1<<0)
        !           187: #define  AHCI_PREG_TFD_STS_DRQ         (1<<3)
        !           188: #define  AHCI_PREG_TFD_STS_BSY         (1<<7)
        !           189: #define  AHCI_PREG_TFD_ERR             0xff00
        !           190: #define AHCI_PFMT_TFD_STS      "\20" "\010BSY" "\004DRQ" "\001ERR"
        !           191: #define AHCI_PREG_SIG          0x24 /* Signature */
        !           192: #define AHCI_PREG_SSTS         0x28 /* SATA Status */
        !           193: #define  AHCI_PREG_SSTS_DET            0xf /* Device Detection */
        !           194: #define  AHCI_PREG_SSTS_DET_NONE       0x0
        !           195: #define  AHCI_PREG_SSTS_DET_DEV_NE     0x1
        !           196: #define  AHCI_PREG_SSTS_DET_DEV                0x3
        !           197: #define  AHCI_PREG_SSTS_DET_PHYOFFLINE 0x4
        !           198: #define  AHCI_PREG_SSTS_SPD            0xf0 /* Current Interface Speed */
        !           199: #define  AHCI_PREG_SSTS_SPD_NONE       0x00
        !           200: #define  AHCI_PREG_SSTS_SPD_GEN1       0x10
        !           201: #define  AHCI_PREG_SSTS_SPD_GEN2       0x20
        !           202: #define  AHCI_PREG_SSTS_IPM            0xf00 /* Interface Power Management */
        !           203: #define  AHCI_PREG_SSTS_IPM_NONE       0x000
        !           204: #define  AHCI_PREG_SSTS_IPM_ACTIVE     0x100
        !           205: #define  AHCI_PREG_SSTS_IPM_PARTIAL    0x200
        !           206: #define  AHCI_PREG_SSTS_IPM_SLUMBER    0x600
        !           207: #define AHCI_PREG_SCTL         0x2c /* SATA Control */
        !           208: #define  AHCI_PREG_SCTL_DET            0xf /* Device Detection */
        !           209: #define  AHCI_PREG_SCTL_DET_NONE       0x0
        !           210: #define  AHCI_PREG_SCTL_DET_INIT       0x1
        !           211: #define  AHCI_PREG_SCTL_DET_DISABLE    0x4
        !           212: #define  AHCI_PREG_SCTL_SPD            0xf0 /* Speed Allowed */
        !           213: #define  AHCI_PREG_SCTL_SPD_ANY                0x00
        !           214: #define  AHCI_PREG_SCTL_SPD_GEN1       0x10
        !           215: #define  AHCI_PREG_SCTL_SPD_GEN2       0x20
        !           216: #define  AHCI_PREG_SCTL_IPM            0xf00 /* Interface Power Management */
        !           217: #define  AHCI_PREG_SCTL_IPM_NONE       0x000
        !           218: #define  AHCI_PREG_SCTL_IPM_NOPARTIAL  0x100
        !           219: #define  AHCI_PREG_SCTL_IPM_NOSLUMBER  0x200
        !           220: #define  AHCI_PREG_SCTL_IPM_DISABLED   0x300
        !           221: #define AHCI_PREG_SERR         0x30 /* SATA Error */
        !           222: #define  AHCI_PREG_SERR_ERR(_r)                ((_r) & 0xffff)
        !           223: #define  AHCI_PREG_SERR_ERR_I          (1<<0) /* Recovered Data Integrity */
        !           224: #define  AHCI_PREG_SERR_ERR_M          (1<<1) /* Recovered Communications */
        !           225: #define  AHCI_PREG_SERR_ERR_T          (1<<8) /* Transient Data Integrity */
        !           226: #define  AHCI_PREG_SERR_ERR_C          (1<<9) /* Persistent Comm/Data */
        !           227: #define  AHCI_PREG_SERR_ERR_P          (1<<10) /* Protocol */
        !           228: #define  AHCI_PREG_SERR_ERR_E          (1<<11) /* Internal */
        !           229: #define  AHCI_PFMT_SERR_ERR    "\020" "\014E" "\013P" "\012C" "\011T" "\002M" \
        !           230:                                    "\001I"
        !           231: #define  AHCI_PREG_SERR_DIAG(_r)       (((_r) >> 16) & 0xffff)
        !           232: #define  AHCI_PREG_SERR_DIAG_N         (1<<0) /* PhyRdy Change */
        !           233: #define  AHCI_PREG_SERR_DIAG_I         (1<<1) /* Phy Internal Error */
        !           234: #define  AHCI_PREG_SERR_DIAG_W         (1<<2) /* Comm Wake */
        !           235: #define  AHCI_PREG_SERR_DIAG_B         (1<<3) /* 10B to 8B Decode Error */
        !           236: #define  AHCI_PREG_SERR_DIAG_D         (1<<4) /* Disparity Error */
        !           237: #define  AHCI_PREG_SERR_DIAG_C         (1<<5) /* CRC Error */
        !           238: #define  AHCI_PREG_SERR_DIAG_H         (1<<6) /* Handshake Error */
        !           239: #define  AHCI_PREG_SERR_DIAG_S         (1<<7) /* Link Sequence Error */
        !           240: #define  AHCI_PREG_SERR_DIAG_T         (1<<8) /* Transport State Trans Err */
        !           241: #define  AHCI_PREG_SERR_DIAG_F         (1<<9) /* Unknown FIS Type */
        !           242: #define  AHCI_PREG_SERR_DIAG_X         (1<<10) /* Exchanged */
        !           243: #define  AHCI_PFMT_SERR_DIAG   "\020" "\013X" "\012F" "\011T" "\010S" "\007H" \
        !           244:                                    "\006C" "\005D" "\004B" "\003W" "\002I" \
        !           245:                                    "\001N"
        !           246: #define AHCI_PREG_SACT         0x34 /* SATA Active */
        !           247: #define AHCI_PREG_CI           0x38 /* Command Issue */
        !           248: #define  AHCI_PREG_CI_ALL_SLOTS        0xffffffff
        !           249: #define AHCI_PREG_SNTF         0x3c /* SNotification */
        !           250:
        !           251: struct ahci_cmd_hdr {
        !           252:        u_int16_t               flags;
        !           253: #define AHCI_CMD_LIST_FLAG_CFL         0x001f /* Command FIS Length */
        !           254: #define AHCI_CMD_LIST_FLAG_A           (1<<5) /* ATAPI */
        !           255: #define AHCI_CMD_LIST_FLAG_W           (1<<6) /* Write */
        !           256: #define AHCI_CMD_LIST_FLAG_P           (1<<7) /* Prefetchable */
        !           257: #define AHCI_CMD_LIST_FLAG_R           (1<<8) /* Reset */
        !           258: #define AHCI_CMD_LIST_FLAG_B           (1<<9) /* BIST */
        !           259: #define AHCI_CMD_LIST_FLAG_C           (1<<10) /* Clear Busy upon R_OK */
        !           260: #define AHCI_CMD_LIST_FLAG_PMP         0xf000 /* Port Multiplier Port */
        !           261:        u_int16_t               prdtl; /* sgl len */
        !           262:
        !           263:        u_int32_t               prdbc; /* transferred byte count */
        !           264:
        !           265:        u_int32_t               ctba_lo;
        !           266:        u_int32_t               ctba_hi;
        !           267:
        !           268:        u_int32_t               reserved[4];
        !           269: } __packed;
        !           270:
        !           271: struct ahci_rfis {
        !           272:        u_int8_t                dsfis[28];
        !           273:        u_int8_t                reserved1[4];
        !           274:        u_int8_t                psfis[24];
        !           275:        u_int8_t                reserved2[8];
        !           276:        u_int8_t                rfis[24];
        !           277:        u_int8_t                reserved3[4];
        !           278:        u_int8_t                sdbfis[4];
        !           279:        u_int8_t                ufis[64];
        !           280:        u_int8_t                reserved4[96];
        !           281: } __packed;
        !           282:
        !           283: struct ahci_prdt {
        !           284:        u_int32_t               dba_lo;
        !           285:        u_int32_t               dba_hi;
        !           286:        u_int32_t               reserved;
        !           287:        u_int32_t               flags;
        !           288: #define AHCI_PRDT_FLAG_INTR            (1<<31) /* interrupt on completion */
        !           289: } __packed;
        !           290:
        !           291: /* this makes ahci_cmd_table 512 bytes, supporting 128-byte alignment */
        !           292: #define AHCI_MAX_PRDT          24
        !           293:
        !           294: struct ahci_cmd_table {
        !           295:        u_int8_t                cfis[64];       /* Command FIS */
        !           296:        u_int8_t                acmd[16];       /* ATAPI Command */
        !           297:        u_int8_t                reserved[48];
        !           298:
        !           299:        struct ahci_prdt        prdt[AHCI_MAX_PRDT];
        !           300: } __packed;
        !           301:
        !           302: #define AHCI_MAX_PORTS         32
        !           303:
        !           304: struct ahci_dmamem {
        !           305:        bus_dmamap_t            adm_map;
        !           306:        bus_dma_segment_t       adm_seg;
        !           307:        size_t                  adm_size;
        !           308:        caddr_t                 adm_kva;
        !           309: };
        !           310: #define AHCI_DMA_MAP(_adm)     ((_adm)->adm_map)
        !           311: #define AHCI_DMA_DVA(_adm)     ((_adm)->adm_map->dm_segs[0].ds_addr)
        !           312: #define AHCI_DMA_KVA(_adm)     ((void *)(_adm)->adm_kva)
        !           313:
        !           314: struct ahci_softc;
        !           315: struct ahci_port;
        !           316:
        !           317: struct ahci_ccb {
        !           318:        /* ATA xfer associated with this CCB.  Must be 1st struct member. */
        !           319:        struct ata_xfer         ccb_xa;
        !           320:
        !           321:        int                     ccb_slot;
        !           322:        struct ahci_port        *ccb_port;
        !           323:
        !           324:        bus_dmamap_t            ccb_dmamap;
        !           325:        struct ahci_cmd_hdr     *ccb_cmd_hdr;
        !           326:        struct ahci_cmd_table   *ccb_cmd_table;
        !           327:
        !           328:        void                    (*ccb_done)(struct ahci_ccb *);
        !           329:
        !           330:        TAILQ_ENTRY(ahci_ccb)   ccb_entry;
        !           331: };
        !           332:
        !           333: struct ahci_port {
        !           334:        struct ahci_softc       *ap_sc;
        !           335:        bus_space_handle_t      ap_ioh;
        !           336:
        !           337: #ifdef AHCI_COALESCE
        !           338:        int                     ap_num;
        !           339: #endif
        !           340:
        !           341:        struct ahci_rfis        *ap_rfis;
        !           342:        struct ahci_dmamem      *ap_dmamem_rfis;
        !           343:
        !           344:        struct ahci_dmamem      *ap_dmamem_cmd_list;
        !           345:        struct ahci_dmamem      *ap_dmamem_cmd_table;
        !           346:
        !           347:        volatile u_int32_t      ap_active;
        !           348:        volatile u_int32_t      ap_active_cnt;
        !           349:        volatile u_int32_t      ap_sactive;
        !           350:        struct ahci_ccb         *ap_ccbs;
        !           351:
        !           352:        TAILQ_HEAD(, ahci_ccb)  ap_ccb_free;
        !           353:        TAILQ_HEAD(, ahci_ccb)  ap_ccb_pending;
        !           354:
        !           355:        u_int32_t               ap_state;
        !           356: #define AP_S_NORMAL                    0
        !           357: #define AP_S_FATAL_ERROR               1
        !           358:
        !           359:        /* For error recovery. */
        !           360: #ifdef DIAGNOSTIC
        !           361:        int                     ap_err_busy;
        !           362: #endif
        !           363:        u_int32_t               ap_err_saved_sactive;
        !           364:        u_int32_t               ap_err_saved_active;
        !           365:        u_int32_t               ap_err_saved_active_cnt;
        !           366:
        !           367:        u_int8_t                ap_err_scratch[512];
        !           368:
        !           369: #ifdef AHCI_DEBUG
        !           370:        char                    ap_name[16];
        !           371: #define PORTNAME(_ap)  ((_ap)->ap_name)
        !           372: #else
        !           373: #define PORTNAME(_ap)  DEVNAME((_ap)->ap_sc)
        !           374: #endif
        !           375: };
        !           376:
        !           377: struct ahci_softc {
        !           378:        struct device           sc_dev;
        !           379:
        !           380:        void                    *sc_ih;
        !           381:
        !           382:        bus_space_tag_t         sc_iot;
        !           383:        bus_space_handle_t      sc_ioh;
        !           384:        bus_size_t              sc_ios;
        !           385:        bus_dma_tag_t           sc_dmat;
        !           386:
        !           387:        int                     sc_flags;
        !           388: #define AHCI_F_NO_NCQ                  (1<<0)
        !           389:
        !           390:        u_int                   sc_ncmds;
        !           391:
        !           392:        struct ahci_port        *sc_ports[AHCI_MAX_PORTS];
        !           393:
        !           394:        struct atascsi          *sc_atascsi;
        !           395:
        !           396: #ifdef AHCI_COALESCE
        !           397:        u_int32_t               sc_ccc_mask;
        !           398:        u_int32_t               sc_ccc_ports;
        !           399:        u_int32_t               sc_ccc_ports_cur;
        !           400: #endif
        !           401: };
        !           402: #define DEVNAME(_s)            ((_s)->sc_dev.dv_xname)
        !           403:
        !           404: struct ahci_device {
        !           405:        pci_vendor_id_t         ad_vendor;
        !           406:        pci_product_id_t        ad_product;
        !           407:        int                     (*ad_match)(struct pci_attach_args *);
        !           408:        int                     (*ad_attach)(struct ahci_softc *,
        !           409:                                    struct pci_attach_args *);
        !           410: };
        !           411:
        !           412: const struct ahci_device *ahci_lookup_device(struct pci_attach_args *);
        !           413:
        !           414: int                    ahci_no_match(struct pci_attach_args *);
        !           415: int                    ahci_vt8251_attach(struct ahci_softc *,
        !           416:                            struct pci_attach_args *);
        !           417:
        !           418: static const struct ahci_device ahci_devices[] = {
        !           419:        { PCI_VENDOR_VIATECH,   PCI_PRODUCT_VIATECH_VT8251_SATA,
        !           420:            ahci_no_match,      ahci_vt8251_attach }
        !           421: };
        !           422:
        !           423: int                    ahci_pci_match(struct device *, void *, void *);
        !           424: void                   ahci_pci_attach(struct device *, struct device *,
        !           425:                            void *);
        !           426:
        !           427: struct cfattach ahci_pci_ca = {
        !           428:        sizeof(struct ahci_softc), ahci_pci_match, ahci_pci_attach
        !           429: };
        !           430:
        !           431: struct cfattach ahci_jmb_ca = {
        !           432:        sizeof(struct ahci_softc), ahci_pci_match, ahci_pci_attach
        !           433: };
        !           434:
        !           435: struct cfdriver ahci_cd = {
        !           436:        NULL, "ahci", DV_DULL
        !           437: };
        !           438:
        !           439:
        !           440: int                    ahci_map_regs(struct ahci_softc *,
        !           441:                            struct pci_attach_args *);
        !           442: void                   ahci_unmap_regs(struct ahci_softc *,
        !           443:                            struct pci_attach_args *);
        !           444: int                    ahci_map_intr(struct ahci_softc *,
        !           445:                            struct pci_attach_args *, pci_intr_handle_t);
        !           446: #ifdef notyet
        !           447: void                   ahci_unmap_intr(struct ahci_softc *,
        !           448:                            struct pci_attach_args *);
        !           449: #endif
        !           450:
        !           451: int                    ahci_init(struct ahci_softc *);
        !           452: int                    ahci_port_alloc(struct ahci_softc *, u_int);
        !           453: void                   ahci_port_free(struct ahci_softc *, u_int);
        !           454:
        !           455: int                    ahci_port_start(struct ahci_port *, int);
        !           456: int                    ahci_port_stop(struct ahci_port *, int);
        !           457: int                    ahci_port_clo(struct ahci_port *);
        !           458: int                    ahci_port_softreset(struct ahci_port *);
        !           459: int                    ahci_port_portreset(struct ahci_port *);
        !           460:
        !           461: int                    ahci_load_prdt(struct ahci_ccb *);
        !           462: void                   ahci_unload_prdt(struct ahci_ccb *);
        !           463:
        !           464: int                    ahci_poll(struct ahci_ccb *, int, void (*)(void *));
        !           465: void                   ahci_start(struct ahci_ccb *);
        !           466:
        !           467: void                   ahci_issue_pending_ncq_commands(struct ahci_port *);
        !           468: void                   ahci_issue_pending_commands(struct ahci_port *, int);
        !           469:
        !           470: int                    ahci_intr(void *);
        !           471: u_int32_t              ahci_port_intr(struct ahci_port *, u_int32_t);
        !           472:
        !           473: struct ahci_ccb                *ahci_get_ccb(struct ahci_port *);
        !           474: void                   ahci_put_ccb(struct ahci_ccb *);
        !           475:
        !           476: struct ahci_ccb                *ahci_get_err_ccb(struct ahci_port *);
        !           477: void                   ahci_put_err_ccb(struct ahci_ccb *);
        !           478:
        !           479: int                    ahci_port_read_ncq_error(struct ahci_port *, int *);
        !           480:
        !           481: struct ahci_dmamem     *ahci_dmamem_alloc(struct ahci_softc *, size_t);
        !           482: void                   ahci_dmamem_free(struct ahci_softc *,
        !           483:                            struct ahci_dmamem *);
        !           484:
        !           485: u_int32_t              ahci_read(struct ahci_softc *, bus_size_t);
        !           486: void                   ahci_write(struct ahci_softc *, bus_size_t, u_int32_t);
        !           487: int                    ahci_wait_ne(struct ahci_softc *, bus_size_t,
        !           488:                            u_int32_t, u_int32_t);
        !           489:
        !           490: u_int32_t              ahci_pread(struct ahci_port *, bus_size_t);
        !           491: void                   ahci_pwrite(struct ahci_port *, bus_size_t, u_int32_t);
        !           492: int                    ahci_pwait_eq(struct ahci_port *, bus_size_t,
        !           493:                            u_int32_t, u_int32_t);
        !           494:
        !           495: /* Wait for all bits in _b to be cleared */
        !           496: #define ahci_pwait_clr(_ap, _r, _b) ahci_pwait_eq((_ap), (_r), (_b), 0)
        !           497:
        !           498: /* Wait for all bits in _b to be set */
        !           499: #define ahci_pwait_set(_ap, _r, _b) ahci_pwait_eq((_ap), (_r), (_b), (_b))
        !           500:
        !           501: /* provide methods for atascsi to call */
        !           502: int                    ahci_ata_probe(void *, int);
        !           503: struct ata_xfer *      ahci_ata_get_xfer(void *, int);
        !           504: void                   ahci_ata_put_xfer(struct ata_xfer *);
        !           505: int                    ahci_ata_cmd(struct ata_xfer *);
        !           506:
        !           507: struct atascsi_methods ahci_atascsi_methods = {
        !           508:        ahci_ata_probe,
        !           509:        ahci_ata_get_xfer,
        !           510:        ahci_ata_cmd
        !           511: };
        !           512:
        !           513: /* ccb completions */
        !           514: void                   ahci_ata_cmd_done(struct ahci_ccb *);
        !           515: void                   ahci_ata_cmd_timeout(void *);
        !           516: void                   ahci_empty_done(struct ahci_ccb *);
        !           517:
        !           518: const struct ahci_device *
        !           519: ahci_lookup_device(struct pci_attach_args *pa)
        !           520: {
        !           521:        int                             i;
        !           522:        const struct ahci_device        *ad;
        !           523:
        !           524:        for (i = 0; i < (sizeof(ahci_devices) / sizeof(ahci_devices[0])); i++) {
        !           525:                ad = &ahci_devices[i];
        !           526:                if (ad->ad_vendor == PCI_VENDOR(pa->pa_id) &&
        !           527:                    ad->ad_product == PCI_PRODUCT(pa->pa_id))
        !           528:                        return (ad);
        !           529:        }
        !           530:
        !           531:        return (NULL);
        !           532: }
        !           533:
        !           534: int
        !           535: ahci_no_match(struct pci_attach_args *pa)
        !           536: {
        !           537:        return (0);
        !           538: }
        !           539:
        !           540: int
        !           541: ahci_vt8251_attach(struct ahci_softc *sc, struct pci_attach_args *pa)
        !           542: {
        !           543:        sc->sc_flags |= AHCI_F_NO_NCQ;
        !           544:
        !           545:        return (0);
        !           546: }
        !           547:
        !           548: int
        !           549: ahci_pci_match(struct device *parent, void *match, void *aux)
        !           550: {
        !           551:        struct pci_attach_args          *pa = aux;
        !           552:        const struct ahci_device        *ad;
        !           553:
        !           554:        ad = ahci_lookup_device(pa);
        !           555:        if (ad != NULL) {
        !           556:                /* the device may need special checks to see if it matches */
        !           557:                if (ad->ad_match != NULL)
        !           558:                        return (ad->ad_match(pa));
        !           559:
        !           560:                return (2); /* match higher than pciide */
        !           561:        }
        !           562:
        !           563:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE &&
        !           564:            PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_SATA &&
        !           565:            PCI_INTERFACE(pa->pa_class) == AHCI_PCI_INTERFACE)
        !           566:                return (2);
        !           567:
        !           568:        return (0);
        !           569: }
        !           570:
        !           571: void
        !           572: ahci_pci_attach(struct device *parent, struct device *self, void *aux)
        !           573: {
        !           574:        struct ahci_softc               *sc = (struct ahci_softc *)self;
        !           575:        struct pci_attach_args          *pa = aux;
        !           576:        struct atascsi_attach_args      aaa;
        !           577:        const struct ahci_device        *ad;
        !           578:        pci_intr_handle_t               ih;
        !           579:        u_int32_t                       cap, pi;
        !           580:        int                             i;
        !           581:
        !           582:        ad = ahci_lookup_device(pa);
        !           583:        if (ad != NULL && ad->ad_attach != NULL) {
        !           584:                if (ad->ad_attach(sc, pa) != 0) {
        !           585:                        /* error should be printed by ad_attach */
        !           586:                        return;
        !           587:                }
        !           588:        }
        !           589:
        !           590:        if (pci_intr_map(pa, &ih) != 0) {
        !           591:                printf(": unable to map interrupt\n");
        !           592:                return;
        !           593:        }
        !           594:        printf(": %s,", pci_intr_string(pa->pa_pc, ih));
        !           595:
        !           596:        if (ahci_map_regs(sc, pa) != 0) {
        !           597:                /* error already printed by ahci_map_regs */
        !           598:                return;
        !           599:        }
        !           600:
        !           601:        if (ahci_init(sc) != 0) {
        !           602:                /* error already printed by ahci_init */
        !           603:                goto unmap;
        !           604:        }
        !           605:
        !           606:        if (ahci_map_intr(sc, pa, ih) != 0) {
        !           607:                /* error already printed by ahci_map_intr */
        !           608:                goto unmap;
        !           609:        }
        !           610:
        !           611:        printf("\n");
        !           612:
        !           613:        sc->sc_dmat = pa->pa_dmat;
        !           614:
        !           615:        cap = ahci_read(sc, AHCI_REG_CAP);
        !           616:        sc->sc_ncmds = AHCI_REG_CAP_NCS(cap);
        !           617: #ifdef AHCI_DEBUG
        !           618:        if (ahcidebug & AHCI_D_VERBOSE) {
        !           619:                const char *gen;
        !           620:
        !           621:                switch (cap & AHCI_REG_CAP_ISS) {
        !           622:                case AHCI_REG_CAP_ISS_G1:
        !           623:                        gen = "1 (1.5Gbps)";
        !           624:                        break;
        !           625:                case AHCI_REG_CAP_ISS_G1_2:
        !           626:                        gen = "1 (1.5Gbps) and 2 (3Gbps)";
        !           627:                        break;
        !           628:                default:
        !           629:                        gen = "unknown";
        !           630:                        break;
        !           631:                }
        !           632:
        !           633:                printf("%s: capabilities 0x%b, %d ports, %d cmds, gen %s\n",
        !           634:                    DEVNAME(sc), cap, AHCI_FMT_CAP,
        !           635:                    AHCI_REG_CAP_NP(cap), sc->sc_ncmds, gen);
        !           636:        }
        !           637: #endif
        !           638:
        !           639:        pi = ahci_read(sc, AHCI_REG_PI);
        !           640:        DPRINTF(AHCI_D_VERBOSE, "%s: ports implemented: 0x%08x\n",
        !           641:            DEVNAME(sc), pi);
        !           642:
        !           643: #ifdef AHCI_COALESCE
        !           644:        /* Naive coalescing support - enable for all ports. */
        !           645:        if (cap & AHCI_REG_CAP_CCCS) {
        !           646:                u_int16_t               ccc_timeout = 20;
        !           647:                u_int8_t                ccc_numcomplete = 12;
        !           648:                u_int32_t               ccc_ctl;
        !           649:
        !           650:                /* disable coalescing during reconfiguration. */
        !           651:                ccc_ctl = ahci_read(sc, AHCI_REG_CCC_CTL);
        !           652:                ccc_ctl &= ~0x00000001;
        !           653:                ahci_write(sc, AHCI_REG_CCC_CTL, ccc_ctl);
        !           654:
        !           655:                sc->sc_ccc_mask = 1 << AHCI_REG_CCC_CTL_INT(ccc_ctl);
        !           656:                if (pi & sc->sc_ccc_mask) {
        !           657:                        /* A conflict with the implemented port list? */
        !           658:                        printf("%s: coalescing interrupt/implemented port list "
        !           659:                            "conflict, PI: %08x, ccc_mask: %08x\n",
        !           660:                            DEVNAME(sc), pi, sc->sc_ccc_mask);
        !           661:                        sc->sc_ccc_mask = 0;
        !           662:                        goto noccc;
        !           663:                }
        !           664:
        !           665:                /* ahci_port_start will enable each port when it starts. */
        !           666:                sc->sc_ccc_ports = pi;
        !           667:                sc->sc_ccc_ports_cur = 0;
        !           668:
        !           669:                /* program thresholds and enable overall coalescing. */
        !           670:                ccc_ctl &= ~0xffffff00;
        !           671:                ccc_ctl |= (ccc_timeout << 16) | (ccc_numcomplete << 8);
        !           672:                ahci_write(sc, AHCI_REG_CCC_CTL, ccc_ctl);
        !           673:                ahci_write(sc, AHCI_REG_CCC_PORTS, 0);
        !           674:                ahci_write(sc, AHCI_REG_CCC_CTL, ccc_ctl | 1);
        !           675:        }
        !           676: noccc:
        !           677: #endif
        !           678:        for (i = 0; i < AHCI_MAX_PORTS; i++) {
        !           679:                if (!ISSET(pi, 1 << i)) {
        !           680:                        /* dont allocate stuff if the port isnt implemented */
        !           681:                        continue;
        !           682:                }
        !           683:
        !           684:                if (ahci_port_alloc(sc, i) == ENOMEM)
        !           685:                        goto freeports;
        !           686:        }
        !           687:
        !           688:        bzero(&aaa, sizeof(aaa));
        !           689:        aaa.aaa_cookie = sc;
        !           690:        aaa.aaa_methods = &ahci_atascsi_methods;
        !           691:        aaa.aaa_minphys = minphys;
        !           692:        aaa.aaa_nports = AHCI_MAX_PORTS;
        !           693:        aaa.aaa_ncmds = sc->sc_ncmds;
        !           694:        aaa.aaa_capability = ASAA_CAP_NEEDS_RESERVED;
        !           695:        if (!(sc->sc_flags & AHCI_F_NO_NCQ) && (cap & AHCI_REG_CAP_SNCQ))
        !           696:                aaa.aaa_capability |= ASAA_CAP_NCQ;
        !           697:
        !           698:        sc->sc_atascsi = atascsi_attach(&sc->sc_dev, &aaa);
        !           699:
        !           700:        /* Enable interrupts */
        !           701:        ahci_write(sc, AHCI_REG_GHC, AHCI_REG_GHC_AE | AHCI_REG_GHC_IE);
        !           702:
        !           703:        return;
        !           704:
        !           705: freeports:
        !           706:        for (i = 0; i < AHCI_MAX_PORTS; i++)
        !           707:                if (sc->sc_ports[i] != NULL)
        !           708:                        ahci_port_free(sc, i);
        !           709: unmap:
        !           710:        /* Disable controller */
        !           711:        ahci_write(sc, AHCI_REG_GHC, 0);
        !           712:        ahci_unmap_regs(sc, pa);
        !           713:        return;
        !           714: }
        !           715:
        !           716: int
        !           717: ahci_map_regs(struct ahci_softc *sc, struct pci_attach_args *pa)
        !           718: {
        !           719:        pcireg_t                        maptype;
        !           720:
        !           721:        maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, AHCI_PCI_BAR);
        !           722:        if (pci_mapreg_map(pa, AHCI_PCI_BAR, maptype, 0, &sc->sc_iot,
        !           723:            &sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) {
        !           724:                printf(" unable to map registers\n");
        !           725:                return (1);
        !           726:        }
        !           727:
        !           728:        return (0);
        !           729: }
        !           730:
        !           731: void
        !           732: ahci_unmap_regs(struct ahci_softc *sc, struct pci_attach_args *pa)
        !           733: {
        !           734:        bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
        !           735:        sc->sc_ios = 0;
        !           736: }
        !           737:
        !           738: int
        !           739: ahci_map_intr(struct ahci_softc *sc, struct pci_attach_args *pa,
        !           740:     pci_intr_handle_t ih)
        !           741: {
        !           742:        sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
        !           743:            ahci_intr, sc, DEVNAME(sc));
        !           744:        if (sc->sc_ih == NULL) {
        !           745:                printf("%s: unable to map interrupt\n", DEVNAME(sc));
        !           746:                return (1);
        !           747:        }
        !           748:
        !           749:        return (0);
        !           750: }
        !           751:
        !           752: #ifdef notyet
        !           753: /* one day we'll have hotplug pci */
        !           754: void
        !           755: ahci_unmap_intr(struct ahci_softc *sc, struct pci_attach_args *pa)
        !           756: {
        !           757:        pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
        !           758: }
        !           759: #endif
        !           760:
        !           761: int
        !           762: ahci_init(struct ahci_softc *sc)
        !           763: {
        !           764:        u_int32_t                       reg, cap, pi;
        !           765:        const char                      *revision;
        !           766:
        !           767:        DPRINTF(AHCI_D_VERBOSE, " GHC 0x%b", ahci_read(sc, AHCI_REG_GHC),
        !           768:            AHCI_FMT_GHC);
        !           769:
        !           770:        /* save BIOS initialised parameters, enable staggered spin up */
        !           771:        cap = ahci_read(sc, AHCI_REG_CAP);
        !           772:        cap &= AHCI_REG_CAP_SMPS;
        !           773:        cap |= AHCI_REG_CAP_SSS;
        !           774:        pi = ahci_read(sc, AHCI_REG_PI);
        !           775:
        !           776:        if (ISSET(AHCI_REG_GHC_AE, ahci_read(sc, AHCI_REG_GHC))) {
        !           777:                /* reset the controller */
        !           778:                ahci_write(sc, AHCI_REG_GHC, AHCI_REG_GHC_HR);
        !           779:                if (ahci_wait_ne(sc, AHCI_REG_GHC, AHCI_REG_GHC_HR,
        !           780:                    AHCI_REG_GHC_HR) != 0) {
        !           781:                        printf(" unable to reset controller\n");
        !           782:                        return (1);
        !           783:                }
        !           784:        }
        !           785:
        !           786:        /* enable ahci (global interrupts disabled) */
        !           787:        ahci_write(sc, AHCI_REG_GHC, AHCI_REG_GHC_AE);
        !           788:
        !           789:        /* restore parameters */
        !           790:        ahci_write(sc, AHCI_REG_CAP, cap);
        !           791:        ahci_write(sc, AHCI_REG_PI, pi);
        !           792:
        !           793:        /* check the revision */
        !           794:        reg = ahci_read(sc, AHCI_REG_VS);
        !           795:        switch (reg) {
        !           796:        case AHCI_REG_VS_0_95:
        !           797:                revision = "0.95";
        !           798:                break;
        !           799:        case AHCI_REG_VS_1_0:
        !           800:                revision = "1.0";
        !           801:                break;
        !           802:        case AHCI_REG_VS_1_1:
        !           803:                revision = "1.1";
        !           804:                break;
        !           805:
        !           806:        default:
        !           807:                printf(" unsupported AHCI revision 0x%08x\n", reg);
        !           808:                return (1);
        !           809:        }
        !           810:
        !           811:        printf(" AHCI %s", revision);
        !           812:
        !           813:        return (0);
        !           814: }
        !           815:
        !           816: int
        !           817: ahci_port_alloc(struct ahci_softc *sc, u_int port)
        !           818: {
        !           819:        struct ahci_port                *ap;
        !           820:        struct ahci_ccb                 *ccb;
        !           821:        u_int64_t                       dva;
        !           822:        u_int32_t                       cmd;
        !           823:        struct ahci_cmd_hdr             *hdr;
        !           824:        struct ahci_cmd_table           *table;
        !           825:        int                             i, rc = ENOMEM;
        !           826:
        !           827:        ap = malloc(sizeof(struct ahci_port), M_DEVBUF, M_NOWAIT);
        !           828:        if (ap == NULL) {
        !           829:                printf("%s: unable to allocate memory for port %d\n",
        !           830:                    DEVNAME(sc), port);
        !           831:                goto reterr;
        !           832:        }
        !           833:        bzero(ap, sizeof(struct ahci_port));
        !           834:
        !           835: #ifdef AHCI_DEBUG
        !           836:        snprintf(ap->ap_name, sizeof(ap->ap_name), "%s.%d",
        !           837:            DEVNAME(sc), port);
        !           838: #endif
        !           839:        sc->sc_ports[port] = ap;
        !           840:
        !           841:        if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
        !           842:            AHCI_PORT_REGION(port), AHCI_PORT_SIZE, &ap->ap_ioh) != 0) {
        !           843:                printf("%s: unable to create register window for port %d\n",
        !           844:                    DEVNAME(sc), port);
        !           845:                goto freeport;
        !           846:        }
        !           847:
        !           848:        ap->ap_sc = sc;
        !           849: #ifdef AHCI_COALESCE
        !           850:        ap->ap_num = port;
        !           851: #endif
        !           852:        TAILQ_INIT(&ap->ap_ccb_free);
        !           853:        TAILQ_INIT(&ap->ap_ccb_pending);
        !           854:
        !           855:        /* Disable port interrupts */
        !           856:        ahci_pwrite(ap, AHCI_PREG_IE, 0);
        !           857:
        !           858:        /* Sec 10.1.2 - deinitialise port if it is already running */
        !           859:        cmd = ahci_pread(ap, AHCI_PREG_CMD);
        !           860:        if (ISSET(cmd, (AHCI_PREG_CMD_ST | AHCI_PREG_CMD_CR |
        !           861:            AHCI_PREG_CMD_FRE | AHCI_PREG_CMD_FR)) ||
        !           862:            ISSET(ahci_pread(ap, AHCI_PREG_SCTL), AHCI_PREG_SCTL_DET)) {
        !           863:                int r;
        !           864:
        !           865:                r = ahci_port_stop(ap, 1);
        !           866:                if (r) {
        !           867:                        printf("%s: unable to disable %s, ignoring port %d\n",
        !           868:                            DEVNAME(sc), r == 2 ? "CR" : "FR", port);
        !           869:                        rc = ENXIO;
        !           870:                        goto freeport;
        !           871:                }
        !           872:
        !           873:                /* Write DET to zero */
        !           874:                ahci_pwrite(ap, AHCI_PREG_SCTL, 0);
        !           875:        }
        !           876:
        !           877:        /* Allocate RFIS */
        !           878:        ap->ap_dmamem_rfis = ahci_dmamem_alloc(sc, sizeof(struct ahci_rfis));
        !           879:        if (ap->ap_dmamem_rfis == NULL)
        !           880:                goto nomem;
        !           881:
        !           882:        /* Setup RFIS base address */
        !           883:        ap->ap_rfis = (struct ahci_rfis *) AHCI_DMA_KVA(ap->ap_dmamem_rfis);
        !           884:        dva = AHCI_DMA_DVA(ap->ap_dmamem_rfis);
        !           885:        ahci_pwrite(ap, AHCI_PREG_FBU, (u_int32_t)(dva >> 32));
        !           886:        ahci_pwrite(ap, AHCI_PREG_FB, (u_int32_t)dva);
        !           887:
        !           888:        /* Enable FIS reception and activate port. */
        !           889:        cmd = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !           890:        cmd |= AHCI_PREG_CMD_FRE | AHCI_PREG_CMD_POD | AHCI_PREG_CMD_SUD;
        !           891:        ahci_pwrite(ap, AHCI_PREG_CMD, cmd | AHCI_PREG_CMD_ICC_ACTIVE);
        !           892:
        !           893:        /* Check whether port activated.  Skip it if not. */
        !           894:        cmd = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !           895:        if (!ISSET(cmd, AHCI_PREG_CMD_FRE)) {
        !           896:                rc = ENXIO;
        !           897:                goto freeport;
        !           898:        }
        !           899:
        !           900:        /* Allocate a CCB for each command slot */
        !           901:        ap->ap_ccbs = malloc(sizeof(struct ahci_ccb) * sc->sc_ncmds, M_DEVBUF,
        !           902:            M_NOWAIT);
        !           903:        if (ap->ap_ccbs == NULL) {
        !           904:                printf("%s: unable to allocate command list for port %d\n",
        !           905:                    DEVNAME(sc), port);
        !           906:                goto freeport;
        !           907:        }
        !           908:        bzero(ap->ap_ccbs, sizeof(struct ahci_ccb) * sc->sc_ncmds);
        !           909:
        !           910:        /* Command List Structures and Command Tables */
        !           911:        ap->ap_dmamem_cmd_list = ahci_dmamem_alloc(sc,
        !           912:            sc->sc_ncmds * sizeof(struct ahci_cmd_hdr));
        !           913:        ap->ap_dmamem_cmd_table = ahci_dmamem_alloc(sc,
        !           914:            sc->sc_ncmds * sizeof(struct ahci_cmd_table));
        !           915:        if (ap->ap_dmamem_cmd_table == NULL || ap->ap_dmamem_cmd_list == NULL) {
        !           916: nomem:
        !           917:                printf("%s: unable to allocate DMA memory for port %d\n",
        !           918:                    DEVNAME(sc), port);
        !           919:                goto freeport;
        !           920:        }
        !           921:
        !           922:        /* Setup command list base address */
        !           923:        dva = AHCI_DMA_DVA(ap->ap_dmamem_cmd_list);
        !           924:        ahci_pwrite(ap, AHCI_PREG_CLBU, (u_int32_t)(dva >> 32));
        !           925:        ahci_pwrite(ap, AHCI_PREG_CLB, (u_int32_t)dva);
        !           926:
        !           927:        /* Split CCB allocation into CCBs and assign to command header/table */
        !           928:        hdr = AHCI_DMA_KVA(ap->ap_dmamem_cmd_list);
        !           929:        table = AHCI_DMA_KVA(ap->ap_dmamem_cmd_table);
        !           930:        for (i = 0; i < sc->sc_ncmds; i++) {
        !           931:                ccb = &ap->ap_ccbs[i];
        !           932:
        !           933:                if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, AHCI_MAX_PRDT,
        !           934:                    (4 * 1024 * 1024), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
        !           935:                    &ccb->ccb_dmamap) != 0) {
        !           936:                        printf("%s: unable to create dmamap for port %d "
        !           937:                            "ccb %d\n", DEVNAME(sc), port, i);
        !           938:                        goto freeport;
        !           939:                }
        !           940:
        !           941:                ccb->ccb_slot = i;
        !           942:                ccb->ccb_port = ap;
        !           943:                ccb->ccb_cmd_hdr = &hdr[i];
        !           944:                ccb->ccb_cmd_table = &table[i];
        !           945:                dva = AHCI_DMA_DVA(ap->ap_dmamem_cmd_table) +
        !           946:                    ccb->ccb_slot * sizeof(struct ahci_cmd_table);
        !           947:                ccb->ccb_cmd_hdr->ctba_hi = htole32((u_int32_t)(dva >> 32));
        !           948:                ccb->ccb_cmd_hdr->ctba_lo = htole32((u_int32_t)dva);
        !           949:
        !           950:                ccb->ccb_xa.fis =
        !           951:                    (struct ata_fis_h2d *)ccb->ccb_cmd_table->cfis;
        !           952:                ccb->ccb_xa.packetcmd = ccb->ccb_cmd_table->acmd;
        !           953:                ccb->ccb_xa.tag = i;
        !           954:
        !           955:                ccb->ccb_xa.ata_put_xfer = ahci_ata_put_xfer;
        !           956:
        !           957:                ccb->ccb_xa.state = ATA_S_COMPLETE;
        !           958:                ahci_put_ccb(ccb);
        !           959:        }
        !           960:
        !           961:        /* Wait for ICC change to complete */
        !           962:        ahci_pwait_clr(ap, AHCI_PREG_CMD, AHCI_PREG_CMD_ICC);
        !           963:
        !           964:        /* Reset port */
        !           965:        rc = ahci_port_portreset(ap);
        !           966:        switch (rc) {
        !           967:        case ENODEV:
        !           968:                switch (ahci_pread(ap, AHCI_PREG_SSTS) & AHCI_PREG_SSTS_DET) {
        !           969:                case AHCI_PREG_SSTS_DET_DEV_NE:
        !           970:                        printf("%s: device not communicating on port %d\n",
        !           971:                            DEVNAME(sc), port);
        !           972:                        break;
        !           973:                case AHCI_PREG_SSTS_DET_PHYOFFLINE:
        !           974:                        printf("%s: PHY offline on port %d\n", DEVNAME(sc),
        !           975:                            port);
        !           976:                        break;
        !           977:                default:
        !           978:                        DPRINTF(AHCI_D_VERBOSE, "%s: no device detected "
        !           979:                            "on port %d\n", DEVNAME(sc), port);
        !           980:                        break;
        !           981:                }
        !           982:                goto freeport;
        !           983:
        !           984:        case EBUSY:
        !           985:                printf("%s: device on port %d didn't come ready, "
        !           986:                    "TFD: 0x%b\n", DEVNAME(sc), port,
        !           987:                    ahci_pread(ap, AHCI_PREG_TFD), AHCI_PFMT_TFD_STS);
        !           988:
        !           989:                /* Try a soft reset to clear busy */
        !           990:                rc = ahci_port_softreset(ap);
        !           991:                if (rc) {
        !           992:                        printf("%s: unable to communicate "
        !           993:                            "with device on port %d\n", DEVNAME(sc), port);
        !           994:                        goto freeport;
        !           995:                }
        !           996:                break;
        !           997:
        !           998:        default:
        !           999:                break;
        !          1000:        }
        !          1001:        DPRINTF(AHCI_D_VERBOSE, "%s: detected device on port %d\n",
        !          1002:            DEVNAME(sc), port);
        !          1003:
        !          1004:        /* Enable command transfers on port */
        !          1005:        if (ahci_port_start(ap, 0)) {
        !          1006:                printf("%s: failed to start command DMA on port %d, "
        !          1007:                    "disabling\n", DEVNAME(sc), port);
        !          1008:                rc = ENXIO;     /* couldn't start port */
        !          1009:        }
        !          1010:
        !          1011:        /* Flush interrupts for port */
        !          1012:        ahci_pwrite(ap, AHCI_PREG_IS, ahci_pread(ap, AHCI_PREG_IS));
        !          1013:        ahci_write(sc, AHCI_REG_IS, 1 << port);
        !          1014:
        !          1015:        /* Enable port interrupts */
        !          1016:        ahci_pwrite(ap, AHCI_PREG_IE, AHCI_PREG_IE_TFEE | AHCI_PREG_IE_HBFE |
        !          1017:            AHCI_PREG_IE_IFE | AHCI_PREG_IE_OFE | AHCI_PREG_IE_DPE |
        !          1018:            AHCI_PREG_IE_UFE |
        !          1019: #ifdef AHCI_COALESCE
        !          1020:            ((sc->sc_ccc_ports & (1 << port)) ? 0 : (AHCI_PREG_IE_SDBE |
        !          1021:            AHCI_PREG_IE_DHRE))
        !          1022: #else
        !          1023:            AHCI_PREG_IE_SDBE | AHCI_PREG_IE_DHRE
        !          1024: #endif
        !          1025:            );
        !          1026:
        !          1027: freeport:
        !          1028:        if (rc != 0)
        !          1029:                ahci_port_free(sc, port);
        !          1030: reterr:
        !          1031:        return (rc);
        !          1032: }
        !          1033:
        !          1034: void
        !          1035: ahci_port_free(struct ahci_softc *sc, u_int port)
        !          1036: {
        !          1037:        struct ahci_port                *ap = sc->sc_ports[port];
        !          1038:        struct ahci_ccb                 *ccb;
        !          1039:
        !          1040:        /* Ensure port is disabled and its interrupts are flushed */
        !          1041:        if (ap->ap_sc) {
        !          1042:                ahci_pwrite(ap, AHCI_PREG_CMD, 0);
        !          1043:                ahci_pwrite(ap, AHCI_PREG_IE, 0);
        !          1044:                ahci_pwrite(ap, AHCI_PREG_IS, ahci_pread(ap, AHCI_PREG_IS));
        !          1045:                ahci_write(sc, AHCI_REG_IS, 1 << port);
        !          1046:        }
        !          1047:
        !          1048:        if (ap->ap_ccbs) {
        !          1049:                while ((ccb = ahci_get_ccb(ap)) != NULL)
        !          1050:                        bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
        !          1051:                free(ap->ap_ccbs, M_DEVBUF);
        !          1052:        }
        !          1053:
        !          1054:        if (ap->ap_dmamem_cmd_list)
        !          1055:                ahci_dmamem_free(sc, ap->ap_dmamem_cmd_list);
        !          1056:        if (ap->ap_dmamem_rfis)
        !          1057:                ahci_dmamem_free(sc, ap->ap_dmamem_rfis);
        !          1058:        if (ap->ap_dmamem_cmd_table)
        !          1059:                ahci_dmamem_free(sc, ap->ap_dmamem_cmd_table);
        !          1060:
        !          1061:        /* bus_space(9) says we dont free the subregions handle */
        !          1062:
        !          1063:        free(ap, M_DEVBUF);
        !          1064:        sc->sc_ports[port] = NULL;
        !          1065: }
        !          1066:
        !          1067: int
        !          1068: ahci_port_start(struct ahci_port *ap, int fre_only)
        !          1069: {
        !          1070:        u_int32_t                       r;
        !          1071:
        !          1072:        /* Turn on FRE (and ST) */
        !          1073:        r = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !          1074:        r |= AHCI_PREG_CMD_FRE;
        !          1075:        if (!fre_only)
        !          1076:                r |= AHCI_PREG_CMD_ST;
        !          1077:        ahci_pwrite(ap, AHCI_PREG_CMD, r);
        !          1078:
        !          1079: #ifdef AHCI_COALESCE
        !          1080:        /* (Re-)enable coalescing on the port. */
        !          1081:        if (ap->ap_sc->sc_ccc_ports & (1 << ap->ap_num)) {
        !          1082:                ap->ap_sc->sc_ccc_ports_cur |= (1 << ap->ap_num);
        !          1083:                ahci_write(ap->ap_sc, AHCI_REG_CCC_PORTS,
        !          1084:                    ap->ap_sc->sc_ccc_ports_cur);
        !          1085:        }
        !          1086: #endif
        !          1087:
        !          1088:        /* Wait for FR to come on */
        !          1089:        if (ahci_pwait_set(ap, AHCI_PREG_CMD, AHCI_PREG_CMD_FR))
        !          1090:                return (2);
        !          1091:
        !          1092:        /* Wait for CR to come on */
        !          1093:        if (!fre_only && ahci_pwait_set(ap, AHCI_PREG_CMD, AHCI_PREG_CMD_CR))
        !          1094:                return (1);
        !          1095:
        !          1096:        return (0);
        !          1097: }
        !          1098:
        !          1099: int
        !          1100: ahci_port_stop(struct ahci_port *ap, int stop_fis_rx)
        !          1101: {
        !          1102:        u_int32_t                       r;
        !          1103:
        !          1104: #ifdef AHCI_COALESCE
        !          1105:        /* Disable coalescing on the port while it is stopped. */
        !          1106:        if (ap->ap_sc->sc_ccc_ports & (1 << ap->ap_num)) {
        !          1107:                ap->ap_sc->sc_ccc_ports_cur &= ~(1 << ap->ap_num);
        !          1108:                ahci_write(ap->ap_sc, AHCI_REG_CCC_PORTS,
        !          1109:                    ap->ap_sc->sc_ccc_ports_cur);
        !          1110:        }
        !          1111: #endif
        !          1112:
        !          1113:        /* Turn off ST (and FRE) */
        !          1114:        r = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !          1115:        r &= ~AHCI_PREG_CMD_ST;
        !          1116:        if (stop_fis_rx)
        !          1117:                r &= ~AHCI_PREG_CMD_FRE;
        !          1118:        ahci_pwrite(ap, AHCI_PREG_CMD, r);
        !          1119:
        !          1120:        /* Wait for CR to go off */
        !          1121:        if (ahci_pwait_clr(ap, AHCI_PREG_CMD, AHCI_PREG_CMD_CR))
        !          1122:                return (1);
        !          1123:
        !          1124:        /* Wait for FR to go off */
        !          1125:        if (stop_fis_rx && ahci_pwait_clr(ap, AHCI_PREG_CMD, AHCI_PREG_CMD_FR))
        !          1126:                return (2);
        !          1127:
        !          1128:        return (0);
        !          1129: }
        !          1130:
        !          1131: /* AHCI command list override -> forcibly clear TFD.STS.{BSY,DRQ} */
        !          1132: int
        !          1133: ahci_port_clo(struct ahci_port *ap)
        !          1134: {
        !          1135:        struct ahci_softc               *sc = ap->ap_sc;
        !          1136:        u_int32_t                       cmd;
        !          1137:
        !          1138:        /* Only attempt CLO if supported by controller */
        !          1139:        if (!ISSET(ahci_read(sc, AHCI_REG_CAP), AHCI_REG_CAP_SCLO))
        !          1140:                return (1);
        !          1141:
        !          1142:        /* Issue CLO */
        !          1143:        cmd = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !          1144: #ifdef DIAGNOSTIC
        !          1145:        if (ISSET(cmd, AHCI_PREG_CMD_ST))
        !          1146:                printf("%s: CLO requested while port running\n", PORTNAME(ap));
        !          1147: #endif
        !          1148:        ahci_pwrite(ap, AHCI_PREG_CMD, cmd | AHCI_PREG_CMD_CLO);
        !          1149:
        !          1150:        /* Wait for completion */
        !          1151:        if (ahci_pwait_clr(ap, AHCI_PREG_CMD, AHCI_PREG_CMD_CLO)) {
        !          1152:                printf("%s: CLO did not complete\n", PORTNAME(ap));
        !          1153:                return (1);
        !          1154:        }
        !          1155:
        !          1156:        return (0);
        !          1157: }
        !          1158:
        !          1159: /* AHCI soft reset, Section 10.4.1 */
        !          1160: int
        !          1161: ahci_port_softreset(struct ahci_port *ap)
        !          1162: {
        !          1163:        struct ahci_ccb                 *ccb = NULL;
        !          1164:        struct ahci_cmd_hdr             *cmd_slot;
        !          1165:        u_int8_t                        *fis;
        !          1166:        int                             s, rc = EIO;
        !          1167:        u_int32_t                       cmd;
        !          1168:
        !          1169:        DPRINTF(AHCI_D_VERBOSE, "%s: soft reset\n", PORTNAME(ap));
        !          1170:
        !          1171:        s = splbio();
        !          1172:
        !          1173:        /* Save previous command register state */
        !          1174:        cmd = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !          1175:
        !          1176:        /* Idle port */
        !          1177:        if (ahci_port_stop(ap, 0)) {
        !          1178:                printf("%s: failed to stop port, cannot softreset\n",
        !          1179:                    PORTNAME(ap));
        !          1180:                goto err;
        !          1181:        }
        !          1182:
        !          1183:        /* Request CLO if device appears hung */
        !          1184:        if (ISSET(ahci_pread(ap, AHCI_PREG_TFD), AHCI_PREG_TFD_STS_BSY |
        !          1185:            AHCI_PREG_TFD_STS_DRQ))
        !          1186:                ahci_port_clo(ap);
        !          1187:
        !          1188:        /* Clear port errors to permit TFD transfer */
        !          1189:        ahci_pwrite(ap, AHCI_PREG_SERR, ahci_pread(ap, AHCI_PREG_SERR));
        !          1190:
        !          1191:        /* Restart port */
        !          1192:        if (ahci_port_start(ap, 0)) {
        !          1193:                printf("%s: failed to start port, cannot softreset\n",
        !          1194:                    PORTNAME(ap));
        !          1195:                goto err;
        !          1196:        }
        !          1197:
        !          1198:        /* Check whether CLO worked */
        !          1199:        if (ahci_pwait_clr(ap, AHCI_PREG_TFD,
        !          1200:            AHCI_PREG_TFD_STS_BSY | AHCI_PREG_TFD_STS_DRQ)) {
        !          1201:                printf("%s: CLO %s, need port reset\n", PORTNAME(ap),
        !          1202:                    ISSET(ahci_read(ap->ap_sc, AHCI_REG_CAP), AHCI_REG_CAP_SCLO)
        !          1203:                    ? "failed" : "unsupported");
        !          1204:                rc = EBUSY;
        !          1205:                goto err;
        !          1206:        }
        !          1207:
        !          1208:        /* Prep first D2H command with SRST feature & clear busy/reset flags */
        !          1209:        ccb = ahci_get_err_ccb(ap);
        !          1210:        cmd_slot = ccb->ccb_cmd_hdr;
        !          1211:        bzero(ccb->ccb_cmd_table, sizeof(struct ahci_cmd_table));
        !          1212:
        !          1213:        fis = ccb->ccb_cmd_table->cfis;
        !          1214:        fis[0] = 0x27;  /* Host to device */
        !          1215:        fis[15] = 0x04; /* SRST DEVCTL */
        !          1216:
        !          1217:        cmd_slot->prdtl = 0;
        !          1218:        cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
        !          1219:        cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_C); /* Clear busy on OK */
        !          1220:        cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_R); /* Reset */
        !          1221:        cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_W); /* Write */
        !          1222:
        !          1223:        ccb->ccb_xa.state = ATA_S_PENDING;
        !          1224:        if (ahci_poll(ccb, 1000, NULL) != 0)
        !          1225:                goto err;
        !          1226:
        !          1227:        /* Prep second D2H command to read status and complete reset sequence */
        !          1228:        fis[0] = 0x27;  /* Host to device */
        !          1229:        fis[15] = 0;
        !          1230:
        !          1231:        cmd_slot->prdtl = 0;
        !          1232:        cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
        !          1233:        cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_W);
        !          1234:
        !          1235:        ccb->ccb_xa.state = ATA_S_PENDING;
        !          1236:        if (ahci_poll(ccb, 1000, NULL) != 0)
        !          1237:                goto err;
        !          1238:
        !          1239:        if (ahci_pwait_clr(ap, AHCI_PREG_TFD, AHCI_PREG_TFD_STS_BSY |
        !          1240:            AHCI_PREG_TFD_STS_DRQ | AHCI_PREG_TFD_STS_ERR)) {
        !          1241:                printf("%s: device didn't come ready after reset, TFD: 0x%b\n",
        !          1242:                    PORTNAME(ap), ahci_pread(ap, AHCI_PREG_TFD),
        !          1243:                    AHCI_PFMT_TFD_STS);
        !          1244:                rc = EBUSY;
        !          1245:                goto err;
        !          1246:        }
        !          1247:
        !          1248:        rc = 0;
        !          1249: err:
        !          1250:        if (ccb != NULL) {
        !          1251:                /* Abort our command, if it failed, by stopping command DMA. */
        !          1252:                if (rc != 0 && ISSET(ap->ap_active, 1 << ccb->ccb_slot)) {
        !          1253:                        printf("%s: stopping the port, softreset slot %d was "
        !          1254:                            "still active.\n", PORTNAME(ap), ccb->ccb_slot);
        !          1255:                        ahci_port_stop(ap, 0);
        !          1256:                }
        !          1257:                ccb->ccb_xa.state = ATA_S_ERROR;
        !          1258:                ahci_put_err_ccb(ccb);
        !          1259:        }
        !          1260:
        !          1261:        /* Restore saved CMD register state */
        !          1262:        ahci_pwrite(ap, AHCI_PREG_CMD, cmd);
        !          1263:
        !          1264:        splx(s);
        !          1265:
        !          1266:        return (rc);
        !          1267: }
        !          1268:
        !          1269: /* AHCI port reset, Section 10.4.2 */
        !          1270: int
        !          1271: ahci_port_portreset(struct ahci_port *ap)
        !          1272: {
        !          1273:        u_int32_t                       cmd, r;
        !          1274:        int                             rc;
        !          1275:
        !          1276:        DPRINTF(AHCI_D_VERBOSE, "%s: port reset\n", PORTNAME(ap));
        !          1277:
        !          1278:        /* Save previous command register state */
        !          1279:        cmd = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !          1280:
        !          1281:        /* Clear ST, ignoring failure */
        !          1282:        ahci_port_stop(ap, 0);
        !          1283:
        !          1284:        /* Perform device detection */
        !          1285:        ahci_pwrite(ap, AHCI_PREG_SCTL, 0);
        !          1286:        delay(10000);
        !          1287:        r = AHCI_PREG_SCTL_IPM_DISABLED | AHCI_PREG_SCTL_SPD_ANY |
        !          1288:            AHCI_PREG_SCTL_DET_INIT;
        !          1289:        ahci_pwrite(ap, AHCI_PREG_SCTL, r);
        !          1290:        delay(10000);   /* wait at least 1ms for COMRESET to be sent */
        !          1291:        r &= ~AHCI_PREG_SCTL_DET_INIT;
        !          1292:        r |= AHCI_PREG_SCTL_DET_NONE;
        !          1293:        ahci_pwrite(ap, AHCI_PREG_SCTL, r);
        !          1294:        delay(10000);
        !          1295:
        !          1296:        /* Wait for device to be detected and communications established */
        !          1297:        if (ahci_pwait_eq(ap, AHCI_PREG_SSTS, AHCI_PREG_SSTS_DET,
        !          1298:            AHCI_PREG_SSTS_DET_DEV)) {
        !          1299:                rc = ENODEV;
        !          1300:                goto err;
        !          1301:        }
        !          1302:
        !          1303:        /* Clear SERR (incl X bit), so TFD can update */
        !          1304:        ahci_pwrite(ap, AHCI_PREG_SERR, ahci_pread(ap, AHCI_PREG_SERR));
        !          1305:
        !          1306:        /* Wait for device to become ready */
        !          1307:        /* XXX maybe more than the default wait is appropriate here? */
        !          1308:        if (ahci_pwait_clr(ap, AHCI_PREG_TFD, AHCI_PREG_TFD_STS_BSY |
        !          1309:            AHCI_PREG_TFD_STS_DRQ | AHCI_PREG_TFD_STS_ERR)) {
        !          1310:                rc = EBUSY;
        !          1311:                goto err;
        !          1312:        }
        !          1313:
        !          1314:        rc = 0;
        !          1315: err:
        !          1316:        /* Restore preserved port state */
        !          1317:        ahci_pwrite(ap, AHCI_PREG_CMD, cmd);
        !          1318:
        !          1319:        return (rc);
        !          1320: }
        !          1321:
        !          1322: int
        !          1323: ahci_load_prdt(struct ahci_ccb *ccb)
        !          1324: {
        !          1325:        struct ahci_port                *ap = ccb->ccb_port;
        !          1326:        struct ahci_softc               *sc = ap->ap_sc;
        !          1327:        struct ata_xfer                 *xa = &ccb->ccb_xa;
        !          1328:        struct ahci_prdt                *prdt = ccb->ccb_cmd_table->prdt, *prd;
        !          1329:        bus_dmamap_t                    dmap = ccb->ccb_dmamap;
        !          1330:        struct ahci_cmd_hdr             *cmd_slot = ccb->ccb_cmd_hdr;
        !          1331:        u_int64_t                       addr;
        !          1332:        int                             i, error;
        !          1333:
        !          1334:        if (xa->datalen == 0) {
        !          1335:                ccb->ccb_cmd_hdr->prdtl = 0;
        !          1336:                return (0);
        !          1337:        }
        !          1338:
        !          1339:        error = bus_dmamap_load(sc->sc_dmat, dmap, xa->data, xa->datalen, NULL,
        !          1340:            (xa->flags & ATA_F_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
        !          1341:        if (error != 0) {
        !          1342:                printf("%s: error %d loading dmamap\n", PORTNAME(ap), error);
        !          1343:                return (1);
        !          1344:        }
        !          1345:
        !          1346:        for (i = 0; i < dmap->dm_nsegs; i++) {
        !          1347:                prd = &prdt[i];
        !          1348:
        !          1349:                addr = dmap->dm_segs[i].ds_addr;
        !          1350:                prd->dba_hi = htole32((u_int32_t)(addr >> 32));
        !          1351:                prd->dba_lo = htole32((u_int32_t)addr);
        !          1352: #ifdef DIAGNOSTIC
        !          1353:                if (addr & 1) {
        !          1354:                        printf("%s: requested DMA at an odd address %llx\n",
        !          1355:                            PORTNAME(ap), (unsigned long long)addr);
        !          1356:                        return (1);
        !          1357:                }
        !          1358:                if (dmap->dm_segs[i].ds_len & 1) {
        !          1359:                        printf("%s: requested DMA length %d is not even\n",
        !          1360:                            PORTNAME(ap), (int)dmap->dm_segs[i].ds_len);
        !          1361:                        return (1);
        !          1362:                }
        !          1363: #endif
        !          1364:                prd->flags = htole32(dmap->dm_segs[i].ds_len - 1);
        !          1365:        }
        !          1366:        if (xa->flags & ATA_F_PIO)
        !          1367:                prd->flags |= htole32(AHCI_PRDT_FLAG_INTR);
        !          1368:
        !          1369:        cmd_slot->prdtl = htole16(dmap->dm_nsegs);
        !          1370:
        !          1371:        bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
        !          1372:            (xa->flags & ATA_F_READ) ? BUS_DMASYNC_PREREAD :
        !          1373:            BUS_DMASYNC_PREWRITE);
        !          1374:
        !          1375:        return (0);
        !          1376: }
        !          1377:
        !          1378: void
        !          1379: ahci_unload_prdt(struct ahci_ccb *ccb)
        !          1380: {
        !          1381:        struct ahci_port                *ap = ccb->ccb_port;
        !          1382:        struct ahci_softc               *sc = ap->ap_sc;
        !          1383:        struct ata_xfer                 *xa = &ccb->ccb_xa;
        !          1384:        bus_dmamap_t                    dmap = ccb->ccb_dmamap;
        !          1385:
        !          1386:        if (xa->datalen != 0) {
        !          1387:                bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
        !          1388:                    (xa->flags & ATA_F_READ) ? BUS_DMASYNC_POSTREAD :
        !          1389:                    BUS_DMASYNC_POSTWRITE);
        !          1390:
        !          1391:                bus_dmamap_unload(sc->sc_dmat, dmap);
        !          1392:
        !          1393:                if (ccb->ccb_xa.flags & ATA_F_NCQ)
        !          1394:                        xa->resid = 0;
        !          1395:                else
        !          1396:                        xa->resid = xa->datalen -
        !          1397:                            letoh32(ccb->ccb_cmd_hdr->prdbc);
        !          1398:        }
        !          1399: }
        !          1400:
        !          1401: int
        !          1402: ahci_poll(struct ahci_ccb *ccb, int timeout, void (*timeout_fn)(void *))
        !          1403: {
        !          1404:        struct ahci_port                *ap = ccb->ccb_port;
        !          1405:        int                             s;
        !          1406:
        !          1407:        s = splbio();
        !          1408:        ahci_start(ccb);
        !          1409:        do {
        !          1410:                if (ISSET(ahci_port_intr(ap, AHCI_PREG_CI_ALL_SLOTS),
        !          1411:                    1 << ccb->ccb_slot)) {
        !          1412:                        splx(s);
        !          1413:                        return (0);
        !          1414:                }
        !          1415:
        !          1416:                delay(1000);
        !          1417:        } while (--timeout > 0);
        !          1418:
        !          1419:        /* Run timeout while at splbio, otherwise ahci_intr could interfere. */
        !          1420:        if (timeout_fn != NULL)
        !          1421:                timeout_fn(ccb);
        !          1422:
        !          1423:        splx(s);
        !          1424:
        !          1425:        return (1);
        !          1426: }
        !          1427:
        !          1428: void
        !          1429: ahci_start(struct ahci_ccb *ccb)
        !          1430: {
        !          1431:        struct ahci_port                *ap = ccb->ccb_port;
        !          1432:        struct ahci_softc               *sc = ap->ap_sc;
        !          1433:
        !          1434:        KASSERT(ccb->ccb_xa.state == ATA_S_PENDING);
        !          1435:
        !          1436:        /* Zero transferred byte count before transfer */
        !          1437:        ccb->ccb_cmd_hdr->prdbc = 0;
        !          1438:
        !          1439:        /* Sync command list entry and corresponding command table entry */
        !          1440:        bus_dmamap_sync(sc->sc_dmat, AHCI_DMA_MAP(ap->ap_dmamem_cmd_list),
        !          1441:            ccb->ccb_slot * sizeof(struct ahci_cmd_hdr),
        !          1442:            sizeof(struct ahci_cmd_hdr), BUS_DMASYNC_PREWRITE);
        !          1443:        bus_dmamap_sync(sc->sc_dmat, AHCI_DMA_MAP(ap->ap_dmamem_cmd_table),
        !          1444:            ccb->ccb_slot * sizeof(struct ahci_cmd_table),
        !          1445:            sizeof(struct ahci_cmd_table), BUS_DMASYNC_PREWRITE);
        !          1446:
        !          1447:        /* Prepare RFIS area for write by controller */
        !          1448:        bus_dmamap_sync(sc->sc_dmat, AHCI_DMA_MAP(ap->ap_dmamem_rfis), 0,
        !          1449:            sizeof(struct ahci_rfis), BUS_DMASYNC_PREREAD);
        !          1450:
        !          1451:        if (ccb->ccb_xa.flags & ATA_F_NCQ) {
        !          1452:                /* Issue NCQ commands only when there are no outstanding
        !          1453:                 * standard commands. */
        !          1454:                if (ap->ap_active != 0 || !TAILQ_EMPTY(&ap->ap_ccb_pending))
        !          1455:                        TAILQ_INSERT_TAIL(&ap->ap_ccb_pending, ccb, ccb_entry);
        !          1456:                else {
        !          1457:                        KASSERT(ap->ap_active_cnt == 0);
        !          1458:                        ap->ap_sactive |= (1 << ccb->ccb_slot);
        !          1459:                        ccb->ccb_xa.state = ATA_S_ONCHIP;
        !          1460:                        ahci_pwrite(ap, AHCI_PREG_SACT, 1 << ccb->ccb_slot);
        !          1461:                        ahci_pwrite(ap, AHCI_PREG_CI, 1 << ccb->ccb_slot);
        !          1462:                }
        !          1463:        } else {
        !          1464:                /* Wait for all NCQ commands to finish before issuing standard
        !          1465:                 * command. */
        !          1466:                if (ap->ap_sactive != 0 || ap->ap_active_cnt == 2)
        !          1467:                        TAILQ_INSERT_TAIL(&ap->ap_ccb_pending, ccb, ccb_entry);
        !          1468:                else if (ap->ap_active_cnt < 2) {
        !          1469:                        ap->ap_active |= 1 << ccb->ccb_slot;
        !          1470:                        ccb->ccb_xa.state = ATA_S_ONCHIP;
        !          1471:                        ahci_pwrite(ap, AHCI_PREG_CI, 1 << ccb->ccb_slot);
        !          1472:                        ap->ap_active_cnt++;
        !          1473:                }
        !          1474:        }
        !          1475: }
        !          1476:
        !          1477: void
        !          1478: ahci_issue_pending_ncq_commands(struct ahci_port *ap)
        !          1479: {
        !          1480:        struct ahci_ccb                 *nextccb;
        !          1481:        u_int32_t                       sact_change = 0;
        !          1482:
        !          1483:        KASSERT(ap->ap_active_cnt == 0);
        !          1484:
        !          1485:        nextccb = TAILQ_FIRST(&ap->ap_ccb_pending);
        !          1486:        if (nextccb == NULL || !(nextccb->ccb_xa.flags & ATA_F_NCQ))
        !          1487:                return;
        !          1488:
        !          1489:        /* Start all the NCQ commands at the head of the pending list. */
        !          1490:        do {
        !          1491:                TAILQ_REMOVE(&ap->ap_ccb_pending, nextccb, ccb_entry);
        !          1492:                sact_change |= 1 << nextccb->ccb_slot;
        !          1493:                nextccb->ccb_xa.state = ATA_S_ONCHIP;
        !          1494:                nextccb = TAILQ_FIRST(&ap->ap_ccb_pending);
        !          1495:        } while (nextccb && (nextccb->ccb_xa.flags & ATA_F_NCQ));
        !          1496:
        !          1497:        ap->ap_sactive |= sact_change;
        !          1498:        ahci_pwrite(ap, AHCI_PREG_SACT, sact_change);
        !          1499:        ahci_pwrite(ap, AHCI_PREG_CI, sact_change);
        !          1500:
        !          1501:        return;
        !          1502: }
        !          1503:
        !          1504: void
        !          1505: ahci_issue_pending_commands(struct ahci_port *ap, int last_was_ncq)
        !          1506: {
        !          1507:        struct ahci_ccb                 *nextccb;
        !          1508:
        !          1509:        nextccb = TAILQ_FIRST(&ap->ap_ccb_pending);
        !          1510:        if (nextccb && (nextccb->ccb_xa.flags & ATA_F_NCQ)) {
        !          1511:                KASSERT(last_was_ncq == 0);     /* otherwise it should have
        !          1512:                                                 * been started already. */
        !          1513:
        !          1514:                /* Issue NCQ commands only when there are no outstanding
        !          1515:                 * standard commands. */
        !          1516:                ap->ap_active_cnt--;
        !          1517:                if (ap->ap_active == 0)
        !          1518:                        ahci_issue_pending_ncq_commands(ap);
        !          1519:                else
        !          1520:                        KASSERT(ap->ap_active_cnt == 1);
        !          1521:        } else if (nextccb) {
        !          1522:                if (ap->ap_sactive != 0 || last_was_ncq)
        !          1523:                        KASSERT(ap->ap_active_cnt == 0);
        !          1524:
        !          1525:                /* Wait for all NCQ commands to finish before issuing standard
        !          1526:                 * command. */
        !          1527:                if (ap->ap_sactive != 0)
        !          1528:                        return;
        !          1529:
        !          1530:                /* Keep up to 2 standard commands on-chip at a time. */
        !          1531:                do {
        !          1532:                        TAILQ_REMOVE(&ap->ap_ccb_pending, nextccb, ccb_entry);
        !          1533:                        ap->ap_active |= 1 << nextccb->ccb_slot;
        !          1534:                        nextccb->ccb_xa.state = ATA_S_ONCHIP;
        !          1535:                        ahci_pwrite(ap, AHCI_PREG_CI, 1 << nextccb->ccb_slot);
        !          1536:                        if (last_was_ncq)
        !          1537:                                ap->ap_active_cnt++;
        !          1538:                        if (ap->ap_active_cnt == 2)
        !          1539:                                break;
        !          1540:                        KASSERT(ap->ap_active_cnt == 1);
        !          1541:                        nextccb = TAILQ_FIRST(&ap->ap_ccb_pending);
        !          1542:                } while (nextccb && !(nextccb->ccb_xa.flags & ATA_F_NCQ));
        !          1543:        } else if (!last_was_ncq) {
        !          1544:                KASSERT(ap->ap_active_cnt == 1 || ap->ap_active_cnt == 2);
        !          1545:
        !          1546:                /* Standard command finished, none waiting to start. */
        !          1547:                ap->ap_active_cnt--;
        !          1548:        } else {
        !          1549:                KASSERT(ap->ap_active_cnt == 0);
        !          1550:
        !          1551:                /* NCQ command finished. */
        !          1552:        }
        !          1553: }
        !          1554:
        !          1555: int
        !          1556: ahci_intr(void *arg)
        !          1557: {
        !          1558:        struct ahci_softc               *sc = arg;
        !          1559:        u_int32_t                       is, ack = 0;
        !          1560:        int                             port;
        !          1561:
        !          1562:        /* Read global interrupt status */
        !          1563:        is = ahci_read(sc, AHCI_REG_IS);
        !          1564:        if (is == 0)
        !          1565:                return (0);
        !          1566:        ack = is;
        !          1567:
        !          1568: #ifdef AHCI_COALESCE
        !          1569:        /* Check coalescing interrupt first */
        !          1570:        if (is & sc->sc_ccc_mask) {
        !          1571:                DPRINTF(AHCI_D_INTR, "%s: command coalescing interrupt\n",
        !          1572:                    DEVNAME(sc));
        !          1573:                is &= ~sc->sc_ccc_mask;
        !          1574:                is |= sc->sc_ccc_ports_cur;
        !          1575:        }
        !          1576: #endif
        !          1577:
        !          1578:        /* Process interrupts for each port */
        !          1579:        while (is) {
        !          1580:                port = ffs(is) - 1;
        !          1581:                if (sc->sc_ports[port])
        !          1582:                        ahci_port_intr(sc->sc_ports[port],
        !          1583:                            AHCI_PREG_CI_ALL_SLOTS);
        !          1584:                is &= ~(1 << port);
        !          1585:        }
        !          1586:
        !          1587:        /* Finally, acknowledge global interrupt */
        !          1588:        ahci_write(sc, AHCI_REG_IS, ack);
        !          1589:
        !          1590:        return (1);
        !          1591: }
        !          1592:
        !          1593: u_int32_t
        !          1594: ahci_port_intr(struct ahci_port *ap, u_int32_t ci_mask)
        !          1595: {
        !          1596:        struct ahci_softc               *sc = ap->ap_sc;
        !          1597:        u_int32_t                       is, ci_saved, ci_masked, processed = 0;
        !          1598:        int                             slot, need_restart = 0;
        !          1599:        struct ahci_ccb                 *ccb;
        !          1600:        volatile u_int32_t              *active;
        !          1601: #ifdef DIAGNOSTIC
        !          1602:        u_int32_t                       tmp;
        !          1603: #endif
        !          1604:
        !          1605:        is = ahci_pread(ap, AHCI_PREG_IS);
        !          1606:
        !          1607:        /* Ack port interrupt only if checking all command slots. */
        !          1608:        if (ci_mask == AHCI_PREG_CI_ALL_SLOTS)
        !          1609:                ahci_pwrite(ap, AHCI_PREG_IS, is);
        !          1610:
        !          1611:        if (is)
        !          1612:                DPRINTF(AHCI_D_INTR, "%s: interrupt: %b\n", PORTNAME(ap),
        !          1613:                    is, AHCI_PFMT_IS);
        !          1614:
        !          1615:        if (ap->ap_sactive) {
        !          1616:                /* Active NCQ commands - use SActive instead of CI */
        !          1617:                KASSERT(ap->ap_active == 0);
        !          1618:                KASSERT(ap->ap_active_cnt == 0);
        !          1619:                ci_saved = ahci_pread(ap, AHCI_PREG_SACT);
        !          1620:                active = &ap->ap_sactive;
        !          1621:        } else {
        !          1622:                /* Save CI */
        !          1623:                ci_saved = ahci_pread(ap, AHCI_PREG_CI);
        !          1624:                active = &ap->ap_active;
        !          1625:        }
        !          1626:
        !          1627:        /* Command failed.  See AHCI 1.1 spec 6.2.2.1 and 6.2.2.2. */
        !          1628:        if (is & AHCI_PREG_IS_TFES) {
        !          1629:                u_int32_t               tfd, serr;
        !          1630:                int                     err_slot;
        !          1631:
        !          1632:                tfd = ahci_pread(ap, AHCI_PREG_TFD);
        !          1633:                serr = ahci_pread(ap, AHCI_PREG_SERR);
        !          1634:
        !          1635:                if (ap->ap_sactive == 0) {
        !          1636:                        /* Errored slot is easy to determine from CMD. */
        !          1637:                        err_slot = AHCI_PREG_CMD_CCS(ahci_pread(ap,
        !          1638:                            AHCI_PREG_CMD));
        !          1639:                        ccb = &ap->ap_ccbs[err_slot];
        !          1640:
        !          1641:                        /* Preserve received taskfile data from the RFIS. */
        !          1642:                        memcpy(&ccb->ccb_xa.rfis, ap->ap_rfis->rfis,
        !          1643:                            sizeof(struct ata_fis_d2h));
        !          1644:                } else
        !          1645:                        err_slot = -1;  /* Must extract error from log page */
        !          1646:
        !          1647:                DPRINTF(AHCI_D_VERBOSE, "%s: errored slot %d, TFD: %b, SERR:"
        !          1648:                    " %b, DIAG: %b\n", PORTNAME(ap), err_slot, tfd,
        !          1649:                    AHCI_PFMT_TFD_STS, AHCI_PREG_SERR_ERR(serr),
        !          1650:                    AHCI_PFMT_SERR_ERR, AHCI_PREG_SERR_DIAG(serr),
        !          1651:                    AHCI_PFMT_SERR_DIAG);
        !          1652:
        !          1653:                /* Turn off ST to clear CI and SACT. */
        !          1654:                ahci_port_stop(ap, 0);
        !          1655:                need_restart = 1;
        !          1656:
        !          1657:                /* Clear SERR to enable capturing new errors. */
        !          1658:                ahci_pwrite(ap, AHCI_PREG_SERR, serr);
        !          1659:
        !          1660:                /* Acknowledge the interrupts we can recover from. */
        !          1661:                ahci_pwrite(ap, AHCI_PREG_IS, AHCI_PREG_IS_TFES |
        !          1662:                    AHCI_PREG_IS_IFS);
        !          1663:                is = ahci_pread(ap, AHCI_PREG_IS);
        !          1664:
        !          1665:                /* If device hasn't cleared its busy status, try to idle it. */
        !          1666:                if (ISSET(tfd, AHCI_PREG_TFD_STS_BSY | AHCI_PREG_TFD_STS_DRQ)) {
        !          1667:                        printf("%s: attempting to idle device\n", PORTNAME(ap));
        !          1668:                        if (ahci_port_softreset(ap)) {
        !          1669:                                printf("%s: failed to soft reset device\n",
        !          1670:                                    PORTNAME(ap));
        !          1671:                                if (ahci_port_portreset(ap)) {
        !          1672:                                        printf("%s: failed to port reset "
        !          1673:                                            "device, give up on it\n",
        !          1674:                                            PORTNAME(ap));
        !          1675:                                        goto fatal;
        !          1676:                                }
        !          1677:                        }
        !          1678:
        !          1679:                        /* Had to reset device, can't gather extended info. */
        !          1680:                } else if (ap->ap_sactive) {
        !          1681:                        /* Recover the NCQ error from log page 10h. */
        !          1682:                        ahci_port_read_ncq_error(ap, &err_slot);
        !          1683:                        if (err_slot < 0)
        !          1684:                                goto failall;
        !          1685:
        !          1686:                        DPRINTF(AHCI_D_VERBOSE, "%s: NCQ errored slot %d\n",
        !          1687:                                PORTNAME(ap), err_slot);
        !          1688:
        !          1689:                        ccb = &ap->ap_ccbs[err_slot];
        !          1690:                } else {
        !          1691:                        /* Didn't reset, could gather extended info from log. */
        !          1692:                }
        !          1693:
        !          1694:                /*
        !          1695:                 * If we couldn't determine the errored slot, reset the port
        !          1696:                 * and fail all the active slots.
        !          1697:                 */
        !          1698:                if (err_slot == -1) {
        !          1699:                        if (ahci_port_softreset(ap) != 0 &&
        !          1700:                            ahci_port_portreset(ap) != 0) {
        !          1701:                                printf("%s: couldn't reset after NCQ error, "
        !          1702:                                    "disabling device.\n", PORTNAME(ap));
        !          1703:                                goto fatal;
        !          1704:                        }
        !          1705:                        printf("%s: couldn't recover NCQ error, failing "
        !          1706:                            "all outstanding commands.\n", PORTNAME(ap));
        !          1707:                        goto failall;
        !          1708:                }
        !          1709:
        !          1710:                /* Clear the failed command in saved CI so completion runs. */
        !          1711:                ci_saved &= ~(1 << err_slot);
        !          1712:
        !          1713:                /* Note the error in the ata_xfer. */
        !          1714:                KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
        !          1715:                ccb->ccb_xa.state = ATA_S_ERROR;
        !          1716:
        !          1717: #ifdef DIAGNOSTIC
        !          1718:                /* There may only be one outstanding standard command now. */
        !          1719:                if (ap->ap_sactive == 0) {
        !          1720:                        tmp = ci_saved;
        !          1721:                        if (tmp) {
        !          1722:                                slot = ffs(tmp) - 1;
        !          1723:                                tmp &= ~(1 << slot);
        !          1724:                                KASSERT(tmp == 0);
        !          1725:                        }
        !          1726:                }
        !          1727: #endif
        !          1728:        }
        !          1729:
        !          1730:        /* Check for remaining errors - they are fatal. */
        !          1731:        if (is & (AHCI_PREG_IS_TFES | AHCI_PREG_IS_HBFS | AHCI_PREG_IS_IFS |
        !          1732:            AHCI_PREG_IS_OFS | AHCI_PREG_IS_UFS)) {
        !          1733:                printf("%s: unrecoverable errors (IS: %b), disabling port.\n",
        !          1734:                    PORTNAME(ap), is, AHCI_PFMT_IS);
        !          1735:
        !          1736:                /* XXX try recovery first */
        !          1737:                goto fatal;
        !          1738:        }
        !          1739:
        !          1740:        /* Fail all outstanding commands if we know the port won't recover. */
        !          1741:        if (ap->ap_state == AP_S_FATAL_ERROR) {
        !          1742: fatal:
        !          1743:                ap->ap_state = AP_S_FATAL_ERROR;
        !          1744: failall:
        !          1745:
        !          1746:                /* Ensure port is shut down. */
        !          1747:                ahci_port_stop(ap, 1);
        !          1748:
        !          1749:                /* Error all the active slots. */
        !          1750:                ci_masked = ci_saved & *active;
        !          1751:                while (ci_masked) {
        !          1752:                        slot = ffs(ci_masked) - 1;
        !          1753:                        ccb = &ap->ap_ccbs[slot];
        !          1754:                        ci_masked &= ~(1 << slot);
        !          1755:                        ccb->ccb_xa.state = ATA_S_ERROR;
        !          1756:                }
        !          1757:
        !          1758:                /* Run completion for all active slots. */
        !          1759:                ci_saved &= ~*active;
        !          1760:
        !          1761:                /* Don't restart the port if our problems were deemed fatal. */
        !          1762:                if (ap->ap_state == AP_S_FATAL_ERROR)
        !          1763:                        need_restart = 0;
        !          1764:        }
        !          1765:
        !          1766:        /*
        !          1767:         * CCB completion is detected by noticing its slot's bit in CI has
        !          1768:         * changed to zero some time after we activated it.
        !          1769:         * If we are polling, we may only be interested in particular slot(s).
        !          1770:         */
        !          1771:        ci_masked = ~ci_saved & *active & ci_mask;
        !          1772:        while (ci_masked) {
        !          1773:                slot = ffs(ci_masked) - 1;
        !          1774:                ccb = &ap->ap_ccbs[slot];
        !          1775:                ci_masked &= ~(1 << slot);
        !          1776:
        !          1777:                DPRINTF(AHCI_D_INTR, "%s: slot %d is complete%s\n",
        !          1778:                    PORTNAME(ap), slot, ccb->ccb_xa.state == ATA_S_ERROR ?
        !          1779:                    " (error)" : "");
        !          1780:
        !          1781:                bus_dmamap_sync(sc->sc_dmat,
        !          1782:                    AHCI_DMA_MAP(ap->ap_dmamem_cmd_list),
        !          1783:                    ccb->ccb_slot * sizeof(struct ahci_cmd_hdr),
        !          1784:                    sizeof(struct ahci_cmd_hdr), BUS_DMASYNC_POSTWRITE);
        !          1785:
        !          1786:                bus_dmamap_sync(sc->sc_dmat,
        !          1787:                    AHCI_DMA_MAP(ap->ap_dmamem_cmd_table),
        !          1788:                    ccb->ccb_slot * sizeof(struct ahci_cmd_table),
        !          1789:                    sizeof(struct ahci_cmd_table), BUS_DMASYNC_POSTWRITE);
        !          1790:
        !          1791:                bus_dmamap_sync(sc->sc_dmat,
        !          1792:                    AHCI_DMA_MAP(ap->ap_dmamem_rfis), 0,
        !          1793:                    sizeof(struct ahci_rfis), BUS_DMASYNC_POSTREAD);
        !          1794:
        !          1795:                *active &= ~(1 << ccb->ccb_slot);
        !          1796:                ccb->ccb_done(ccb);
        !          1797:
        !          1798:                processed |= 1 << ccb->ccb_slot;
        !          1799:        }
        !          1800:
        !          1801:        if (need_restart) {
        !          1802:                /* Restart command DMA on the port */
        !          1803:                ahci_port_start(ap, 0);
        !          1804:
        !          1805:                /* Re-enable outstanding commands on port. */
        !          1806:                if (ci_saved) {
        !          1807: #ifdef DIAGNOSTIC
        !          1808:                        tmp = ci_saved;
        !          1809:                        while (tmp) {
        !          1810:                                slot = ffs(tmp) - 1;
        !          1811:                                tmp &= ~(1 << slot);
        !          1812:                                ccb = &ap->ap_ccbs[slot];
        !          1813:                                KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
        !          1814:                                KASSERT((!!(ccb->ccb_xa.flags & ATA_F_NCQ)) ==
        !          1815:                                    (!!ap->ap_sactive));
        !          1816:                        }
        !          1817: #endif
        !          1818:                        DPRINTF(AHCI_D_VERBOSE, "%s: ahci_port_intr "
        !          1819:                            "re-enabling%s slots %08x\n", PORTNAME(ap),
        !          1820:                            ap->ap_sactive ? " NCQ" : "", ci_saved);
        !          1821:
        !          1822:                        if (ap->ap_sactive)
        !          1823:                                ahci_pwrite(ap, AHCI_PREG_SACT, ci_saved);
        !          1824:                        ahci_pwrite(ap, AHCI_PREG_CI, ci_saved);
        !          1825:                }
        !          1826:        }
        !          1827:
        !          1828:        return (processed);
        !          1829: }
        !          1830:
        !          1831: struct ahci_ccb *
        !          1832: ahci_get_ccb(struct ahci_port *ap)
        !          1833: {
        !          1834:        struct ahci_ccb                 *ccb;
        !          1835:
        !          1836:        ccb = TAILQ_FIRST(&ap->ap_ccb_free);
        !          1837:        if (ccb != NULL) {
        !          1838:                KASSERT(ccb->ccb_xa.state == ATA_S_PUT);
        !          1839:                TAILQ_REMOVE(&ap->ap_ccb_free, ccb, ccb_entry);
        !          1840:                ccb->ccb_xa.state = ATA_S_SETUP;
        !          1841:        }
        !          1842:
        !          1843:        return (ccb);
        !          1844: }
        !          1845:
        !          1846: void
        !          1847: ahci_put_ccb(struct ahci_ccb *ccb)
        !          1848: {
        !          1849:        struct ahci_port                *ap = ccb->ccb_port;
        !          1850:
        !          1851: #ifdef DIAGNOSTIC
        !          1852:        if (ccb->ccb_xa.state != ATA_S_COMPLETE &&
        !          1853:            ccb->ccb_xa.state != ATA_S_TIMEOUT &&
        !          1854:            ccb->ccb_xa.state != ATA_S_ERROR) {
        !          1855:                printf("%s: invalid ata_xfer state %02x in ahci_put_ccb, "
        !          1856:                    "slot %d\n", PORTNAME(ccb->ccb_port), ccb->ccb_xa.state,
        !          1857:                    ccb->ccb_slot);
        !          1858:        }
        !          1859: #endif
        !          1860:
        !          1861:        ccb->ccb_xa.state = ATA_S_PUT;
        !          1862:        TAILQ_INSERT_TAIL(&ap->ap_ccb_free, ccb, ccb_entry);
        !          1863: }
        !          1864:
        !          1865: struct ahci_ccb *
        !          1866: ahci_get_err_ccb(struct ahci_port *ap)
        !          1867: {
        !          1868:        struct ahci_ccb *err_ccb;
        !          1869:        u_int32_t sact;
        !          1870:
        !          1871:        splassert(IPL_BIO);
        !          1872:
        !          1873:        /* No commands may be active on the chip. */
        !          1874:        sact = ahci_pread(ap, AHCI_PREG_SACT);
        !          1875:        if (sact != 0)
        !          1876:                printf("ahci_get_err_ccb but SACT %08x != 0?\n", sact);
        !          1877:        KASSERT(ahci_pread(ap, AHCI_PREG_CI) == 0);
        !          1878:
        !          1879: #ifdef DIAGNOSTIC
        !          1880:        KASSERT(ap->ap_err_busy == 0);
        !          1881:        ap->ap_err_busy = 1;
        !          1882: #endif
        !          1883:        /* Save outstanding command state. */
        !          1884:        ap->ap_err_saved_active = ap->ap_active;
        !          1885:        ap->ap_err_saved_active_cnt = ap->ap_active_cnt;
        !          1886:        ap->ap_err_saved_sactive = ap->ap_sactive;
        !          1887:
        !          1888:        /*
        !          1889:         * Pretend we have no commands outstanding, so that completions won't
        !          1890:         * run prematurely.
        !          1891:         */
        !          1892:        ap->ap_active = ap->ap_active_cnt = ap->ap_sactive = 0;
        !          1893:
        !          1894:        /*
        !          1895:         * Grab a CCB to use for error recovery.  This should never fail, as
        !          1896:         * we ask atascsi to reserve one for us at init time.
        !          1897:         */
        !          1898:        err_ccb = ahci_get_ccb(ap);
        !          1899:        KASSERT(err_ccb != NULL);
        !          1900:        err_ccb->ccb_xa.flags = 0;
        !          1901:        err_ccb->ccb_done = ahci_empty_done;
        !          1902:
        !          1903:        return err_ccb;
        !          1904: }
        !          1905:
        !          1906: void
        !          1907: ahci_put_err_ccb(struct ahci_ccb *ccb)
        !          1908: {
        !          1909:        struct ahci_port *ap = ccb->ccb_port;
        !          1910:        u_int32_t sact;
        !          1911:
        !          1912:        splassert(IPL_BIO);
        !          1913:
        !          1914: #ifdef DIAGNOSTIC
        !          1915:        KASSERT(ap->ap_err_busy);
        !          1916: #endif
        !          1917:        /* No commands may be active on the chip */
        !          1918:        sact = ahci_pread(ap, AHCI_PREG_SACT);
        !          1919:        if (sact != 0)
        !          1920:                printf("ahci_port_err_ccb_restore but SACT %08x != 0?\n", sact);
        !          1921:        KASSERT(ahci_pread(ap, AHCI_PREG_CI) == 0);
        !          1922:
        !          1923:        /* Done with the CCB */
        !          1924:        ahci_put_ccb(ccb);
        !          1925:
        !          1926:        /* Restore outstanding command state */
        !          1927:        ap->ap_sactive = ap->ap_err_saved_sactive;
        !          1928:        ap->ap_active_cnt = ap->ap_err_saved_active_cnt;
        !          1929:        ap->ap_active = ap->ap_err_saved_active;
        !          1930:
        !          1931: #ifdef DIAGNOSTIC
        !          1932:        ap->ap_err_busy = 0;
        !          1933: #endif
        !          1934: }
        !          1935:
        !          1936: int
        !          1937: ahci_port_read_ncq_error(struct ahci_port *ap, int *err_slotp)
        !          1938: {
        !          1939:        struct ahci_ccb                 *ccb;
        !          1940:        struct ahci_cmd_hdr             *cmd_slot;
        !          1941:        u_int32_t                       cmd;
        !          1942:        struct ata_fis_h2d              *fis;
        !          1943:        int                             rc = EIO;
        !          1944:
        !          1945:        DPRINTF(AHCI_D_VERBOSE, "%s: read log page\n", PORTNAME(ap));
        !          1946:
        !          1947:        /* Save command register state. */
        !          1948:        cmd = ahci_pread(ap, AHCI_PREG_CMD) & ~AHCI_PREG_CMD_ICC;
        !          1949:
        !          1950:        /* Port should have been idled already.  Start it. */
        !          1951:        KASSERT((cmd & AHCI_PREG_CMD_CR) == 0);
        !          1952:        ahci_port_start(ap, 0);
        !          1953:
        !          1954:        /* Prep error CCB for READ LOG EXT, page 10h, 1 sector. */
        !          1955:        ccb = ahci_get_err_ccb(ap);
        !          1956:        ccb->ccb_xa.flags = ATA_F_NOWAIT | ATA_F_READ | ATA_F_POLL;
        !          1957:        ccb->ccb_xa.data = ap->ap_err_scratch;
        !          1958:        ccb->ccb_xa.datalen = 512;
        !          1959:        cmd_slot = ccb->ccb_cmd_hdr;
        !          1960:        bzero(ccb->ccb_cmd_table, sizeof(struct ahci_cmd_table));
        !          1961:
        !          1962:        fis = (struct ata_fis_h2d *)ccb->ccb_cmd_table->cfis;
        !          1963:        fis->type = ATA_FIS_TYPE_H2D;
        !          1964:        fis->flags = ATA_H2D_FLAGS_CMD;
        !          1965:        fis->command = ATA_C_READ_LOG_EXT;
        !          1966:        fis->lba_low = 0x10;            /* queued error log page (10h) */
        !          1967:        fis->sector_count = 1;          /* number of sectors (1) */
        !          1968:        fis->sector_count_exp = 0;
        !          1969:        fis->lba_mid = 0;               /* starting offset */
        !          1970:        fis->lba_mid_exp = 0;
        !          1971:        fis->device = 0;
        !          1972:
        !          1973:        cmd_slot->flags = htole16(5);   /* FIS length: 5 DWORDS */
        !          1974:
        !          1975:        if (ahci_load_prdt(ccb) != 0) {
        !          1976:                rc = ENOMEM;    /* XXX caller must abort all commands */
        !          1977:                goto err;
        !          1978:        }
        !          1979:
        !          1980:        ccb->ccb_xa.state = ATA_S_PENDING;
        !          1981:        if (ahci_poll(ccb, 1000, NULL) != 0)
        !          1982:                goto err;
        !          1983:
        !          1984:        rc = 0;
        !          1985: err:
        !          1986:        /* Abort our command, if it failed, by stopping command DMA. */
        !          1987:        if (rc != 0 && ISSET(ap->ap_active, 1 << ccb->ccb_slot)) {
        !          1988:                printf("%s: log page read failed, slot %d was still active.\n",
        !          1989:                    PORTNAME(ap), ccb->ccb_slot);
        !          1990:                ahci_port_stop(ap, 0);
        !          1991:        }
        !          1992:
        !          1993:        /* Done with the error CCB now. */
        !          1994:        ahci_unload_prdt(ccb);
        !          1995:        ahci_put_err_ccb(ccb);
        !          1996:
        !          1997:        /* Extract failed register set and tags from the scratch space. */
        !          1998:        if (rc == 0) {
        !          1999:                struct ata_log_page_10h         *log;
        !          2000:                int                             err_slot;
        !          2001:
        !          2002:                log = (struct ata_log_page_10h *)ap->ap_err_scratch;
        !          2003:                if (ISSET(log->err_regs.type, ATA_LOG_10H_TYPE_NOTQUEUED)) {
        !          2004:                        /* Not queued bit was set - wasn't an NCQ error? */
        !          2005:                        printf("%s: read NCQ error page, but not an NCQ "
        !          2006:                            "error?\n", PORTNAME(ap));
        !          2007:                        rc = ESRCH;
        !          2008:                } else {
        !          2009:                        /* Copy back the log record as a D2H register FIS. */
        !          2010:                        *err_slotp = err_slot = log->err_regs.type &
        !          2011:                            ATA_LOG_10H_TYPE_TAG_MASK;
        !          2012:
        !          2013:                        ccb = &ap->ap_ccbs[err_slot];
        !          2014:                        memcpy(&ccb->ccb_xa.rfis, &log->err_regs,
        !          2015:                            sizeof(struct ata_fis_d2h));
        !          2016:                        ccb->ccb_xa.rfis.type = ATA_FIS_TYPE_D2H;
        !          2017:                        ccb->ccb_xa.rfis.flags = 0;
        !          2018:                }
        !          2019:        }
        !          2020:
        !          2021:        /* Restore saved CMD register state */
        !          2022:        ahci_pwrite(ap, AHCI_PREG_CMD, cmd);
        !          2023:
        !          2024:        return (rc);
        !          2025: }
        !          2026:
        !          2027: struct ahci_dmamem *
        !          2028: ahci_dmamem_alloc(struct ahci_softc *sc, size_t size)
        !          2029: {
        !          2030:        struct ahci_dmamem              *adm;
        !          2031:        int                             nsegs;
        !          2032:
        !          2033:        adm = malloc(sizeof(struct ahci_dmamem), M_DEVBUF, M_NOWAIT);
        !          2034:        if (adm == NULL)
        !          2035:                return (NULL);
        !          2036:
        !          2037:        bzero(adm, sizeof(struct ahci_dmamem));
        !          2038:        adm->adm_size = size;
        !          2039:
        !          2040:        if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
        !          2041:            BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &adm->adm_map) != 0)
        !          2042:                goto admfree;
        !          2043:
        !          2044:        if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &adm->adm_seg,
        !          2045:            1, &nsegs, BUS_DMA_NOWAIT) != 0)
        !          2046:                goto destroy;
        !          2047:
        !          2048:        if (bus_dmamem_map(sc->sc_dmat, &adm->adm_seg, nsegs, size,
        !          2049:            &adm->adm_kva, BUS_DMA_NOWAIT) != 0)
        !          2050:                goto free;
        !          2051:
        !          2052:        if (bus_dmamap_load(sc->sc_dmat, adm->adm_map, adm->adm_kva, size,
        !          2053:            NULL, BUS_DMA_NOWAIT) != 0)
        !          2054:                goto unmap;
        !          2055:
        !          2056:        bzero(adm->adm_kva, size);
        !          2057:
        !          2058:        return (adm);
        !          2059:
        !          2060: unmap:
        !          2061:        bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, size);
        !          2062: free:
        !          2063:        bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1);
        !          2064: destroy:
        !          2065:        bus_dmamap_destroy(sc->sc_dmat, adm->adm_map);
        !          2066: admfree:
        !          2067:        free(adm, M_DEVBUF);
        !          2068:
        !          2069:        return (NULL);
        !          2070: }
        !          2071:
        !          2072: void
        !          2073: ahci_dmamem_free(struct ahci_softc *sc, struct ahci_dmamem *adm)
        !          2074: {
        !          2075:        bus_dmamap_unload(sc->sc_dmat, adm->adm_map);
        !          2076:        bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, adm->adm_size);
        !          2077:        bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1);
        !          2078:        bus_dmamap_destroy(sc->sc_dmat, adm->adm_map);
        !          2079:        free(adm, M_DEVBUF);
        !          2080: }
        !          2081:
        !          2082: u_int32_t
        !          2083: ahci_read(struct ahci_softc *sc, bus_size_t r)
        !          2084: {
        !          2085:        bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
        !          2086:            BUS_SPACE_BARRIER_READ);
        !          2087:        return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, r));
        !          2088: }
        !          2089:
        !          2090: void
        !          2091: ahci_write(struct ahci_softc *sc, bus_size_t r, u_int32_t v)
        !          2092: {
        !          2093:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
        !          2094:        bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
        !          2095:            BUS_SPACE_BARRIER_WRITE);
        !          2096: }
        !          2097:
        !          2098: int
        !          2099: ahci_wait_ne(struct ahci_softc *sc, bus_size_t r, u_int32_t mask,
        !          2100:     u_int32_t target)
        !          2101: {
        !          2102:        int                             i;
        !          2103:
        !          2104:        for (i = 0; i < 1000; i++) {
        !          2105:                if ((ahci_read(sc, r) & mask) != target)
        !          2106:                        return (0);
        !          2107:                delay(1000);
        !          2108:        }
        !          2109:
        !          2110:        return (1);
        !          2111: }
        !          2112:
        !          2113: u_int32_t
        !          2114: ahci_pread(struct ahci_port *ap, bus_size_t r)
        !          2115: {
        !          2116:        bus_space_barrier(ap->ap_sc->sc_iot, ap->ap_ioh, r, 4,
        !          2117:            BUS_SPACE_BARRIER_READ);
        !          2118:        return (bus_space_read_4(ap->ap_sc->sc_iot, ap->ap_ioh, r));
        !          2119: }
        !          2120:
        !          2121: void
        !          2122: ahci_pwrite(struct ahci_port *ap, bus_size_t r, u_int32_t v)
        !          2123: {
        !          2124:        bus_space_write_4(ap->ap_sc->sc_iot, ap->ap_ioh, r, v);
        !          2125:        bus_space_barrier(ap->ap_sc->sc_iot, ap->ap_ioh, r, 4,
        !          2126:            BUS_SPACE_BARRIER_WRITE);
        !          2127: }
        !          2128:
        !          2129: int
        !          2130: ahci_pwait_eq(struct ahci_port *ap, bus_size_t r, u_int32_t mask,
        !          2131:     u_int32_t target)
        !          2132: {
        !          2133:        int                             i;
        !          2134:
        !          2135:        for (i = 0; i < 1000; i++) {
        !          2136:                if ((ahci_pread(ap, r) & mask) == target)
        !          2137:                        return (0);
        !          2138:                delay(1000);
        !          2139:        }
        !          2140:
        !          2141:        return (1);
        !          2142: }
        !          2143:
        !          2144: int
        !          2145: ahci_ata_probe(void *xsc, int port)
        !          2146: {
        !          2147:        struct ahci_softc               *sc = xsc;
        !          2148:        struct ahci_port                *ap = sc->sc_ports[port];
        !          2149:        u_int32_t                       sig;
        !          2150:
        !          2151:        if (ap == NULL)
        !          2152:                return (ATA_PORT_T_NONE);
        !          2153:
        !          2154:        sig = ahci_pread(ap, AHCI_PREG_SIG);
        !          2155:        if ((sig & 0xffff0000) == (SATA_SIGNATURE_ATAPI & 0xffff0000))
        !          2156:                return (ATA_PORT_T_ATAPI);
        !          2157:        else
        !          2158:                return (ATA_PORT_T_DISK);
        !          2159: }
        !          2160:
        !          2161: struct ata_xfer *
        !          2162: ahci_ata_get_xfer(void *aaa_cookie, int port)
        !          2163: {
        !          2164:        struct ahci_softc               *sc = aaa_cookie;
        !          2165:        struct ahci_port                *ap = sc->sc_ports[port];
        !          2166:        struct ahci_ccb                 *ccb;
        !          2167:
        !          2168:        splassert(IPL_BIO);
        !          2169:
        !          2170:        ccb = ahci_get_ccb(ap);
        !          2171:        if (ccb == NULL) {
        !          2172:                DPRINTF(AHCI_D_XFER, "%s: ahci_ata_get_xfer: NULL ccb\n",
        !          2173:                    PORTNAME(ap));
        !          2174:                return (NULL);
        !          2175:        }
        !          2176:
        !          2177:        DPRINTF(AHCI_D_XFER, "%s: ahci_ata_get_xfer got slot %d\n",
        !          2178:            PORTNAME(ap), ccb->ccb_slot);
        !          2179:
        !          2180:        return ((struct ata_xfer *)ccb);
        !          2181: }
        !          2182:
        !          2183: void
        !          2184: ahci_ata_put_xfer(struct ata_xfer *xa)
        !          2185: {
        !          2186:        struct ahci_ccb                 *ccb = (struct ahci_ccb *)xa;
        !          2187:
        !          2188:        splassert(IPL_BIO);
        !          2189:
        !          2190:        DPRINTF(AHCI_D_XFER, "ahci_ata_put_xfer slot %d\n", ccb->ccb_slot);
        !          2191:
        !          2192:        ahci_put_ccb(ccb);
        !          2193: }
        !          2194:
        !          2195: int
        !          2196: ahci_ata_cmd(struct ata_xfer *xa)
        !          2197: {
        !          2198:        struct ahci_ccb                 *ccb = (struct ahci_ccb *)xa;
        !          2199:        struct ahci_cmd_hdr             *cmd_slot;
        !          2200:        int                             s;
        !          2201:
        !          2202:        KASSERT(xa->state == ATA_S_SETUP);
        !          2203:
        !          2204:        if (ccb->ccb_port->ap_state == AP_S_FATAL_ERROR)
        !          2205:                goto failcmd;
        !          2206:
        !          2207:        ccb->ccb_done = ahci_ata_cmd_done;
        !          2208:
        !          2209:        cmd_slot = ccb->ccb_cmd_hdr;
        !          2210:        cmd_slot->flags = htole16(5); /* FIS length (in DWORDs) */
        !          2211:
        !          2212:        if (xa->flags & ATA_F_WRITE)
        !          2213:                cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_W);
        !          2214:
        !          2215:        if (xa->flags & ATA_F_PACKET)
        !          2216:                cmd_slot->flags |= htole16(AHCI_CMD_LIST_FLAG_A);
        !          2217:
        !          2218:        if (ahci_load_prdt(ccb) != 0)
        !          2219:                goto failcmd;
        !          2220:
        !          2221:        timeout_set(&xa->stimeout, ahci_ata_cmd_timeout, ccb);
        !          2222:
        !          2223:        xa->state = ATA_S_PENDING;
        !          2224:
        !          2225:        if (xa->flags & ATA_F_POLL) {
        !          2226:                ahci_poll(ccb, xa->timeout, ahci_ata_cmd_timeout);
        !          2227:                return (ATA_COMPLETE);
        !          2228:        }
        !          2229:
        !          2230:        timeout_add(&xa->stimeout, (xa->timeout * hz) / 1000);
        !          2231:
        !          2232:        s = splbio();
        !          2233:        ahci_start(ccb);
        !          2234:        splx(s);
        !          2235:        return (ATA_QUEUED);
        !          2236:
        !          2237: failcmd:
        !          2238:        s = splbio();
        !          2239:        xa->state = ATA_S_ERROR;
        !          2240:        xa->complete(xa);
        !          2241:        splx(s);
        !          2242:        return (ATA_ERROR);
        !          2243: }
        !          2244:
        !          2245: void
        !          2246: ahci_ata_cmd_done(struct ahci_ccb *ccb)
        !          2247: {
        !          2248:        struct ata_xfer                 *xa = &ccb->ccb_xa;
        !          2249:
        !          2250:        timeout_del(&xa->stimeout);
        !          2251:
        !          2252:        if (xa->state == ATA_S_ONCHIP || xa->state == ATA_S_ERROR)
        !          2253:                ahci_issue_pending_commands(ccb->ccb_port,
        !          2254:                    xa->flags & ATA_F_NCQ);
        !          2255:
        !          2256:        ahci_unload_prdt(ccb);
        !          2257:
        !          2258:        if (xa->state == ATA_S_ONCHIP)
        !          2259:                xa->state = ATA_S_COMPLETE;
        !          2260: #ifdef DIAGNOSTIC
        !          2261:        else if (xa->state != ATA_S_ERROR && xa->state != ATA_S_TIMEOUT)
        !          2262:                printf("%s: invalid ata_xfer state %02x in ahci_ata_cmd_done, "
        !          2263:                    "slot %d\n", PORTNAME(ccb->ccb_port), xa->state,
        !          2264:                    ccb->ccb_slot);
        !          2265: #endif
        !          2266:        if (xa->state != ATA_S_TIMEOUT)
        !          2267:                xa->complete(xa);
        !          2268: }
        !          2269:
        !          2270: void
        !          2271: ahci_ata_cmd_timeout(void *arg)
        !          2272: {
        !          2273:        struct ahci_ccb                 *ccb = arg;
        !          2274:        struct ata_xfer                 *xa = &ccb->ccb_xa;
        !          2275:        struct ahci_port                *ap = ccb->ccb_port;
        !          2276:        int                             s, ccb_was_started, ncq_cmd;
        !          2277:        volatile u_int32_t              *active;
        !          2278:
        !          2279:        s = splbio();
        !          2280:
        !          2281:        ncq_cmd = (xa->flags & ATA_F_NCQ);
        !          2282:        active = ncq_cmd ? &ap->ap_sactive : &ap->ap_active;
        !          2283:
        !          2284:        if (ccb->ccb_xa.state == ATA_S_PENDING) {
        !          2285:                DPRINTF(AHCI_D_TIMEOUT, "%s: command for slot %d timed out "
        !          2286:                    "before it got on chip\n", PORTNAME(ap), ccb->ccb_slot);
        !          2287:                TAILQ_REMOVE(&ap->ap_ccb_pending, ccb, ccb_entry);
        !          2288:                ccb_was_started = 0;
        !          2289:        } else if (ccb->ccb_xa.state == ATA_S_ONCHIP && ahci_port_intr(ap,
        !          2290:            1 << ccb->ccb_slot)) {
        !          2291:                DPRINTF(AHCI_D_TIMEOUT, "%s: final poll of port completed "
        !          2292:                    "command in slot %d\n", PORTNAME(ap), ccb->ccb_slot);
        !          2293:                goto ret;
        !          2294:        } else if (ccb->ccb_xa.state != ATA_S_ONCHIP) {
        !          2295:                DPRINTF(AHCI_D_TIMEOUT, "%s: command slot %d already "
        !          2296:                    "handled%s\n", PORTNAME(ap), ccb->ccb_slot,
        !          2297:                    ISSET(*active, 1 << ccb->ccb_slot) ?
        !          2298:                    " but slot is still active?" : ".");
        !          2299:                goto ret;
        !          2300:        } else if (!ISSET(ahci_pread(ap, ncq_cmd ? AHCI_PREG_SACT :
        !          2301:            AHCI_PREG_CI), 1 << ccb->ccb_slot) && ISSET(*active,
        !          2302:            1 << ccb->ccb_slot)) {
        !          2303:                DPRINTF(AHCI_D_TIMEOUT, "%s: command slot %d completed but "
        !          2304:                    "IRQ handler didn't detect it.  Why?\n", PORTNAME(ap),
        !          2305:                    ccb->ccb_slot);
        !          2306:                *active &= ~(1 << ccb->ccb_slot);
        !          2307:                ccb->ccb_done(ccb);
        !          2308:                goto ret;
        !          2309:        } else {
        !          2310:                ccb_was_started = 1;
        !          2311:        }
        !          2312:
        !          2313:        /* Complete the slot with a timeout error. */
        !          2314:        ccb->ccb_xa.state = ATA_S_TIMEOUT;
        !          2315:        *active &= ~(1 << ccb->ccb_slot);
        !          2316:        DPRINTF(AHCI_D_TIMEOUT, "%s: run completion (1)\n", PORTNAME(ap));
        !          2317:        ccb->ccb_done(ccb);     /* This won't issue pending commands or run the
        !          2318:                                   atascsi completion. */
        !          2319:
        !          2320:        /* Reset port to abort running command. */
        !          2321:        if (ccb_was_started) {
        !          2322:                DPRINTF(AHCI_D_TIMEOUT, "%s: resetting port to abort%s command "
        !          2323:                    "in slot %d, active %08x\n", PORTNAME(ap), ncq_cmd ? " NCQ"
        !          2324:                    : "", ccb->ccb_slot, *active);
        !          2325:                if (ahci_port_softreset(ap) != 0 && ahci_port_portreset(ap)
        !          2326:                    != 0) {
        !          2327:                        printf("%s: failed to reset port during timeout "
        !          2328:                            "handling, disabling it\n", PORTNAME(ap));
        !          2329:                        ap->ap_state = AP_S_FATAL_ERROR;
        !          2330:                }
        !          2331:
        !          2332:                /* Restart any other commands that were aborted by the reset. */
        !          2333:                if (*active) {
        !          2334:                        DPRINTF(AHCI_D_TIMEOUT, "%s: re-enabling%s slots "
        !          2335:                            "%08x\n", PORTNAME(ap), ncq_cmd ? " NCQ" : "",
        !          2336:                            *active);
        !          2337:                        if (ncq_cmd)
        !          2338:                                ahci_pwrite(ap, AHCI_PREG_SACT, *active);
        !          2339:                        ahci_pwrite(ap, AHCI_PREG_CI, *active);
        !          2340:                }
        !          2341:        }
        !          2342:
        !          2343:        /* Issue any pending commands now. */
        !          2344:        DPRINTF(AHCI_D_TIMEOUT, "%s: issue pending\n", PORTNAME(ap));
        !          2345:        if (ccb_was_started)
        !          2346:                ahci_issue_pending_commands(ap, ncq_cmd);
        !          2347:        else if (ap->ap_active == 0)
        !          2348:                ahci_issue_pending_ncq_commands(ap);
        !          2349:
        !          2350:        /* Complete the timed out ata_xfer I/O (may generate new I/O). */
        !          2351:        DPRINTF(AHCI_D_TIMEOUT, "%s: run completion (2)\n", PORTNAME(ap));
        !          2352:        xa->complete(xa);
        !          2353:
        !          2354:        DPRINTF(AHCI_D_TIMEOUT, "%s: splx\n", PORTNAME(ap));
        !          2355: ret:
        !          2356:        splx(s);
        !          2357: }
        !          2358:
        !          2359: void
        !          2360: ahci_empty_done(struct ahci_ccb *ccb)
        !          2361: {
        !          2362:        ccb->ccb_xa.state = ATA_S_COMPLETE;
        !          2363: }

CVSweb