Mercurial > illumos > illumos-gate
changeset 10881:a3a5f64c08c9
6891348 ahci driver should disable 64-bit DMA for AMD/ATI SB600 by default again
author | ying tian - Beijing China <Ying.Tian@Sun.COM> |
---|---|
date | Tue, 27 Oct 2009 10:21:22 +0800 |
parents | 94b6193debfc |
children | 640bb4bb88b6 |
files | usr/src/uts/common/io/sata/adapters/ahci/ahci.c usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h |
diffstat | 2 files changed, 56 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/sata/adapters/ahci/ahci.c Mon Oct 26 15:48:31 2009 -0700 +++ b/usr/src/uts/common/io/sata/adapters/ahci/ahci.c Tue Oct 27 10:21:22 2009 +0800 @@ -371,6 +371,21 @@ boolean_t ahci_commu_64bit_dma = B_TRUE; /* + * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600 + * chipset. If the users want to have a try with 64-bit dma, please change + * the below variable value to enable it. + */ +boolean_t sb600_buf_64bit_dma_disable = B_TRUE; + +/* + * By default, 64-bit dma for command buffer will be disabled for AMD/ATI + * SB600/700/710/750/800. If the users want to have a try with 64-bit dma, + * please change the below value to enable it. + */ +boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE; + + +/* * End of global tunable variable definition */ @@ -833,14 +848,29 @@ ahci_ctlp->ahcictl_cmd_list_dma_attr = cmd_list_dma_attr; ahci_ctlp->ahcictl_cmd_table_dma_attr = cmd_table_dma_attr; + /* + * enable 64bit dma for data buffer for SB600 if + * sb600_buf_64bit_dma_disable is B_FALSE + */ if ((ahci_buf_64bit_dma == B_FALSE) || - (ahci_ctlp->ahcictl_cap & AHCI_CAP_BUF_32BIT_DMA)) { + ((ahci_ctlp->ahcictl_cap & AHCI_CAP_BUF_32BIT_DMA) && + !(sb600_buf_64bit_dma_disable == B_FALSE && + ahci_ctlp->ahcictl_venid == 0x1002 && + ahci_ctlp->ahcictl_devid == 0x4380))) { ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_addr_hi = 0xffffffffull; } + /* + * enable 64bit dma for command buffer for SB600/700/710/800 + * if sbxxx_commu_64bit_dma_disable is B_FALSE + */ if ((ahci_commu_64bit_dma == B_FALSE) || - (ahci_ctlp->ahcictl_cap & AHCI_CAP_COMMU_32BIT_DMA)) { + ((ahci_ctlp->ahcictl_cap & AHCI_CAP_COMMU_32BIT_DMA) && + !(sbxxx_commu_64bit_dma_disable == B_FALSE && + ahci_ctlp->ahcictl_venid == 0x1002 && + (ahci_ctlp->ahcictl_devid == 0x4380 || + ahci_ctlp->ahcictl_devid == 0x4391)))) { ahci_ctlp->ahcictl_rcvd_fis_dma_attr.dma_attr_addr_hi = 0xffffffffull; ahci_ctlp->ahcictl_cmd_list_dma_attr.dma_attr_addr_hi = @@ -3656,7 +3686,6 @@ static int ahci_config_space_init(ahci_ctl_t *ahci_ctlp) { - ushort_t venid, devid; ushort_t caps_ptr, cap_count, cap; #if AHCI_DEBUG ushort_t pmcap, pmcsr; @@ -3664,10 +3693,12 @@ #endif uint8_t revision; - venid = pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle, + ahci_ctlp->ahcictl_venid = + pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle, PCI_CONF_VENID); - devid = pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle, + ahci_ctlp->ahcictl_devid = + pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle, PCI_CONF_DEVID); /* @@ -3680,7 +3711,7 @@ * of PxCI can be re-written in the register write, so a flag will be * set to record this defect - AHCI_CAP_NO_MCMDLIST_NONQUEUE. */ - if (venid == VIA_VENID) { + if (ahci_ctlp->ahcictl_venid == VIA_VENID) { revision = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle, PCI_CONF_REVID); AHCIDBG(AHCIDBG_INIT, ahci_ctlp, @@ -3700,14 +3731,10 @@ /* * AMD/ATI SB600 (0x1002,0x4380) AHCI chipset doesn't support 64-bit * DMA addressing for communication memory descriptors though S64A bit - * of CAP register declares it supports. However, it does support - * 64-bit DMA for data buffer. So only AHCI_CAP_COMMU_32BIT_DMA is - * set for this controller. - * - * Please note that AHCI_CAP_BUF_32BIT_DMA was ever set because we - * found 64-bit DMA cannot work on ASUS M2A-VM with old BIOS version. - * However, the issue can be resolved by upgrade of 1501+ BIOS, so - * we decided to remove the flag. + * of CAP register declares it supports. Even though 64-bit DMA for + * data buffer works on ASUS M2A-VM with newer BIOS, three other + * motherboards are known not, so both AHCI_CAP_BUF_32BIT_DMA and + * AHCI_CAP_COMMU_32BIT_DMA are set for this controller. * * Due to certain hardware issue, the chipset must do port reset during * initialization, otherwise, when retrieving device signature, @@ -3721,15 +3748,17 @@ * reset got failure, the driver will try to do another software reset * with pmport 0. */ - if (venid == 0x1002 && devid == 0x4380) { + if (ahci_ctlp->ahcictl_venid == 0x1002 && + ahci_ctlp->ahcictl_devid == 0x4380) { + ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA; ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA; ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET; ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT; AHCIDBG(AHCIDBG_INIT, ahci_ctlp, - "ATI SB600 cannot do 64-bit DMA for communication " - "memory descriptors though CAP indicates support, " - "so force it to use 32-bit DMA", NULL); + "ATI SB600 cannot do 64-bit DMA for both data buffer and " + "communication memory descriptors though CAP indicates " + "support, so force it to use 32-bit DMA", NULL); AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ATI SB600 need to do a port reset during initialization", NULL); @@ -3754,7 +3783,8 @@ * SB700 also has the same issue about software reset, and thus * AHCI_CAP_SRST_NO_HOSTPORT flag also is needed. */ - if (venid == 0x1002 && devid == 0x4391) { + if (ahci_ctlp->ahcictl_venid == 0x1002 && + ahci_ctlp->ahcictl_devid == 0x4391) { ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA; ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET; ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
--- a/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h Mon Oct 26 15:48:31 2009 -0700 +++ b/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h Tue Oct 27 10:21:22 2009 +0800 @@ -345,6 +345,10 @@ typedef struct ahci_ctl { dev_info_t *ahcictl_dip; + + ushort_t ahcictl_venid; + ushort_t ahcictl_devid; + /* To map port number to cport number */ uint8_t ahcictl_port_to_cport[AHCI_MAX_PORTS]; /* To map cport number to port number */ @@ -369,12 +373,14 @@ * AHCI_CAP_NO_MCMDLIST_NONQUEUE * AHCI_CAP_NCQ * AHCI_CAP_PM - * AHCI_CAP_32BIT_DMA + * AHCI_CAP_BUF_32BIT_DMA * AHCI_CAP_SCLO + * AHCI_CAP_COMMU_32BIT_DMA * AHCI_CAP_INIT_PORT_RESET * AHCI_CAP_SNTF * AHCI_CAP_PMULT_CBSS * AHCI_CAP_PMULT_FBSS + * AHCI_CAP_SRST_NO_HOSTPORT */ int ahcictl_cap;