linux/drivers/ata/pata_serverworks.c
<<
>>
Prefs
   1/*
   2 * pata_serverworks.c   - Serverworks PATA for new ATA layer
   3 *                        (C) 2005 Red Hat Inc
   4 *                        (C) 2010 Bartlomiej Zolnierkiewicz
   5 *
   6 * based upon
   7 *
   8 * serverworks.c
   9 *
  10 * Copyright (C) 1998-2000 Michel Aubry
  11 * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
  12 * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
  13 * Portions copyright (c) 2001 Sun Microsystems
  14 *
  15 *
  16 * RCC/ServerWorks IDE driver for Linux
  17 *
  18 *   OSB4: `Open South Bridge' IDE Interface (fn 1)
  19 *         supports UDMA mode 2 (33 MB/s)
  20 *
  21 *   CSB5: `Champion South Bridge' IDE Interface (fn 1)
  22 *         all revisions support UDMA mode 4 (66 MB/s)
  23 *         revision A2.0 and up support UDMA mode 5 (100 MB/s)
  24 *
  25 *         *** The CSB5 does not provide ANY register ***
  26 *         *** to detect 80-conductor cable presence. ***
  27 *
  28 *   CSB6: `Champion South Bridge' IDE Interface (optional: third channel)
  29 *
  30 * Documentation:
  31 *      Available under NDA only. Errata info very hard to get.
  32 */
  33
  34#include <linux/kernel.h>
  35#include <linux/module.h>
  36#include <linux/pci.h>
  37#include <linux/blkdev.h>
  38#include <linux/delay.h>
  39#include <scsi/scsi_host.h>
  40#include <linux/libata.h>
  41
  42#define DRV_NAME "pata_serverworks"
  43#define DRV_VERSION "0.4.3"
  44
  45#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
  46#define SVWKS_CSB6_REVISION     0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
  47
  48/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
  49 * can overrun their FIFOs when used with the CSB5 */
  50
  51static const char *csb_bad_ata100[] = {
  52        "ST320011A",
  53        "ST340016A",
  54        "ST360021A",
  55        "ST380021A",
  56        NULL
  57};
  58
  59/**
  60 *      oem_cable       -       Dell/Sun serverworks cable detection
  61 *      @ap: ATA port to do cable detect
  62 *
  63 *      Dell PowerEdge and Sun Cobalt 'Alpine' hide the 40/80 pin select
  64 *      for their interfaces in the top two bits of the subsystem ID.
  65 */
  66
  67static int oem_cable(struct ata_port *ap)
  68{
  69        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  70
  71        if (pdev->subsystem_device & (1 << (ap->port_no + 14)))
  72                return ATA_CBL_PATA80;
  73        return ATA_CBL_PATA40;
  74}
  75
  76struct sv_cable_table {
  77        int device;
  78        int subvendor;
  79        int (*cable_detect)(struct ata_port *ap);
  80};
  81
  82static struct sv_cable_table cable_detect[] = {
  83        { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE,   PCI_VENDOR_ID_DELL, oem_cable },
  84        { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE,   PCI_VENDOR_ID_DELL, oem_cable },
  85        { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE,   PCI_VENDOR_ID_SUN,  oem_cable },
  86        { PCI_DEVICE_ID_SERVERWORKS_OSB4IDE,   PCI_ANY_ID, ata_cable_40wire  },
  87        { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE,   PCI_ANY_ID, ata_cable_unknown },
  88        { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE,   PCI_ANY_ID, ata_cable_unknown },
  89        { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2,  PCI_ANY_ID, ata_cable_unknown },
  90        { PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, ata_cable_unknown },
  91        { }
  92};
  93
  94/**
  95 *      serverworks_cable_detect        -       cable detection
  96 *      @ap: ATA port
  97 *
  98 *      Perform cable detection according to the device and subvendor
  99 *      identifications
 100 */
 101
 102static int serverworks_cable_detect(struct ata_port *ap)
 103{
 104        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 105        struct sv_cable_table *cb = cable_detect;
 106
 107        while(cb->device) {
 108                if (cb->device == pdev->device &&
 109                    (cb->subvendor == pdev->subsystem_vendor ||
 110                      cb->subvendor == PCI_ANY_ID)) {
 111                        return cb->cable_detect(ap);
 112                }
 113                cb++;
 114        }
 115
 116        BUG();
 117        return -1;      /* kill compiler warning */
 118}
 119
 120/**
 121 *      serverworks_is_csb      -       Check for CSB or OSB
 122 *      @pdev: PCI device to check
 123 *
 124 *      Returns true if the device being checked is known to be a CSB
 125 *      series device.
 126 */
 127
 128static u8 serverworks_is_csb(struct pci_dev *pdev)
 129{
 130        switch (pdev->device) {
 131                case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
 132                case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
 133                case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
 134                case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
 135                        return 1;
 136                default:
 137                        break;
 138        }
 139        return 0;
 140}
 141
 142/**
 143 *      serverworks_osb4_filter -       mode selection filter
 144 *      @adev: ATA device
 145 *      @mask: Mask of proposed modes
 146 *
 147 *      Filter the offered modes for the device to apply controller
 148 *      specific rules. OSB4 requires no UDMA for disks due to a FIFO
 149 *      bug we hit.
 150 */
 151
 152static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned long mask)
 153{
 154        if (adev->class == ATA_DEV_ATA)
 155                mask &= ~ATA_MASK_UDMA;
 156        return mask;
 157}
 158
 159
 160/**
 161 *      serverworks_csb_filter  -       mode selection filter
 162 *      @adev: ATA device
 163 *      @mask: Mask of proposed modes
 164 *
 165 *      Check the blacklist and disable UDMA5 if matched
 166 */
 167
 168static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned long mask)
 169{
 170        const char *p;
 171        char model_num[ATA_ID_PROD_LEN + 1];
 172        int i;
 173
 174        /* Disk, UDMA */
 175        if (adev->class != ATA_DEV_ATA)
 176                return mask;
 177
 178        /* Actually do need to check */
 179        ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
 180
 181        for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
 182                if (!strcmp(p, model_num))
 183                        mask &= ~(0xE0 << ATA_SHIFT_UDMA);
 184        }
 185        return mask;
 186}
 187
 188/**
 189 *      serverworks_set_piomode -       set initial PIO mode data
 190 *      @ap: ATA interface
 191 *      @adev: ATA device
 192 *
 193 *      Program the OSB4/CSB5 timing registers for PIO. The PIO register
 194 *      load is done as a simple lookup.
 195 */
 196static void serverworks_set_piomode(struct ata_port *ap, struct ata_device *adev)
 197{
 198        static const u8 pio_mode[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
 199        int offset = 1 + 2 * ap->port_no - adev->devno;
 200        int devbits = (2 * ap->port_no + adev->devno) * 4;
 201        u16 csb5_pio;
 202        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 203        int pio = adev->pio_mode - XFER_PIO_0;
 204
 205        pci_write_config_byte(pdev, 0x40 + offset, pio_mode[pio]);
 206
 207        /* The OSB4 just requires the timing but the CSB series want the
 208           mode number as well */
 209        if (serverworks_is_csb(pdev)) {
 210                pci_read_config_word(pdev, 0x4A, &csb5_pio);
 211                csb5_pio &= ~(0x0F << devbits);
 212                pci_write_config_word(pdev, 0x4A, csb5_pio | (pio << devbits));
 213        }
 214}
 215
 216/**
 217 *      serverworks_set_dmamode -       set initial DMA mode data
 218 *      @ap: ATA interface
 219 *      @adev: ATA device
 220 *
 221 *      Program the MWDMA/UDMA modes for the serverworks OSB4/CSB5
 222 *      chipset. The MWDMA mode values are pulled from a lookup table
 223 *      while the chipset uses mode number for UDMA.
 224 */
 225
 226static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 227{
 228        static const u8 dma_mode[] = { 0x77, 0x21, 0x20 };
 229        int offset = 1 + 2 * ap->port_no - adev->devno;
 230        int devbits = 2 * ap->port_no + adev->devno;
 231        u8 ultra;
 232        u8 ultra_cfg;
 233        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 234
 235        pci_read_config_byte(pdev, 0x54, &ultra_cfg);
 236        pci_read_config_byte(pdev, 0x56 + ap->port_no, &ultra);
 237        ultra &= ~(0x0F << (adev->devno * 4));
 238
 239        if (adev->dma_mode >= XFER_UDMA_0) {
 240                pci_write_config_byte(pdev, 0x44 + offset,  0x20);
 241
 242                ultra |= (adev->dma_mode - XFER_UDMA_0)
 243                                        << (adev->devno * 4);
 244                ultra_cfg |=  (1 << devbits);
 245        } else {
 246                pci_write_config_byte(pdev, 0x44 + offset,
 247                        dma_mode[adev->dma_mode - XFER_MW_DMA_0]);
 248                ultra_cfg &= ~(1 << devbits);
 249        }
 250        pci_write_config_byte(pdev, 0x56 + ap->port_no, ultra);
 251        pci_write_config_byte(pdev, 0x54, ultra_cfg);
 252}
 253
 254static struct scsi_host_template serverworks_osb4_sht = {
 255        ATA_BMDMA_SHT(DRV_NAME),
 256        .sg_tablesize   = LIBATA_DUMB_MAX_PRD,
 257};
 258
 259static struct scsi_host_template serverworks_csb_sht = {
 260        ATA_BMDMA_SHT(DRV_NAME),
 261};
 262
 263static struct ata_port_operations serverworks_osb4_port_ops = {
 264        .inherits       = &ata_bmdma_port_ops,
 265        .qc_prep        = ata_bmdma_dumb_qc_prep,
 266        .cable_detect   = serverworks_cable_detect,
 267        .mode_filter    = serverworks_osb4_filter,
 268        .set_piomode    = serverworks_set_piomode,
 269        .set_dmamode    = serverworks_set_dmamode,
 270};
 271
 272static struct ata_port_operations serverworks_csb_port_ops = {
 273        .inherits       = &serverworks_osb4_port_ops,
 274        .qc_prep        = ata_bmdma_qc_prep,
 275        .mode_filter    = serverworks_csb_filter,
 276};
 277
 278static int serverworks_fixup_osb4(struct pci_dev *pdev)
 279{
 280        u32 reg;
 281        struct pci_dev *isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
 282                  PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
 283        if (isa_dev) {
 284                pci_read_config_dword(isa_dev, 0x64, &reg);
 285                reg &= ~0x00002000; /* disable 600ns interrupt mask */
 286                if (!(reg & 0x00004000))
 287                        printk(KERN_DEBUG DRV_NAME ": UDMA not BIOS enabled.\n");
 288                reg |=  0x00004000; /* enable UDMA/33 support */
 289                pci_write_config_dword(isa_dev, 0x64, reg);
 290                pci_dev_put(isa_dev);
 291                return 0;
 292        }
 293        printk(KERN_WARNING DRV_NAME ": Unable to find bridge.\n");
 294        return -ENODEV;
 295}
 296
 297static int serverworks_fixup_csb(struct pci_dev *pdev)
 298{
 299        u8 btr;
 300
 301        /* Third Channel Test */
 302        if (!(PCI_FUNC(pdev->devfn) & 1)) {
 303                struct pci_dev * findev = NULL;
 304                u32 reg4c = 0;
 305                findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
 306                        PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL);
 307                if (findev) {
 308                        pci_read_config_dword(findev, 0x4C, &reg4c);
 309                        reg4c &= ~0x000007FF;
 310                        reg4c |=  0x00000040;
 311                        reg4c |=  0x00000020;
 312                        pci_write_config_dword(findev, 0x4C, reg4c);
 313                        pci_dev_put(findev);
 314                }
 315        } else {
 316                struct pci_dev * findev = NULL;
 317                u8 reg41 = 0;
 318
 319                findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
 320                                PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL);
 321                if (findev) {
 322                        pci_read_config_byte(findev, 0x41, &reg41);
 323                        reg41 &= ~0x40;
 324                        pci_write_config_byte(findev, 0x41, reg41);
 325                        pci_dev_put(findev);
 326                }
 327        }
 328        /* setup the UDMA Control register
 329         *
 330         * 1. clear bit 6 to enable DMA
 331         * 2. enable DMA modes with bits 0-1
 332         *      00 : legacy
 333         *      01 : udma2
 334         *      10 : udma2/udma4
 335         *      11 : udma2/udma4/udma5
 336         */
 337        pci_read_config_byte(pdev, 0x5A, &btr);
 338        btr &= ~0x40;
 339        if (!(PCI_FUNC(pdev->devfn) & 1))
 340                btr |= 0x2;
 341        else
 342                btr |= (pdev->revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
 343        pci_write_config_byte(pdev, 0x5A, btr);
 344
 345        return btr;
 346}
 347
 348static void serverworks_fixup_ht1000(struct pci_dev *pdev)
 349{
 350        u8 btr;
 351        /* Setup HT1000 SouthBridge Controller - Single Channel Only */
 352        pci_read_config_byte(pdev, 0x5A, &btr);
 353        btr &= ~0x40;
 354        btr |= 0x3;
 355        pci_write_config_byte(pdev, 0x5A, btr);
 356}
 357
 358static int serverworks_fixup(struct pci_dev *pdev)
 359{
 360        int rc = 0;
 361
 362        /* Force master latency timer to 64 PCI clocks */
 363        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
 364
 365        switch (pdev->device) {
 366        case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
 367                rc = serverworks_fixup_osb4(pdev);
 368                break;
 369        case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
 370                ata_pci_bmdma_clear_simplex(pdev);
 371                /* fall through */
 372        case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
 373        case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
 374                rc = serverworks_fixup_csb(pdev);
 375                break;
 376        case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
 377                serverworks_fixup_ht1000(pdev);
 378                break;
 379        }
 380
 381        return rc;
 382}
 383
 384static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 385{
 386        static const struct ata_port_info info[4] = {
 387                { /* OSB4 */
 388                        .flags = ATA_FLAG_SLAVE_POSS,
 389                        .pio_mask = ATA_PIO4,
 390                        .mwdma_mask = ATA_MWDMA2,
 391                        .udma_mask = ATA_UDMA2,
 392                        .port_ops = &serverworks_osb4_port_ops
 393                }, { /* OSB4 no UDMA */
 394                        .flags = ATA_FLAG_SLAVE_POSS,
 395                        .pio_mask = ATA_PIO4,
 396                        .mwdma_mask = ATA_MWDMA2,
 397                        /* No UDMA */
 398                        .port_ops = &serverworks_osb4_port_ops
 399                }, { /* CSB5 */
 400                        .flags = ATA_FLAG_SLAVE_POSS,
 401                        .pio_mask = ATA_PIO4,
 402                        .mwdma_mask = ATA_MWDMA2,
 403                        .udma_mask = ATA_UDMA4,
 404                        .port_ops = &serverworks_csb_port_ops
 405                }, { /* CSB5 - later revisions*/
 406                        .flags = ATA_FLAG_SLAVE_POSS,
 407                        .pio_mask = ATA_PIO4,
 408                        .mwdma_mask = ATA_MWDMA2,
 409                        .udma_mask = ATA_UDMA5,
 410                        .port_ops = &serverworks_csb_port_ops
 411                }
 412        };
 413        const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
 414        struct scsi_host_template *sht = &serverworks_csb_sht;
 415        int rc;
 416
 417        rc = pcim_enable_device(pdev);
 418        if (rc)
 419                return rc;
 420
 421        rc = serverworks_fixup(pdev);
 422
 423        /* OSB4 : South Bridge and IDE */
 424        if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
 425                /* Select non UDMA capable OSB4 if we can't do fixups */
 426                if (rc < 0)
 427                        ppi[0] = &info[1];
 428                sht = &serverworks_osb4_sht;
 429        }
 430        /* setup CSB5/CSB6 : South Bridge and IDE option RAID */
 431        else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ||
 432                 (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
 433                 (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
 434
 435                 /* If the returned btr is the newer revision then
 436                    select the right info block */
 437                 if (rc == 3)
 438                        ppi[0] = &info[3];
 439
 440                /* Is this the 3rd channel CSB6 IDE ? */
 441                if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)
 442                        ppi[1] = &ata_dummy_port_info;
 443        }
 444
 445        return ata_pci_bmdma_init_one(pdev, ppi, sht, NULL, 0);
 446}
 447
 448#ifdef CONFIG_PM_SLEEP
 449static int serverworks_reinit_one(struct pci_dev *pdev)
 450{
 451        struct ata_host *host = pci_get_drvdata(pdev);
 452        int rc;
 453
 454        rc = ata_pci_device_do_resume(pdev);
 455        if (rc)
 456                return rc;
 457
 458        (void)serverworks_fixup(pdev);
 459
 460        ata_host_resume(host);
 461        return 0;
 462}
 463#endif
 464
 465static const struct pci_device_id serverworks[] = {
 466        { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
 467        { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
 468        { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
 469        { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2},
 470        { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2},
 471
 472        { },
 473};
 474
 475static struct pci_driver serverworks_pci_driver = {
 476        .name           = DRV_NAME,
 477        .id_table       = serverworks,
 478        .probe          = serverworks_init_one,
 479        .remove         = ata_pci_remove_one,
 480#ifdef CONFIG_PM_SLEEP
 481        .suspend        = ata_pci_device_suspend,
 482        .resume         = serverworks_reinit_one,
 483#endif
 484};
 485
 486module_pci_driver(serverworks_pci_driver);
 487
 488MODULE_AUTHOR("Alan Cox");
 489MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6");
 490MODULE_LICENSE("GPL");
 491MODULE_DEVICE_TABLE(pci, serverworks);
 492MODULE_VERSION(DRV_VERSION);
 493