linux/drivers/ata/sata_sis.c
<<
>>
Prefs
   1/*
   2 *  sata_sis.c - Silicon Integrated Systems SATA
   3 *
   4 *  Maintained by:  Uwe Koziolek
   5 *                  Please ALWAYS copy linux-ide@vger.kernel.org
   6 *                  on emails.
   7 *
   8 *  Copyright 2004 Uwe Koziolek
   9 *
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; either version 2, or (at your option)
  14 *  any later version.
  15 *
  16 *  This program is distributed in the hope that it will be useful,
  17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 *  GNU General Public License for more details.
  20 *
  21 *  You should have received a copy of the GNU General Public License
  22 *  along with this program; see the file COPYING.  If not, write to
  23 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24 *
  25 *
  26 *  libata documentation is available via 'make {ps|pdf}docs',
  27 *  as Documentation/DocBook/libata.*
  28 *
  29 *  Hardware documentation available under NDA.
  30 *
  31 */
  32
  33#include <linux/kernel.h>
  34#include <linux/module.h>
  35#include <linux/pci.h>
  36#include <linux/init.h>
  37#include <linux/blkdev.h>
  38#include <linux/delay.h>
  39#include <linux/interrupt.h>
  40#include <linux/device.h>
  41#include <scsi/scsi_host.h>
  42#include <linux/libata.h>
  43#include "sis.h"
  44
  45#define DRV_NAME        "sata_sis"
  46#define DRV_VERSION     "1.0"
  47
  48enum {
  49        sis_180                 = 0,
  50        SIS_SCR_PCI_BAR         = 5,
  51
  52        /* PCI configuration registers */
  53        SIS_GENCTL              = 0x54, /* IDE General Control register */
  54        SIS_SCR_BASE            = 0xc0, /* sata0 phy SCR registers */
  55        SIS180_SATA1_OFS        = 0x10, /* offset from sata0->sata1 phy regs */
  56        SIS182_SATA1_OFS        = 0x20, /* offset from sata0->sata1 phy regs */
  57        SIS_PMR                 = 0x90, /* port mapping register */
  58        SIS_PMR_COMBINED        = 0x30,
  59
  60        /* random bits */
  61        SIS_FLAG_CFGSCR         = (1 << 30), /* host flag: SCRs via PCI cfg */
  62
  63        GENCTL_IOMAPPED_SCR     = (1 << 26), /* if set, SCRs are in IO space */
  64};
  65
  66static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
  67static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
  68static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
  69
  70static const struct pci_device_id sis_pci_tbl[] = {
  71        { PCI_VDEVICE(SI, 0x0180), sis_180 },   /* SiS 964/180 */
  72        { PCI_VDEVICE(SI, 0x0181), sis_180 },   /* SiS 964/180 */
  73        { PCI_VDEVICE(SI, 0x0182), sis_180 },   /* SiS 965/965L */
  74        { PCI_VDEVICE(SI, 0x0183), sis_180 },   /* SiS 965/965L */
  75        { PCI_VDEVICE(SI, 0x1182), sis_180 },   /* SiS 966/680 */
  76        { PCI_VDEVICE(SI, 0x1183), sis_180 },   /* SiS 966/966L/968/680 */
  77
  78        { }     /* terminate list */
  79};
  80
  81static struct pci_driver sis_pci_driver = {
  82        .name                   = DRV_NAME,
  83        .id_table               = sis_pci_tbl,
  84        .probe                  = sis_init_one,
  85        .remove                 = ata_pci_remove_one,
  86};
  87
  88static struct scsi_host_template sis_sht = {
  89        ATA_BMDMA_SHT(DRV_NAME),
  90};
  91
  92static struct ata_port_operations sis_ops = {
  93        .inherits               = &ata_bmdma_port_ops,
  94        .scr_read               = sis_scr_read,
  95        .scr_write              = sis_scr_write,
  96};
  97
  98static const struct ata_port_info sis_port_info = {
  99        .flags          = ATA_FLAG_SATA,
 100        .pio_mask       = ATA_PIO4,
 101        .mwdma_mask     = ATA_MWDMA2,
 102        .udma_mask      = ATA_UDMA6,
 103        .port_ops       = &sis_ops,
 104};
 105
 106MODULE_AUTHOR("Uwe Koziolek");
 107MODULE_DESCRIPTION("low-level driver for Silicon Integrated Systems SATA controller");
 108MODULE_LICENSE("GPL");
 109MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
 110MODULE_VERSION(DRV_VERSION);
 111
 112static unsigned int get_scr_cfg_addr(struct ata_link *link, unsigned int sc_reg)
 113{
 114        struct ata_port *ap = link->ap;
 115        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 116        unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
 117        u8 pmr;
 118
 119        if (ap->port_no)  {
 120                switch (pdev->device) {
 121                case 0x0180:
 122                case 0x0181:
 123                        pci_read_config_byte(pdev, SIS_PMR, &pmr);
 124                        if ((pmr & SIS_PMR_COMBINED) == 0)
 125                                addr += SIS180_SATA1_OFS;
 126                        break;
 127
 128                case 0x0182:
 129                case 0x0183:
 130                case 0x1182:
 131                        addr += SIS182_SATA1_OFS;
 132                        break;
 133                }
 134        }
 135        if (link->pmp)
 136                addr += 0x10;
 137
 138        return addr;
 139}
 140
 141static u32 sis_scr_cfg_read(struct ata_link *link,
 142                            unsigned int sc_reg, u32 *val)
 143{
 144        struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
 145        unsigned int cfg_addr = get_scr_cfg_addr(link, sc_reg);
 146
 147        if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
 148                return -EINVAL;
 149
 150        pci_read_config_dword(pdev, cfg_addr, val);
 151        return 0;
 152}
 153
 154static int sis_scr_cfg_write(struct ata_link *link,
 155                             unsigned int sc_reg, u32 val)
 156{
 157        struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
 158        unsigned int cfg_addr = get_scr_cfg_addr(link, sc_reg);
 159
 160        pci_write_config_dword(pdev, cfg_addr, val);
 161        return 0;
 162}
 163
 164static int sis_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
 165{
 166        struct ata_port *ap = link->ap;
 167        void __iomem *base = ap->ioaddr.scr_addr + link->pmp * 0x10;
 168
 169        if (sc_reg > SCR_CONTROL)
 170                return -EINVAL;
 171
 172        if (ap->flags & SIS_FLAG_CFGSCR)
 173                return sis_scr_cfg_read(link, sc_reg, val);
 174
 175        *val = ioread32(base + sc_reg * 4);
 176        return 0;
 177}
 178
 179static int sis_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
 180{
 181        struct ata_port *ap = link->ap;
 182        void __iomem *base = ap->ioaddr.scr_addr + link->pmp * 0x10;
 183
 184        if (sc_reg > SCR_CONTROL)
 185                return -EINVAL;
 186
 187        if (ap->flags & SIS_FLAG_CFGSCR)
 188                return sis_scr_cfg_write(link, sc_reg, val);
 189
 190        iowrite32(val, base + (sc_reg * 4));
 191        return 0;
 192}
 193
 194static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 195{
 196        struct ata_port_info pi = sis_port_info;
 197        const struct ata_port_info *ppi[] = { &pi, &pi };
 198        struct ata_host *host;
 199        u32 genctl, val;
 200        u8 pmr;
 201        u8 port2_start = 0x20;
 202        int i, rc;
 203
 204        ata_print_version_once(&pdev->dev, DRV_VERSION);
 205
 206        rc = pcim_enable_device(pdev);
 207        if (rc)
 208                return rc;
 209
 210        /* check and see if the SCRs are in IO space or PCI cfg space */
 211        pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
 212        if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
 213                pi.flags |= SIS_FLAG_CFGSCR;
 214
 215        /* if hardware thinks SCRs are in IO space, but there are
 216         * no IO resources assigned, change to PCI cfg space.
 217         */
 218        if ((!(pi.flags & SIS_FLAG_CFGSCR)) &&
 219            ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) ||
 220             (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) {
 221                genctl &= ~GENCTL_IOMAPPED_SCR;
 222                pci_write_config_dword(pdev, SIS_GENCTL, genctl);
 223                pi.flags |= SIS_FLAG_CFGSCR;
 224        }
 225
 226        pci_read_config_byte(pdev, SIS_PMR, &pmr);
 227        switch (ent->device) {
 228        case 0x0180:
 229        case 0x0181:
 230
 231                /* The PATA-handling is provided by pata_sis */
 232                switch (pmr & 0x30) {
 233                case 0x10:
 234                        ppi[1] = &sis_info133_for_sata;
 235                        break;
 236
 237                case 0x30:
 238                        ppi[0] = &sis_info133_for_sata;
 239                        break;
 240                }
 241                if ((pmr & SIS_PMR_COMBINED) == 0) {
 242                        dev_info(&pdev->dev,
 243                                 "Detected SiS 180/181/964 chipset in SATA mode\n");
 244                        port2_start = 64;
 245                } else {
 246                        dev_info(&pdev->dev,
 247                                 "Detected SiS 180/181 chipset in combined mode\n");
 248                        port2_start = 0;
 249                        pi.flags |= ATA_FLAG_SLAVE_POSS;
 250                }
 251                break;
 252
 253        case 0x0182:
 254        case 0x0183:
 255                pci_read_config_dword(pdev, 0x6C, &val);
 256                if (val & (1L << 31)) {
 257                        dev_info(&pdev->dev, "Detected SiS 182/965 chipset\n");
 258                        pi.flags |= ATA_FLAG_SLAVE_POSS;
 259                } else {
 260                        dev_info(&pdev->dev, "Detected SiS 182/965L chipset\n");
 261                }
 262                break;
 263
 264        case 0x1182:
 265                dev_info(&pdev->dev,
 266                         "Detected SiS 1182/966/680 SATA controller\n");
 267                pi.flags |= ATA_FLAG_SLAVE_POSS;
 268                break;
 269
 270        case 0x1183:
 271                dev_info(&pdev->dev,
 272                         "Detected SiS 1183/966/966L/968/680 controller in PATA mode\n");
 273                ppi[0] = &sis_info133_for_sata;
 274                ppi[1] = &sis_info133_for_sata;
 275                break;
 276        }
 277
 278        rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
 279        if (rc)
 280                return rc;
 281
 282        for (i = 0; i < 2; i++) {
 283                struct ata_port *ap = host->ports[i];
 284
 285                if (ap->flags & ATA_FLAG_SATA &&
 286                    ap->flags & ATA_FLAG_SLAVE_POSS) {
 287                        rc = ata_slave_link_init(ap);
 288                        if (rc)
 289                                return rc;
 290                }
 291        }
 292
 293        if (!(pi.flags & SIS_FLAG_CFGSCR)) {
 294                void __iomem *mmio;
 295
 296                rc = pcim_iomap_regions(pdev, 1 << SIS_SCR_PCI_BAR, DRV_NAME);
 297                if (rc)
 298                        return rc;
 299                mmio = host->iomap[SIS_SCR_PCI_BAR];
 300
 301                host->ports[0]->ioaddr.scr_addr = mmio;
 302                host->ports[1]->ioaddr.scr_addr = mmio + port2_start;
 303        }
 304
 305        pci_set_master(pdev);
 306        pci_intx(pdev, 1);
 307        return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
 308                                 IRQF_SHARED, &sis_sht);
 309}
 310
 311module_pci_driver(sis_pci_driver);
 312
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.