sis5513.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/drivers/ide/pci/sis5513.c Version 0.16ac+vp Jun 18, 2003 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * May be copied or modified under the terms of the GNU General Public License 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Thanks : 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SiS Taiwan : for direct support and hardware. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Daniela Engert : for initial ATA100 advices and numerous others. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * John Fremlin, Manfred Spraul, Dave Morgan, Peter Kjellerstedt : 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for checking code correctness, providing patches. 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Original tests and design on the SiS620 chipset. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA100 tests and design on the SiS735 chipset. 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA16/33 support from specs 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ATA133 961/962/963 fixes by Vojtech Pavlik <vojtech@suse.cz> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Documentation: 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SiS chipset documentation available under NDA to companies only 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (not to individuals). 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The original SiS5513 comes from a SiS5511/55112/5513 chipset. The original 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SiS5513 was also used in the SiS5596/5513 chipset. Thus if we see a SiS5511 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or SiS5596, we can assume we see the first MWDMA-16 capable SiS5513 chip. 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Later SiS chipsets integrated the 5513 functionality into the NorthBridge, 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * starting with SiS5571 and up to SiS745. The PCI ID didn't change, though. We 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * can figure out that we have a more modern and more capable 5513 by looking 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for the respective NorthBridge IDs. 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Even later (96x family) SiS chipsets use the MuTIOL link and place the 5513 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * into the SouthBrige. Here we cannot rely on looking up the NorthBridge PCI 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ID, while the now ATA-133 capable 5513 still has the same PCI ID. 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fortunately the 5513 can be 'unmasked' by fiddling with some config space 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bits, changing its device id to the true one - 5517 for 961 and 5518 for 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 962/963. 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/config.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/timer.h> 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkdev.h> 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/hdreg.h> 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ide.h> 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ide-timing.h" 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DISPLAY_SIS_TIMINGS 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* registers layout and init values are chipset family dependant */ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_16 0x01 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_33 0x02 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_66 0x03 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_100a 0x04 // SiS730/SiS550 is ATA100 with ATA66 layout 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_100 0x05 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_133a 0x06 // SiS961b with 133 support 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ATA_133 0x07 // SiS962/963 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 chipset_family; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Devices supported 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const struct { 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *name; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 host_id; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 chipset_family; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 flags; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} SiSHostChipInfo[] = { 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 }, 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 }, 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 }, 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100 }, 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS633", PCI_DEVICE_ID_SI_633, ATA_100 }, 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a }, 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS550", PCI_DEVICE_ID_SI_550, ATA_100a }, 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66 }, 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66 }, 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66 }, 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66 }, 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66 }, 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33 }, 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33 }, 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33 }, 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5591/2", PCI_DEVICE_ID_SI_5591, ATA_33 }, 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5582", PCI_DEVICE_ID_SI_5582, ATA_33 }, 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5581", PCI_DEVICE_ID_SI_5581, ATA_33 }, 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5596", PCI_DEVICE_ID_SI_5596, ATA_16 }, 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS5571", PCI_DEVICE_ID_SI_5571, ATA_16 }, 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { "SiS551x", PCI_DEVICE_ID_SI_5511, ATA_16 }, 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Cycle time bits and values vary across chip dma capabilities 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds These three arrays hold the register layout and the values to set. 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 cycle_time_offset[] = {0,0,5,4,4,0,0}; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 cycle_time_range[] = {0,0,2,3,3,4,4}; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0}, /* no udma */ 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0}, /* no udma */ 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {3,2,1,0,0,0,0}, /* ATA_33 */ 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {7,5,3,2,1,0,0}, /* ATA_66 */ 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {7,5,3,2,1,0,0}, /* ATA_100a (730 specific), differences are on cycle_time range and offset */ 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {11,7,5,4,2,1,0}, /* ATA_100 */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {15,10,7,5,3,2,1}, /* ATA_133a (earliest 691 southbridges) */ 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {15,10,7,5,3,2,1}, /* ATA_133 */ 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds See SiS962 data sheet for more detail */ 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0}, /* no udma */ 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0}, /* no udma */ 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {2,1,1,0,0,0,0}, 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {4,3,2,1,0,0,0}, 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {4,3,2,1,0,0,0}, 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {6,4,3,1,1,1,0}, 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {9,6,4,2,2,2,2}, 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {9,6,4,2,2,2,2}, 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Initialize time, Active time, Recovery time vary across 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IDE clock settings. These 3 arrays hold the register value 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for PIO0/1/2/3/4 and DMA0/1/2 mode in order */ 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 ini_time_value[][8] = { 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0,0}, 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0,0}, 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {2,1,0,0,0,1,0,0}, 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {4,3,1,1,1,3,1,1}, 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {4,3,1,1,1,3,1,1}, 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {6,4,2,2,2,4,2,2}, 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {9,6,3,3,3,6,3,3}, 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {9,6,3,3,3,6,3,3}, 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 act_time_value[][8] = { 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0,0}, 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0,0}, 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {9,9,9,2,2,7,2,2}, 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {19,19,19,5,4,14,5,4}, 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {19,19,19,5,4,14,5,4}, 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {28,28,28,7,6,21,7,6}, 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {38,38,38,10,9,28,10,9}, 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {38,38,38,10,9,28,10,9}, 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 rco_time_value[][8] = { 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0,0}, 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,0,0,0,0,0,0,0}, 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {9,2,0,2,0,7,1,1}, 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {19,5,1,5,2,16,3,2}, 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {19,5,1,5,2,16,3,2}, 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {30,9,3,9,4,25,6,4}, 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {40,12,4,12,5,34,12,5}, 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {40,12,4,12,5,34,12,5}, 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Printing configuration 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Used for chipset type printing at boot time */ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* chipset_capability[] = { 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA", "ATA 16", 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA 33", "ATA 66", 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA 100 (1st gen)", "ATA 100 (2nd gen)", 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ATA 133 (1st gen)", "ATA 133 (2nd gen)" 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stat.h> 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/proc_fs.h> 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 sis_proc = 0; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_dev *bmide_dev; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* cable_type[] = { 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "80 pins", 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "40 pins" 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* recovery_time[] ={ 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "12 PCICLK", "1 PCICLK", 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "2 PCICLK", "3 PCICLK", 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "4 PCICLK", "5 PCICLCK", 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "6 PCICLK", "7 PCICLCK", 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "8 PCICLK", "9 PCICLCK", 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "10 PCICLK", "11 PCICLK", 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "13 PCICLK", "14 PCICLK", 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "15 PCICLK", "15 PCICLK" 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* active_time[] = { 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "8 PCICLK", "1 PCICLCK", 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "2 PCICLK", "3 PCICLK", 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "4 PCICLK", "5 PCICLK", 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "6 PCICLK", "12 PCICLK" 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* cycle_time[] = { 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Reserved", "2 CLK", 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "3 CLK", "4 CLK", 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "5 CLK", "6 CLK", 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "7 CLK", "8 CLK", 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "9 CLK", "10 CLK", 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "11 CLK", "12 CLK", 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "13 CLK", "14 CLK", 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "15 CLK", "16 CLK" 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Generic add master or slave info function */ 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* get_drives_info (char *buffer, u8 pos) 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg00, reg01, reg10, reg11; /* timing registers */ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 regdw0, regdw1; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char* p = buffer; 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Postwrite/Prefetch */ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family < ATA_133) { 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x4b, ®00); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "Drive %d: Postwrite %s \t \t Postwrite %s\n", 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pos, (reg00 & (0x10 << pos)) ? "Enabled" : "Disabled", 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg00 & (0x40 << pos)) ? "Enabled" : "Disabled"); 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n", 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg00 & (0x01 << pos)) ? "Enabled" : "Disabled", 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg00 & (0x04 << pos)) ? "Enabled" : "Disabled"); 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x40+2*pos, ®00); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x41+2*pos, ®01); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x44+2*pos, ®10); 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x45+2*pos, ®11); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 reg54h; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 drive_pci = 0x40; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(bmide_dev, 0x54, ®54h); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reg54h & 0x40000000) { 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // Configuration space remapped to 0x70 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_pci = 0x70; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, ®dw0); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, ®dw1); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "Drive %d:\n", pos); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* UDMA */ 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family >= ATA_133) { 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (regdw0 & 0x04) ? "Enabled" : "Disabled", 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (regdw1 & 0x04) ? "Enabled" : "Disabled"); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cycle_time[(regdw0 & 0xF0) >> 4], 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cycle_time[(regdw1 & 0xF0) >> 4]); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (chipset_family >= ATA_33) { 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg01 & 0x80) ? "Enabled" : "Disabled", 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg11 & 0x80) ? "Enabled" : "Disabled"); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " UDMA Cycle Time "); 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(chipset_family) { 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_33: p += sprintf(p, cycle_time[(reg01 & 0x60) >> 5]); break; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_66: 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100a: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100: 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133a: p += sprintf(p, cycle_time[reg01 & 0x0F]); break; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: p += sprintf(p, "?"); break; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " \t UDMA Cycle Time "); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(chipset_family) { 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_33: p += sprintf(p, cycle_time[(reg11 & 0x60) >> 5]); break; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_66: 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100a: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100: 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133a: p += sprintf(p, cycle_time[reg11 & 0x0F]); break; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: p += sprintf(p, "?"); break; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "\n"); 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family < ATA_133) { /* else case TODO */ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Data Active */ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " Data Active Time "); 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(chipset_family) { 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_16: /* confirmed */ 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_33: 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_66: 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100: 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: p += sprintf(p, "?"); break; 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " \t Data Active Time "); 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(chipset_family) { 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_16: 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_33: 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_66: 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100: 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: p += sprintf(p, "?"); break; 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "\n"); 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Data Recovery */ 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* warning: may need (reg&0x07) for pre ATA66 chips */ 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]); 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return p; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* get_masters_info(char* buffer) 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return get_drives_info(buffer, 0); 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char* get_slaves_info(char* buffer) 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return get_drives_info(buffer, 1); 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Main get_info, called on /proc/ide/sis reads */ 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sis_get_info (char *buffer, char **addr, off_t offset, int count) 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *p = buffer; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 reg2, reg3; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "\nSiS 5513 "); 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(chipset_family) { 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_16: p += sprintf(p, "DMA 16"); break; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_33: p += sprintf(p, "Ultra 33"); break; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_66: p += sprintf(p, "Ultra 66"); break; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100a: 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100: p += sprintf(p, "Ultra 100"); break; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133a: 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133: p += sprintf(p, "Ultra 133"); break; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: p+= sprintf(p, "Unknown???"); break; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, " chipset\n"); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "--------------- Primary Channel " 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "---------------- Secondary Channel " 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "-------------\n"); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Status */ 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x4a, ®); 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family == ATA_133) { 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(bmide_dev, 0x50, ®2); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(bmide_dev, 0x52, ®3); 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "Channel Status: "); 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family < ATA_66) { 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "%s \t \t \t \t %s\n", 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x04) ? "On" : "Off", 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x02) ? "On" : "Off"); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (chipset_family < ATA_133) { 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "%s \t \t \t \t %s \n", 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x02) ? "On" : "Off", 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x04) ? "On" : "Off"); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { /* ATA_133 */ 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "%s \t \t \t \t %s \n", 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg2 & 0x02) ? "On" : "Off", 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg3 & 0x02) ? "On" : "Off"); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Operation Mode */ 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x09, ®); 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "Operation Mode: %s \t \t \t %s \n", 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x01) ? "Native" : "Compatible", 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x04) ? "Native" : "Compatible"); 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 80-pin cable ? */ 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family >= ATA_133) { 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "Cable Type: %s \t \t \t %s\n", 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg2 & 0x01) ? cable_type[1] : cable_type[0], 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg3 & 0x01) ? cable_type[1] : cable_type[0]); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (chipset_family > ATA_33) { 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(bmide_dev, 0x48, ®); 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "Cable Type: %s \t \t \t %s\n", 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x10) ? cable_type[1] : cable_type[0], 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (reg & 0x20) ? cable_type[1] : cable_type[0]); 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Prefetch Count */ 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family < ATA_133) { 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(bmide_dev, 0x4c, ®2); 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(bmide_dev, 0x4e, ®3); 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n", 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reg2, reg3); 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = get_masters_info(p); 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = get_slaves_info(p); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = (p - buffer) - offset; 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *addr = buffer + offset; 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return len > count ? count : len; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */ 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 sis5513_ratemask (ide_drive_t *drive) 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 }; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 mode = rates[chipset_family]; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!eighty_ninty_three(drive)) 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = min(mode, (u8)1); 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mode; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Configuration functions 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Enables per-drive prefetch and postwrite */ 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void config_drive_art_rwp (ide_drive_t *drive) 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ide_hwif_t *hwif = HWIF(drive); 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *dev = hwif->pci_dev; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg4bh = 0; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 rw_prefetch = (0x11 << drive->dn); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drive->media != ide_disk) 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x4b, ®4bh); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((reg4bh & rw_prefetch) != rw_prefetch) 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Set per-drive active and recovery time */ 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void config_art_rwp_pio (ide_drive_t *drive, u8 pio) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ide_hwif_t *hwif = HWIF(drive); 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *dev = hwif->pci_dev; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 timing, drive_pci, test1, test2; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90}; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 xfer_pio = drive->id->eide_pio_modes; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds config_drive_art_rwp(drive); 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pio = ide_get_best_pio_mode(drive, 255, pio, NULL); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (xfer_pio> 4) 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xfer_pio = 0; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drive->id->eide_pio_iordy > 0) { 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (xfer_pio = 5; 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (xfer_pio > 0) && 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]); 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xfer_pio--); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (drive->id->eide_pio_modes & 2) ? 0x04 : 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timing = (xfer_pio >= pio) ? xfer_pio : pio; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */ 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_pci = 0x40; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */ 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family >= ATA_133) { 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 reg54h; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(dev, 0x54, ®54h); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reg54h & 0x40000000) drive_pci = 0x70; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_pci += ((drive->dn)*0x4); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_pci += ((drive->dn)*0x2); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* register layout changed with newer ATA100 chips */ 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family < ATA_100) { 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, drive_pci, &test1); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, drive_pci+1, &test2); 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Clear active and recovery timings */ 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test1 &= ~0x0F; 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test2 &= ~0x07; 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(timing) { 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: test1 |= 0x01; test2 |= 0x03; break; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: test1 |= 0x03; test2 |= 0x03; break; 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: test1 |= 0x04; test2 |= 0x04; break; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: test1 |= 0x07; test2 |= 0x06; break; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: break; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, drive_pci, test1); 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, drive_pci+1, test2); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (chipset_family < ATA_133) { 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(timing) { /* active recovery 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v v */ 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: test1 = 0x30|0x01; break; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: test1 = 0x30|0x03; break; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: test1 = 0x40|0x04; break; 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: test1 = 0x60|0x07; break; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: break; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, drive_pci, test1); 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { /* ATA_133 */ 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 test3; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(dev, drive_pci, &test3); 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test3 &= 0xc0c00fff; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test3 & 0x08) { 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12; 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24; 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12; 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16; 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24; 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, drive_pci, test3); 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int config_chipset_for_pio (ide_drive_t *drive, u8 pio) 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pio == 255) 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds config_art_rwp_pio(drive, pio); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4)); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ide_hwif_t *hwif = HWIF(drive); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *dev = hwif->pci_dev; 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 drive_pci, reg, speed; 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 regdw; 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed); 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* See config_art_rwp_pio for drive pci config registers */ 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_pci = 0x40; 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family >= ATA_133) { 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 reg54h; 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(dev, 0x54, ®54h); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reg54h & 0x40000000) drive_pci = 0x70; 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_pci += ((drive->dn)*0x4); 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(dev, (unsigned long)drive_pci, ®dw); 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable UDMA bit for non UDMA modes on UDMA chips */ 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (speed < XFER_UDMA_0) { 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regdw &= 0xfffffffb; 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_pci += ((drive->dn)*0x2); 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, drive_pci+1, ®); 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable UDMA bit for non UDMA modes on UDMA chips */ 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) { 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reg &= 0x7F; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, drive_pci+1, reg); 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Config chip for mode */ 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(speed) { 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_UDMA_6: 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_UDMA_5: 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_UDMA_4: 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_UDMA_3: 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_UDMA_2: 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_UDMA_1: 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_UDMA_0: 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family >= ATA_133) { 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regdw |= 0x04; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regdw &= 0xfffff00f; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if ATA133 enable */ 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (regdw & 0x08) { 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4; 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8; 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if ATA133 disable, we should not set speed above UDMA5 */ 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (speed > XFER_UDMA_5) 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds speed = XFER_UDMA_5; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Force the UDMA bit on if we want to use UDMA */ 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reg |= 0x80; 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* clean reg cycle time bits */ 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family])) 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds << cycle_time_offset[chipset_family]); 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set reg cycle time bits */ 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reg |= cycle_time_value[chipset_family][speed-XFER_UDMA_0] 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds << cycle_time_offset[chipset_family]; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, drive_pci+1, reg); 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_MW_DMA_2: 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_MW_DMA_1: 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_MW_DMA_0: 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_SW_DMA_2: 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_SW_DMA_1: 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_SW_DMA_0: 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4)); 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3)); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2)); 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1)); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case XFER_PIO_0: 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: return((int) config_chipset_for_pio(drive, 0)); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((int) ide_config_drive_speed(drive, speed)); 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sis5513_tune_drive (ide_drive_t *drive, u8 pio) 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void) config_chipset_for_pio(drive, pio); 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four)) 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int config_chipset_for_dma (ide_drive_t *drive) 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 speed = ide_dma_speed(drive, sis5513_ratemask(drive)); 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef DEBUG 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("SIS5513: config_chipset_for_dma, drive %d, ultra %x\n", 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive->dn, drive->id->dma_ultra); 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(speed)) 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sis5513_tune_chipset(drive, speed); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ide_dma_enable(drive); 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sis5513_config_drive_xfer_rate (ide_drive_t *drive) 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ide_hwif_t *hwif = HWIF(drive); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct hd_driveid *id = drive->id; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive->init_speed = 0; 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (id && (id->capability & 1) && drive->autodma) { 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ide_use_dma(drive)) { 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (config_chipset_for_dma(drive)) 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return hwif->ide_dma_on(drive); 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto fast_ata_pio; 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((id->capability & 8) || (id->field_valid & 2)) { 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfast_ata_pio: 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sis5513_tune_drive(drive, 5); 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return hwif->ide_dma_off_quietly(drive); 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* IORDY not supported */ 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* initiates/aborts (U)DMA read/write operations on a drive. */ 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sis5513_config_xfer_rate (ide_drive_t *drive) 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds config_drive_art_rwp(drive); 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds config_art_rwp_pio(drive, 5); 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sis5513_config_drive_xfer_rate(drive); 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Future simpler config_xfer_rate : 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds When ide_find_best_mode is made bad-drive aware 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds - remove config_drive_xfer_rate and config_chipset_for_dma, 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds - replace config_xfer_rate with the following 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sis5513_config_xfer_rate (ide_drive_t *drive) 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 w80 = HWIF(drive)->udma_four; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 speed; 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds config_drive_art_rwp(drive); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds config_art_rwp_pio(drive, 5); 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds speed = ide_find_best_mode(drive, 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (chipset_family >= ATA_33 ? XFER_UDMA : 0) | 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) | 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) | 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0)); 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sis5513_tune_chipset(drive, speed); 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return HWIF(drive)->ide_dma_on(drive); 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return HWIF(drive)->ide_dma_off_quietly(drive); 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Chip detection and general config */ 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name) 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *host; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = 0; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) { 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host = pci_find_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL); 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!host) 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = SiSHostChipInfo[i].chipset_family; 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Special case for SiS630 : 630S/ET is ATA_100a */ 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) { 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 hostrev; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(host, PCI_REVISION_ID, &hostrev); 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hostrev >= 0x30) 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_100a; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "SIS5513: %s %s controller\n", 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SiSHostChipInfo[i].name, chipset_capability[chipset_family]); 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!chipset_family) { /* Belongs to pci-quirks */ 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 idemisc; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 trueid; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable ID masking and register remapping */ 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_dword(dev, 0x54, &idemisc); 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff)); 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, 0x54, idemisc); 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (trueid == 0x5518) { 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "SIS5513: SiS 962/963 MuTIOL IDE UDMA133 controller\n"); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_133; 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check for 5513 compability mapping 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We must use this, else the port enabled code will fail, 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as it expects the enablebits at 0x4a. 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((idemisc & 0x40000000) == 0) { 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_dword(dev, 0x54, idemisc | 0x40000000); 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "SIS5513: Switching to 5513 register mapping\n"); 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!chipset_family) { /* Belongs to pci-quirks */ 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *lpc_bridge; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 trueid; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 prefctl; 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 idecfg; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 sbrev; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x4a, &idecfg); 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x4a, idecfg | 0x10); 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x4a, idecfg); 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (trueid == 0x5517) { /* SiS 961/961B */ 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lpc_bridge = pci_find_slot(0x00, 0x10); /* Bus 0, Dev 2, Fn 0 */ 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev); 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x49, &prefctl); 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sbrev == 0x10 && (prefctl & 0x80)) { 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n"); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_133a; 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "SIS5513: SiS 961 MuTIOL IDE UDMA100 controller\n"); 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chipset_family = ATA_100; 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!chipset_family) 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make general config ops here 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1/ tell IDE channels to operate in Compatibility mode only 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2/ tell old chips to allow per drive IDE timings */ 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg; 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 regw; 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(chipset_family) { 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133: 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* SiS962 operation mode */ 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(dev, 0x50, ®w); 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (regw & 0x08) 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_word(dev, 0x50, regw&0xfff7); 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(dev, 0x52, ®w); 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (regw & 0x08) 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_word(dev, 0x52, regw&0xfff7); 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_133a: 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100: 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Fixup latency */ 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set compatibility bit */ 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x49, ®); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(reg & 0x01)) { 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x49, reg|0x01); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_100a: 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_66: 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Fixup latency */ 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* On ATA_66 chips the bit was elsewhere */ 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x52, ®); 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(reg & 0x04)) { 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x52, reg|0x04); 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_33: 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* On ATA_33 we didn't have a single bit to set */ 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x09, ®); 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((reg & 0x0f) != 0x00) { 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x09, reg&0xf0); 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ATA_16: 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* force per drive recovery and active timings 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds needed on ATA_33 and below chips */ 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(dev, 0x52, ®); 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(reg & 0x08)) { 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_write_config_byte(dev, 0x52, reg|0x08); 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sis_proc) { 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sis_proc = 1; 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bmide_dev = dev; 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ide_pci_create_host_proc("sis", sis_get_info); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int __init ata66_sis5513 (ide_hwif_t *hwif) 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 ata66 = 0; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family >= ATA_133) { 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 regw = 0; 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 reg_addr = hwif->channel ? 0x52: 0x50; 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_word(hwif->pci_dev, reg_addr, ®w); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ata66 = (regw & 0x8000) ? 0 : 1; 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (chipset_family >= ATA_66) { 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg48h = 0; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 mask = hwif->channel ? 0x20 : 0x10; 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_read_config_byte(hwif->pci_dev, 0x48, ®48h); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ata66 = (reg48h & mask) ? 0 : 1; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ata66; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init init_hwif_sis5513 (ide_hwif_t *hwif) 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->autodma = 0; 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!hwif->irq) 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->irq = hwif->channel ? 15 : 14; 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->tuneproc = &sis5513_tune_drive; 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->speedproc = &sis5513_tune_chipset; 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(hwif->dma_base)) { 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->drives[0].autotune = 1; 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->drives[1].autotune = 1; 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->atapi_dma = 1; 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->ultra_mask = 0x7f; 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->mwdma_mask = 0x07; 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->swdma_mask = 0x07; 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!chipset_family) 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(hwif->udma_four)) 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->udma_four = ata66_sis5513(hwif); 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chipset_family > ATA_16) { 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->ide_dma_check = &sis5513_config_xfer_rate; 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!noautodma) 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->autodma = 1; 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->drives[0].autodma = hwif->autodma; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hwif->drives[1].autodma = hwif->autodma; 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ide_pci_device_t sis5513_chipset __devinitdata = { 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "SIS5513", 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init_chipset = init_chipset_sis5513, 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init_hwif = init_hwif_sis5513, 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .channels = 2, 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .autodma = NOAUTODMA, 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .bootable = ON_BOARD, 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ide_setup_pci_device(dev, &sis5513_chipset); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_device_id sis5513_pci_tbl[] = { 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5518, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, }, 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(pci, sis5513_pci_tbl); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_driver driver = { 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "SIS_IDE", 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .id_table = sis5513_pci_tbl, 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .probe = sis5513_init_one, 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sis5513_ide_init(void) 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ide_pci_register_driver(&driver); 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(sis5513_ide_init); 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik"); 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("PCI driver module for SIS IDE"); 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TODO: 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - CLEANUP 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Use drivers/ide/ide-timing.h ! 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - More checks in the config registers (force values instead of 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * relying on the BIOS setting them correctly). 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Further optimisations ? 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * . for example ATA66+ regs 0x48 & 0x4A 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 985