Index: stable/8/sys/amd64/include/xen =================================================================== --- stable/8/sys/amd64/include/xen (revision 212718) +++ stable/8/sys/amd64/include/xen (revision 212719) Property changes on: stable/8/sys/amd64/include/xen ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/sys/amd64/include/xen:r212145 Index: stable/8/sys/cddl/contrib/opensolaris =================================================================== --- stable/8/sys/cddl/contrib/opensolaris (revision 212718) +++ stable/8/sys/cddl/contrib/opensolaris (revision 212719) Property changes on: stable/8/sys/cddl/contrib/opensolaris ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/sys/cddl/contrib/opensolaris:r212145 Index: stable/8/sys/contrib/dev/acpica =================================================================== --- stable/8/sys/contrib/dev/acpica (revision 212718) +++ stable/8/sys/contrib/dev/acpica (revision 212719) Property changes on: stable/8/sys/contrib/dev/acpica ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/sys/contrib/dev/acpica:r212145 Index: stable/8/sys/contrib/pf =================================================================== --- stable/8/sys/contrib/pf (revision 212718) +++ stable/8/sys/contrib/pf (revision 212719) Property changes on: stable/8/sys/contrib/pf ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/sys/contrib/pf:r212145 Index: stable/8/sys/dev/ata/ata-all.h =================================================================== --- stable/8/sys/dev/ata/ata-all.h (revision 212718) +++ stable/8/sys/dev/ata/ata-all.h (revision 212719) @@ -1,765 +1,766 @@ /*- * Copyright (c) 1998 - 2008 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #include "opt_ata.h" #if 0 #define ATA_LEGACY_SUPPORT /* Enable obsolete features that break * some modern devices */ #endif /* ATA register defines */ #define ATA_DATA 0 /* (RW) data */ #define ATA_FEATURE 1 /* (W) feature */ #define ATA_F_DMA 0x01 /* enable DMA */ #define ATA_F_OVL 0x02 /* enable overlap */ #define ATA_COUNT 2 /* (W) sector count */ #define ATA_SECTOR 3 /* (RW) sector # */ #define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ #define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ #define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ #define ATA_D_LBA 0x40 /* use LBA addressing */ #define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ #define ATA_COMMAND 7 /* (W) command */ #define ATA_ERROR 8 /* (R) error */ #define ATA_E_ILI 0x01 /* illegal length */ #define ATA_E_NM 0x02 /* no media */ #define ATA_E_ABORT 0x04 /* command aborted */ #define ATA_E_MCR 0x08 /* media change request */ #define ATA_E_IDNF 0x10 /* ID not found */ #define ATA_E_MC 0x20 /* media changed */ #define ATA_E_UNC 0x40 /* uncorrectable data */ #define ATA_E_ICRC 0x80 /* UDMA crc error */ #define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ #define ATA_IREASON 9 /* (R) interrupt reason */ #define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ #define ATA_I_IN 0x02 /* read (1) | write (0) */ #define ATA_I_RELEASE 0x04 /* released bus (1) */ #define ATA_I_TAGMASK 0xf8 /* tag mask */ #define ATA_STATUS 10 /* (R) status */ #define ATA_ALTSTAT 11 /* (R) alternate status */ #define ATA_S_ERROR 0x01 /* error */ #define ATA_S_INDEX 0x02 /* index */ #define ATA_S_CORR 0x04 /* data corrected */ #define ATA_S_DRQ 0x08 /* data request */ #define ATA_S_DSC 0x10 /* drive seek completed */ #define ATA_S_SERVICE 0x10 /* drive needs service */ #define ATA_S_DWF 0x20 /* drive write fault */ #define ATA_S_DMA 0x20 /* DMA ready */ #define ATA_S_READY 0x40 /* drive ready */ #define ATA_S_BUSY 0x80 /* busy */ #define ATA_CONTROL 12 /* (W) control */ #define ATA_CTLOFFSET 0x206 /* control register offset */ #define ATA_PCCARD_CTLOFFSET 0x0e /* do for PCCARD devices */ #define ATA_PC98_CTLOFFSET 0x10c /* do for PC98 devices */ #define ATA_A_IDS 0x02 /* disable interrupts */ #define ATA_A_RESET 0x04 /* RESET controller */ #ifdef ATA_LEGACY_SUPPORT #define ATA_A_4BIT 0x08 /* 4 head bits: obsolete 1996 */ #else #define ATA_A_4BIT 0x00 #endif #define ATA_A_HOB 0x80 /* High Order Byte enable */ /* SATA register defines */ #define ATA_SSTATUS 13 #define ATA_SS_DET_MASK 0x0000000f #define ATA_SS_DET_NO_DEVICE 0x00000000 #define ATA_SS_DET_DEV_PRESENT 0x00000001 #define ATA_SS_DET_PHY_ONLINE 0x00000003 #define ATA_SS_DET_PHY_OFFLINE 0x00000004 #define ATA_SS_SPD_MASK 0x000000f0 #define ATA_SS_SPD_NO_SPEED 0x00000000 #define ATA_SS_SPD_GEN1 0x00000010 #define ATA_SS_SPD_GEN2 0x00000020 #define ATA_SS_IPM_MASK 0x00000f00 #define ATA_SS_IPM_NO_DEVICE 0x00000000 #define ATA_SS_IPM_ACTIVE 0x00000100 #define ATA_SS_IPM_PARTIAL 0x00000200 #define ATA_SS_IPM_SLUMBER 0x00000600 #define ATA_SS_CONWELL_MASK \ (ATA_SS_DET_MASK|ATA_SS_SPD_MASK|ATA_SS_IPM_MASK) #define ATA_SS_CONWELL_GEN1 \ (ATA_SS_DET_PHY_ONLINE|ATA_SS_SPD_GEN1|ATA_SS_IPM_ACTIVE) #define ATA_SS_CONWELL_GEN2 \ (ATA_SS_DET_PHY_ONLINE|ATA_SS_SPD_GEN2|ATA_SS_IPM_ACTIVE) #define ATA_SERROR 14 #define ATA_SE_DATA_CORRECTED 0x00000001 #define ATA_SE_COMM_CORRECTED 0x00000002 #define ATA_SE_DATA_ERR 0x00000100 #define ATA_SE_COMM_ERR 0x00000200 #define ATA_SE_PROT_ERR 0x00000400 #define ATA_SE_HOST_ERR 0x00000800 #define ATA_SE_PHY_CHANGED 0x00010000 #define ATA_SE_PHY_IERROR 0x00020000 #define ATA_SE_COMM_WAKE 0x00040000 #define ATA_SE_DECODE_ERR 0x00080000 #define ATA_SE_PARITY_ERR 0x00100000 #define ATA_SE_CRC_ERR 0x00200000 #define ATA_SE_HANDSHAKE_ERR 0x00400000 #define ATA_SE_LINKSEQ_ERR 0x00800000 #define ATA_SE_TRANSPORT_ERR 0x01000000 #define ATA_SE_UNKNOWN_FIS 0x02000000 #define ATA_SCONTROL 15 #define ATA_SC_DET_MASK 0x0000000f #define ATA_SC_DET_IDLE 0x00000000 #define ATA_SC_DET_RESET 0x00000001 #define ATA_SC_DET_DISABLE 0x00000004 #define ATA_SC_SPD_MASK 0x000000f0 #define ATA_SC_SPD_NO_SPEED 0x00000000 #define ATA_SC_SPD_SPEED_GEN1 0x00000010 #define ATA_SC_SPD_SPEED_GEN2 0x00000020 #define ATA_SC_IPM_MASK 0x00000f00 #define ATA_SC_IPM_NONE 0x00000000 #define ATA_SC_IPM_DIS_PARTIAL 0x00000100 #define ATA_SC_IPM_DIS_SLUMBER 0x00000200 #define ATA_SACTIVE 16 /* SATA AHCI v1.0 register defines */ #define ATA_AHCI_CAP 0x00 #define ATA_AHCI_CAP_NPMASK 0x0000001f #define ATA_AHCI_CAP_SXS 0x00000020 #define ATA_AHCI_CAP_EMS 0x00000040 #define ATA_AHCI_CAP_CCCS 0x00000080 #define ATA_AHCI_CAP_NCS 0x00001F00 #define ATA_AHCI_CAP_NCS_SHIFT 8 #define ATA_AHCI_CAP_PSC 0x00002000 #define ATA_AHCI_CAP_SSC 0x00004000 #define ATA_AHCI_CAP_PMD 0x00008000 #define ATA_AHCI_CAP_FBSS 0x00010000 #define ATA_AHCI_CAP_SPM 0x00020000 #define ATA_AHCI_CAP_SAM 0x00080000 #define ATA_AHCI_CAP_ISS 0x00F00000 #define ATA_AHCI_CAP_ISS_SHIFT 20 #define ATA_AHCI_CAP_SCLO 0x01000000 #define ATA_AHCI_CAP_SAL 0x02000000 #define ATA_AHCI_CAP_SALP 0x04000000 #define ATA_AHCI_CAP_SSS 0x08000000 #define ATA_AHCI_CAP_SMPS 0x10000000 #define ATA_AHCI_CAP_SSNTF 0x20000000 #define ATA_AHCI_CAP_SNCQ 0x40000000 #define ATA_AHCI_CAP_64BIT 0x80000000 #define ATA_AHCI_GHC 0x04 #define ATA_AHCI_GHC_AE 0x80000000 #define ATA_AHCI_GHC_IE 0x00000002 #define ATA_AHCI_GHC_HR 0x00000001 #define ATA_AHCI_IS 0x08 #define ATA_AHCI_PI 0x0c #define ATA_AHCI_VS 0x10 #define ATA_AHCI_OFFSET 0x80 #define ATA_AHCI_P_CLB 0x100 #define ATA_AHCI_P_CLBU 0x104 #define ATA_AHCI_P_FB 0x108 #define ATA_AHCI_P_FBU 0x10c #define ATA_AHCI_P_IS 0x110 #define ATA_AHCI_P_IE 0x114 #define ATA_AHCI_P_IX_DHR 0x00000001 #define ATA_AHCI_P_IX_PS 0x00000002 #define ATA_AHCI_P_IX_DS 0x00000004 #define ATA_AHCI_P_IX_SDB 0x00000008 #define ATA_AHCI_P_IX_UF 0x00000010 #define ATA_AHCI_P_IX_DP 0x00000020 #define ATA_AHCI_P_IX_PC 0x00000040 #define ATA_AHCI_P_IX_DI 0x00000080 #define ATA_AHCI_P_IX_PRC 0x00400000 #define ATA_AHCI_P_IX_IPM 0x00800000 #define ATA_AHCI_P_IX_OF 0x01000000 #define ATA_AHCI_P_IX_INF 0x04000000 #define ATA_AHCI_P_IX_IF 0x08000000 #define ATA_AHCI_P_IX_HBD 0x10000000 #define ATA_AHCI_P_IX_HBF 0x20000000 #define ATA_AHCI_P_IX_TFE 0x40000000 #define ATA_AHCI_P_IX_CPD 0x80000000 #define ATA_AHCI_P_CMD 0x118 #define ATA_AHCI_P_CMD_ST 0x00000001 #define ATA_AHCI_P_CMD_SUD 0x00000002 #define ATA_AHCI_P_CMD_POD 0x00000004 #define ATA_AHCI_P_CMD_CLO 0x00000008 #define ATA_AHCI_P_CMD_FRE 0x00000010 #define ATA_AHCI_P_CMD_CCS_MASK 0x00001f00 #define ATA_AHCI_P_CMD_ISS 0x00002000 #define ATA_AHCI_P_CMD_FR 0x00004000 #define ATA_AHCI_P_CMD_CR 0x00008000 #define ATA_AHCI_P_CMD_CPS 0x00010000 #define ATA_AHCI_P_CMD_PMA 0x00020000 #define ATA_AHCI_P_CMD_HPCP 0x00040000 #define ATA_AHCI_P_CMD_ISP 0x00080000 #define ATA_AHCI_P_CMD_CPD 0x00100000 #define ATA_AHCI_P_CMD_ATAPI 0x01000000 #define ATA_AHCI_P_CMD_DLAE 0x02000000 #define ATA_AHCI_P_CMD_ALPE 0x04000000 #define ATA_AHCI_P_CMD_ASP 0x08000000 #define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000 #define ATA_AHCI_P_CMD_NOOP 0x00000000 #define ATA_AHCI_P_CMD_ACTIVE 0x10000000 #define ATA_AHCI_P_CMD_PARTIAL 0x20000000 #define ATA_AHCI_P_CMD_SLUMBER 0x60000000 #define ATA_AHCI_P_TFD 0x120 #define ATA_AHCI_P_SIG 0x124 #define ATA_AHCI_P_SSTS 0x128 #define ATA_AHCI_P_SCTL 0x12c #define ATA_AHCI_P_SERR 0x130 #define ATA_AHCI_P_SACT 0x134 #define ATA_AHCI_P_CI 0x138 #define ATA_AHCI_P_SNTF 0x13C #define ATA_AHCI_P_FBS 0x140 #define ATA_AHCI_CL_SIZE 32 #define ATA_AHCI_CL_OFFSET 0 #define ATA_AHCI_FB_OFFSET (ATA_AHCI_CL_SIZE * 32) #define ATA_AHCI_CT_OFFSET (ATA_AHCI_FB_OFFSET + 4096) #define ATA_AHCI_CT_SIZE (2176 + 128) struct ata_ahci_dma_prd { u_int64_t dba; u_int32_t reserved; u_int32_t dbc; /* 0 based */ #define ATA_AHCI_PRD_MASK 0x003fffff /* max 4MB */ #define ATA_AHCI_PRD_IPC (1<<31) } __packed; struct ata_ahci_cmd_tab { u_int8_t cfis[64]; u_int8_t acmd[32]; u_int8_t reserved[32]; #define ATA_AHCI_DMA_ENTRIES 129 struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES]; } __packed; struct ata_ahci_cmd_list { u_int16_t cmd_flags; #define ATA_AHCI_CMD_ATAPI 0x0020 #define ATA_AHCI_CMD_WRITE 0x0040 #define ATA_AHCI_CMD_PREFETCH 0x0080 #define ATA_AHCI_CMD_RESET 0x0100 #define ATA_AHCI_CMD_BIST 0x0200 #define ATA_AHCI_CMD_CLR_BUSY 0x0400 u_int16_t prd_length; /* PRD entries */ u_int32_t bytecount; u_int64_t cmd_table_phys; /* 128byte aligned */ } __packed; /* DMA register defines */ #define ATA_DMA_ENTRIES 256 #define ATA_DMA_EOT 0x80000000 #define ATA_BMCMD_PORT 17 #define ATA_BMCMD_START_STOP 0x01 #define ATA_BMCMD_WRITE_READ 0x08 #define ATA_BMDEVSPEC_0 18 #define ATA_BMSTAT_PORT 19 #define ATA_BMSTAT_ACTIVE 0x01 #define ATA_BMSTAT_ERROR 0x02 #define ATA_BMSTAT_INTERRUPT 0x04 #define ATA_BMSTAT_MASK 0x07 #define ATA_BMSTAT_DMA_MASTER 0x20 #define ATA_BMSTAT_DMA_SLAVE 0x40 #define ATA_BMSTAT_DMA_SIMPLEX 0x80 #define ATA_BMDEVSPEC_1 20 #define ATA_BMDTP_PORT 21 #define ATA_IDX_ADDR 22 #define ATA_IDX_DATA 23 #define ATA_MAX_RES 24 /* misc defines */ #define ATA_PRIMARY 0x1f0 #define ATA_SECONDARY 0x170 #define ATA_PC98_BANK 0x432 #define ATA_IOSIZE 0x08 #define ATA_PC98_IOSIZE 0x10 #define ATA_CTLIOSIZE 0x01 #define ATA_BMIOSIZE 0x08 #define ATA_PC98_BANKIOSIZE 0x01 #define ATA_IOADDR_RID 0 #define ATA_CTLADDR_RID 1 #define ATA_BMADDR_RID 0x20 #define ATA_PC98_CTLADDR_RID 8 #define ATA_PC98_BANKADDR_RID 9 #define ATA_IRQ_RID 0 #define ATA_DEV(unit) ((unit > 0) ? 0x10 : 0) #define ATA_CFA_MAGIC1 0x844A #define ATA_CFA_MAGIC2 0x848A #define ATA_CFA_MAGIC3 0x8400 #define ATAPI_MAGIC_LSB 0x14 #define ATAPI_MAGIC_MSB 0xeb #define ATAPI_P_READ (ATA_S_DRQ | ATA_I_IN) #define ATAPI_P_WRITE (ATA_S_DRQ) #define ATAPI_P_CMDOUT (ATA_S_DRQ | ATA_I_CMD) #define ATAPI_P_DONEDRQ (ATA_S_DRQ | ATA_I_CMD | ATA_I_IN) #define ATAPI_P_DONE (ATA_I_CMD | ATA_I_IN) #define ATAPI_P_ABORT 0 #define ATA_INTR_FLAGS (INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY) #define ATA_OP_CONTINUES 0 #define ATA_OP_FINISHED 1 #define ATA_MAX_28BIT_LBA 268435455UL #ifndef ATA_REQUEST_TIMEOUT #define ATA_REQUEST_TIMEOUT 10 #endif /* structure used for composite atomic operations */ #define MAX_COMPOSITES 32 /* u_int32_t bits */ struct ata_composite { struct mtx lock; /* control lock */ u_int32_t rd_needed; /* needed read subdisks */ u_int32_t rd_done; /* done read subdisks */ u_int32_t wr_needed; /* needed write subdisks */ u_int32_t wr_depend; /* write depends on subdisks */ u_int32_t wr_done; /* done write subdisks */ struct ata_request *request[MAX_COMPOSITES]; u_int32_t residual; /* bytes still to transfer */ caddr_t data_1; caddr_t data_2; }; /* structure used to queue an ATA/ATAPI request */ struct ata_request { device_t dev; /* device handle */ device_t parent; /* channel handle */ int unit; /* physical unit */ union { struct { u_int8_t command; /* command reg */ u_int16_t feature; /* feature reg */ u_int16_t count; /* count reg */ u_int64_t lba; /* lba reg */ } ata; struct { u_int8_t ccb[16]; /* ATAPI command block */ struct atapi_sense sense; /* ATAPI request sense data */ u_int8_t saved_cmd; /* ATAPI saved command */ } atapi; } u; u_int32_t bytecount; /* bytes to transfer */ u_int32_t transfersize; /* bytes pr transfer */ caddr_t data; /* pointer to data buf */ u_int32_t tag; /* HW tag of this request */ int flags; #define ATA_R_CONTROL 0x00000001 #define ATA_R_READ 0x00000002 #define ATA_R_WRITE 0x00000004 #define ATA_R_ATAPI 0x00000008 #define ATA_R_DMA 0x00000010 #define ATA_R_QUIET 0x00000020 #define ATA_R_TIMEOUT 0x00000040 #define ATA_R_48BIT 0x00000080 #define ATA_R_ORDERED 0x00000100 #define ATA_R_AT_HEAD 0x00000200 #define ATA_R_REQUEUE 0x00000400 #define ATA_R_THREAD 0x00000800 #define ATA_R_DIRECT 0x00001000 #define ATA_R_ATAPI16 0x00010000 #define ATA_R_ATAPI_INTR 0x00020000 #define ATA_R_DEBUG 0x10000000 #define ATA_R_DANGER1 0x20000000 #define ATA_R_DANGER2 0x40000000 struct ata_dmaslot *dma; /* DMA slot of this request */ u_int8_t status; /* ATA status */ u_int8_t error; /* ATA error */ u_int32_t donecount; /* bytes transferred */ int result; /* result error code */ void (*callback)(struct ata_request *request); struct sema done; /* request done sema */ int retries; /* retry count */ int timeout; /* timeout for this cmd */ struct callout callout; /* callout management */ struct task task; /* task management */ struct bio *bio; /* bio for this request */ int this; /* this request ID */ struct ata_composite *composite; /* for composite atomic ops */ void *driver; /* driver specific */ TAILQ_ENTRY(ata_request) chain; /* list management */ #ifdef ATA_CAM union ccb *ccb; #endif }; /* define this for debugging request processing */ #if 0 #define ATA_DEBUG_RQ(request, string) \ { \ if (request->flags & ATA_R_DEBUG) \ device_printf(request->parent, "req=%p %s " string "\n", \ request, ata_cmd2str(request)); \ } #else #define ATA_DEBUG_RQ(request, string) #endif /* structure describing an ATA/ATAPI device */ struct ata_device { device_t dev; /* device handle */ int unit; /* physical unit */ #define ATA_MASTER 0x00 #define ATA_SLAVE 0x01 #define ATA_PM 0x0f struct ata_params param; /* ata param structure */ int mode; /* current transfermode */ u_int32_t max_iosize; /* max IO size */ int spindown; /* idle spindown timeout */ struct callout spindown_timer; int spindown_state; int flags; #define ATA_D_USE_CHS 0x0001 #define ATA_D_MEDIA_CHANGED 0x0002 #define ATA_D_ENC_PRESENT 0x0004 }; /* structure for holding DMA Physical Region Descriptors (PRD) entries */ struct ata_dma_prdentry { u_int32_t addr; u_int32_t count; }; /* structure used by the setprd function */ struct ata_dmasetprd_args { void *dmatab; int nsegs; int error; }; struct ata_dmaslot { u_int8_t status; /* DMA status */ bus_dma_tag_t sg_tag; /* SG list DMA tag */ bus_dmamap_t sg_map; /* SG list DMA map */ void *sg; /* DMA transfer table */ bus_addr_t sg_bus; /* bus address of dmatab */ bus_dma_tag_t data_tag; /* data DMA tag */ bus_dmamap_t data_map; /* data DMA map */ }; /* structure holding DMA related information */ struct ata_dma { bus_dma_tag_t dmatag; /* parent DMA tag */ bus_dma_tag_t work_tag; /* workspace DMA tag */ bus_dmamap_t work_map; /* workspace DMA map */ u_int8_t *work; /* workspace */ bus_addr_t work_bus; /* bus address of dmatab */ #define ATA_DMA_SLOTS 1 int dma_slots; /* DMA slots allocated */ struct ata_dmaslot slot[ATA_DMA_SLOTS]; u_int32_t alignment; /* DMA SG list alignment */ u_int32_t boundary; /* DMA SG list boundary */ u_int32_t segsize; /* DMA SG list segment size */ u_int32_t max_iosize; /* DMA data max IO size */ u_int64_t max_address; /* highest DMA'able address */ int flags; #define ATA_DMA_ACTIVE 0x01 /* DMA transfer in progress */ void (*alloc)(device_t dev); void (*free)(device_t dev); void (*setprd)(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); int (*load)(struct ata_request *request, void *addr, int *nsegs); int (*unload)(struct ata_request *request); int (*start)(struct ata_request *request); int (*stop)(struct ata_request *request); void (*reset)(device_t dev); }; /* structure holding lowlevel functions */ struct ata_lowlevel { u_int32_t (*softreset)(device_t dev, int pmport); int (*pm_read)(device_t dev, int port, int reg, u_int32_t *result); int (*pm_write)(device_t dev, int port, int reg, u_int32_t value); int (*status)(device_t dev); int (*begin_transaction)(struct ata_request *request); int (*end_transaction)(struct ata_request *request); int (*command)(struct ata_request *request); void (*tf_read)(struct ata_request *request); void (*tf_write)(struct ata_request *request); }; /* structure holding resources for an ATA channel */ struct ata_resource { struct resource *res; int offset; }; #ifdef ATA_CAM struct ata_cam_device { u_int revision; int mode; u_int bytecount; u_int atapi; }; #endif /* structure describing an ATA channel */ struct ata_channel { device_t dev; /* device handle */ int unit; /* physical channel */ int attached; /* channel is attached */ struct ata_resource r_io[ATA_MAX_RES];/* I/O resources */ struct resource *r_irq; /* interrupt of this channel */ void *ih; /* interrupt handle */ struct ata_lowlevel hw; /* lowlevel HW functions */ struct ata_dma dma; /* DMA data / functions */ int flags; /* channel flags */ #define ATA_NO_SLAVE 0x01 #define ATA_USE_16BIT 0x02 #define ATA_ATAPI_DMA_RO 0x04 #define ATA_NO_48BIT_DMA 0x08 #define ATA_ALWAYS_DMASTAT 0x10 #define ATA_CHECKS_CABLE 0x20 #define ATA_NO_ATAPI_DMA 0x40 #define ATA_SATA 0x80 #define ATA_DMA_BEFORE_CMD 0x100 +#define ATA_KNOWN_PRESENCE 0x200 int pm_level; /* power management level */ int devices; /* what is present */ #define ATA_ATA_MASTER 0x00000001 #define ATA_ATA_SLAVE 0x00000002 #define ATA_PORTMULTIPLIER 0x00008000 #define ATA_ATAPI_MASTER 0x00010000 #define ATA_ATAPI_SLAVE 0x00020000 struct mtx state_mtx; /* state lock */ int state; /* ATA channel state */ #define ATA_IDLE 0x0000 #define ATA_ACTIVE 0x0001 #define ATA_STALL_QUEUE 0x0002 struct mtx queue_mtx; /* queue lock */ TAILQ_HEAD(, ata_request) ata_queue; /* head of ATA queue */ struct ata_request *freezepoint; /* composite freezepoint */ struct ata_request *running; /* currently running request */ struct task conntask; /* PHY events handling task */ #ifdef ATA_CAM struct cam_sim *sim; struct cam_path *path; struct ata_cam_device user[16]; /* User-specified settings */ struct ata_cam_device curr[16]; /* Current settings */ #endif }; /* disk bay/enclosure related */ #define ATA_LED_OFF 0x00 #define ATA_LED_RED 0x01 #define ATA_LED_GREEN 0x02 #define ATA_LED_ORANGE 0x03 #define ATA_LED_MASK 0x03 /* externs */ extern int (*ata_raid_ioctl_func)(u_long cmd, caddr_t data); extern struct intr_config_hook *ata_delayed_attach; extern devclass_t ata_devclass; extern int ata_wc; extern int ata_setmax; extern int ata_dma_check_80pin; /* public prototypes */ /* ata-all.c: */ int ata_probe(device_t dev); int ata_attach(device_t dev); int ata_detach(device_t dev); int ata_reinit(device_t dev); int ata_suspend(device_t dev); int ata_resume(device_t dev); void ata_interrupt(void *data); int ata_device_ioctl(device_t dev, u_long cmd, caddr_t data); int ata_getparam(struct ata_device *atadev, int init); int ata_identify(device_t dev); void ata_default_registers(device_t dev); void ata_modify_if_48bit(struct ata_request *request); void ata_udelay(int interval); char *ata_unit2str(struct ata_device *atadev); const char *ata_mode2str(int mode); int ata_str2mode(const char *str); const char *ata_satarev2str(int rev); int ata_atapi(device_t dev, int target); int ata_pmode(struct ata_params *ap); int ata_wmode(struct ata_params *ap); int ata_umode(struct ata_params *ap); int ata_limit_mode(device_t dev, int mode, int maxmode); void ata_setmode(device_t dev); void ata_print_cable(device_t dev, u_int8_t *who); int ata_check_80pin(device_t dev, int mode); #ifdef ATA_CAM void ata_cam_begin_transaction(device_t dev, union ccb *ccb); void ata_cam_end_transaction(device_t dev, struct ata_request *request); #endif /* ata-queue.c: */ int ata_controlcmd(device_t dev, u_int8_t command, u_int16_t feature, u_int64_t lba, u_int16_t count); int ata_atapicmd(device_t dev, u_int8_t *ccb, caddr_t data, int count, int flags, int timeout); void ata_queue_request(struct ata_request *request); void ata_start(device_t dev); void ata_finish(struct ata_request *request); void ata_timeout(struct ata_request *); void ata_catch_inflight(device_t dev); void ata_fail_requests(device_t dev); void ata_drop_requests(device_t dev); char *ata_cmd2str(struct ata_request *request); /* ata-lowlevel.c: */ void ata_generic_hw(device_t dev); int ata_begin_transaction(struct ata_request *); int ata_end_transaction(struct ata_request *); void ata_generic_reset(device_t dev); int ata_generic_command(struct ata_request *request); /* ata-dma.c: */ void ata_dmainit(device_t); void ata_dmafini(device_t dev); /* ata-sata.c: */ void ata_sata_phy_check_events(device_t dev); int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val); int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val); int ata_sata_phy_reset(device_t dev, int port, int quick); int ata_sata_setmode(device_t dev, int target, int mode); int ata_sata_getrev(device_t dev, int target); int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis); void ata_pm_identify(device_t dev); /* macros for alloc/free of struct ata_request */ extern uma_zone_t ata_request_zone; #define ata_alloc_request() uma_zalloc(ata_request_zone, M_NOWAIT | M_ZERO) #define ata_free_request(request) { \ if (!(request->flags & ATA_R_DANGER2)) \ uma_zfree(ata_request_zone, request); \ } /* macros for alloc/free of struct ata_composite */ extern uma_zone_t ata_composite_zone; #define ata_alloc_composite() uma_zalloc(ata_composite_zone, M_NOWAIT | M_ZERO) #define ata_free_composite(composite) uma_zfree(ata_composite_zone, composite) MALLOC_DECLARE(M_ATA); /* misc newbus defines */ #define GRANDPARENT(dev) device_get_parent(device_get_parent(dev)) /* macros to hide busspace uglyness */ #define ATA_INB(res, offset) \ bus_read_1((res), (offset)) #define ATA_INW(res, offset) \ bus_read_2((res), (offset)) #define ATA_INL(res, offset) \ bus_read_4((res), (offset)) #define ATA_INSW(res, offset, addr, count) \ bus_read_multi_2((res), (offset), (addr), (count)) #define ATA_INSW_STRM(res, offset, addr, count) \ bus_read_multi_stream_2((res), (offset), (addr), (count)) #define ATA_INSL(res, offset, addr, count) \ bus_read_multi_4((res), (offset), (addr), (count)) #define ATA_INSL_STRM(res, offset, addr, count) \ bus_read_multi_stream_4((res), (offset), (addr), (count)) #define ATA_OUTB(res, offset, value) \ bus_write_1((res), (offset), (value)) #define ATA_OUTW(res, offset, value) \ bus_write_2((res), (offset), (value)) #define ATA_OUTL(res, offset, value) \ bus_write_4((res), (offset), (value)) #define ATA_OUTSW(res, offset, addr, count) \ bus_write_multi_2((res), (offset), (addr), (count)) #define ATA_OUTSW_STRM(res, offset, addr, count) \ bus_write_multi_stream_2((res), (offset), (addr), (count)) #define ATA_OUTSL(res, offset, addr, count) \ bus_write_multi_4((res), (offset), (addr), (count)) #define ATA_OUTSL_STRM(res, offset, addr, count) \ bus_write_multi_stream_4((res), (offset), (addr), (count)) #define ATA_IDX_INB(ch, idx) \ ATA_INB(ch->r_io[idx].res, ch->r_io[idx].offset) #define ATA_IDX_INW(ch, idx) \ ATA_INW(ch->r_io[idx].res, ch->r_io[idx].offset) #define ATA_IDX_INL(ch, idx) \ ATA_INL(ch->r_io[idx].res, ch->r_io[idx].offset) #define ATA_IDX_INSW(ch, idx, addr, count) \ ATA_INSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_INSW_STRM(ch, idx, addr, count) \ ATA_INSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_INSL(ch, idx, addr, count) \ ATA_INSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_INSL_STRM(ch, idx, addr, count) \ ATA_INSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTB(ch, idx, value) \ ATA_OUTB(ch->r_io[idx].res, ch->r_io[idx].offset, value) #define ATA_IDX_OUTW(ch, idx, value) \ ATA_OUTW(ch->r_io[idx].res, ch->r_io[idx].offset, value) #define ATA_IDX_OUTL(ch, idx, value) \ ATA_OUTL(ch->r_io[idx].res, ch->r_io[idx].offset, value) #define ATA_IDX_OUTSW(ch, idx, addr, count) \ ATA_OUTSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTSW_STRM(ch, idx, addr, count) \ ATA_OUTSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTSL(ch, idx, addr, count) \ ATA_OUTSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) #define ATA_IDX_OUTSL_STRM(ch, idx, addr, count) \ ATA_OUTSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) Index: stable/8/sys/dev/ata/ata-lowlevel.c =================================================================== --- stable/8/sys/dev/ata/ata-lowlevel.c (revision 212718) +++ stable/8/sys/dev/ata/ata-lowlevel.c (revision 212719) @@ -1,876 +1,872 @@ /*- * Copyright (c) 1998 - 2008 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "opt_ata.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* prototypes */ static int ata_generic_status(device_t dev); static int ata_wait(struct ata_channel *ch, int unit, u_int8_t); static void ata_pio_read(struct ata_request *, int); static void ata_pio_write(struct ata_request *, int); static void ata_tf_read(struct ata_request *); static void ata_tf_write(struct ata_request *); /* * low level ATA functions */ void ata_generic_hw(device_t dev) { struct ata_channel *ch = device_get_softc(dev); ch->hw.begin_transaction = ata_begin_transaction; ch->hw.end_transaction = ata_end_transaction; ch->hw.status = ata_generic_status; ch->hw.softreset = NULL; ch->hw.command = ata_generic_command; ch->hw.tf_read = ata_tf_read; ch->hw.tf_write = ata_tf_write; ch->hw.pm_read = NULL; ch->hw.pm_write = NULL; } /* must be called with ATA channel locked and state_mtx held */ int ata_begin_transaction(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); int dummy, error; ATA_DEBUG_RQ(request, "begin transaction"); /* disable ATAPI DMA writes if HW doesn't support it */ if ((ch->flags & ATA_NO_ATAPI_DMA) && (request->flags & ATA_R_ATAPI) == ATA_R_ATAPI) request->flags &= ~ATA_R_DMA; if ((ch->flags & ATA_ATAPI_DMA_RO) && ((request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)) == (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE))) request->flags &= ~ATA_R_DMA; switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA)) { /* ATA PIO data transfer and control commands */ default: { /* record command direction here as our request might be gone later */ int write = (request->flags & ATA_R_WRITE); /* issue command */ if (ch->hw.command(request)) { device_printf(request->parent, "error issuing %s command\n", ata_cmd2str(request)); request->result = EIO; goto begin_finished; } /* device reset doesn't interrupt */ if (request->u.ata.command == ATA_DEVICE_RESET) { int timeout = 1000000; do { DELAY(10); request->status = ATA_IDX_INB(ch, ATA_STATUS); } while (request->status & ATA_S_BUSY && timeout--); if (request->status & ATA_S_ERROR) request->error = ATA_IDX_INB(ch, ATA_ERROR); goto begin_finished; } /* if write command output the data */ if (write) { if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) { device_printf(request->parent, "timeout waiting for write DRQ\n"); request->result = EIO; goto begin_finished; } ata_pio_write(request, request->transfersize); } } goto begin_continue; /* ATA DMA data transfer commands */ case ATA_R_DMA: /* check sanity, setup SG list and DMA engine */ if ((error = ch->dma.load(request, NULL, &dummy))) { device_printf(request->parent, "setting up DMA failed\n"); request->result = error; goto begin_finished; } /* start DMA engine if necessary */ if ((ch->flags & ATA_DMA_BEFORE_CMD) && ch->dma.start && ch->dma.start(request)) { device_printf(request->parent, "error starting DMA\n"); request->result = EIO; goto begin_finished; } /* issue command */ if (ch->hw.command(request)) { device_printf(request->parent, "error issuing %s command\n", ata_cmd2str(request)); request->result = EIO; goto begin_finished; } /* start DMA engine */ if (!(ch->flags & ATA_DMA_BEFORE_CMD) && ch->dma.start && ch->dma.start(request)) { device_printf(request->parent, "error starting DMA\n"); request->result = EIO; goto begin_finished; } goto begin_continue; /* ATAPI PIO commands */ case ATA_R_ATAPI: /* is this just a POLL DSC command ? */ if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit)); DELAY(10); if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC)) request->result = EBUSY; goto begin_finished; } /* start ATAPI operation */ if (ch->hw.command(request)) { device_printf(request->parent, "error issuing ATA PACKET command\n"); request->result = EIO; goto begin_finished; } goto begin_continue; /* ATAPI DMA commands */ case ATA_R_ATAPI|ATA_R_DMA: /* is this just a POLL DSC command ? */ if (request->u.atapi.ccb[0] == ATAPI_POLL_DSC) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit)); DELAY(10); if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DSC)) request->result = EBUSY; goto begin_finished; } /* check sanity, setup SG list and DMA engine */ if ((error = ch->dma.load(request, NULL, &dummy))) { device_printf(request->parent, "setting up DMA failed\n"); request->result = error; goto begin_finished; } /* start ATAPI operation */ if (ch->hw.command(request)) { device_printf(request->parent, "error issuing ATA PACKET command\n"); request->result = EIO; goto begin_finished; } /* start DMA engine */ if (ch->dma.start && ch->dma.start(request)) { request->result = EIO; goto begin_finished; } goto begin_continue; } /* NOT REACHED */ printf("ata_begin_transaction OOPS!!!\n"); begin_finished: if (ch->dma.unload) { ch->dma.unload(request); } return ATA_OP_FINISHED; begin_continue: callout_reset(&request->callout, request->timeout * hz, (timeout_t*)ata_timeout, request); return ATA_OP_CONTINUES; } /* must be called with ATA channel locked and state_mtx held */ int ata_end_transaction(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); int length; ATA_DEBUG_RQ(request, "end transaction"); /* clear interrupt and get status */ request->status = ATA_IDX_INB(ch, ATA_STATUS); switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_CONTROL)) { /* ATA PIO data transfer and control commands */ default: /* on timeouts we have no data or anything so just return */ if (request->flags & ATA_R_TIMEOUT) goto end_finished; /* on control commands read back registers to the request struct */ if (request->flags & ATA_R_CONTROL) { ch->hw.tf_read(request); } /* if we got an error we are done with the HW */ if (request->status & ATA_S_ERROR) { request->error = ATA_IDX_INB(ch, ATA_ERROR); goto end_finished; } /* are we moving data ? */ if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { /* if read data get it */ if (request->flags & ATA_R_READ) { int flags = ATA_S_DRQ; if (request->u.ata.command != ATA_ATAPI_IDENTIFY) flags |= ATA_S_READY; if (ata_wait(ch, request->unit, flags) < 0) { device_printf(request->parent, "timeout waiting for read DRQ\n"); request->result = EIO; goto end_finished; } ata_pio_read(request, request->transfersize); } /* update how far we've gotten */ request->donecount += request->transfersize; /* do we need a scoop more ? */ if (request->bytecount > request->donecount) { /* set this transfer size according to HW capabilities */ request->transfersize = min((request->bytecount - request->donecount), request->transfersize); /* if data write command, output the data */ if (request->flags & ATA_R_WRITE) { /* if we get an error here we are done with the HW */ if (ata_wait(ch, request->unit, (ATA_S_READY | ATA_S_DRQ)) < 0) { device_printf(request->parent, "timeout waiting for write DRQ\n"); request->status = ATA_IDX_INB(ch, ATA_STATUS); goto end_finished; } /* output data and return waiting for new interrupt */ ata_pio_write(request, request->transfersize); goto end_continue; } /* if data read command, return & wait for interrupt */ if (request->flags & ATA_R_READ) goto end_continue; } } /* done with HW */ goto end_finished; /* ATA DMA data transfer commands */ case ATA_R_DMA: /* stop DMA engine and get status */ if (ch->dma.stop) request->dma->status = ch->dma.stop(request); /* did we get error or data */ if (request->status & ATA_S_ERROR) request->error = ATA_IDX_INB(ch, ATA_ERROR); else if (request->dma->status & ATA_BMSTAT_ERROR) request->status |= ATA_S_ERROR; else if (!(request->flags & ATA_R_TIMEOUT)) request->donecount = request->bytecount; /* release SG list etc */ ch->dma.unload(request); /* done with HW */ goto end_finished; /* ATAPI PIO commands */ case ATA_R_ATAPI: length = ATA_IDX_INB(ch, ATA_CYL_LSB)|(ATA_IDX_INB(ch, ATA_CYL_MSB)<<8); /* on timeouts we have no data or anything so just return */ if (request->flags & ATA_R_TIMEOUT) goto end_finished; switch ((ATA_IDX_INB(ch, ATA_IREASON) & (ATA_I_CMD | ATA_I_IN)) | (request->status & ATA_S_DRQ)) { case ATAPI_P_CMDOUT: /* this seems to be needed for some (slow) devices */ DELAY(10); if (!(request->status & ATA_S_DRQ)) { device_printf(request->parent, "command interrupt without DRQ\n"); request->status = ATA_S_ERROR; goto end_finished; } ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, (request->flags & ATA_R_ATAPI16) ? 8 : 6); /* return wait for interrupt */ goto end_continue; case ATAPI_P_WRITE: if (request->flags & ATA_R_READ) { request->status = ATA_S_ERROR; device_printf(request->parent, "%s trying to write on read buffer\n", ata_cmd2str(request)); goto end_finished; break; } ata_pio_write(request, length); request->donecount += length; /* set next transfer size according to HW capabilities */ request->transfersize = min((request->bytecount-request->donecount), request->transfersize); /* return wait for interrupt */ goto end_continue; case ATAPI_P_READ: if (request->flags & ATA_R_WRITE) { request->status = ATA_S_ERROR; device_printf(request->parent, "%s trying to read on write buffer\n", ata_cmd2str(request)); goto end_finished; } ata_pio_read(request, length); request->donecount += length; /* set next transfer size according to HW capabilities */ request->transfersize = min((request->bytecount-request->donecount), request->transfersize); /* return wait for interrupt */ goto end_continue; case ATAPI_P_DONEDRQ: device_printf(request->parent, "WARNING - %s DONEDRQ non conformant device\n", ata_cmd2str(request)); if (request->flags & ATA_R_READ) { ata_pio_read(request, length); request->donecount += length; } else if (request->flags & ATA_R_WRITE) { ata_pio_write(request, length); request->donecount += length; } else request->status = ATA_S_ERROR; /* FALLTHROUGH */ case ATAPI_P_ABORT: case ATAPI_P_DONE: if (request->status & (ATA_S_ERROR | ATA_S_DWF)) request->error = ATA_IDX_INB(ch, ATA_ERROR); goto end_finished; default: device_printf(request->parent, "unknown transfer phase\n"); request->status = ATA_S_ERROR; } /* done with HW */ goto end_finished; /* ATAPI DMA commands */ case ATA_R_ATAPI|ATA_R_DMA: /* stop DMA engine and get status */ if (ch->dma.stop) request->dma->status = ch->dma.stop(request); /* did we get error or data */ if (request->status & (ATA_S_ERROR | ATA_S_DWF)) request->error = ATA_IDX_INB(ch, ATA_ERROR); else if (request->dma->status & ATA_BMSTAT_ERROR) request->status |= ATA_S_ERROR; else if (!(request->flags & ATA_R_TIMEOUT)) request->donecount = request->bytecount; /* release SG list etc */ ch->dma.unload(request); /* done with HW */ goto end_finished; } /* NOT REACHED */ printf("ata_end_transaction OOPS!!\n"); end_finished: callout_stop(&request->callout); return ATA_OP_FINISHED; end_continue: return ATA_OP_CONTINUES; } /* must be called with ATA channel locked and state_mtx held */ void ata_generic_reset(device_t dev) { struct ata_channel *ch = device_get_softc(dev); u_int8_t ostat0 = 0, stat0 = 0, ostat1 = 0, stat1 = 0; u_int8_t err = 0, lsb = 0, msb = 0; int mask = 0, timeout; /* do we have any signs of ATA/ATAPI HW being present ? */ ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER)); DELAY(10); ostat0 = ATA_IDX_INB(ch, ATA_STATUS); - if ((ostat0 & 0xf8) != 0xf8 && ostat0 != 0xa5) { + if (((ostat0 & 0xf8) != 0xf8 || (ch->flags & ATA_KNOWN_PRESENCE)) && + ostat0 != 0xa5) { stat0 = ATA_S_BUSY; mask |= 0x01; } /* in some setups we dont want to test for a slave */ if (!(ch->flags & ATA_NO_SLAVE)) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_SLAVE)); DELAY(10); ostat1 = ATA_IDX_INB(ch, ATA_STATUS); - if ((ostat1 & 0xf8) != 0xf8 && ostat1 != 0xa5) { + if (((ostat1 & 0xf8) != 0xf8 || (ch->flags & ATA_KNOWN_PRESENCE)) && + ostat1 != 0xa5) { stat1 = ATA_S_BUSY; mask |= 0x02; } } if (bootverbose) device_printf(dev, "reset tp1 mask=%02x ostat0=%02x ostat1=%02x\n", mask, ostat0, ostat1); /* if nothing showed up there is no need to get any further */ /* XXX SOS is that too strong?, we just might loose devices here */ ch->devices = 0; if (!mask) return; /* reset (both) devices on this channel */ ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(ATA_MASTER)); DELAY(10); ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS | ATA_A_RESET); ata_udelay(10000); ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS); ata_udelay(100000); ATA_IDX_INB(ch, ATA_ERROR); /* wait for BUSY to go inactive */ for (timeout = 0; timeout < 310; timeout++) { if ((mask & 0x01) && (stat0 & ATA_S_BUSY)) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(ATA_MASTER)); DELAY(10); err = ATA_IDX_INB(ch, ATA_ERROR); lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); msb = ATA_IDX_INB(ch, ATA_CYL_MSB); stat0 = ATA_IDX_INB(ch, ATA_STATUS); if (bootverbose) device_printf(dev, "stat0=0x%02x err=0x%02x lsb=0x%02x msb=0x%02x\n", stat0, err, lsb, msb); if (stat0 == err && lsb == err && msb == err && timeout > (stat0 & ATA_S_BUSY ? 100 : 10)) mask &= ~0x01; if (!(stat0 & ATA_S_BUSY)) { if ((err & 0x7f) == ATA_E_ILI) { if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) { ch->devices |= ATA_ATAPI_MASTER; } else if (stat0 & ATA_S_READY) { ch->devices |= ATA_ATA_MASTER; } } else if ((stat0 & 0x0f) && err == lsb && err == msb) { stat0 |= ATA_S_BUSY; } } } if ((mask & 0x02) && (stat1 & ATA_S_BUSY) && !((mask & 0x01) && (stat0 & ATA_S_BUSY))) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(ATA_SLAVE)); DELAY(10); err = ATA_IDX_INB(ch, ATA_ERROR); lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); msb = ATA_IDX_INB(ch, ATA_CYL_MSB); stat1 = ATA_IDX_INB(ch, ATA_STATUS); if (bootverbose) device_printf(dev, "stat1=0x%02x err=0x%02x lsb=0x%02x msb=0x%02x\n", stat1, err, lsb, msb); if (stat1 == err && lsb == err && msb == err && timeout > (stat1 & ATA_S_BUSY ? 100 : 10)) mask &= ~0x02; if (!(stat1 & ATA_S_BUSY)) { if ((err & 0x7f) == ATA_E_ILI) { if (lsb == ATAPI_MAGIC_LSB && msb == ATAPI_MAGIC_MSB) { ch->devices |= ATA_ATAPI_SLAVE; } else if (stat1 & ATA_S_READY) { ch->devices |= ATA_ATA_SLAVE; } } else if ((stat1 & 0x0f) && err == lsb && err == msb) { stat1 |= ATA_S_BUSY; } } } - if (mask == 0x00) /* nothing to wait for */ - break; - if (mask == 0x01) /* wait for master only */ - if (!(stat0 & ATA_S_BUSY) || (stat0 == 0xff && timeout > 10)) - break; - if (mask == 0x02) /* wait for slave only */ - if (!(stat1 & ATA_S_BUSY) || (stat1 == 0xff && timeout > 10)) - break; - if (mask == 0x03) { /* wait for both master & slave */ - if (!(stat0 & ATA_S_BUSY) && !(stat1 & ATA_S_BUSY)) - break; - if ((stat0 == 0xff) && (timeout > 20)) - mask &= ~0x01; - if ((stat1 == 0xff) && (timeout > 20)) - mask &= ~0x02; + if ((ch->flags & ATA_KNOWN_PRESENCE) == 0 && + timeout > ((mask == 0x03) ? 20 : 10)) { + if ((mask & 0x01) && stat0 == 0xff) + mask &= ~0x01; + if ((mask & 0x02) && stat1 == 0xff) + mask &= ~0x02; } + if (((mask & 0x01) == 0 || !(stat0 & ATA_S_BUSY)) && + ((mask & 0x02) == 0 || !(stat1 & ATA_S_BUSY))) + break; ata_udelay(100000); } if (bootverbose) device_printf(dev, "reset tp2 stat0=%02x stat1=%02x devices=0x%x\n", stat0, stat1, ch->devices); } /* must be called with ATA channel locked and state_mtx held */ int ata_generic_status(device_t dev) { struct ata_channel *ch = device_get_softc(dev); if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) { DELAY(100); if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) return 0; } return 1; } static int ata_wait(struct ata_channel *ch, int unit, u_int8_t mask) { u_int8_t status; int timeout = 0; DELAY(1); /* wait at max 1 second for device to get !BUSY */ while (timeout < 1000000) { status = ATA_IDX_INB(ch, ATA_ALTSTAT); /* if drive fails status, reselect the drive and try again */ if (status == 0xff) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(unit)); timeout += 1000; DELAY(1000); continue; } /* are we done ? */ if (!(status & ATA_S_BUSY)) break; if (timeout > 1000) { timeout += 1000; DELAY(1000); } else { timeout += 10; DELAY(10); } } if (timeout >= 1000000) return -2; if (!mask) return (status & ATA_S_ERROR); DELAY(1); /* wait 50 msec for bits wanted */ timeout = 5000; while (timeout--) { status = ATA_IDX_INB(ch, ATA_ALTSTAT); if ((status & mask) == mask) return (status & ATA_S_ERROR); DELAY(10); } return -3; } int ata_generic_command(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); /* select device */ ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit)); /* ready to issue command ? */ if (ata_wait(ch, request->unit, 0) < 0) { device_printf(request->parent, "timeout waiting to issue command\n"); return -1; } /* enable interrupt */ ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); if (request->flags & ATA_R_ATAPI) { int timeout = 5000; int res; /* issue packet command to controller */ if (request->flags & ATA_R_DMA) { ATA_IDX_OUTB(ch, ATA_FEATURE, ATA_F_DMA); ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0); ATA_IDX_OUTB(ch, ATA_CYL_MSB, 0); } else { ATA_IDX_OUTB(ch, ATA_FEATURE, 0); ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->transfersize); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->transfersize >> 8); } ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_PACKET_CMD); /* command interrupt device ? just return and wait for interrupt */ if (request->flags & ATA_R_ATAPI_INTR) return 0; /* command processed ? */ res = ata_wait(ch, request->unit, 0); if (res != 0) { if (res < 0) device_printf(request->parent, "timeout waiting for PACKET command\n"); return (-1); } /* wait for ready to write ATAPI command block */ while (timeout--) { int reason = ATA_IDX_INB(ch, ATA_IREASON); int status = ATA_IDX_INB(ch, ATA_STATUS); if (((reason & (ATA_I_CMD | ATA_I_IN)) | (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT) break; DELAY(20); } if (timeout <= 0) { device_printf(request->parent, "timeout waiting for ATAPI ready\n"); request->result = EIO; return -1; } /* this seems to be needed for some (slow) devices */ DELAY(10); /* output command block */ ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, (request->flags & ATA_R_ATAPI16) ? 8 : 6); } else { ch->hw.tf_write(request); /* issue command to controller */ ATA_IDX_OUTB(ch, ATA_COMMAND, request->u.ata.command); } return 0; } static void ata_tf_read(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT | ATA_A_HOB); request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8); request->u.ata.lba = ((u_int64_t)(ATA_IDX_INB(ch, ATA_SECTOR)) << 24) | ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_LSB)) << 32) | ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_MSB)) << 40); ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); request->u.ata.count |= ATA_IDX_INB(ch, ATA_COUNT); request->u.ata.lba |= (ATA_IDX_INB(ch, ATA_SECTOR) | (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16)); } else { request->u.ata.count = ATA_IDX_INB(ch, ATA_COUNT); request->u.ata.lba = ATA_IDX_INB(ch, ATA_SECTOR) | (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16) | ((ATA_IDX_INB(ch, ATA_DRIVE) & 0xf) << 24); } } static void ata_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); #ifndef ATA_CAM struct ata_device *atadev = device_get_softc(request->dev); #endif if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8); ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count >> 8); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba >> 24); ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 32); ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 40); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | ATA_DEV(request->unit)); } else { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); #ifndef ATA_CAM if (atadev->flags & ATA_D_USE_CHS) { int heads, sectors; if (atadev->param.atavalid & ATA_FLAG_54_58) { heads = atadev->param.current_heads; sectors = atadev->param.current_sectors; } else { heads = atadev->param.heads; sectors = atadev->param.sectors; } ATA_IDX_OUTB(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); ATA_IDX_OUTB(ch, ATA_CYL_LSB, (request->u.ata.lba / (sectors * heads))); ATA_IDX_OUTB(ch, ATA_CYL_MSB, (request->u.ata.lba / (sectors * heads)) >> 8); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) | (((request->u.ata.lba% (sectors * heads)) / sectors) & 0xf)); } else { #endif ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) | ((request->u.ata.lba >> 24) & 0x0f)); #ifndef ATA_CAM } #endif } } static void ata_pio_read(struct ata_request *request, int length) { struct ata_channel *ch = device_get_softc(request->parent); int size = min(request->transfersize, length); int resid; if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int16_t)); else ATA_IDX_INSL_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int32_t)); if (request->transfersize < length) { device_printf(request->parent, "WARNING - %s read data overrun %d>%d\n", ata_cmd2str(request), length, request->transfersize); for (resid = request->transfersize; resid < length; resid += sizeof(int16_t)) ATA_IDX_INW(ch, ATA_DATA); } } static void ata_pio_write(struct ata_request *request, int length) { struct ata_channel *ch = device_get_softc(request->parent); int size = min(request->transfersize, length); int resid; if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int16_t)); else ATA_IDX_OUTSL_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int32_t)); if (request->transfersize < length) { device_printf(request->parent, "WARNING - %s write data underrun %d>%d\n", ata_cmd2str(request), length, request->transfersize); for (resid = request->transfersize; resid < length; resid += sizeof(int16_t)) ATA_IDX_OUTW(ch, ATA_DATA, 0); } } Index: stable/8/sys/dev/ata/chipsets/ata-siliconimage.c =================================================================== --- stable/8/sys/dev/ata/chipsets/ata-siliconimage.c (revision 212718) +++ stable/8/sys/dev/ata/chipsets/ata-siliconimage.c (revision 212719) @@ -1,878 +1,879 @@ /*- * Copyright (c) 1998 - 2008 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "opt_ata.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* local prototypes */ static int ata_cmd_ch_attach(device_t dev); static int ata_cmd_status(device_t dev); static int ata_cmd_setmode(device_t dev, int target, int mode); static int ata_sii_ch_attach(device_t dev); static int ata_sii_ch_detach(device_t dev); static int ata_sii_status(device_t dev); static void ata_sii_reset(device_t dev); static int ata_sii_setmode(device_t dev, int target, int mode); static int ata_siiprb_ch_attach(device_t dev); static int ata_siiprb_ch_detach(device_t dev); static int ata_siiprb_status(device_t dev); static int ata_siiprb_begin_transaction(struct ata_request *request); static int ata_siiprb_end_transaction(struct ata_request *request); static int ata_siiprb_pm_read(device_t dev, int port, int reg, u_int32_t *result); static int ata_siiprb_pm_write(device_t dev, int port, int reg, u_int32_t result); static u_int32_t ata_siiprb_softreset(device_t dev, int port); static void ata_siiprb_reset(device_t dev); static void ata_siiprb_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error); static void ata_siiprb_dmainit(device_t dev); /* misc defines */ #define SII_MEMIO 1 #define SII_PRBIO 2 #define SII_INTR 0x01 #define SII_SETCLK 0x02 #define SII_BUG 0x04 #define SII_4CH 0x08 /* * Silicon Image Inc. (SiI) (former CMD) chipset support functions */ static int ata_sii_probe(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); static struct ata_chip_id ids[] = {{ ATA_SII3114, 0x00, SII_MEMIO, SII_4CH, ATA_SA150, "3114" }, { ATA_SII3512, 0x02, SII_MEMIO, 0, ATA_SA150, "3512" }, { ATA_SII3112, 0x02, SII_MEMIO, 0, ATA_SA150, "3112" }, { ATA_SII3112_1, 0x02, SII_MEMIO, 0, ATA_SA150, "3112" }, { ATA_SII3512, 0x00, SII_MEMIO, SII_BUG, ATA_SA150, "3512" }, { ATA_SII3112, 0x00, SII_MEMIO, SII_BUG, ATA_SA150, "3112" }, { ATA_SII3112_1, 0x00, SII_MEMIO, SII_BUG, ATA_SA150, "3112" }, { ATA_SII3124, 0x00, SII_PRBIO, SII_4CH, ATA_SA300, "3124" }, { ATA_SII3132, 0x00, SII_PRBIO, 0, ATA_SA300, "3132" }, { ATA_SII3132_1, 0x00, SII_PRBIO, 0, ATA_SA300, "3132" }, { ATA_SII3132_2, 0x00, SII_PRBIO, 0, ATA_SA300, "3132" }, { ATA_SII0680, 0x00, SII_MEMIO, SII_SETCLK, ATA_UDMA6, "680" }, { ATA_CMD649, 0x00, 0, SII_INTR, ATA_UDMA5, "(CMD) 649" }, { ATA_CMD648, 0x00, 0, SII_INTR, ATA_UDMA4, "(CMD) 648" }, { ATA_CMD646, 0x07, 0, 0, ATA_UDMA2, "(CMD) 646U2" }, { ATA_CMD646, 0x00, 0, 0, ATA_WDMA2, "(CMD) 646" }, { 0, 0, 0, 0, 0, 0}}; if (pci_get_vendor(dev) != ATA_SILICON_IMAGE_ID) return ENXIO; if (!(ctlr->chip = ata_match_chip(dev, ids))) return ENXIO; ata_set_desc(dev); ctlr->chipinit = ata_sii_chipinit; return (BUS_PROBE_DEFAULT); } int ata_sii_chipinit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; switch (ctlr->chip->cfg1) { case SII_PRBIO: ctlr->r_type1 = SYS_RES_MEMORY; ctlr->r_rid1 = PCIR_BAR(0); if (!(ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1, &ctlr->r_rid1, RF_ACTIVE))) return ENXIO; ctlr->r_rid2 = PCIR_BAR(2); ctlr->r_type2 = SYS_RES_MEMORY; if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, &ctlr->r_rid2, RF_ACTIVE))){ bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1,ctlr->r_res1); return ENXIO; } ctlr->ch_attach = ata_siiprb_ch_attach; ctlr->ch_detach = ata_siiprb_ch_detach; ctlr->reset = ata_siiprb_reset; ctlr->setmode = ata_sata_setmode; ctlr->getrev = ata_sata_getrev; ctlr->channels = (ctlr->chip->cfg2 == SII_4CH) ? 4 : 2; /* reset controller */ ATA_OUTL(ctlr->r_res1, 0x0040, 0x80000000); DELAY(10000); ATA_OUTL(ctlr->r_res1, 0x0040, 0x0000000f); break; case SII_MEMIO: ctlr->r_type2 = SYS_RES_MEMORY; ctlr->r_rid2 = PCIR_BAR(5); if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, &ctlr->r_rid2, RF_ACTIVE))){ if (ctlr->chip->chipid != ATA_SII0680 || (pci_read_config(dev, 0x8a, 1) & 1)) return ENXIO; } if (ctlr->chip->cfg2 & SII_SETCLK) { if ((pci_read_config(dev, 0x8a, 1) & 0x30) != 0x10) pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0xcf)|0x10,1); if ((pci_read_config(dev, 0x8a, 1) & 0x30) != 0x10) device_printf(dev, "%s could not set ATA133 clock\n", ctlr->chip->text); } /* if we have 4 channels enable the second set */ if (ctlr->chip->cfg2 & SII_4CH) { ATA_OUTL(ctlr->r_res2, 0x0200, 0x00000002); ctlr->channels = 4; } /* dont block interrupts from any channel */ pci_write_config(dev, 0x48, (pci_read_config(dev, 0x48, 4) & ~0x03c00000), 4); /* enable PCI interrupt as BIOS might not */ pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1); if (ctlr->r_res2) { ctlr->ch_attach = ata_sii_ch_attach; ctlr->ch_detach = ata_sii_ch_detach; } if (ctlr->chip->max_dma >= ATA_SA150) { ctlr->reset = ata_sii_reset; ctlr->setmode = ata_sata_setmode; ctlr->getrev = ata_sata_getrev; } else ctlr->setmode = ata_sii_setmode; break; default: if ((pci_read_config(dev, 0x51, 1) & 0x08) != 0x08) { device_printf(dev, "HW has secondary channel disabled\n"); ctlr->channels = 1; } /* enable interrupt as BIOS might not */ pci_write_config(dev, 0x71, 0x01, 1); ctlr->ch_attach = ata_cmd_ch_attach; ctlr->ch_detach = ata_pci_ch_detach; ctlr->setmode = ata_cmd_setmode; break; } return 0; } static int ata_cmd_ch_attach(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); /* setup the usual register normal pci style */ if (ata_pci_ch_attach(dev)) return ENXIO; if (ctlr->chip->cfg2 & SII_INTR) ch->hw.status = ata_cmd_status; return 0; } static int ata_cmd_status(device_t dev) { struct ata_channel *ch = device_get_softc(dev); u_int8_t reg71; if (((reg71 = pci_read_config(device_get_parent(dev), 0x71, 1)) & (ch->unit ? 0x08 : 0x04))) { pci_write_config(device_get_parent(dev), 0x71, reg71 & ~(ch->unit ? 0x04 : 0x08), 1); return ata_pci_status(dev); } return 0; } static int ata_cmd_setmode(device_t dev, int target, int mode) { device_t parent = device_get_parent(dev); struct ata_pci_controller *ctlr = device_get_softc(parent); struct ata_channel *ch = device_get_softc(dev); int devno = (ch->unit << 1) + target; int treg = 0x54 + ((devno < 3) ? (devno << 1) : 7); int ureg = ch->unit ? 0x7b : 0x73; int piomode; uint8_t piotimings[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f, 0x87, 0x32, 0x3f }; uint8_t udmatimings[][2] = { { 0x31, 0xc2 }, { 0x21, 0x82 }, { 0x11, 0x42 }, { 0x25, 0x8a }, { 0x15, 0x4a }, { 0x05, 0x0a } }; mode = min(mode, ctlr->chip->max_dma); if (mode >= ATA_UDMA0) { u_int8_t umode = pci_read_config(parent, ureg, 1); umode &= ~(target == 0 ? 0x35 : 0xca); umode |= udmatimings[mode & ATA_MODE_MASK][target]; pci_write_config(parent, ureg, umode, 1); piomode = ATA_PIO4; } else { pci_write_config(parent, ureg, pci_read_config(parent, ureg, 1) & ~(target == 0 ? 0x35 : 0xca), 1); piomode = mode; } pci_write_config(parent, treg, piotimings[ata_mode2idx(piomode)], 1); return (mode); } static int ata_sii_ch_attach(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); int unit01 = (ch->unit & 1), unit10 = (ch->unit & 2); int i; ata_pci_dmainit(dev); for (i = ATA_DATA; i <= ATA_COMMAND; i++) { ch->r_io[i].res = ctlr->r_res2; ch->r_io[i].offset = 0x80 + i + (unit01 << 6) + (unit10 << 8); } ch->r_io[ATA_CONTROL].res = ctlr->r_res2; ch->r_io[ATA_CONTROL].offset = 0x8a + (unit01 << 6) + (unit10 << 8); ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2; ata_default_registers(dev); ch->r_io[ATA_BMCMD_PORT].res = ctlr->r_res2; ch->r_io[ATA_BMCMD_PORT].offset = 0x00 + (unit01 << 3) + (unit10 << 8); ch->r_io[ATA_BMSTAT_PORT].res = ctlr->r_res2; ch->r_io[ATA_BMSTAT_PORT].offset = 0x02 + (unit01 << 3) + (unit10 << 8); ch->r_io[ATA_BMDTP_PORT].res = ctlr->r_res2; ch->r_io[ATA_BMDTP_PORT].offset = 0x04 + (unit01 << 3) + (unit10 << 8); if (ctlr->chip->max_dma >= ATA_SA150) { ch->r_io[ATA_SSTATUS].res = ctlr->r_res2; ch->r_io[ATA_SSTATUS].offset = 0x104 + (unit01 << 7) + (unit10 << 8); ch->r_io[ATA_SERROR].res = ctlr->r_res2; ch->r_io[ATA_SERROR].offset = 0x108 + (unit01 << 7) + (unit10 << 8); ch->r_io[ATA_SCONTROL].res = ctlr->r_res2; ch->r_io[ATA_SCONTROL].offset = 0x100 + (unit01 << 7) + (unit10 << 8); ch->flags |= ATA_NO_SLAVE; ch->flags |= ATA_SATA; + ch->flags |= ATA_KNOWN_PRESENCE; /* enable PHY state change interrupt */ ATA_OUTL(ctlr->r_res2, 0x148 + (unit01 << 7) + (unit10 << 8),(1 << 16)); } if (ctlr->chip->cfg2 & SII_BUG) { /* work around errata in early chips */ ch->dma.boundary = 8192; ch->dma.segsize = 15 * DEV_BSIZE; } ata_pci_hw(dev); ch->hw.status = ata_sii_status; if (ctlr->chip->cfg2 & SII_SETCLK) ch->flags |= ATA_CHECKS_CABLE; return 0; } static int ata_sii_ch_detach(device_t dev) { ata_pci_dmafini(dev); return (0); } static int ata_sii_status(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); int offset0 = ((ch->unit & 1) << 3) + ((ch->unit & 2) << 8); int offset1 = ((ch->unit & 1) << 6) + ((ch->unit & 2) << 8); /* do we have any PHY events ? */ if (ctlr->chip->max_dma >= ATA_SA150 && (ATA_INL(ctlr->r_res2, 0x10 + offset0) & 0x00000010)) ata_sata_phy_check_events(dev); if (ATA_INL(ctlr->r_res2, 0xa0 + offset1) & 0x00000800) return ata_pci_status(dev); else return 0; } static void ata_sii_reset(device_t dev) { struct ata_channel *ch = device_get_softc(dev); if (ata_sata_phy_reset(dev, -1, 1)) ata_generic_reset(dev); else ch->devices = 0; } static int ata_sii_setmode(device_t dev, int target, int mode) { device_t parent = device_get_parent(dev); struct ata_pci_controller *ctlr = device_get_softc(parent); struct ata_channel *ch = device_get_softc(dev); int rego = (ch->unit << 4) + (target << 1); int mreg = ch->unit ? 0x84 : 0x80; int mask = 0x03 << (target << 2); int mval = pci_read_config(parent, mreg, 1) & ~mask; int piomode; u_int8_t preg = 0xa4 + rego; u_int8_t dreg = 0xa8 + rego; u_int8_t ureg = 0xac + rego; u_int16_t piotimings[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; u_int16_t dmatimings[] = { 0x2208, 0x10c2, 0x10c1 }; u_int8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 }; mode = min(mode, ctlr->chip->max_dma); if (ctlr->chip->cfg2 & SII_SETCLK) { if (ata_dma_check_80pin && mode > ATA_UDMA2 && (pci_read_config(parent, 0x79, 1) & (ch->unit ? 0x02 : 0x01))) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } if (mode >= ATA_UDMA0) { pci_write_config(parent, mreg, mval | (0x03 << (target << 2)), 1); pci_write_config(parent, ureg, (pci_read_config(parent, ureg, 1) & ~0x3f) | udmatimings[mode & ATA_MODE_MASK], 1); piomode = ATA_PIO4; } else if (mode >= ATA_WDMA0) { pci_write_config(parent, mreg, mval | (0x02 << (target << 2)), 1); pci_write_config(parent, dreg, dmatimings[mode & ATA_MODE_MASK], 2); piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; } else { pci_write_config(parent, mreg, mval | (0x01 << (target << 2)), 1); piomode = mode; } pci_write_config(parent, preg, piotimings[ata_mode2idx(piomode)], 2); return (mode); } struct ata_siiprb_dma_prdentry { u_int64_t addr; u_int32_t count; u_int32_t control; } __packed; #define ATA_SIIPRB_DMA_ENTRIES 129 struct ata_siiprb_ata_command { struct ata_siiprb_dma_prdentry prd[ATA_SIIPRB_DMA_ENTRIES]; } __packed; struct ata_siiprb_atapi_command { u_int8_t ccb[16]; struct ata_siiprb_dma_prdentry prd[ATA_SIIPRB_DMA_ENTRIES]; } __packed; struct ata_siiprb_command { u_int16_t control; u_int16_t protocol_override; u_int32_t transfer_count; u_int8_t fis[24]; union { struct ata_siiprb_ata_command ata; struct ata_siiprb_atapi_command atapi; } u; } __packed; static int ata_siiprb_ch_attach(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); int offset = ch->unit * 0x2000; ata_siiprb_dmainit(dev); /* set the SATA resources */ ch->r_io[ATA_SSTATUS].res = ctlr->r_res2; ch->r_io[ATA_SSTATUS].offset = 0x1f04 + offset; ch->r_io[ATA_SERROR].res = ctlr->r_res2; ch->r_io[ATA_SERROR].offset = 0x1f08 + offset; ch->r_io[ATA_SCONTROL].res = ctlr->r_res2; ch->r_io[ATA_SCONTROL].offset = 0x1f00 + offset; ch->r_io[ATA_SACTIVE].res = ctlr->r_res2; ch->r_io[ATA_SACTIVE].offset = 0x1f0c + offset; ch->hw.status = ata_siiprb_status; ch->hw.begin_transaction = ata_siiprb_begin_transaction; ch->hw.end_transaction = ata_siiprb_end_transaction; ch->hw.command = NULL; /* not used here */ ch->hw.softreset = ata_siiprb_softreset; ch->hw.pm_read = ata_siiprb_pm_read; ch->hw.pm_write = ata_siiprb_pm_write; ch->flags |= ATA_NO_SLAVE; ch->flags |= ATA_SATA; return 0; } static int ata_siiprb_ch_detach(device_t dev) { ata_dmafini(dev); return 0; } static int ata_siiprb_status(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); u_int32_t action = ATA_INL(ctlr->r_res1, 0x0044); int offset = ch->unit * 0x2000; if (action & (1 << ch->unit)) { u_int32_t istatus = ATA_INL(ctlr->r_res2, 0x1008 + offset); /* do we have any PHY events ? */ ata_sata_phy_check_events(dev); /* clear interrupt(s) */ ATA_OUTL(ctlr->r_res2, 0x1008 + offset, istatus); /* do we have any device action ? */ return (istatus & 0x00000003); } return 0; } static int ata_siiprb_begin_transaction(struct ata_request *request) { struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent)); struct ata_channel *ch = device_get_softc(request->parent); struct ata_siiprb_command *prb; struct ata_siiprb_dma_prdentry *prd; int offset = ch->unit * 0x2000; u_int64_t prb_bus; /* SOS XXX */ if (request->u.ata.command == ATA_DEVICE_RESET) { request->result = 0; return ATA_OP_FINISHED; } /* get a piece of the workspace for this request */ prb = (struct ata_siiprb_command *)ch->dma.work; /* clear the prb structure */ bzero(prb, sizeof(struct ata_siiprb_command)); /* setup the FIS for this request */ if (!ata_request2fis_h2d(request, &prb->fis[0])) { device_printf(request->parent, "setting up SATA FIS failed\n"); request->result = EIO; return ATA_OP_FINISHED; } /* setup transfer type */ if (request->flags & ATA_R_ATAPI) { bcopy(request->u.atapi.ccb, prb->u.atapi.ccb, 16); if (request->flags & ATA_R_ATAPI16) ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x00000020); else ATA_OUTL(ctlr->r_res2, 0x1004 + offset, 0x00000020); if (request->flags & ATA_R_READ) prb->control = htole16(0x0010); if (request->flags & ATA_R_WRITE) prb->control = htole16(0x0020); prd = &prb->u.atapi.prd[0]; } else prd = &prb->u.ata.prd[0]; /* if request moves data setup and load SG list */ if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { if (ch->dma.load(request, prd, NULL)) { device_printf(request->parent, "setting up DMA failed\n"); request->result = EIO; return ATA_OP_FINISHED; } } /* activate the prb */ prb_bus = ch->dma.work_bus; ATA_OUTL(ctlr->r_res2, 0x1c00 + offset, prb_bus); ATA_OUTL(ctlr->r_res2, 0x1c04 + offset, prb_bus>>32); /* start the timeout */ callout_reset(&request->callout, request->timeout * hz, (timeout_t*)ata_timeout, request); return ATA_OP_CONTINUES; } static int ata_siiprb_end_transaction(struct ata_request *request) { struct ata_pci_controller *ctlr=device_get_softc(device_get_parent(request->parent)); struct ata_channel *ch = device_get_softc(request->parent); struct ata_siiprb_command *prb; int offset = ch->unit * 0x2000; int error, timeout; /* kill the timeout */ callout_stop(&request->callout); prb = (struct ata_siiprb_command *) ((u_int8_t *)rman_get_virtual(ctlr->r_res2) + offset); /* any controller errors flagged ? */ if ((error = ATA_INL(ctlr->r_res2, 0x1024 + offset))) { if (bootverbose) printf("ata_siiprb_end_transaction %s error=%08x\n", ata_cmd2str(request), error); /* if device error status get details */ if (error == 1 || error == 2) { request->status = prb->fis[2]; if (request->status & ATA_S_ERROR) request->error = prb->fis[3]; } /* SOS XXX handle other controller errors here */ /* initialize port */ ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x00000004); /* poll for port ready */ for (timeout = 0; timeout < 1000; timeout++) { DELAY(1000); if (ATA_INL(ctlr->r_res2, 0x1008 + offset) & 0x00040000) break; } if (bootverbose) { if (timeout >= 1000) device_printf(ch->dev, "port initialize timeout\n"); else device_printf(ch->dev, "port initialize time=%dms\n", timeout); } } /* on control commands read back registers to the request struct */ if (request->flags & ATA_R_CONTROL) { request->u.ata.count = prb->fis[12] | ((u_int16_t)prb->fis[13] << 8); request->u.ata.lba = prb->fis[4] | ((u_int64_t)prb->fis[5] << 8) | ((u_int64_t)prb->fis[6] << 16); if (request->flags & ATA_R_48BIT) request->u.ata.lba |= ((u_int64_t)prb->fis[8] << 24) | ((u_int64_t)prb->fis[9] << 32) | ((u_int64_t)prb->fis[10] << 40); else request->u.ata.lba |= ((u_int64_t)(prb->fis[7] & 0x0f) << 24); } /* update progress */ if (!(request->status & ATA_S_ERROR) && !(request->flags & ATA_R_TIMEOUT)) { if (request->flags & ATA_R_READ) request->donecount = prb->transfer_count; else request->donecount = request->bytecount; } /* release SG list etc */ ch->dma.unload(request); return ATA_OP_FINISHED; } static int ata_siiprb_issue_cmd(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); u_int64_t prb_bus = ch->dma.work_bus; u_int32_t status; int offset = ch->unit * 0x2000; int timeout; /* issue command to chip */ ATA_OUTL(ctlr->r_res2, 0x1c00 + offset, prb_bus); ATA_OUTL(ctlr->r_res2, 0x1c04 + offset, prb_bus >> 32); /* poll for command finished */ for (timeout = 0; timeout < 10000; timeout++) { DELAY(1000); if ((status = ATA_INL(ctlr->r_res2, 0x1008 + offset)) & 0x00010000) break; } // SOS XXX ATA_OUTL(ctlr->r_res2, 0x1008 + offset, 0x00010000); ATA_OUTL(ctlr->r_res2, 0x1008 + offset, 0x08ff08ff); if (timeout >= 1000) return EIO; if (bootverbose) device_printf(dev, "siiprb_issue_cmd time=%dms status=%08x\n", timeout, status); return 0; } static int ata_siiprb_pm_read(device_t dev, int port, int reg, u_int32_t *result) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); struct ata_siiprb_command *prb = (struct ata_siiprb_command *)ch->dma.work; int offset = ch->unit * 0x2000; bzero(prb, sizeof(struct ata_siiprb_command)); prb->fis[0] = 0x27; /* host to device */ prb->fis[1] = 0x8f; /* command FIS to PM port */ prb->fis[2] = ATA_READ_PM; prb->fis[3] = reg; prb->fis[7] = port; if (ata_siiprb_issue_cmd(dev)) { device_printf(dev, "error reading PM port\n"); return EIO; } prb = (struct ata_siiprb_command *) ((u_int8_t *)rman_get_virtual(ctlr->r_res2) + offset); *result = prb->fis[12]|(prb->fis[4]<<8)|(prb->fis[5]<<16)|(prb->fis[6]<<24); return 0; } static int ata_siiprb_pm_write(device_t dev, int port, int reg, u_int32_t value) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); struct ata_siiprb_command *prb = (struct ata_siiprb_command *)ch->dma.work; int offset = ch->unit * 0x2000; bzero(prb, sizeof(struct ata_siiprb_command)); prb->fis[0] = 0x27; /* host to device */ prb->fis[1] = 0x8f; /* command FIS to PM port */ prb->fis[2] = ATA_WRITE_PM; prb->fis[3] = reg; prb->fis[7] = port; prb->fis[12] = value & 0xff; prb->fis[4] = (value >> 8) & 0xff; prb->fis[5] = (value >> 16) & 0xff; prb->fis[6] = (value >> 24) & 0xff; if (ata_siiprb_issue_cmd(dev)) { device_printf(dev, "error writing PM port\n"); return ATA_E_ABORT; } prb = (struct ata_siiprb_command *) ((u_int8_t *)rman_get_virtual(ctlr->r_res2) + offset); return prb->fis[3]; } static u_int32_t ata_siiprb_softreset(device_t dev, int port) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); struct ata_siiprb_command *prb = (struct ata_siiprb_command *)ch->dma.work; u_int32_t signature; int offset = ch->unit * 0x2000; /* setup the workspace for a soft reset command */ bzero(prb, sizeof(struct ata_siiprb_command)); prb->control = htole16(0x0080); prb->fis[1] = port & 0x0f; /* issue soft reset */ if (ata_siiprb_issue_cmd(dev)) return -1; ata_udelay(150000); /* get possible signature */ prb = (struct ata_siiprb_command *) ((u_int8_t *)rman_get_virtual(ctlr->r_res2) + offset); signature=prb->fis[12]|(prb->fis[4]<<8)|(prb->fis[5]<<16)|(prb->fis[6]<<24); /* clear error bits/interrupt */ ATA_IDX_OUTL(ch, ATA_SERROR, 0xffffffff); return signature; } static void ata_siiprb_reset(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); int offset = ch->unit * 0x2000; u_int32_t status, signature; int timeout; /* disable interrupts */ ATA_OUTL(ctlr->r_res2, 0x1014 + offset, 0x000000ff); /* reset channel HW */ ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x00000001); DELAY(1000); ATA_OUTL(ctlr->r_res2, 0x1004 + offset, 0x00000001); DELAY(10000); /* poll for channel ready */ for (timeout = 0; timeout < 1000; timeout++) { if ((status = ATA_INL(ctlr->r_res2, 0x1008 + offset)) & 0x00040000) break; DELAY(1000); } if (bootverbose) { if (timeout >= 1000) device_printf(dev, "channel HW reset timeout\n"); else device_printf(dev, "channel HW reset time=%dms\n", timeout); } /* reset phy */ if (!ata_sata_phy_reset(dev, -1, 1)) { if (bootverbose) device_printf(dev, "phy reset found no device\n"); ch->devices = 0; goto finish; } /* issue soft reset */ signature = ata_siiprb_softreset(dev, ATA_PM); if (bootverbose) device_printf(dev, "SIGNATURE=%08x\n", signature); /* figure out whats there */ switch (signature >> 16) { case 0x0000: ch->devices = ATA_ATA_MASTER; break; case 0x9669: ch->devices = ATA_PORTMULTIPLIER; ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x2000); /* enable PM support */ //SOS XXX need to clear all PM status and interrupts!!!! ata_pm_identify(dev); break; case 0xeb14: ch->devices = ATA_ATAPI_MASTER; break; default: ch->devices = 0; } if (bootverbose) device_printf(dev, "siiprb_reset devices=%08x\n", ch->devices); finish: /* clear interrupt(s) */ ATA_OUTL(ctlr->r_res2, 0x1008 + offset, 0x000008ff); /* require explicit interrupt ack */ ATA_OUTL(ctlr->r_res2, 0x1000 + offset, 0x00000008); /* 64bit mode */ ATA_OUTL(ctlr->r_res2, 0x1004 + offset, 0x00000400); /* enable interrupts wanted */ ATA_OUTL(ctlr->r_res2, 0x1010 + offset, 0x000000ff); } static void ata_siiprb_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) { struct ata_dmasetprd_args *args = xsc; struct ata_siiprb_dma_prdentry *prd = args->dmatab; int i; if ((args->error = error)) return; for (i = 0; i < nsegs; i++) { prd[i].addr = htole64(segs[i].ds_addr); prd[i].count = htole32(segs[i].ds_len); } prd[i - 1].control = htole32(ATA_DMA_EOT); KASSERT(nsegs <= ATA_SIIPRB_DMA_ENTRIES,("too many DMA segment entries\n")); args->nsegs = nsegs; } static void ata_siiprb_dmainit(device_t dev) { struct ata_channel *ch = device_get_softc(dev); ata_dmainit(dev); /* note start and stop are not used here */ ch->dma.setprd = ata_siiprb_dmasetprd; ch->dma.max_address = BUS_SPACE_MAXADDR; ch->dma.max_iosize = (ATA_SIIPRB_DMA_ENTRIES - 1) * PAGE_SIZE; } ATA_DECLARE_DRIVER(ata_sii); Index: stable/8/sys/dev/xen/xenpci =================================================================== --- stable/8/sys/dev/xen/xenpci (revision 212718) +++ stable/8/sys/dev/xen/xenpci (revision 212719) Property changes on: stable/8/sys/dev/xen/xenpci ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/sys/dev/xen/xenpci:r212145 Index: stable/8/sys =================================================================== --- stable/8/sys (revision 212718) +++ stable/8/sys (revision 212719) Property changes on: stable/8/sys ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/sys:r212145