| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *  sata_sil.c - Silicon Image SATA | 
 | 3 |  * | 
 | 4 |  *  Maintained by:  Jeff Garzik <jgarzik@pobox.com> | 
 | 5 |  *  		    Please ALWAYS copy linux-ide@vger.kernel.org | 
 | 6 |  *		    on emails. | 
 | 7 |  * | 
 | 8 |  *  Copyright 2003 Red Hat, Inc. | 
 | 9 |  *  Copyright 2003 Benjamin Herrenschmidt | 
 | 10 |  * | 
 | 11 |  *  The contents of this file are subject to the Open | 
 | 12 |  *  Software License version 1.1 that can be found at | 
 | 13 |  *  http://www.opensource.org/licenses/osl-1.1.txt and is included herein | 
 | 14 |  *  by reference. | 
 | 15 |  * | 
 | 16 |  *  Alternatively, the contents of this file may be used under the terms | 
 | 17 |  *  of the GNU General Public License version 2 (the "GPL") as distributed | 
 | 18 |  *  in the kernel source COPYING file, in which case the provisions of | 
 | 19 |  *  the GPL are applicable instead of the above.  If you wish to allow | 
 | 20 |  *  the use of your version of this file only under the terms of the | 
 | 21 |  *  GPL and not to allow others to use your version of this file under | 
 | 22 |  *  the OSL, indicate your decision by deleting the provisions above and | 
 | 23 |  *  replace them with the notice and other provisions required by the GPL. | 
 | 24 |  *  If you do not delete the provisions above, a recipient may use your | 
 | 25 |  *  version of this file under either the OSL or the GPL. | 
 | 26 |  * | 
 | 27 |  */ | 
 | 28 |  | 
 | 29 | #include <linux/kernel.h> | 
 | 30 | #include <linux/module.h> | 
 | 31 | #include <linux/pci.h> | 
 | 32 | #include <linux/init.h> | 
 | 33 | #include <linux/blkdev.h> | 
 | 34 | #include <linux/delay.h> | 
 | 35 | #include <linux/interrupt.h> | 
 | 36 | #include "scsi.h" | 
 | 37 | #include <scsi/scsi_host.h> | 
 | 38 | #include <linux/libata.h> | 
 | 39 |  | 
 | 40 | #define DRV_NAME	"sata_sil" | 
 | 41 | #define DRV_VERSION	"0.9" | 
 | 42 |  | 
 | 43 | enum { | 
 | 44 | 	sil_3112		= 0, | 
 | 45 | 	sil_3114		= 1, | 
 | 46 |  | 
 | 47 | 	SIL_FIFO_R0		= 0x40, | 
 | 48 | 	SIL_FIFO_W0		= 0x41, | 
 | 49 | 	SIL_FIFO_R1		= 0x44, | 
 | 50 | 	SIL_FIFO_W1		= 0x45, | 
 | 51 | 	SIL_FIFO_R2		= 0x240, | 
 | 52 | 	SIL_FIFO_W2		= 0x241, | 
 | 53 | 	SIL_FIFO_R3		= 0x244, | 
 | 54 | 	SIL_FIFO_W3		= 0x245, | 
 | 55 |  | 
 | 56 | 	SIL_SYSCFG		= 0x48, | 
 | 57 | 	SIL_MASK_IDE0_INT	= (1 << 22), | 
 | 58 | 	SIL_MASK_IDE1_INT	= (1 << 23), | 
 | 59 | 	SIL_MASK_IDE2_INT	= (1 << 24), | 
 | 60 | 	SIL_MASK_IDE3_INT	= (1 << 25), | 
 | 61 | 	SIL_MASK_2PORT		= SIL_MASK_IDE0_INT | SIL_MASK_IDE1_INT, | 
 | 62 | 	SIL_MASK_4PORT		= SIL_MASK_2PORT | | 
 | 63 | 				  SIL_MASK_IDE2_INT | SIL_MASK_IDE3_INT, | 
 | 64 |  | 
 | 65 | 	SIL_IDE2_BMDMA		= 0x200, | 
 | 66 |  | 
 | 67 | 	SIL_INTR_STEERING	= (1 << 1), | 
 | 68 | 	SIL_QUIRK_MOD15WRITE	= (1 << 0), | 
 | 69 | 	SIL_QUIRK_UDMA5MAX	= (1 << 1), | 
 | 70 | }; | 
 | 71 |  | 
 | 72 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 
 | 73 | static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); | 
 | 74 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); | 
 | 75 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 
 | 76 | static void sil_post_set_mode (struct ata_port *ap); | 
 | 77 |  | 
 | 78 | static struct pci_device_id sil_pci_tbl[] = { | 
 | 79 | 	{ 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 
 | 80 | 	{ 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 
 | 81 | 	{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 
 | 82 | 	{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 
 | 83 | 	{ 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 
 | 84 | 	{ 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 
| NAKAMURA Kenta | 525a099 | 2005-05-25 19:28:38 -0400 | [diff] [blame] | 85 | 	{ 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | 	{ }	/* terminate list */ | 
 | 87 | }; | 
 | 88 |  | 
 | 89 |  | 
 | 90 | /* TODO firmware versions should be added - eric */ | 
 | 91 | static const struct sil_drivelist { | 
 | 92 | 	const char * product; | 
 | 93 | 	unsigned int quirk; | 
 | 94 | } sil_blacklist [] = { | 
 | 95 | 	{ "ST320012AS",		SIL_QUIRK_MOD15WRITE }, | 
 | 96 | 	{ "ST330013AS",		SIL_QUIRK_MOD15WRITE }, | 
 | 97 | 	{ "ST340017AS",		SIL_QUIRK_MOD15WRITE }, | 
 | 98 | 	{ "ST360015AS",		SIL_QUIRK_MOD15WRITE }, | 
 | 99 | 	{ "ST380013AS",		SIL_QUIRK_MOD15WRITE }, | 
 | 100 | 	{ "ST380023AS",		SIL_QUIRK_MOD15WRITE }, | 
 | 101 | 	{ "ST3120023AS",	SIL_QUIRK_MOD15WRITE }, | 
 | 102 | 	{ "ST3160023AS",	SIL_QUIRK_MOD15WRITE }, | 
 | 103 | 	{ "ST3120026AS",	SIL_QUIRK_MOD15WRITE }, | 
 | 104 | 	{ "ST3200822AS",	SIL_QUIRK_MOD15WRITE }, | 
 | 105 | 	{ "ST340014ASL",	SIL_QUIRK_MOD15WRITE }, | 
 | 106 | 	{ "ST360014ASL",	SIL_QUIRK_MOD15WRITE }, | 
 | 107 | 	{ "ST380011ASL",	SIL_QUIRK_MOD15WRITE }, | 
 | 108 | 	{ "ST3120022ASL",	SIL_QUIRK_MOD15WRITE }, | 
 | 109 | 	{ "ST3160021ASL",	SIL_QUIRK_MOD15WRITE }, | 
 | 110 | 	{ "Maxtor 4D060H3",	SIL_QUIRK_UDMA5MAX }, | 
 | 111 | 	{ } | 
 | 112 | }; | 
 | 113 |  | 
 | 114 | static struct pci_driver sil_pci_driver = { | 
 | 115 | 	.name			= DRV_NAME, | 
 | 116 | 	.id_table		= sil_pci_tbl, | 
 | 117 | 	.probe			= sil_init_one, | 
 | 118 | 	.remove			= ata_pci_remove_one, | 
 | 119 | }; | 
 | 120 |  | 
 | 121 | static Scsi_Host_Template sil_sht = { | 
 | 122 | 	.module			= THIS_MODULE, | 
 | 123 | 	.name			= DRV_NAME, | 
 | 124 | 	.ioctl			= ata_scsi_ioctl, | 
 | 125 | 	.queuecommand		= ata_scsi_queuecmd, | 
 | 126 | 	.eh_strategy_handler	= ata_scsi_error, | 
 | 127 | 	.can_queue		= ATA_DEF_QUEUE, | 
 | 128 | 	.this_id		= ATA_SHT_THIS_ID, | 
 | 129 | 	.sg_tablesize		= LIBATA_MAX_PRD, | 
 | 130 | 	.max_sectors		= ATA_MAX_SECTORS, | 
 | 131 | 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN, | 
 | 132 | 	.emulated		= ATA_SHT_EMULATED, | 
 | 133 | 	.use_clustering		= ATA_SHT_USE_CLUSTERING, | 
 | 134 | 	.proc_name		= DRV_NAME, | 
 | 135 | 	.dma_boundary		= ATA_DMA_BOUNDARY, | 
 | 136 | 	.slave_configure	= ata_scsi_slave_config, | 
 | 137 | 	.bios_param		= ata_std_bios_param, | 
 | 138 | 	.ordered_flush		= 1, | 
 | 139 | }; | 
 | 140 |  | 
 | 141 | static struct ata_port_operations sil_ops = { | 
 | 142 | 	.port_disable		= ata_port_disable, | 
 | 143 | 	.dev_config		= sil_dev_config, | 
 | 144 | 	.tf_load		= ata_tf_load, | 
 | 145 | 	.tf_read		= ata_tf_read, | 
 | 146 | 	.check_status		= ata_check_status, | 
 | 147 | 	.exec_command		= ata_exec_command, | 
 | 148 | 	.dev_select		= ata_std_dev_select, | 
 | 149 | 	.phy_reset		= sata_phy_reset, | 
 | 150 | 	.post_set_mode		= sil_post_set_mode, | 
 | 151 | 	.bmdma_setup            = ata_bmdma_setup, | 
 | 152 | 	.bmdma_start            = ata_bmdma_start, | 
 | 153 | 	.bmdma_stop		= ata_bmdma_stop, | 
 | 154 | 	.bmdma_status		= ata_bmdma_status, | 
 | 155 | 	.qc_prep		= ata_qc_prep, | 
 | 156 | 	.qc_issue		= ata_qc_issue_prot, | 
 | 157 | 	.eng_timeout		= ata_eng_timeout, | 
 | 158 | 	.irq_handler		= ata_interrupt, | 
 | 159 | 	.irq_clear		= ata_bmdma_irq_clear, | 
 | 160 | 	.scr_read		= sil_scr_read, | 
 | 161 | 	.scr_write		= sil_scr_write, | 
 | 162 | 	.port_start		= ata_port_start, | 
 | 163 | 	.port_stop		= ata_port_stop, | 
| Jeff Garzik | aa8f0dc | 2005-05-26 21:54:27 -0400 | [diff] [blame] | 164 | 	.host_stop		= ata_host_stop, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 165 | }; | 
 | 166 |  | 
 | 167 | static struct ata_port_info sil_port_info[] = { | 
 | 168 | 	/* sil_3112 */ | 
 | 169 | 	{ | 
 | 170 | 		.sht		= &sil_sht, | 
 | 171 | 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 
 | 172 | 				  ATA_FLAG_SRST | ATA_FLAG_MMIO, | 
 | 173 | 		.pio_mask	= 0x1f,			/* pio0-4 */ | 
 | 174 | 		.mwdma_mask	= 0x07,			/* mwdma0-2 */ | 
 | 175 | 		.udma_mask	= 0x3f,			/* udma0-5 */ | 
 | 176 | 		.port_ops	= &sil_ops, | 
 | 177 | 	}, /* sil_3114 */ | 
 | 178 | 	{ | 
 | 179 | 		.sht		= &sil_sht, | 
 | 180 | 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 
 | 181 | 				  ATA_FLAG_SRST | ATA_FLAG_MMIO, | 
 | 182 | 		.pio_mask	= 0x1f,			/* pio0-4 */ | 
 | 183 | 		.mwdma_mask	= 0x07,			/* mwdma0-2 */ | 
 | 184 | 		.udma_mask	= 0x3f,			/* udma0-5 */ | 
 | 185 | 		.port_ops	= &sil_ops, | 
 | 186 | 	}, | 
 | 187 | }; | 
 | 188 |  | 
 | 189 | /* per-port register offsets */ | 
 | 190 | /* TODO: we can probably calculate rather than use a table */ | 
 | 191 | static const struct { | 
 | 192 | 	unsigned long tf;	/* ATA taskfile register block */ | 
 | 193 | 	unsigned long ctl;	/* ATA control/altstatus register block */ | 
 | 194 | 	unsigned long bmdma;	/* DMA register block */ | 
 | 195 | 	unsigned long scr;	/* SATA control register block */ | 
 | 196 | 	unsigned long sien;	/* SATA Interrupt Enable register */ | 
 | 197 | 	unsigned long xfer_mode;/* data transfer mode register */ | 
 | 198 | } sil_port[] = { | 
 | 199 | 	/* port 0 ... */ | 
 | 200 | 	{ 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, | 
 | 201 | 	{ 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, | 
 | 202 | 	{ 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, | 
 | 203 | 	{ 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, | 
 | 204 | 	/* ... port 3 */ | 
 | 205 | }; | 
 | 206 |  | 
 | 207 | MODULE_AUTHOR("Jeff Garzik"); | 
 | 208 | MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller"); | 
 | 209 | MODULE_LICENSE("GPL"); | 
 | 210 | MODULE_DEVICE_TABLE(pci, sil_pci_tbl); | 
 | 211 | MODULE_VERSION(DRV_VERSION); | 
 | 212 |  | 
 | 213 | static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) | 
 | 214 | { | 
 | 215 | 	u8 cache_line = 0; | 
 | 216 | 	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line); | 
 | 217 | 	return cache_line; | 
 | 218 | } | 
 | 219 |  | 
 | 220 | static void sil_post_set_mode (struct ata_port *ap) | 
 | 221 | { | 
 | 222 | 	struct ata_host_set *host_set = ap->host_set; | 
 | 223 | 	struct ata_device *dev; | 
 | 224 | 	void *addr = host_set->mmio_base + sil_port[ap->port_no].xfer_mode; | 
 | 225 | 	u32 tmp, dev_mode[2]; | 
 | 226 | 	unsigned int i; | 
 | 227 |  | 
 | 228 | 	for (i = 0; i < 2; i++) { | 
 | 229 | 		dev = &ap->device[i]; | 
 | 230 | 		if (!ata_dev_present(dev)) | 
 | 231 | 			dev_mode[i] = 0;	/* PIO0/1/2 */ | 
 | 232 | 		else if (dev->flags & ATA_DFLAG_PIO) | 
 | 233 | 			dev_mode[i] = 1;	/* PIO3/4 */ | 
 | 234 | 		else | 
 | 235 | 			dev_mode[i] = 3;	/* UDMA */ | 
 | 236 | 		/* value 2 indicates MDMA */ | 
 | 237 | 	} | 
 | 238 |  | 
 | 239 | 	tmp = readl(addr); | 
 | 240 | 	tmp &= ~((1<<5) | (1<<4) | (1<<1) | (1<<0)); | 
 | 241 | 	tmp |= dev_mode[0]; | 
 | 242 | 	tmp |= (dev_mode[1] << 4); | 
 | 243 | 	writel(tmp, addr); | 
 | 244 | 	readl(addr);	/* flush */ | 
 | 245 | } | 
 | 246 |  | 
 | 247 | static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_reg) | 
 | 248 | { | 
 | 249 | 	unsigned long offset = ap->ioaddr.scr_addr; | 
 | 250 |  | 
 | 251 | 	switch (sc_reg) { | 
 | 252 | 	case SCR_STATUS: | 
 | 253 | 		return offset + 4; | 
 | 254 | 	case SCR_ERROR: | 
 | 255 | 		return offset + 8; | 
 | 256 | 	case SCR_CONTROL: | 
 | 257 | 		return offset; | 
 | 258 | 	default: | 
 | 259 | 		/* do nothing */ | 
 | 260 | 		break; | 
 | 261 | 	} | 
 | 262 |  | 
 | 263 | 	return 0; | 
 | 264 | } | 
 | 265 |  | 
 | 266 | static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg) | 
 | 267 | { | 
 | 268 | 	void *mmio = (void *) sil_scr_addr(ap, sc_reg); | 
 | 269 | 	if (mmio) | 
 | 270 | 		return readl(mmio); | 
 | 271 | 	return 0xffffffffU; | 
 | 272 | } | 
 | 273 |  | 
 | 274 | static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 
 | 275 | { | 
 | 276 | 	void *mmio = (void *) sil_scr_addr(ap, sc_reg); | 
 | 277 | 	if (mmio) | 
 | 278 | 		writel(val, mmio); | 
 | 279 | } | 
 | 280 |  | 
 | 281 | /** | 
 | 282 |  *	sil_dev_config - Apply device/host-specific errata fixups | 
 | 283 |  *	@ap: Port containing device to be examined | 
 | 284 |  *	@dev: Device to be examined | 
 | 285 |  * | 
 | 286 |  *	After the IDENTIFY [PACKET] DEVICE step is complete, and a | 
 | 287 |  *	device is known to be present, this function is called. | 
 | 288 |  *	We apply two errata fixups which are specific to Silicon Image, | 
 | 289 |  *	a Seagate and a Maxtor fixup. | 
 | 290 |  * | 
 | 291 |  *	For certain Seagate devices, we must limit the maximum sectors | 
 | 292 |  *	to under 8K. | 
 | 293 |  * | 
 | 294 |  *	For certain Maxtor devices, we must not program the drive | 
 | 295 |  *	beyond udma5. | 
 | 296 |  * | 
 | 297 |  *	Both fixups are unfairly pessimistic.  As soon as I get more | 
 | 298 |  *	information on these errata, I will create a more exhaustive | 
 | 299 |  *	list, and apply the fixups to only the specific | 
 | 300 |  *	devices/hosts/firmwares that need it. | 
 | 301 |  * | 
 | 302 |  *	20040111 - Seagate drives affected by the Mod15Write bug are blacklisted | 
 | 303 |  *	The Maxtor quirk is in the blacklist, but I'm keeping the original | 
 | 304 |  *	pessimistic fix for the following reasons... | 
 | 305 |  *	- There seems to be less info on it, only one device gleaned off the | 
 | 306 |  *	Windows	driver, maybe only one is affected.  More info would be greatly | 
 | 307 |  *	appreciated. | 
 | 308 |  *	- But then again UDMA5 is hardly anything to complain about | 
 | 309 |  */ | 
 | 310 | static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | 
 | 311 | { | 
 | 312 | 	unsigned int n, quirks = 0; | 
 | 313 | 	unsigned char model_num[40]; | 
 | 314 | 	const char *s; | 
 | 315 | 	unsigned int len; | 
 | 316 |  | 
 | 317 | 	ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, | 
 | 318 | 			  sizeof(model_num)); | 
 | 319 | 	s = &model_num[0]; | 
 | 320 | 	len = strnlen(s, sizeof(model_num)); | 
 | 321 |  | 
 | 322 | 	/* ATAPI specifies that empty space is blank-filled; remove blanks */ | 
 | 323 | 	while ((len > 0) && (s[len - 1] == ' ')) | 
 | 324 | 		len--; | 
 | 325 |  | 
 | 326 | 	for (n = 0; sil_blacklist[n].product; n++)  | 
 | 327 | 		if (!memcmp(sil_blacklist[n].product, s, | 
 | 328 | 			    strlen(sil_blacklist[n].product))) { | 
 | 329 | 			quirks = sil_blacklist[n].quirk; | 
 | 330 | 			break; | 
 | 331 | 		} | 
 | 332 | 	 | 
 | 333 | 	/* limit requests to 15 sectors */ | 
 | 334 | 	if (quirks & SIL_QUIRK_MOD15WRITE) { | 
 | 335 | 		printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", | 
 | 336 | 		       ap->id, dev->devno); | 
 | 337 | 		ap->host->max_sectors = 15; | 
 | 338 | 		ap->host->hostt->max_sectors = 15; | 
 | 339 | 		dev->flags |= ATA_DFLAG_LOCK_SECTORS; | 
 | 340 | 		return; | 
 | 341 | 	} | 
 | 342 |  | 
 | 343 | 	/* limit to udma5 */ | 
 | 344 | 	if (quirks & SIL_QUIRK_UDMA5MAX) { | 
 | 345 | 		printk(KERN_INFO "ata%u(%u): applying Maxtor errata fix %s\n", | 
 | 346 | 		       ap->id, dev->devno, s); | 
 | 347 | 		ap->udma_mask &= ATA_UDMA5; | 
 | 348 | 		return; | 
 | 349 | 	} | 
 | 350 | } | 
 | 351 |  | 
 | 352 | static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 
 | 353 | { | 
 | 354 | 	static int printed_version; | 
 | 355 | 	struct ata_probe_ent *probe_ent = NULL; | 
 | 356 | 	unsigned long base; | 
 | 357 | 	void *mmio_base; | 
 | 358 | 	int rc; | 
 | 359 | 	unsigned int i; | 
 | 360 | 	int pci_dev_busy = 0; | 
 | 361 | 	u32 tmp, irq_mask; | 
 | 362 | 	u8 cls; | 
 | 363 |  | 
 | 364 | 	if (!printed_version++) | 
 | 365 | 		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); | 
 | 366 |  | 
 | 367 | 	/* | 
 | 368 | 	 * If this driver happens to only be useful on Apple's K2, then | 
 | 369 | 	 * we should check that here as it has a normal Serverworks ID | 
 | 370 | 	 */ | 
 | 371 | 	rc = pci_enable_device(pdev); | 
 | 372 | 	if (rc) | 
 | 373 | 		return rc; | 
 | 374 |  | 
 | 375 | 	rc = pci_request_regions(pdev, DRV_NAME); | 
 | 376 | 	if (rc) { | 
 | 377 | 		pci_dev_busy = 1; | 
 | 378 | 		goto err_out; | 
 | 379 | 	} | 
 | 380 |  | 
 | 381 | 	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 
 | 382 | 	if (rc) | 
 | 383 | 		goto err_out_regions; | 
 | 384 | 	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | 
 | 385 | 	if (rc) | 
 | 386 | 		goto err_out_regions; | 
 | 387 |  | 
 | 388 | 	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); | 
 | 389 | 	if (probe_ent == NULL) { | 
 | 390 | 		rc = -ENOMEM; | 
 | 391 | 		goto err_out_regions; | 
 | 392 | 	} | 
 | 393 |  | 
 | 394 | 	memset(probe_ent, 0, sizeof(*probe_ent)); | 
 | 395 | 	INIT_LIST_HEAD(&probe_ent->node); | 
 | 396 | 	probe_ent->dev = pci_dev_to_dev(pdev); | 
 | 397 | 	probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops; | 
 | 398 | 	probe_ent->sht = sil_port_info[ent->driver_data].sht; | 
 | 399 | 	probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2; | 
 | 400 | 	probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask; | 
 | 401 | 	probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask; | 
 | 402 | 	probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask; | 
 | 403 |        	probe_ent->irq = pdev->irq; | 
 | 404 |        	probe_ent->irq_flags = SA_SHIRQ; | 
 | 405 | 	probe_ent->host_flags = sil_port_info[ent->driver_data].host_flags; | 
 | 406 |  | 
 | 407 | 	mmio_base = ioremap(pci_resource_start(pdev, 5), | 
 | 408 | 		            pci_resource_len(pdev, 5)); | 
 | 409 | 	if (mmio_base == NULL) { | 
 | 410 | 		rc = -ENOMEM; | 
 | 411 | 		goto err_out_free_ent; | 
 | 412 | 	} | 
 | 413 |  | 
 | 414 | 	probe_ent->mmio_base = mmio_base; | 
 | 415 |  | 
 | 416 | 	base = (unsigned long) mmio_base; | 
 | 417 |  | 
 | 418 | 	for (i = 0; i < probe_ent->n_ports; i++) { | 
 | 419 | 		probe_ent->port[i].cmd_addr = base + sil_port[i].tf; | 
 | 420 | 		probe_ent->port[i].altstatus_addr = | 
 | 421 | 		probe_ent->port[i].ctl_addr = base + sil_port[i].ctl; | 
 | 422 | 		probe_ent->port[i].bmdma_addr = base + sil_port[i].bmdma; | 
 | 423 | 		probe_ent->port[i].scr_addr = base + sil_port[i].scr; | 
 | 424 | 		ata_std_ports(&probe_ent->port[i]); | 
 | 425 | 	} | 
 | 426 |  | 
 | 427 | 	/* Initialize FIFO PCI bus arbitration */ | 
 | 428 | 	cls = sil_get_device_cache_line(pdev); | 
 | 429 | 	if (cls) { | 
 | 430 | 		cls >>= 3; | 
 | 431 | 		cls++;  /* cls = (line_size/8)+1 */ | 
 | 432 | 		writeb(cls, mmio_base + SIL_FIFO_R0); | 
 | 433 | 		writeb(cls, mmio_base + SIL_FIFO_W0); | 
 | 434 | 		writeb(cls, mmio_base + SIL_FIFO_R1); | 
| Jens Axboe | e1dd23a | 2005-06-08 13:02:25 +0200 | [diff] [blame] | 435 | 		writeb(cls, mmio_base + SIL_FIFO_W1); | 
 | 436 | 		if (ent->driver_data == sil_3114) { | 
 | 437 | 			writeb(cls, mmio_base + SIL_FIFO_R2); | 
 | 438 | 			writeb(cls, mmio_base + SIL_FIFO_W2); | 
 | 439 | 			writeb(cls, mmio_base + SIL_FIFO_R3); | 
 | 440 | 			writeb(cls, mmio_base + SIL_FIFO_W3); | 
 | 441 | 		} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 442 | 	} else | 
 | 443 | 		printk(KERN_WARNING DRV_NAME "(%s): cache line size not set.  Driver may not function\n", | 
 | 444 | 			pci_name(pdev)); | 
 | 445 |  | 
 | 446 | 	if (ent->driver_data == sil_3114) { | 
 | 447 | 		irq_mask = SIL_MASK_4PORT; | 
 | 448 |  | 
 | 449 | 		/* flip the magic "make 4 ports work" bit */ | 
 | 450 | 		tmp = readl(mmio_base + SIL_IDE2_BMDMA); | 
 | 451 | 		if ((tmp & SIL_INTR_STEERING) == 0) | 
 | 452 | 			writel(tmp | SIL_INTR_STEERING, | 
 | 453 | 			       mmio_base + SIL_IDE2_BMDMA); | 
 | 454 |  | 
 | 455 | 	} else { | 
 | 456 | 		irq_mask = SIL_MASK_2PORT; | 
 | 457 | 	} | 
 | 458 |  | 
 | 459 | 	/* make sure IDE0/1/2/3 interrupts are not masked */ | 
 | 460 | 	tmp = readl(mmio_base + SIL_SYSCFG); | 
 | 461 | 	if (tmp & irq_mask) { | 
 | 462 | 		tmp &= ~irq_mask; | 
 | 463 | 		writel(tmp, mmio_base + SIL_SYSCFG); | 
 | 464 | 		readl(mmio_base + SIL_SYSCFG);	/* flush */ | 
 | 465 | 	} | 
 | 466 |  | 
 | 467 | 	/* mask all SATA phy-related interrupts */ | 
 | 468 | 	/* TODO: unmask bit 6 (SError N bit) for hotplug */ | 
 | 469 | 	for (i = 0; i < probe_ent->n_ports; i++) | 
 | 470 | 		writel(0, mmio_base + sil_port[i].sien); | 
 | 471 |  | 
 | 472 | 	pci_set_master(pdev); | 
 | 473 |  | 
 | 474 | 	/* FIXME: check ata_device_add return value */ | 
 | 475 | 	ata_device_add(probe_ent); | 
 | 476 | 	kfree(probe_ent); | 
 | 477 |  | 
 | 478 | 	return 0; | 
 | 479 |  | 
 | 480 | err_out_free_ent: | 
 | 481 | 	kfree(probe_ent); | 
 | 482 | err_out_regions: | 
 | 483 | 	pci_release_regions(pdev); | 
 | 484 | err_out: | 
 | 485 | 	if (!pci_dev_busy) | 
 | 486 | 		pci_disable_device(pdev); | 
 | 487 | 	return rc; | 
 | 488 | } | 
 | 489 |  | 
 | 490 | static int __init sil_init(void) | 
 | 491 | { | 
 | 492 | 	return pci_module_init(&sil_pci_driver); | 
 | 493 | } | 
 | 494 |  | 
 | 495 | static void __exit sil_exit(void) | 
 | 496 | { | 
 | 497 | 	pci_unregister_driver(&sil_pci_driver); | 
 | 498 | } | 
 | 499 |  | 
 | 500 |  | 
 | 501 | module_init(sil_init); | 
 | 502 | module_exit(sil_exit); |