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