11ac8d5baSMatthew Dillon /* 21ac8d5baSMatthew Dillon * Copyright (c) 2006 David Gwynne <dlg@openbsd.org> 31ac8d5baSMatthew Dillon * 41ac8d5baSMatthew Dillon * Permission to use, copy, modify, and distribute this software for any 51ac8d5baSMatthew Dillon * purpose with or without fee is hereby granted, provided that the above 61ac8d5baSMatthew Dillon * copyright notice and this permission notice appear in all copies. 71ac8d5baSMatthew Dillon * 81ac8d5baSMatthew Dillon * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 91ac8d5baSMatthew Dillon * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 101ac8d5baSMatthew Dillon * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 111ac8d5baSMatthew Dillon * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 121ac8d5baSMatthew Dillon * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 131ac8d5baSMatthew Dillon * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 141ac8d5baSMatthew Dillon * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 151ac8d5baSMatthew Dillon * 161ac8d5baSMatthew Dillon * $OpenBSD: sili.c,v 1.147 2009/02/16 21:19:07 miod Exp $ 171ac8d5baSMatthew Dillon */ 181ac8d5baSMatthew Dillon 191ac8d5baSMatthew Dillon #if defined(__DragonFly__) 201ac8d5baSMatthew Dillon #include "sili_dragonfly.h" 211ac8d5baSMatthew Dillon #else 221ac8d5baSMatthew Dillon #error "build for OS unknown" 231ac8d5baSMatthew Dillon #endif 241ac8d5baSMatthew Dillon #include "pmreg.h" 251ac8d5baSMatthew Dillon #include "atascsi.h" 261ac8d5baSMatthew Dillon 271ac8d5baSMatthew Dillon /* change to SILI_DEBUG for dmesg spam */ 281ac8d5baSMatthew Dillon #define NO_SILI_DEBUG 291ac8d5baSMatthew Dillon 301ac8d5baSMatthew Dillon #ifdef SILI_DEBUG 311ac8d5baSMatthew Dillon #define DPRINTF(m, f...) do { if ((silidebug & (m)) == (m)) kprintf(f); } \ 321ac8d5baSMatthew Dillon while (0) 331ac8d5baSMatthew Dillon #define SILI_D_TIMEOUT 0x00 341ac8d5baSMatthew Dillon #define SILI_D_VERBOSE 0x01 351ac8d5baSMatthew Dillon #define SILI_D_INTR 0x02 361ac8d5baSMatthew Dillon #define SILI_D_XFER 0x08 371ac8d5baSMatthew Dillon int silidebug = SILI_D_VERBOSE; 381ac8d5baSMatthew Dillon #else 391ac8d5baSMatthew Dillon #define DPRINTF(m, f...) 401ac8d5baSMatthew Dillon #endif 411ac8d5baSMatthew Dillon 421ac8d5baSMatthew Dillon /* 431ac8d5baSMatthew Dillon * BAR0 - Global Registers 128-byte aligned, 128-byte region 441ac8d5baSMatthew Dillon * BAR1 - Port Registers and LRAM 32KB-aligned 451ac8d5baSMatthew Dillon * BAR2 - Indirect I/O registers (we don't use this) 461ac8d5baSMatthew Dillon */ 471ac8d5baSMatthew Dillon 481ac8d5baSMatthew Dillon /* 491ac8d5baSMatthew Dillon * Port-N Slot Status. 501ac8d5baSMatthew Dillon * 511ac8d5baSMatthew Dillon * NOTE: Mirrors SILI_PREG_SLOTST 521ac8d5baSMatthew Dillon */ 531ac8d5baSMatthew Dillon #define SILI_REG_SLOTST(n) (0x0000 + ((n) * 4)) 541ac8d5baSMatthew Dillon #define SILI_REG_SLOTST_ATTN 0x80000000 /* attention required */ 551ac8d5baSMatthew Dillon 561ac8d5baSMatthew Dillon #define SILI_REG_GCTL 0x0040 /* Global Control */ 571ac8d5baSMatthew Dillon #define SILI_REG_GCTL_PORTEN(n) (1 << (n)) /* Port interrupt ena */ 581ac8d5baSMatthew Dillon #define SILI_REG_GCTL_300CAP 0x01000000 /* 3Gb/s capable (R) */ 591ac8d5baSMatthew Dillon #define SILI_REG_GCTL_I2C_IEN 0x20000000 /* I2C Int enable */ 601ac8d5baSMatthew Dillon #define SILI_REG_GCTL_MSIACK 0x40000000 /* MSI Ack W1C */ 611ac8d5baSMatthew Dillon #define SILI_REG_GCTL_GRESET 0x80000000 /* global reset */ 621ac8d5baSMatthew Dillon 631ac8d5baSMatthew Dillon #define SILI_REG_GINT 0x0044 /* Global Interrupt Status */ 641ac8d5baSMatthew Dillon #define SILI_REG_GINT_I2C 0x20000000 /* I2C Int Status */ 651ac8d5baSMatthew Dillon #define SILI_REG_GINT_PORTST(n) (1 << (n)) /* Port interrupt stat */ 661ac8d5baSMatthew Dillon #define SILI_REG_GINT_PORTMASK 0x0000FFFF 671ac8d5baSMatthew Dillon 681ac8d5baSMatthew Dillon /* 691ac8d5baSMatthew Dillon * Most bits in phyconf should not be modified. Setting the low four bits 701ac8d5baSMatthew Dillon * to 1's, all channel Tx outputs spread spectrum clocking. 711ac8d5baSMatthew Dillon */ 721ac8d5baSMatthew Dillon #define SILI_REG_PHYCONF 0x0048 /* PHY Configuration */ 731ac8d5baSMatthew Dillon #define SILI_REG_PHYCONF_ALLSS 0x000F /* spread spectrum tx */ 741ac8d5baSMatthew Dillon 751ac8d5baSMatthew Dillon /* 761ac8d5baSMatthew Dillon * BIST_CTL_TEN - Enable data paths for running data loopback BIST 771ac8d5baSMatthew Dillon * BIST_CTL_TPAT - Select repeating pattern (1) or pseudo-random 781ac8d5baSMatthew Dillon * pattern (0) 791ac8d5baSMatthew Dillon * BIST_CTL_RXSEL- Select the rx port for pattern comparison 801ac8d5baSMatthew Dillon * BIST_CTL_TXSEL- Select the tx ports that transmit loopback data 811ac8d5baSMatthew Dillon */ 821ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL 0x0050 831ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_TEN 0x80000000 841ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_TPAT 0x40000000 851ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_RXSEL(n) ((n) << 16) 861ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_TXSEL(n) (1 << (n)) 871ac8d5baSMatthew Dillon 881ac8d5baSMatthew Dillon #define SILI_REG_BIST_PATTERN 0x0054 /* 32 bit pattern */ 891ac8d5baSMatthew Dillon 901ac8d5baSMatthew Dillon /* 911ac8d5baSMatthew Dillon * GOOD is set to 1 on BIST initiation, and reset to 0 on the first 921ac8d5baSMatthew Dillon * comparison failure. 931ac8d5baSMatthew Dillon */ 941ac8d5baSMatthew Dillon #define SILI_REG_BIST_STATUS 0x0058 951ac8d5baSMatthew Dillon #define SILI_REG_BIST_STATUS_CNT 0x000007FF /* pattern counter */ 961ac8d5baSMatthew Dillon #define SILI_REG_BIST_STATUS_GOOD 0x80000000 /* set to 0 on compare fail */ 971ac8d5baSMatthew Dillon 981ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL 0x0060 991ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_START 0x00000001 1001ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_STOP 0x00000002 1011ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_NACK 0x00000004 /* send nack on data byte rx */ 1021ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_TFDATA 0x00000008 /* set to initiate txfer */ 1031ac8d5baSMatthew Dillon /* to/from data buffer */ 1041ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_MABORT 0x00000010 /* set w/STOP to send stop */ 1051ac8d5baSMatthew Dillon /* without first xfering a */ 1061ac8d5baSMatthew Dillon /* byte */ 1071ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_SCLEN 0x00000020 /* clock-en for master mode */ 1081ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_UNITEN 0x00000040 /* enable controller */ 1091ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_GCALLD 0x00000080 /* Disable detect of a */ 1101ac8d5baSMatthew Dillon /* general call address */ 1111ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_TXBEI 0x00000100 /* xmit buffer empty int en */ 1121ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_RXBFI 0x00000200 /* rx buffer full int en */ 1131ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_BERRI 0x00000400 /* bus error int en */ 1141ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_STOPI 0x00000800 /* stop detect int en */ 1151ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_ARBLI 0x00001000 /* arb loss int en */ 1161ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_ARBDI 0x00002000 /* arb detect int en */ 1171ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_UNITRS 0x00004000 /* reset I2C controller */ 1181ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_FASTM 0x00008000 /* 400kbit/s (else 100kbit/s)*/ 1191ac8d5baSMatthew Dillon 1201ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS 0x0064 1211ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_RW 0x00000001 1221ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_ACKSTS 0x00000002 /* ack/nack status(R) last */ 1231ac8d5baSMatthew Dillon /* ack or nack sent or rcvd */ 1241ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_UNTBSY 0x00000004 /* unit busy (R) */ 1251ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_BUSBSY 0x00000008 /* bus busy with activity(R) */ 1261ac8d5baSMatthew Dillon /* other then from controller*/ 1271ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_STOPDT 0x00000010 /* stop detect (R/W1C) */ 1281ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_ARBLD 0x00000020 /* arb loss detect (R/W1C) */ 1291ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_TXBED 0x00000040 /* tx buffer empty (R) */ 1301ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_RXBFD 0x00000080 /* rx buffer full (R/W1C) */ 1311ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_GCALLD 0x00000100 /* Gen Call detect (R/W1C) */ 1321ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_SADDRD 0x00000200 /* Slave addr detect (R/W1C) */ 1331ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_BERRD 0x00000400 /* Bus error detect (R/W1C) */ 1341ac8d5baSMatthew Dillon 1351ac8d5baSMatthew Dillon #define SILI_REG_I2C_SADDR 0x0068 /* our slave address */ 1361ac8d5baSMatthew Dillon #define SILI_REG_I2C_SADDR_MASK 0x0000003F /* 6 bits */ 1371ac8d5baSMatthew Dillon 1381ac8d5baSMatthew Dillon #define SILI_REG_I2C_DATA 0x006C /* data buffer (8 bits) */ 1391ac8d5baSMatthew Dillon 1401ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR 0x0070 /* Flash control & addr reg */ 1411ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MEMPRS 0x04000000 /* Flash memory present */ 1421ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_GPIOEN 0x80000000 /* use flash data pins for */ 1431ac8d5baSMatthew Dillon /* GPIO */ 1441ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MEMST 0x02000000 /* Mem Access Start (R/W) */ 1451ac8d5baSMatthew Dillon /* (clears on op complete) */ 1461ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MEMRD 0x01000000 /* 0=write, 1=read */ 1471ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MASK 0x0003FFFF /* 18 bit memory address */ 1481ac8d5baSMatthew Dillon 1491ac8d5baSMatthew Dillon /* 1501ac8d5baSMatthew Dillon * NOTE: In order to set a GPIO pin to read the DATA bit must be written to 1511ac8d5baSMatthew Dillon * 1and the DCTL (drain control) bit must be written to 1 as well 1521ac8d5baSMatthew Dillon * to make it open-drain only (drive on low only). 1531ac8d5baSMatthew Dillon */ 1541ac8d5baSMatthew Dillon #define SILI_REG_GPIO 0x0074 1551ac8d5baSMatthew Dillon #define SILI_REG_GPIO_DATA_SHIFT 0 /* 8 bits Flash or GPIO data */ 1561ac8d5baSMatthew Dillon #define SILI_REG_GPIO_TDET_SHIFT 8 /* 8 bits transition detect */ 1571ac8d5baSMatthew Dillon #define SILI_REG_GPIO_DCTL_SHIFT 16 /* 8 bits drain control */ 1581ac8d5baSMatthew Dillon 1591ac8d5baSMatthew Dillon /* 1601ac8d5baSMatthew Dillon * Per-port registers 1611ac8d5baSMatthew Dillon * 1621ac8d5baSMatthew Dillon */ 1631ac8d5baSMatthew Dillon 1641ac8d5baSMatthew Dillon #define SILI_PORT_REGION(port) (8192 * (port)) 1651ac8d5baSMatthew Dillon #define SILI_PORT_SIZE 8192 1661ac8d5baSMatthew Dillon #define SILI_PREG_LRAM 0x0000 /* 0x0000-0x0F7F */ 1671ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_SLOT(n) (0x0000 + (128 * (n))) 1681ac8d5baSMatthew Dillon 1691ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_SLOT_FIS 0x0000 /* Current FIS and Control */ 1701ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_DMA0 0x0020 /* DMA Entry 0 or ATAPI cmd */ 1711ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_DMA1 0x0030 /* DMA Entry 0 or ATAPI cmd */ 1721ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_CMDACT 0x0040 /* Cmd Act Reg (actual) 64b */ 1731ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_DMATAB 0x0040 /* Scatter Gather Table */ 1741ac8d5baSMatthew Dillon 1751ac8d5baSMatthew Dillon /* 1761ac8d5baSMatthew Dillon * Each port has a port status and qactive register for each target behind 1771ac8d5baSMatthew Dillon * the port multiplier, if there is a port multiplier. 1781ac8d5baSMatthew Dillon * 1791ac8d5baSMatthew Dillon * SERVICE - Service received from device, service command from controller 1801ac8d5baSMatthew Dillon * not yet acknowledged. 1811ac8d5baSMatthew Dillon * 1821ac8d5baSMatthew Dillon * LEGACY - One or more legacy queued commands is outstanding. 1831ac8d5baSMatthew Dillon * 1841ac8d5baSMatthew Dillon * NATIVE - One or more NCQ queued commands is outstanding. 1851ac8d5baSMatthew Dillon * 1861ac8d5baSMatthew Dillon * VBSY - A virtual device busy indicating that a command has been issued 1871ac8d5baSMatthew Dillon * to the device and the device has not yet sent the final D2H 1881ac8d5baSMatthew Dillon * register FIS, or that a data transfer is in progress. 1891ac8d5baSMatthew Dillon * 1901ac8d5baSMatthew Dillon * The PM_QACTIVE register contains a demultiplexed bitmap of slots queued 1911ac8d5baSMatthew Dillon * to each target behind the port multiplier. 1921ac8d5baSMatthew Dillon * 1931ac8d5baSMatthew Dillon */ 1941ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS(n) (0x0F80 + (8 * (n))) 1951ac8d5baSMatthew Dillon #define SILI_PREG_PM_QACTIVE(n) (0x0F84 + (8 * (n))) 1961ac8d5baSMatthew Dillon 1971ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_SERVICE 0x00010000 /* Service pending */ 1981ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_LEGACY 0x00008000 /* Legacy outstanding*/ 1991ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_NATIVE 0x00004000 /* NCQ outstanding */ 2001ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_VBSY 0x00002000 /* virtual dev busy */ 2011ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_EXEC_SHIFT 8 /* last active slot */ 2021ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_EXEC_MASK 0x1F 2031ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_PIO_MASK 0xFF /* last PIO setup */ 2041ac8d5baSMatthew Dillon 2051ac8d5baSMatthew Dillon /* 2061ac8d5baSMatthew Dillon * NOTE: SILI_PREG_STATUS uses the same address as SILI_PREG_CTL_SET, 2071ac8d5baSMatthew Dillon * but for read. 2081ac8d5baSMatthew Dillon */ 2091ac8d5baSMatthew Dillon #define SILI_PREG_STATUS 0x1000 /* Port Control Status (R) */ 2101ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_READY 0x80000000 /* Port Ready (R) */ 2111ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_SLOT 0x001F0000 /* Active Slot (R) */ 2121ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_SLOT_SHIFT 16 /* Shift value */ 2131ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_MASK 0x0200FFFF /* see PREG_CTL_xxx */ 2141ac8d5baSMatthew Dillon 2151ac8d5baSMatthew Dillon /* 2161ac8d5baSMatthew Dillon * NOTE: Reset sequence. Set CTL_RESET, Clear CTL_RESET, then Wait for 2171ac8d5baSMatthew Dillon * the port to become ready. 2181ac8d5baSMatthew Dillon * 2191ac8d5baSMatthew Dillon * NOTE: NOAUTOCC. If set to 1 a 1 must be written to the command completion 2201ac8d5baSMatthew Dillon * bit in the port interrupt status register to clear it. When set to 2211ac8d5baSMatthew Dillon * 0 then reading the port slot status register will automatically clear 2221ac8d5baSMatthew Dillon * the command completion interrupt. 2231ac8d5baSMatthew Dillon * 2241ac8d5baSMatthew Dillon * NOTE: ATA16 controls whether a PACKET mode command is 12 or 16 bytes. 2251ac8d5baSMatthew Dillon * 2261ac8d5baSMatthew Dillon * NOTE: RESUME if set to 1 processing is enabled for outstanding commands 2271ac8d5baSMatthew Dillon * to additional targets connected to a port multiplier after a command 2281ac8d5baSMatthew Dillon * error has occured. When set the internal BUSY status will be set 2291ac8d5baSMatthew Dillon * for the target that errored, preventing additional commands from 2301ac8d5baSMatthew Dillon * being sent until a Port Initialize operation is performed. 2311ac8d5baSMatthew Dillon * 2321ac8d5baSMatthew Dillon * NOTE: 32BITDMA if 1 causes a write to the low 32 bits of a Command 2331ac8d5baSMatthew Dillon * Activation register to copy PREG_32BIT_ACTUA to the upper 32 2341ac8d5baSMatthew Dillon * bits and start command execution. If 0 you must write to the 2351ac8d5baSMatthew Dillon * low 32 bits and then the high 32 bits and your write to the 2361ac8d5baSMatthew Dillon * high 32 bits will start command execution. 2371ac8d5baSMatthew Dillon * 2381ac8d5baSMatthew Dillon * NOTE: OOB_BYP is set on global reset and not changed by a port reset. 2391ac8d5baSMatthew Dillon */ 2401ac8d5baSMatthew Dillon #define SILI_PREG_CTL_SET 0x1000 /* Port Control Set (W1S) */ 2411ac8d5baSMatthew Dillon #define SILI_PREG_CTL_CLR 0x1004 /* Port Control Clear (W1C) */ 2421ac8d5baSMatthew Dillon #define SILI_PREG_CTL_RESET 0x00000001 /* Hold port in reset */ 2431ac8d5baSMatthew Dillon #define SILI_PREG_CTL_DEVRESET 0x00000002 /* Device reset */ 2441ac8d5baSMatthew Dillon /* (Self clearing) */ 2451ac8d5baSMatthew Dillon #define SILI_PREG_CTL_INIT 0x00000004 /* Port initialize */ 2461ac8d5baSMatthew Dillon /* (Self clearing) */ 2471ac8d5baSMatthew Dillon #define SILI_PREG_CTL_NOAUTOCC 0x00000008 2481ac8d5baSMatthew Dillon #define SILI_PREG_CTL_NOLED 0x00000010 /* Disable the LED port */ 2491ac8d5baSMatthew Dillon /* activity indicator. */ 2501ac8d5baSMatthew Dillon #define SILI_PREG_CTL_ATA16 0x00000020 /* 0=12 byte 1=16 byte */ 2511ac8d5baSMatthew Dillon #define SILI_PREG_CTL_RESUME 0x00000040 /* PM special error handling */ 2521ac8d5baSMatthew Dillon #define SILI_PREG_CTL_TXBIST 0x00000080 /* transmit a BIST FIS */ 2531ac8d5baSMatthew Dillon #define SILI_PREG_CTL_CONT_DIS 0x00000100 /* no CONT on repeat primitves*/ 2541ac8d5baSMatthew Dillon #define SILI_PREG_CTL_NOSCRAM 0x00000200 /* Disable link scrambler */ 2551ac8d5baSMatthew Dillon #define SILI_PREG_CTL_32BITDMA 0x00000400 /* see above */ 2561ac8d5baSMatthew Dillon #define SILI_PREG_CTL_ACC_ILCK 0x00000800 /* accept interlocked FIS rx */ 2571ac8d5baSMatthew Dillon /* (Self clearing) */ 2581ac8d5baSMatthew Dillon #define SILI_PREG_CTL_REJ_ILCK 0x00001000 /* reject interlocked FIS rx */ 2591ac8d5baSMatthew Dillon /* (Self clearing) */ 2601ac8d5baSMatthew Dillon #define SILI_PREG_CTL_PMA 0x00002000 /* Enable PM support */ 2611ac8d5baSMatthew Dillon #define SILI_PREG_CTL_AUTO_ILCK 0x00004000 /* Auto interlock accept */ 2621ac8d5baSMatthew Dillon #define SILI_PREG_CTL_LEDON 0x00008000 /* LED on */ 2631ac8d5baSMatthew Dillon #define SILI_PREG_CTL_OOB_BYP 0x02000000 /* Bypass OOB initialization */ 2641ac8d5baSMatthew Dillon 2651ac8d5baSMatthew Dillon /* 2661ac8d5baSMatthew Dillon * Status bits in the upper half of the register report the actual condition 2671ac8d5baSMatthew Dillon * while the status bits in the lower half of the register are masked by 2681ac8d5baSMatthew Dillon * the interrupt enable bits or threshold registers. Writing a 1 to either 2691ac8d5baSMatthew Dillon * version will clear it. 2701ac8d5baSMatthew Dillon * 2711ac8d5baSMatthew Dillon * NOTE: The steering bits written to INT_ENABLE will not show up in the 2721ac8d5baSMatthew Dillon * status register. The INT_ENABLE/INT_DISABLE registers are R+W1S 2731ac8d5baSMatthew Dillon * or R+W1C and thus can be read. 2741ac8d5baSMatthew Dillon * 2751ac8d5baSMatthew Dillon * NOTE: PHYRDYCHG, COMWAKE, UNRECFIS, DEVEXCHG: Can be cleared by writing 2761ac8d5baSMatthew Dillon * W1C either here or via the DIAG.xxx bit bit in SError. 2771ac8d5baSMatthew Dillon */ 2781ac8d5baSMatthew Dillon #define SILI_PREG_INT_STATUS 0x1008 /* Control clear */ 2791ac8d5baSMatthew Dillon #define SILI_PREG_INT_ENABLE 0x1010 /* Interrupt Enable Set */ 2801ac8d5baSMatthew Dillon #define SILI_PREG_INT_DISABLE 0x1014 /* Interrupt Enable Clear */ 2811ac8d5baSMatthew Dillon 2821ac8d5baSMatthew Dillon #define SILI_PREG_INT_STEER(n) ((n) << 30) /* Port Int -> INTA...INTD */ 2831ac8d5baSMatthew Dillon #define SILI_PREG_INT_CCOMPLETE 0x00000001 /* one or more cmds completed*/ 2841ac8d5baSMatthew Dillon #define SILI_PREG_INT_CERROR 0x00000002 /* read port error register */ 2851ac8d5baSMatthew Dillon /* to get error */ 2861ac8d5baSMatthew Dillon #define SILI_PREG_INT_READY 0x00000004 /* Port is ready for cmds */ 2871ac8d5baSMatthew Dillon #define SILI_PREG_INT_PMCHANGE 0x00000008 /* Change in power mng state */ 2881ac8d5baSMatthew Dillon #define SILI_PREG_INT_PHYRDYCHG 0x00000010 /* Mirrors DIAG.N in SError */ 2891ac8d5baSMatthew Dillon #define SILI_PREG_INT_COMWAKE 0x00000020 /* Mirrors DIAG.W in SError */ 2901ac8d5baSMatthew Dillon #define SILI_PREG_INT_UNRECFIS 0x00000040 /* Mirrors DIAG.F in SError */ 2911ac8d5baSMatthew Dillon #define SILI_PREG_INT_DEVEXCHG 0x00000080 /* Mirrors DIAG.X in SError */ 2921ac8d5baSMatthew Dillon #define SILI_PREG_INT_DECODE 0x00000100 /* 8b/10b dec err cnt > thr */ 2931ac8d5baSMatthew Dillon #define SILI_PREG_INT_CRC 0x00000200 /* CRC err count > thr */ 2941ac8d5baSMatthew Dillon #define SILI_PREG_INT_HANDSHK 0x00000400 /* Handshake err count > thr */ 2951ac8d5baSMatthew Dillon #define SILI_PREG_INT_SDB 0x00000800 /* Set Device Bits (SNotify) */ 2961ac8d5baSMatthew Dillon #define SILI_PREG_INT_SHIFT 16 /* shift upper bits of status*/ 2971ac8d5baSMatthew Dillon 2981ac8d5baSMatthew Dillon #define SILI_PREG_IST_CCOMPLETE 0x00010000 /* one or more cmds completed*/ 2991ac8d5baSMatthew Dillon #define SILI_PREG_IST_CERROR 0x00020000 /* read port error register */ 3001ac8d5baSMatthew Dillon /* to get error */ 3011ac8d5baSMatthew Dillon #define SILI_PREG_IST_READY 0x00040000 /* Port is ready for cmds */ 3021ac8d5baSMatthew Dillon #define SILI_PREG_IST_PMCHANGE 0x00080000 /* Change in power mng state */ 3031ac8d5baSMatthew Dillon #define SILI_PREG_IST_PHYRDYCHG 0x00100000 /* Mirrors DIAG.N in SError */ 3041ac8d5baSMatthew Dillon #define SILI_PREG_IST_COMWAKE 0x00200000 /* Mirrors DIAG.W in SError */ 3051ac8d5baSMatthew Dillon #define SILI_PREG_IST_UNRECFIS 0x00400000 /* Mirrors DIAG.F in SError */ 3061ac8d5baSMatthew Dillon #define SILI_PREG_IST_DEVEXCHG 0x00800000 /* Mirrors DIAG.X in SError */ 3071ac8d5baSMatthew Dillon #define SILI_PREG_IST_DECODE 0x01000000 /* 8b/10b dec err cnt > thr */ 3081ac8d5baSMatthew Dillon #define SILI_PREG_IST_CRC 0x02000000 /* CRC err count > thr */ 3091ac8d5baSMatthew Dillon #define SILI_PREG_IST_HANDSHK 0x04000000 /* Handshake err count > thr */ 3101ac8d5baSMatthew Dillon #define SILI_PREG_IST_SDB 0x08000000 /* Set Device Bits (SNotify) */ 3111ac8d5baSMatthew Dillon 3121ac8d5baSMatthew Dillon #define SILI_PREG_INT_MASK (SILI_PREG_INT_CCOMPLETE | \ 3131ac8d5baSMatthew Dillon SILI_PREG_INT_CERROR | \ 3141ac8d5baSMatthew Dillon SILI_PREG_INT_READY | \ 3151ac8d5baSMatthew Dillon SILI_PREG_INT_PMCHANGE | \ 3161ac8d5baSMatthew Dillon SILI_PREG_INT_PHYRDYCHG | \ 3171ac8d5baSMatthew Dillon SILI_PREG_INT_COMWAKE | \ 3181ac8d5baSMatthew Dillon SILI_PREG_INT_UNRECFIS | \ 3191ac8d5baSMatthew Dillon SILI_PREG_INT_DEVEXCHG | \ 3201ac8d5baSMatthew Dillon SILI_PREG_INT_DECODE | \ 3211ac8d5baSMatthew Dillon SILI_PREG_INT_CRC | \ 3221ac8d5baSMatthew Dillon SILI_PREG_INT_HANDSHK | \ 3231ac8d5baSMatthew Dillon SILI_PREG_INT_SDB) 3241ac8d5baSMatthew Dillon #define SILI_PREG_IST_MASK (SILI_PREG_INT_MASK << 16) 3251ac8d5baSMatthew Dillon 3261ac8d5baSMatthew Dillon #define SILI_PFMT_INT_STATUS "\020" \ 3271ac8d5baSMatthew Dillon "\034SDB" \ 3281ac8d5baSMatthew Dillon "\033HANDSHK" \ 3291ac8d5baSMatthew Dillon "\032CRC" \ 3301ac8d5baSMatthew Dillon "\031DECODE" \ 3311ac8d5baSMatthew Dillon "\030DEVEXCHG" \ 3321ac8d5baSMatthew Dillon "\027UNRECFIS" \ 3331ac8d5baSMatthew Dillon "\026COMWAKE" \ 3341ac8d5baSMatthew Dillon "\025PHYRDYCHG" \ 3351ac8d5baSMatthew Dillon "\024PMCHANGE" \ 3361ac8d5baSMatthew Dillon "\023READY" \ 3371ac8d5baSMatthew Dillon "\022ERROR" \ 3381ac8d5baSMatthew Dillon "\021COMPLETE" \ 3391ac8d5baSMatthew Dillon \ 3401ac8d5baSMatthew Dillon "\014SDBm" \ 3411ac8d5baSMatthew Dillon "\013HANDSHKm" \ 3421ac8d5baSMatthew Dillon "\012CRCm" \ 3431ac8d5baSMatthew Dillon "\011DECODEm" \ 3441ac8d5baSMatthew Dillon "\010DEVEXCHGm" \ 3451ac8d5baSMatthew Dillon "\007UNRECFISm" \ 3461ac8d5baSMatthew Dillon "\006COMWAKEm" \ 3471ac8d5baSMatthew Dillon "\005PHYRDYCHGm" \ 3481ac8d5baSMatthew Dillon "\004PMCHANGEm" \ 3491ac8d5baSMatthew Dillon "\003READYm" \ 3501ac8d5baSMatthew Dillon "\002ERRORm" \ 3511ac8d5baSMatthew Dillon "\001COMPLETEm" 3521ac8d5baSMatthew Dillon 3531ac8d5baSMatthew Dillon /* 3541ac8d5baSMatthew Dillon * 32BIT_ACTUA is only used when DMA is 32 bits. It is typically set to 0. 3551ac8d5baSMatthew Dillon */ 3561ac8d5baSMatthew Dillon #define SILI_PREG_32BIT_ACTUA 0x101C /* 32b activation upper addr */ 3571ac8d5baSMatthew Dillon 3581ac8d5baSMatthew Dillon /* 3591ac8d5baSMatthew Dillon * Writing a slot number 0-30 to CMD_FIFO starts the command from LRAM. 3601ac8d5baSMatthew Dillon */ 3611ac8d5baSMatthew Dillon #define SILI_PREG_CMD_FIFO 0x1020 /* Command execution FIFO */ 3621ac8d5baSMatthew Dillon 3631ac8d5baSMatthew Dillon /* 3641ac8d5baSMatthew Dillon * If the port is interrupted via INT_CERROR this register contains 3651ac8d5baSMatthew Dillon * the error code. 3661ac8d5baSMatthew Dillon * 3671ac8d5baSMatthew Dillon * Most errors write the task file register back to the PRB slot for host 3681ac8d5baSMatthew Dillon * scrutiny. 3691ac8d5baSMatthew Dillon */ 3701ac8d5baSMatthew Dillon #define SILI_PREG_CERROR 0x1024 /* Command error */ 3711ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_DEVICE 1 /* ERR set in D2H FIS */ 3721ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_SDBERROR 2 /* ERR set in SDB from device*/ 3731ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_DATAFISERR 3 /* Sil3132 error on send */ 3741ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_SENDFISERR 4 /* Sil3132 error on send */ 3751ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_BADSTATE 5 /* Sil3132 inconsistency */ 3761ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_DIRECTION 6 /* DMA direction mismatch */ 3771ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_UNDERRUN 7 /* DMA SG H2D list too small */ 3781ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_OVERRUN 8 /* DMA SG D2H list too small */ 3791ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_LLOVERUN 9 /* Too much data from device */ 3801ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PKTPROTO 11 /* Packet protocol error */ 3811ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_BADALIGN 16 /* Bad SG list, not 8-byte */ 3821ac8d5baSMatthew Dillon /* aligned */ 3831ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCITGTABRT 17 /* PCI target abort received */ 3841ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIMASABRT 18 /* PCI master abort received */ 3851ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIPARABRT 19 /* PCI parity abort received */ 3861ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PRBALIGN 24 /* PRB addr not 8-byte algned*/ 3871ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCITGTABRT2 25 /* During fetch of PRB */ 3881ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIMASABRT2 26 /* During fetch of PRB */ 3891ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIPARABRT3 33 /* During data transfer */ 3901ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCITGTABRT3 34 /* During data transfer */ 3911ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIMASABRT3 35 /* During data transfer */ 3921ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_SERVICE 36 /* FIS received during tx */ 3931ac8d5baSMatthew Dillon /* phase */ 3941ac8d5baSMatthew Dillon 3951ac8d5baSMatthew Dillon /* 3961ac8d5baSMatthew Dillon * Port FIS Configuration. Fir each possible FIS type, a 2-bit code 3971ac8d5baSMatthew Dillon * defines the desired reception behavior as follows. Bits [1:0] define 3981ac8d5baSMatthew Dillon * the code for all other FIS types not defined by [29:2]. 3991ac8d5baSMatthew Dillon * 4001ac8d5baSMatthew Dillon * 00 Accept FIS without interlock 4011ac8d5baSMatthew Dillon * 01 Reject FIS without interlock 4021ac8d5baSMatthew Dillon * 10 Interlock FIS 4031ac8d5baSMatthew Dillon * 11 (reserved) 4041ac8d5baSMatthew Dillon * 4051ac8d5baSMatthew Dillon * FIS Code Name Start Default 4061ac8d5baSMatthew Dillon * -------- ------ ------ ------- 4071ac8d5baSMatthew Dillon * ---- (reserved) 30 4081ac8d5baSMatthew Dillon * 0x27 Register (H2D) 28 01 4091ac8d5baSMatthew Dillon * 0x34 Register (D2H) 26 00 4101ac8d5baSMatthew Dillon * 0x39 DMA Activate 24 00 4111ac8d5baSMatthew Dillon * 0x41 DMA Setup 22 00 4121ac8d5baSMatthew Dillon * 0x46 Data 20 00 4131ac8d5baSMatthew Dillon * 0x58 BIST Activate 18 00 4141ac8d5baSMatthew Dillon * 0x5F PIO Setup 16 00 4151ac8d5baSMatthew Dillon * 0xA1 Set Device Bits 14 00 4161ac8d5baSMatthew Dillon * 0xA6 (reserved) 12 01 4171ac8d5baSMatthew Dillon * 0xB8 (reserved) 10 01 4181ac8d5baSMatthew Dillon * 0xBF (reserved) 8 01 4191ac8d5baSMatthew Dillon * 0xC7 (reserved) 6 01 4201ac8d5baSMatthew Dillon * 0xD4 (reserved) 4 01 4211ac8d5baSMatthew Dillon * 0xD9 (reserved) 2 01 4221ac8d5baSMatthew Dillon * ALL OTHERS (reserved) 0 01 4231ac8d5baSMatthew Dillon */ 4241ac8d5baSMatthew Dillon #define SILI_PREG_FIS_CONFIG 0x1028 /* FIS configuration */ 4251ac8d5baSMatthew Dillon 4261ac8d5baSMatthew Dillon /* 4271ac8d5baSMatthew Dillon * The data FIFO is 2KBytes in each direction. 4281ac8d5baSMatthew Dillon * 4291ac8d5baSMatthew Dillon * When DMAing from the device the Write Request Threshold is used. 4301ac8d5baSMatthew Dillon * When DMAing to the device the Read Request Threshold is used. 4311ac8d5baSMatthew Dillon * 4321ac8d5baSMatthew Dillon * The threshold can be set from 1-2040 bytes (write 0-2039), in multiples 4331ac8d5baSMatthew Dillon * of 8 bits. The low 3 bits are hardwired to 0. A value of 0 causes a 4341ac8d5baSMatthew Dillon * request whenever possible. 4351ac8d5baSMatthew Dillon */ 4361ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL 0x102C /* PCIex request FIFO thresh */ 4371ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL_READ_SHIFT 0 4381ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL_WRITE_SHIFT 16 4391ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL_MASK 0xFF 4402102f407SMatthew Dillon #define SILI_PREG_FIFO_CTL_ENCODE(rlevel, wlevel) (rlevel | (wlevel << 16)) 4411ac8d5baSMatthew Dillon 4421ac8d5baSMatthew Dillon /* 4431ac8d5baSMatthew Dillon * Error counters and thresholds. The counter occupies the low 16 bits 4441ac8d5baSMatthew Dillon * and the threshold occupies the high 16 bits. The appropriate interrupt 4451ac8d5baSMatthew Dillon * occurs when the counter exceeds the threshold. Clearing the interrupt 4461ac8d5baSMatthew Dillon * clears the counter as well. A threshold of 0 disables the interrupt 4471ac8d5baSMatthew Dillon * assertion and masks the interrupt status bit in the port interrupt status 4481ac8d5baSMatthew Dillon * register. 4491ac8d5baSMatthew Dillon */ 4501ac8d5baSMatthew Dillon #define SILI_PREG_CTR_DECODE 0x1040 /* 8B/10B Decode Error Ctr */ 4511ac8d5baSMatthew Dillon #define SILI_PREG_CTR_CRC 0x1044 /* CRC Error Counter */ 4521ac8d5baSMatthew Dillon #define SILI_PREG_CTR_HANDSHK 0x1048 /* Handshake Error Counter */ 4531ac8d5baSMatthew Dillon 4541ac8d5baSMatthew Dillon /* 4551ac8d5baSMatthew Dillon * NOTE: This register is reset only by the global reset and will not be 4561ac8d5baSMatthew Dillon * reset by a port reset. 4571ac8d5baSMatthew Dillon * 4581ac8d5baSMatthew Dillon * NOTE: Bits 15:5 configure the PHY and should not be changed unless you 4591ac8d5baSMatthew Dillon * want to blow up the part. 4601ac8d5baSMatthew Dillon * 4611ac8d5baSMatthew Dillon * Bits 4:0 define the nominal output swing for the transmitter 4621ac8d5baSMatthew Dillon * and are set to 0x0C by default. Generally speaking, don't mess 4631ac8d5baSMatthew Dillon * with them. 4641ac8d5baSMatthew Dillon */ 4651ac8d5baSMatthew Dillon #define SILI_PREG_PHY_CONFIG 0x1050 /* Handshake Error Counter */ 4661ac8d5baSMatthew Dillon #define SILI_PREG_PHY_CONFIG_AMP_MASK 0x1F 4671ac8d5baSMatthew Dillon 4681ac8d5baSMatthew Dillon #define SILI_PREG_SLOTST 0x1800 /* Slot Status */ 4691ac8d5baSMatthew Dillon #define SILI_PREG_SLOTST_ATTN 0x80000000 /* 0-30 bit for each slot */ 4701ac8d5baSMatthew Dillon 4711ac8d5baSMatthew Dillon /* 4721ac8d5baSMatthew Dillon * Shadow command activation register, shadows low or high 32 bits 4731ac8d5baSMatthew Dillon * of actual command activation register. 4741ac8d5baSMatthew Dillon */ 4752102f407SMatthew Dillon #define SILI_PREG_CMDACT(n) (0x1C00 + (8 * (n))) 4761ac8d5baSMatthew Dillon 4771ac8d5baSMatthew Dillon /* 4781ac8d5baSMatthew Dillon * Port Context Register. Contains the port multipler target (0-15) and 4791ac8d5baSMatthew Dillon * the command slot (0-31) for the PM port state machine. 4801ac8d5baSMatthew Dillon * 4811ac8d5baSMatthew Dillon * Upon a processing halt due to a device specific error, the port multipler 4821ac8d5baSMatthew Dillon * target is the one that returned the error status. 4831ac8d5baSMatthew Dillon * 4841ac8d5baSMatthew Dillon * The command slot is NOT deterministic in this case and should not be 4851ac8d5baSMatthew Dillon * assumed valid. Use READ LOG EXTENDED to determine the tag number. 4861ac8d5baSMatthew Dillon * However, the documentation does appear to indicate that for non-NCQ 4871ac8d5baSMatthew Dillon * errors the command slot does contain the tag that errored (since there 4881ac8d5baSMatthew Dillon * will be only one truely active). 4891ac8d5baSMatthew Dillon */ 4901ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT 0x1E04 4911ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_SLOT_MASK 0x1F 4921ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_PMPORT_MASK 0x0F 4931ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_SLOT_SHIFT 0 4941ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_PMPORT_SHIFT 5 4951ac8d5baSMatthew Dillon 4961ac8d5baSMatthew Dillon /* 4971ac8d5baSMatthew Dillon * SControl register - power management, speed negotiation, and COMRESET 4981ac8d5baSMatthew Dillon * operation. 4991ac8d5baSMatthew Dillon */ 5001ac8d5baSMatthew Dillon #define SILI_PREG_SCTL 0x1F00 5011ac8d5baSMatthew Dillon 5021ac8d5baSMatthew Dillon /* 5031ac8d5baSMatthew Dillon * PMP: Identify the PM port for accessing the SActive register and some 5041ac8d5baSMatthew Dillon * bit fields of the Diagnostic registers. 5051ac8d5baSMatthew Dillon */ 5061ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_PMP 0x000F0000 5071ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_PMP_SHIFT 16 5081ac8d5baSMatthew Dillon 5091ac8d5baSMatthew Dillon /* 5101ac8d5baSMatthew Dillon * SPM: It is unclear from mode 4 is. "Transition from a power management 5111ac8d5baSMatthew Dillon * state initiate (ComWake asserted)". When setting a state, the field 5121ac8d5baSMatthew Dillon * will self-reset to 0 as soon as the action is initiated. 5131ac8d5baSMatthew Dillon */ 5141ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPM 0x0000F000 5151ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPM_NONE 0x00000000 5161ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPM_PARTIAL 0x00010000 5171ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPM_SLUMBER 0x00020000 5181ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPM_FROM 0x00040000 5191ac8d5baSMatthew Dillon 5201ac8d5baSMatthew Dillon /* 5211ac8d5baSMatthew Dillon * IPM: Identify interface power management states not supported (bits). 5221ac8d5baSMatthew Dillon */ 5231ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_IPM 0x00000F00 5241ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_IPM_NONE 0x00000000 5251ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_IPM_NPARTIAL 0x00000100 5261ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_IPM_NSLUMBER 0x00000200 5271ac8d5baSMatthew Dillon 5281ac8d5baSMatthew Dillon /* 5291ac8d5baSMatthew Dillon * SPD: Limit speed negotiation (0000 for no restrictions) 5301ac8d5baSMatthew Dillon */ 5311ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPD 0x000000F0 5321ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPD_NONE 0x00000000 5331ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPD_GEN1 0x00000010 5341ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPD_GEN2 0x00000020 5351ac8d5baSMatthew Dillon 5361ac8d5baSMatthew Dillon /* 5371ac8d5baSMatthew Dillon * DET: Control host adapter device detection and interface initialization 5381ac8d5baSMatthew Dillon */ 5391ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_DET 0x0000000F 5401ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_DET_NONE 0x00000000 /* nop/complete */ 5411ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_DET_INIT 0x00000001 /* hold in COMRESET */ 5421ac8d5baSMatthew Dillon 5431ac8d5baSMatthew Dillon /* 5441ac8d5baSMatthew Dillon * SStatus register - Probe status 5451ac8d5baSMatthew Dillon */ 5461ac8d5baSMatthew Dillon #define SILI_PREG_SSTS 0x1F04 5471ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_IPM 0x00000F00 5481ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_IPM_NOCOMM 0x00000000 5491ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_IPM_ACTIVE 0x00000100 5501ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_IPM_PARTIAL 0x00000200 5511ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_IPM_SLUMBER 0x00000600 5521ac8d5baSMatthew Dillon 5531ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_SPD 0x000000F0 5541ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_SPD_NONE 0x00000000 5551ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_SPD_GEN1 0x00000010 5561ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_SPD_GEN2 0x00000020 5571ac8d5baSMatthew Dillon 5581ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_DET 0x0000000F 5591ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_DET_NOPHY 0x00000000 /* no dev, no phy */ 5601ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_DET_DEV_NE 0x00000001 /* dev, no phy */ 5611ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_DET_DEV 0x00000003 /* dev and phy */ 5621ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_DET_OFFLINE 0x00000004 /* BIST/LOOPBACK */ 5631ac8d5baSMatthew Dillon 5641ac8d5baSMatthew Dillon /* 5651ac8d5baSMatthew Dillon * These are mostly R/W1C bits. "B", "C", and "H" operate independantly 5661ac8d5baSMatthew Dillon * and depend on the corresponding error counter register. 5671ac8d5baSMatthew Dillon */ 5681ac8d5baSMatthew Dillon #define SILI_PREG_SERR 0x1F08 5691ac8d5baSMatthew Dillon #define SILI_PREG_SERR_ERR_I (1<<0) /* Recovered Data Integrity */ 5701ac8d5baSMatthew Dillon #define SILI_PREG_SERR_ERR_M (1<<1) /* Recovered Communications */ 5711ac8d5baSMatthew Dillon #define SILI_PREG_SERR_ERR_T (1<<8) /* Transient Data Integrity */ 5721ac8d5baSMatthew Dillon #define SILI_PREG_SERR_ERR_C (1<<9) /* Persistent Comm/Data */ 5731ac8d5baSMatthew Dillon #define SILI_PREG_SERR_ERR_P (1<<10) /* Protocol */ 5741ac8d5baSMatthew Dillon #define SILI_PREG_SERR_ERR_E (1<<11) /* Internal */ 5751ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_N (1<<16) /* PhyRdy Change */ 5761ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_I (1<<17) /* Phy Internal Error */ 5771ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_W (1<<18) /* Comm Wake */ 5781ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_B (1<<19) /* 10B to 8B Decode Error */ 5791ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_D (1<<20) /* Disparity Error */ 5801ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_C (1<<21) /* CRC Error */ 5811ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_H (1<<22) /* Handshake Error */ 5821ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_S (1<<23) /* Link Sequence Error */ 5831ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_T (1<<24) /* Transport State Trans Err */ 5841ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_F (1<<25) /* Unknown FIS Type */ 5851ac8d5baSMatthew Dillon #define SILI_PREG_SERR_DIAG_X (1<<26) /* Exchanged */ 5861ac8d5baSMatthew Dillon 5871ac8d5baSMatthew Dillon #define SILI_PFMT_SERR "\020" \ 5881ac8d5baSMatthew Dillon "\033DIAG.X" "\032DIAG.F" "\031DIAG.T" "\030DIAG.S" \ 5891ac8d5baSMatthew Dillon "\027DIAG.H" "\026DIAG.C" "\025DIAG.D" "\024DIAG.B" \ 5901ac8d5baSMatthew Dillon "\023DIAG.W" "\022DIAG.I" "\021DIAG.N" \ 5911ac8d5baSMatthew Dillon "\014ERR.E" "\013ERR.P" "\012ERR.C" "\011ERR.T" \ 5921ac8d5baSMatthew Dillon "\002ERR.M" "\001ERR.I" 5931ac8d5baSMatthew Dillon 5941ac8d5baSMatthew Dillon /* 5951ac8d5baSMatthew Dillon * SACT provides indirect access to the Port Device QActive registers. 5961ac8d5baSMatthew Dillon * We have direct access and do not have to use this. 5971ac8d5baSMatthew Dillon */ 5981ac8d5baSMatthew Dillon #define SILI_PREG_SACT 0x1F0C 5991ac8d5baSMatthew Dillon 6001ac8d5baSMatthew Dillon /* 6011ac8d5baSMatthew Dillon * Indicate which devices have sent a Set Device Bits FIS with Notifcation 6021ac8d5baSMatthew Dillon * set. R/W1C 6031ac8d5baSMatthew Dillon */ 6041ac8d5baSMatthew Dillon #define SILI_PREG_SNTF 0x1F10 6051ac8d5baSMatthew Dillon 6061ac8d5baSMatthew Dillon /* 6071ac8d5baSMatthew Dillon * Internal register space indirect register access via the PCI I/O space. 6081ac8d5baSMatthew Dillon * (This is for BIOSes running in 16-bit mode, we use the direct map). 6091ac8d5baSMatthew Dillon * 6101ac8d5baSMatthew Dillon * All offsets must be 4-byte aligned 6111ac8d5baSMatthew Dillon */ 6121ac8d5baSMatthew Dillon #define SILI_BAR2_GRO 0x0000 /* Global Register Offset */ 6131ac8d5baSMatthew Dillon #define SILI_BAR2_GRD 0x0004 /* Global Register Data */ 6141ac8d5baSMatthew Dillon #define SILI_BAR2_PRO 0x0008 /* Port Register Offset */ 6151ac8d5baSMatthew Dillon #define SILI_BAR2_PRD 0x000C /* Port Register Data */ 6161ac8d5baSMatthew Dillon 6171ac8d5baSMatthew Dillon /* 6181ac8d5baSMatthew Dillon * SILI mapped structures 6191ac8d5baSMatthew Dillon */ 6201ac8d5baSMatthew Dillon struct sili_sge { 6211ac8d5baSMatthew Dillon u_int64_t sge_paddr; 6221ac8d5baSMatthew Dillon u_int32_t sge_count; 6231ac8d5baSMatthew Dillon u_int32_t sge_flags; 6241ac8d5baSMatthew Dillon } __packed; 6251ac8d5baSMatthew Dillon 6261ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_TRM 0x80000000 /* last SGE associated w/cmd */ 6271ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_LNK 0x40000000 /* link to SGE array */ 6281ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_DRD 0x20000000 /* discard (ign sge_paddr) */ 6291ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_XCF 0x10000000 /* external cmd fetch */ 6301ac8d5baSMatthew Dillon 6311ac8d5baSMatthew Dillon /* 632f606d6ecSFrançois Tigeot * Each sge is 16 bytes. 6332102f407SMatthew Dillon * 6342102f407SMatthew Dillon * We want our prb structure to be power-of-2 aligned (it is required to be 6352102f407SMatthew Dillon * at least 8-byte aligned). the prb base header is 4 SGE's but includes 2 6362102f407SMatthew Dillon * SGE's within it. 637f606d6ecSFrançois Tigeot * The prb structure also can't cross a 64KB boundary, and thus can only 638f606d6ecSFrançois Tigeot * have a maximum size of 65536 / 16 / 32 == ~128 entries (128 - 4) 6392102f407SMatthew Dillon */ 640f606d6ecSFrançois Tigeot #define SILI_MAX_SGET (128 - 4) 6412102f407SMatthew Dillon #define SILI_MAX_PMPORTS 16 642f606d6ecSFrançois Tigeot #define SILI_MAXPHYS (256 * 1024) /* 256 KB */ 6432102f407SMatthew Dillon 644f606d6ecSFrançois Tigeot #if SILI_MAXPHYS / PAGE_SIZE + 1 > (SILI_MAX_SGET * 3 / 4) 6452102f407SMatthew Dillon #error "SILI_MAX_SGET is not big enough" 6462102f407SMatthew Dillon #endif 6472102f407SMatthew Dillon 6482102f407SMatthew Dillon 6492102f407SMatthew Dillon /* 6501ac8d5baSMatthew Dillon * The PRB 6511ac8d5baSMatthew Dillon * 6521ac8d5baSMatthew Dillon * NOTE: ATAPI PACKETS. The packet is stored in prb_sge[0] and sge[1] 6531ac8d5baSMatthew Dillon * is the first SGE. 6542102f407SMatthew Dillon * 6552102f407SMatthew Dillon * NOTE: LRAM PRB. The PRB layout in the LRAM includes a single struct 6562102f407SMatthew Dillon * sili_sge[4]. We could use the LRAM for the PRB and host memory 6572102f407SMatthew Dillon * for an external SGE array, but LRAM in general has some serious 6582102f407SMatthew Dillon * hardware bugs. 6592102f407SMatthew Dillon * 6602102f407SMatthew Dillon * From linux: Reading the LRAM for a port while a command is 6612102f407SMatthew Dillon * outstanding can corrupt DMA. So we use a completely external PRB. 6621ac8d5baSMatthew Dillon */ 6631ac8d5baSMatthew Dillon struct sili_prb { 6641ac8d5baSMatthew Dillon u_int16_t prb_control; 6651ac8d5baSMatthew Dillon u_int16_t prb_override; 6661ac8d5baSMatthew Dillon u_int32_t prb_xfer_count; 6671ac8d5baSMatthew Dillon union { 6681ac8d5baSMatthew Dillon struct ata_fis_h2d h2d; 6691ac8d5baSMatthew Dillon struct ata_fis_d2h d2h; 6701ac8d5baSMatthew Dillon } prb_fis; 6711ac8d5baSMatthew Dillon u_int32_t prb_reserved1c; 6722102f407SMatthew Dillon struct sili_sge prb_sge_base[2]; 6732102f407SMatthew Dillon struct sili_sge prb_sge[SILI_MAX_SGET]; 6741ac8d5baSMatthew Dillon } __packed; 6751ac8d5baSMatthew Dillon 6761ac8d5baSMatthew Dillon #define prb_h2d prb_fis.h2d 6771ac8d5baSMatthew Dillon #define prb_d2h prb_fis.d2h 6781ac8d5baSMatthew Dillon #define prb_activation prb_ext[0].sge_paddr 6791ac8d5baSMatthew Dillon #define prb_packet(prb) ((u_int8_t *)&(prb)->prb_sge[0]) 6802102f407SMatthew Dillon #define prb_sge_normal prb_sge_base[0] 6812102f407SMatthew Dillon #define prb_sge_packet prb_sge_base[1] 6821ac8d5baSMatthew Dillon 6831ac8d5baSMatthew Dillon /* 6841ac8d5baSMatthew Dillon * NOTE: override may be left 0 and the SIL3132 will decode the 6851ac8d5baSMatthew Dillon * 8-bit ATA command and use the correct protocol. 6861ac8d5baSMatthew Dillon */ 6871ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_OVERRIDE 0x0001 /* use protocol field override */ 6881ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_REXMIT 0x0002 /* ok to rexmit ext command */ 6891ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_EXTCMD 0x0004 /* FIS fetched from host memory */ 6901ac8d5baSMatthew Dillon /* (else from LRAM) */ 6911ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_RECEIVE 0x0008 /* Reserve cmd slot to receive */ 6921ac8d5baSMatthew Dillon /* an interlocked FIS */ 6931ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_READ 0x0010 /* device to host data */ 6941ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_WRITE 0x0020 /* host to device data */ 6951ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_NOINT 0x0040 /* do not post int on completion*/ 6961ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_SOFTRESET 0x0080 /* issue soft reset (special) */ 6971ac8d5baSMatthew Dillon 6981ac8d5baSMatthew Dillon #define SILI_PRB_OVER_ATAPI 0x0001 6991ac8d5baSMatthew Dillon #define SILI_PRB_OVER_ATA 0x0002 7001ac8d5baSMatthew Dillon #define SILI_PRB_OVER_NCQ 0x0004 7011ac8d5baSMatthew Dillon #define SILI_PRB_OVER_READ 0x0008 /* device to host data */ 7021ac8d5baSMatthew Dillon #define SILI_PRB_OVER_WRITE 0x0010 /* host to device data */ 7031ac8d5baSMatthew Dillon #define SILI_PRB_OVER_RAW 0x0020 /* no protocol special case */ 7041ac8d5baSMatthew Dillon 7051ac8d5baSMatthew Dillon #define SILI_MAX_PORTS 16 7061ac8d5baSMatthew Dillon #define SILI_MAX_CMDS 31 /* not 32 */ 7071ac8d5baSMatthew Dillon 7081ac8d5baSMatthew Dillon struct sili_dmamem { 7091ac8d5baSMatthew Dillon bus_dma_tag_t adm_tag; 7101ac8d5baSMatthew Dillon bus_dmamap_t adm_map; 7111ac8d5baSMatthew Dillon bus_dma_segment_t adm_seg; 7121ac8d5baSMatthew Dillon bus_addr_t adm_busaddr; 7131ac8d5baSMatthew Dillon caddr_t adm_kva; 7141ac8d5baSMatthew Dillon }; 7151ac8d5baSMatthew Dillon #define SILI_DMA_MAP(_adm) ((_adm)->adm_map) 7161ac8d5baSMatthew Dillon #define SILI_DMA_DVA(_adm) ((_adm)->adm_busaddr) 7171ac8d5baSMatthew Dillon #define SILI_DMA_KVA(_adm) ((void *)(_adm)->adm_kva) 7181ac8d5baSMatthew Dillon 7191ac8d5baSMatthew Dillon struct sili_softc; 7201ac8d5baSMatthew Dillon struct sili_port; 7211ac8d5baSMatthew Dillon struct sili_device; 7221ac8d5baSMatthew Dillon 7231ac8d5baSMatthew Dillon struct sili_ccb { 7241ac8d5baSMatthew Dillon /* ATA xfer associated with this CCB. Must be 1st struct member. */ 7251ac8d5baSMatthew Dillon struct ata_xfer ccb_xa; 7261ac8d5baSMatthew Dillon struct callout ccb_timeout; 7271ac8d5baSMatthew Dillon 7281ac8d5baSMatthew Dillon int ccb_slot; 7291ac8d5baSMatthew Dillon struct sili_port *ccb_port; 7301ac8d5baSMatthew Dillon 7311ac8d5baSMatthew Dillon bus_dmamap_t ccb_dmamap; 7321ac8d5baSMatthew Dillon struct sili_prb *ccb_prb; 7334383d440SMatthew Dillon struct sili_prb *ccb_prb_lram; 7342102f407SMatthew Dillon u_int64_t ccb_prb_paddr; /* phys addr of prb */ 7351ac8d5baSMatthew Dillon 7361ac8d5baSMatthew Dillon void (*ccb_done)(struct sili_ccb *); 7371ac8d5baSMatthew Dillon 7381ac8d5baSMatthew Dillon TAILQ_ENTRY(sili_ccb) ccb_entry; 7391ac8d5baSMatthew Dillon }; 7401ac8d5baSMatthew Dillon 7411ac8d5baSMatthew Dillon struct sili_port { 7421ac8d5baSMatthew Dillon struct sili_softc *ap_sc; 7431ac8d5baSMatthew Dillon bus_space_handle_t ap_ioh; 7441ac8d5baSMatthew Dillon 7451ac8d5baSMatthew Dillon int ap_num; 7461ac8d5baSMatthew Dillon int ap_pmcount; 7471ac8d5baSMatthew Dillon int ap_flags; 7481ac8d5baSMatthew Dillon #define AP_F_BUS_REGISTERED 0x0001 7491ac8d5baSMatthew Dillon #define AP_F_CAM_ATTACHED 0x0002 7501ac8d5baSMatthew Dillon #define AP_F_IN_RESET 0x0004 7511ac8d5baSMatthew Dillon #define AP_F_SCAN_RUNNING 0x0008 7521ac8d5baSMatthew Dillon #define AP_F_SCAN_REQUESTED 0x0010 7531ac8d5baSMatthew Dillon #define AP_F_SCAN_COMPLETED 0x0020 7541ac8d5baSMatthew Dillon #define AP_F_IGNORE_IFS 0x0040 7554383d440SMatthew Dillon #define AP_F_UNUSED0200 0x0200 7561ac8d5baSMatthew Dillon #define AP_F_ERR_CCB_RESERVED 0x0400 757187cac04SMatthew Dillon #define AP_F_REINIT_ACTIVE 0x0800 7581ac8d5baSMatthew Dillon int ap_signal; /* os per-port thread sig */ 7591ac8d5baSMatthew Dillon thread_t ap_thread; /* os per-port thread */ 7601ac8d5baSMatthew Dillon struct lock ap_lock; /* os per-port lock */ 761fb00c6edSMatthew Dillon struct lock ap_sim_lock; /* cam sim lock */ 762fb00c6edSMatthew Dillon struct lock ap_sig_lock; /* signal thread */ 7631ac8d5baSMatthew Dillon #define AP_SIGF_INIT 0x0001 7641ac8d5baSMatthew Dillon #define AP_SIGF_TIMEOUT 0x0002 7651ac8d5baSMatthew Dillon #define AP_SIGF_PORTINT 0x0004 7661ac8d5baSMatthew Dillon #define AP_SIGF_STOP 0x8000 7671ac8d5baSMatthew Dillon struct cam_sim *ap_sim; 7681ac8d5baSMatthew Dillon 7692102f407SMatthew Dillon struct sili_prb *ap_prbs; 7701ac8d5baSMatthew Dillon 7712102f407SMatthew Dillon struct sili_dmamem *ap_dmamem_prbs;/* separate sge tables */ 7721ac8d5baSMatthew Dillon 7731ac8d5baSMatthew Dillon u_int32_t ap_active; /* active bmask */ 7741ac8d5baSMatthew Dillon u_int32_t ap_active_cnt; /* active count */ 7751ac8d5baSMatthew Dillon u_int32_t ap_expired; /* deferred expired bmask */ 7761ac8d5baSMatthew Dillon struct sili_ccb *ap_ccbs; 7771ac8d5baSMatthew Dillon struct sili_ccb *ap_err_ccb; /* used to read LOG page */ 7786f3b9849SMatthew Dillon int ap_run_flags; /* used to check excl mode */ 7791ac8d5baSMatthew Dillon 7801ac8d5baSMatthew Dillon TAILQ_HEAD(, sili_ccb) ap_ccb_free; 7811ac8d5baSMatthew Dillon TAILQ_HEAD(, sili_ccb) ap_ccb_pending; 7821ac8d5baSMatthew Dillon struct lock ap_ccb_lock; 7831ac8d5baSMatthew Dillon 7841ac8d5baSMatthew Dillon int ap_type; /* ATA_PORT_T_xxx */ 7851ac8d5baSMatthew Dillon int ap_probe; /* ATA_PROBE_xxx */ 7861ac8d5baSMatthew Dillon struct ata_port *ap_ata; 7871ac8d5baSMatthew Dillon 7881ac8d5baSMatthew Dillon u_int32_t ap_state; 7891ac8d5baSMatthew Dillon #define AP_S_NORMAL 0 7901ac8d5baSMatthew Dillon #define AP_S_FATAL_ERROR 1 7911ac8d5baSMatthew Dillon 7921ac8d5baSMatthew Dillon /* For error recovery. */ 7936f3b9849SMatthew Dillon u_int8_t *ap_err_scratch; 7941ac8d5baSMatthew Dillon 7951ac8d5baSMatthew Dillon char ap_name[16]; 7961ac8d5baSMatthew Dillon }; 7971ac8d5baSMatthew Dillon 7981ac8d5baSMatthew Dillon #define PORTNAME(_ap) ((_ap)->ap_name) 7991ac8d5baSMatthew Dillon #define ATANAME(_ap, _at) ((_at) ? (_at)->at_name : (_ap)->ap_name) 8001ac8d5baSMatthew Dillon 8011ac8d5baSMatthew Dillon struct sili_softc { 8021ac8d5baSMatthew Dillon device_t sc_dev; 8031ac8d5baSMatthew Dillon const struct sili_device *sc_ad; /* special casing */ 8041ac8d5baSMatthew Dillon 8051ac8d5baSMatthew Dillon struct resource *sc_irq; /* bus resources */ 8061ac8d5baSMatthew Dillon struct resource *sc_regs; /* bus resources */ 8071ac8d5baSMatthew Dillon struct resource *sc_pregs; /* bus resources */ 8081ac8d5baSMatthew Dillon bus_space_tag_t sc_iot; /* split from sc_regs */ 8091ac8d5baSMatthew Dillon bus_space_handle_t sc_ioh; /* split from sc_regs */ 8101ac8d5baSMatthew Dillon bus_space_tag_t sc_piot; /* split from sc_pregs */ 8111ac8d5baSMatthew Dillon bus_space_handle_t sc_pioh; /* split from sc_pregs */ 8121ac8d5baSMatthew Dillon 813*c2a27f53SSepherosa Ziehau int sc_irq_type; 8141ac8d5baSMatthew Dillon int sc_rid_irq; /* saved bus RIDs */ 8151ac8d5baSMatthew Dillon int sc_rid_regs; 8161ac8d5baSMatthew Dillon int sc_rid_pregs; 8171ac8d5baSMatthew Dillon 8181ac8d5baSMatthew Dillon void *sc_irq_handle; /* installed irq vector */ 8191ac8d5baSMatthew Dillon 8202102f407SMatthew Dillon bus_dma_tag_t sc_tag_prbs; 8211ac8d5baSMatthew Dillon bus_dma_tag_t sc_tag_data; 8221ac8d5baSMatthew Dillon 8231ac8d5baSMatthew Dillon int sc_flags; 8241ac8d5baSMatthew Dillon #define SILI_F_NO_NCQ 0x0001 8251ac8d5baSMatthew Dillon #define SILI_F_IGN_FR 0x0002 8261ac8d5baSMatthew Dillon #define SILI_F_INT_GOOD 0x0004 8271ac8d5baSMatthew Dillon #define SILI_F_64BIT 0x0008 8281ac8d5baSMatthew Dillon #define SILI_F_300 0x0010 8291ac8d5baSMatthew Dillon #define SILI_F_NCQ 0x0020 8301ac8d5baSMatthew Dillon #define SILI_F_SSNTF 0x0040 8311ac8d5baSMatthew Dillon #define SILI_F_SPM 0x0080 8321ac8d5baSMatthew Dillon 8331ac8d5baSMatthew Dillon u_int sc_ncmds; /* max 31, NOT 32 */ 8341ac8d5baSMatthew Dillon 8351ac8d5baSMatthew Dillon struct sili_port *sc_ports[SILI_MAX_PORTS]; 8361ac8d5baSMatthew Dillon }; 8371ac8d5baSMatthew Dillon #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) 8381ac8d5baSMatthew Dillon 8391ac8d5baSMatthew Dillon struct sili_device { 8401ac8d5baSMatthew Dillon pci_vendor_id_t ad_vendor; 8411ac8d5baSMatthew Dillon pci_product_id_t ad_product; 8421ac8d5baSMatthew Dillon int ad_nports; 8431ac8d5baSMatthew Dillon int (*ad_attach)(device_t dev); 8441ac8d5baSMatthew Dillon int (*ad_detach)(device_t dev); 8451ac8d5baSMatthew Dillon char *name; 8461ac8d5baSMatthew Dillon }; 8471ac8d5baSMatthew Dillon 848a35ddbb4SMatthew Dillon /* Wait for all bits in _b to be cleared */ 849a35ddbb4SMatthew Dillon #define sili_pwait_clr(_ap, _r, _b) \ 850a35ddbb4SMatthew Dillon sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), 0) 851a35ddbb4SMatthew Dillon #define sili_pwait_clr_to(_ap, _to, _r, _b) \ 852a35ddbb4SMatthew Dillon sili_pwait_eq((_ap), _to, (_r), (_b), 0) 853a35ddbb4SMatthew Dillon 854a35ddbb4SMatthew Dillon /* Wait for all bits in _b to be set */ 855a35ddbb4SMatthew Dillon #define sili_pwait_set(_ap, _r, _b) \ 856a35ddbb4SMatthew Dillon sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), (_b)) 857a35ddbb4SMatthew Dillon #define sili_pwait_set_to(_ap, _to, _r, _b) \ 858a35ddbb4SMatthew Dillon sili_pwait_eq((_ap), _to, (_r), (_b), (_b)) 859a35ddbb4SMatthew Dillon 860187cac04SMatthew Dillon /* 861187cac04SMatthew Dillon * Misc defines 862187cac04SMatthew Dillon */ 863a35ddbb4SMatthew Dillon #define SILI_PWAIT_TIMEOUT 1000 864a35ddbb4SMatthew Dillon 865187cac04SMatthew Dillon /* 866187cac04SMatthew Dillon * Prototypes 867187cac04SMatthew Dillon */ 8681ac8d5baSMatthew Dillon const struct sili_device *sili_lookup_device(device_t dev); 8691ac8d5baSMatthew Dillon int sili_init(struct sili_softc *); 870a35ddbb4SMatthew Dillon int sili_port_init(struct sili_port *ap); 8711ac8d5baSMatthew Dillon int sili_port_alloc(struct sili_softc *, u_int); 8721ac8d5baSMatthew Dillon void sili_port_state_machine(struct sili_port *ap, int initial); 8731ac8d5baSMatthew Dillon void sili_port_free(struct sili_softc *, u_int); 8741ac8d5baSMatthew Dillon int sili_port_reset(struct sili_port *, struct ata_port *at, int); 875187cac04SMatthew Dillon void sili_exclusive_access(struct sili_port *ap); 8761ac8d5baSMatthew Dillon 8771ac8d5baSMatthew Dillon u_int32_t sili_read(struct sili_softc *, bus_size_t); 8781ac8d5baSMatthew Dillon void sili_write(struct sili_softc *, bus_size_t, u_int32_t); 8791ac8d5baSMatthew Dillon int sili_wait_ne(struct sili_softc *, bus_size_t, u_int32_t, u_int32_t); 8801ac8d5baSMatthew Dillon u_int32_t sili_pread(struct sili_port *, bus_size_t); 8811ac8d5baSMatthew Dillon void sili_pwrite(struct sili_port *, bus_size_t, u_int32_t); 8821ac8d5baSMatthew Dillon int sili_pwait_eq(struct sili_port *, int, bus_size_t, 8831ac8d5baSMatthew Dillon u_int32_t, u_int32_t); 8841ac8d5baSMatthew Dillon void sili_intr(void *); 8851ac8d5baSMatthew Dillon void sili_port_intr(struct sili_port *ap, int blockable); 8861ac8d5baSMatthew Dillon 8871ac8d5baSMatthew Dillon int sili_cam_attach(struct sili_port *ap); 8881ac8d5baSMatthew Dillon void sili_cam_changed(struct sili_port *ap, struct ata_port *at, int found); 8891ac8d5baSMatthew Dillon void sili_cam_detach(struct sili_port *ap); 8901ac8d5baSMatthew Dillon int sili_cam_probe(struct sili_port *ap, struct ata_port *at); 8911ac8d5baSMatthew Dillon 8921ac8d5baSMatthew Dillon struct ata_xfer *sili_ata_get_xfer(struct sili_port *ap, struct ata_port *at); 8931ac8d5baSMatthew Dillon void sili_ata_put_xfer(struct ata_xfer *xa); 8941ac8d5baSMatthew Dillon int sili_ata_cmd(struct ata_xfer *xa); 8951ac8d5baSMatthew Dillon 896a35ddbb4SMatthew Dillon int sili_pm_port_probe(struct sili_port *ap, int); 897a35ddbb4SMatthew Dillon int sili_pm_port_init(struct sili_port *ap, struct ata_port *at); 8986f3b9849SMatthew Dillon int sili_pm_identify(struct sili_port *ap); 8991ac8d5baSMatthew Dillon int sili_pm_set_feature(struct sili_port *ap, int feature, int enable); 9001ac8d5baSMatthew Dillon int sili_pm_hardreset(struct sili_port *ap, int target, int hard); 9011ac8d5baSMatthew Dillon int sili_pm_softreset(struct sili_port *ap, int target); 9021ac8d5baSMatthew Dillon int sili_pm_phy_status(struct sili_port *ap, int target, u_int32_t *datap); 9031ac8d5baSMatthew Dillon int sili_pm_read(struct sili_port *ap, int target, 9041ac8d5baSMatthew Dillon int which, u_int32_t *res); 9051ac8d5baSMatthew Dillon int sili_pm_write(struct sili_port *ap, int target, 9061ac8d5baSMatthew Dillon int which, u_int32_t data); 9071ac8d5baSMatthew Dillon void sili_pm_check_good(struct sili_port *ap, int target); 9081ac8d5baSMatthew Dillon void sili_ata_cmd_timeout(struct sili_ccb *ccb); 909a35ddbb4SMatthew Dillon void sili_quick_timeout(struct sili_ccb *ccb); 9101ac8d5baSMatthew Dillon struct sili_ccb *sili_get_ccb(struct sili_port *ap); 9111ac8d5baSMatthew Dillon void sili_put_ccb(struct sili_ccb *ccb); 9121ac8d5baSMatthew Dillon struct sili_ccb *sili_get_err_ccb(struct sili_port *); 9131ac8d5baSMatthew Dillon void sili_put_err_ccb(struct sili_ccb *); 9141ac8d5baSMatthew Dillon int sili_poll(struct sili_ccb *ccb, int timeout, 9151ac8d5baSMatthew Dillon void (*timeout_fn)(struct sili_ccb *)); 9161ac8d5baSMatthew Dillon 9171ac8d5baSMatthew Dillon int sili_port_signature(struct sili_port *ap, struct ata_port *at, 9181ac8d5baSMatthew Dillon u_int32_t sig); 9191ac8d5baSMatthew Dillon void sili_port_thread_core(struct sili_port *ap, int mask); 9201ac8d5baSMatthew Dillon 9211ac8d5baSMatthew Dillon void sili_os_sleep(int ms); 9221ac8d5baSMatthew Dillon void sili_os_hardsleep(int us); 9231ac8d5baSMatthew Dillon int sili_os_softsleep(void); 9241ac8d5baSMatthew Dillon void sili_os_start_port(struct sili_port *ap); 9251ac8d5baSMatthew Dillon void sili_os_stop_port(struct sili_port *ap); 9261ac8d5baSMatthew Dillon void sili_os_signal_port_thread(struct sili_port *ap, int mask); 9271ac8d5baSMatthew Dillon void sili_os_lock_port(struct sili_port *ap); 9281ac8d5baSMatthew Dillon int sili_os_lock_port_nb(struct sili_port *ap); 9291ac8d5baSMatthew Dillon void sili_os_unlock_port(struct sili_port *ap); 9301ac8d5baSMatthew Dillon 9311ac8d5baSMatthew Dillon extern u_int32_t SiliForceGen1; 9321ac8d5baSMatthew Dillon extern u_int32_t SiliNoFeatures; 933