Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &reg);
^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, &reg4c);
^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, &reg41);
^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);