11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org)
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  May be copied or modified under the terms of the GNU General Public License
8ccd32e221c3e3797ac56305c554ad8b07c13c815Alan Cox *  Copyright (C) 2002 Alan Cox
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw>
1021b824771309927172247546b0bff0c4e6831875Sergei Shtylyov *  Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
113c8cc8df5a67a539cd185026e6b6f49b576869baBartlomiej Zolnierkiewicz *  Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  (U)DMA capable version of ali 1533/1543(C), 1535(D)
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **********************************************************************
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  9/7/99 --Parts from the above author are included and need to be
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  converted into standard interface, once I finish the thought.
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Recent changes
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Don't use LBA48 mode on ALi <= 0xC4
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Don't poke 0x79 with a non ALi northbridge
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Don't flip undefined bits on newer chipsets (fix Fujitsu laptop hang)
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Allow UDMA6 on revisions > 0xC4
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Documentation
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Chipset documentation available under NDA only
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ide.h>
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
3695ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz#include <linux/dmi.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz#define DRV_NAME "alim15x3"
41ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	ALi devices are not plug in. Otherwise these static values would
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	need to go. They ought to go away anyway
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 m5229_revision;
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 chip_is_1543c_e;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_dev *isa_dev;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewiczstatic void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on)
52293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz{
53293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	struct pci_dev *pdev = to_pci_dev(hwif->dev);
54293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	int pio_fifo = 0x54 + hwif->channel;
55293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	u8 fifo;
56293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	int shift = 4 * (drive->dn & 1);
57293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz
58293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	pci_read_config_byte(pdev, pio_fifo, &fifo);
59293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	fifo &= ~(0x0F << shift);
60293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	fifo |= (on << shift);
61293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	pci_write_config_byte(pdev, pio_fifo, fifo);
62293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz}
63293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz
64a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewiczstatic void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive,
65e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz				struct ide_timing *t, u8 ultra)
66a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz{
67a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	struct pci_dev *dev = to_pci_dev(hwif->dev);
68a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	int port = hwif->channel ? 0x5c : 0x58;
69e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	int udmat = 0x56 + hwif->channel;
70e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	u8 unit = drive->dn & 1, udma;
71e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	int shift = 4 * unit;
72e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz
73e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	/* Set up the UDMA */
74e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	pci_read_config_byte(dev, udmat, &udma);
75e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	udma &= ~(0x0F << shift);
76e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	udma |= ultra << shift;
77e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	pci_write_config_byte(dev, udmat, udma);
78e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz
79e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	if (t == NULL)
80e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz		return;
81a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz
82a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	t->setup = clamp_val(t->setup, 1, 8) & 7;
83a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	t->act8b = clamp_val(t->act8b, 1, 8) & 7;
84a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
85a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	t->active = clamp_val(t->active, 1, 8) & 7;
86a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	t->recover = clamp_val(t->recover, 1, 16) & 15;
87a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz
88a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	pci_write_config_byte(dev, port, t->setup);
89a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b);
90a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	pci_write_config_byte(dev, port + unit + 2,
91a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz			      (t->active << 4) | t->recover);
92a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz}
93a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
9588b2b32babd46cd54d2de4d17eb869aea3383e11Bartlomiej Zolnierkiewicz *	ali_set_pio_mode	-	set host controller for PIO mode
96e085b3cae85af47eb0a3eda3186bd898310fb322Bartlomiej Zolnierkiewicz *	@hwif: port
9726bcb879c03254545a19c6700fe5bcef6f21e7b1Bartlomiej Zolnierkiewicz *	@drive: drive
9821b824771309927172247546b0bff0c4e6831875Sergei Shtylyov *
9926bcb879c03254545a19c6700fe5bcef6f21e7b1Bartlomiej Zolnierkiewicz *	Program the controller for the given PIO mode.
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
10126bcb879c03254545a19c6700fe5bcef6f21e7b1Bartlomiej Zolnierkiewicz
102e085b3cae85af47eb0a3eda3186bd898310fb322Bartlomiej Zolnierkiewiczstatic void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
104cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz	ide_drive_t *pair = ide_get_pair_dev(drive);
10530e5ee4d1a651a0c66e86c6612c003034bd20ba2Bartlomiej Zolnierkiewicz	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
1063c8cc8df5a67a539cd185026e6b6f49b576869baBartlomiej Zolnierkiewicz	unsigned long T =  1000000 / bus_speed; /* PCI clock based */
1073c8cc8df5a67a539cd185026e6b6f49b576869baBartlomiej Zolnierkiewicz	struct ide_timing t;
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
109e085b3cae85af47eb0a3eda3186bd898310fb322Bartlomiej Zolnierkiewicz	ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
110cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz	if (pair) {
111cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz		struct ide_timing p;
112cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz
113cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz		ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
1145740345b877e2c8745cdf454674b45919679f231Bartlomiej Zolnierkiewicz		ide_timing_merge(&p, &t, &t,
1155740345b877e2c8745cdf454674b45919679f231Bartlomiej Zolnierkiewicz			IDE_TIMING_SETUP | IDE_TIMING_8BIT);
116cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz		if (pair->dma_mode) {
117cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz			ide_timing_compute(pair, pair->dma_mode, &p, T, 1);
1185740345b877e2c8745cdf454674b45919679f231Bartlomiej Zolnierkiewicz			ide_timing_merge(&p, &t, &t,
1195740345b877e2c8745cdf454674b45919679f231Bartlomiej Zolnierkiewicz				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
120cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz		}
121cde727be967a86aee01042f35c8a861728272cf1Bartlomiej Zolnierkiewicz	}
1223c8cc8df5a67a539cd185026e6b6f49b576869baBartlomiej Zolnierkiewicz
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * PIO mode => ATA FIFO on, ATAPI FIFO off
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
126293f18ad720f7c10f9f4b8a87827a1f0989e19eeBartlomiej Zolnierkiewicz	ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00);
1273c8cc8df5a67a539cd185026e6b6f49b576869baBartlomiej Zolnierkiewicz
128e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	ali_program_timings(hwif, drive, &t, 0);
12921b824771309927172247546b0bff0c4e6831875Sergei Shtylyov}
13021b824771309927172247546b0bff0c4e6831875Sergei Shtylyov
13121b824771309927172247546b0bff0c4e6831875Sergei Shtylyov/**
1322d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz *	ali_udma_filter		-	compute UDMA mask
1332d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz *	@drive: IDE device
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1352d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz *	Return available UDMA modes.
1362d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz *
1372d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz *	The actual rules for the ALi are:
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		No UDMA on revisions <= 0x20
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		Disk only for revisions < 0xC2
14063b1623ef0e33160d782fd1b0044e9a8af5d16cfBartlomiej Zolnierkiewicz *		Not WDC drives on M1543C-E (?)
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1432d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewiczstatic u8 ali_udma_filter(ide_drive_t *drive)
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1452d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz	if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
1462d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz		if (drive->media != ide_disk)
1472d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz			return 0;
1482db3dae51c1a096cfbd0e6f14c5ecca16e79a1d0Bartlomiej Zolnierkiewicz		if (chip_is_1543c_e &&
1494dde4492d850a4c9bcaa92e5bd7f4eebe3e2f5abBartlomiej Zolnierkiewicz		    strstr((char *)&drive->id[ATA_ID_PROD], "WDC "))
1502d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz			return 0;
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1532d5eaa6dd744a641e75503232a01f52d0768884cBartlomiej Zolnierkiewicz	return drive->hwif->ultra_mask;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
15788b2b32babd46cd54d2de4d17eb869aea3383e11Bartlomiej Zolnierkiewicz *	ali_set_dma_mode	-	set host controller for DMA mode
1588776168ca2151850164af1de5565d01f7b8b2c53Bartlomiej Zolnierkiewicz *	@hwif: port
15988b2b32babd46cd54d2de4d17eb869aea3383e11Bartlomiej Zolnierkiewicz *	@drive: drive
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Configure the hardware for the desired IDE transfer mode.
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
163f212ff28f08e4ddcef9f25b13463c45cc4204a0cBartlomiej Zolnierkiewicz
1648776168ca2151850164af1de5565d01f7b8b2c53Bartlomiej Zolnierkiewiczstatic void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
166e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz	static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD };
16736501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz	struct pci_dev *dev	= to_pci_dev(hwif->dev);
168a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	ide_drive_t *pair	= ide_get_pair_dev(drive);
169a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	int bus_speed		= ide_pci_clk ? ide_pci_clk : 33;
170a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	unsigned long T		=  1000000 / bus_speed; /* PCI clock based */
1718776168ca2151850164af1de5565d01f7b8b2c53Bartlomiej Zolnierkiewicz	const u8 speed		= drive->dma_mode;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 tmpbyte		= 0x00;
173a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz	struct ide_timing t;
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (speed < XFER_UDMA_0) {
176a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz		ide_timing_compute(drive, drive->dma_mode, &t, T, 1);
177a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz		if (pair) {
178a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz			struct ide_timing p;
179a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz
180a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz			ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
181a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz			ide_timing_merge(&p, &t, &t,
182a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz				IDE_TIMING_SETUP | IDE_TIMING_8BIT);
183a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz			if (pair->dma_mode) {
184a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz				ide_timing_compute(pair, pair->dma_mode,
185a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz						&p, T, 1);
186a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz				ide_timing_merge(&p, &t, &t,
187a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz					IDE_TIMING_SETUP | IDE_TIMING_8BIT);
188a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz			}
189a345c7856e52bf8b21a5ae6a24fb824bfedefbe9Bartlomiej Zolnierkiewicz		}
190e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz		ali_program_timings(hwif, drive, &t, 0);
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
192e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz		ali_program_timings(hwif, drive, NULL,
193e4c7112b5686c70ba7be86dbc83c989c75aca802Bartlomiej Zolnierkiewicz				udma_timing[speed - XFER_UDMA_0]);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (speed >= XFER_UDMA_3) {
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pci_read_config_byte(dev, 0x4b, &tmpbyte);
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmpbyte |= 1;
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pci_write_config_byte(dev, 0x4b, tmpbyte);
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2038a4a5738ba499083cf4c5668895efe220b1946d3Bartlomiej Zolnierkiewicz *	ali_dma_check	-	DMA check
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@drive:	target device
2052298169418f43ba5e0919762a4bab95a1227872aBartlomiej Zolnierkiewicz *	@cmd: command
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Returns 1 if the DMA cannot be performed, zero on success.
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2108a4a5738ba499083cf4c5668895efe220b1946d3Bartlomiej Zolnierkiewiczstatic int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (m5229_revision < 0xC2 && drive->media != ide_disk) {
2132298169418f43ba5e0919762a4bab95a1227872aBartlomiej Zolnierkiewicz		if (cmd->tf_flags & IDE_TFLAG_WRITE)
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 1;	/* try PIO instead of DMA */
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2168a4a5738ba499083cf4c5668895efe220b1946d3Bartlomiej Zolnierkiewicz	return 0;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	init_chipset_ali15x3	-	Initialise an ALi IDE controller
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev: PCI device
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This function initializes the ALI IDE controller and where
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	appropriate also sets up the 1533 southbridge.
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
226a326b02b0c576001353dbc489154959b0889c6bfBartlomiej Zolnierkiewicz
2272ed0ef543ae3f3ea4f8bd0433fb1fed22625a309Bartlomiej Zolnierkiewiczstatic int init_chipset_ali15x3(struct pci_dev *dev)
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 tmpbyte;
231b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox	struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0));
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23344c10138fd4bbc4b6d6bff0873c24902f2a9da65Auke Kok	m5229_revision = dev->revision;
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
235b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox	isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (m5229_revision < 0xC2) {
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * revision 0x20 (1543-E, 1543-F)
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E)
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_read_config_byte(dev, 0x4b, &tmpbyte);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * clear bit 7
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F);
250cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		/*
251cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		 * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
252cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		 */
253cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		if (m5229_revision >= 0x20 && isa_dev) {
254cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz			pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
255cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz			chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
256cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		}
257b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox		goto out;
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 1543C-B?, 1535, 1535D, 1553
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Note 1: not all "motherboard" support this detection
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Note 2: if no udma 66 device, the detection may "error".
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *         but in this case, we will not set the device to
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *         ultra 66, the detection result is not important
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * enable "Cable Detection", m5229, 0x4b, bit3
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pci_read_config_byte(dev, 0x4b, &tmpbyte);
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08);
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We should only tune the 1533 enable if we are using an ALi
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * North bridge. We might have no north found on some zany
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * box without a device at 0:0.0. The ALi bridge will be at
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * 0:0.0 so if we didn't find one we know what is cooking.
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
280b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox	if (north && north->vendor != PCI_VENDOR_ID_AL)
281b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox		goto out;
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (m5229_revision < 0xC5 && isa_dev)
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * set south-bridge's enable bit, m1533, 0x79
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_read_config_byte(isa_dev, 0x79, &tmpbyte);
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (m5229_revision == 0xC2) {
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * 1543C-B0 (m1533, 0x79, bit 2)
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04);
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (m5229_revision >= 0xC3) {
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * 1553/1535 (m1533, 0x79, bit 1)
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
302cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz
303b1489009963b8c5132f2ffe23483e811d9ae5607Alan Coxout:
304cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	/*
305cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 * CD_ROM DMA on (m5229, 0x53, bit0)
306cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 *      Enable this bit even if we want to use PIO.
307cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 * PIO FIFO off (m5229, 0x53, bit1)
308cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 *      The hardware will use 0x54h and 0x55h to control PIO FIFO.
309cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 *	(Not on later devices it seems)
310cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 *
311cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 *	0x53 changes meaning on later revs - we must no touch
312cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 *	bit 1 on them.  Need to check if 0x20 is the right break.
313cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	 */
314cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	if (m5229_revision >= 0x20) {
315cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		pci_read_config_byte(dev, 0x53, &tmpbyte);
316cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz
317cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		if (m5229_revision <= 0x20)
318cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz			tmpbyte = (tmpbyte & (~0x02)) | 0x01;
319cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
320cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz			tmpbyte |= 0x03;
321cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		else
322cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz			tmpbyte |= 0x01;
323cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz
324cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz		pci_write_config_byte(dev, 0x53, tmpbyte);
325cad221aa82c6f434c1d78bee1d485b5b69c626f8Bartlomiej Zolnierkiewicz	}
326b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox	pci_dev_put(north);
327b1489009963b8c5132f2ffe23483e811d9ae5607Alan Cox	pci_dev_put(isa_dev);
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
33295ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz/*
33395ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz *	Cable special cases
33495ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz */
33595ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz
3361855256c497ecfefc730df6032243f26855ce52cJeff Garzikstatic const struct dmi_system_id cable_dmi_table[] = {
33795ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	{
33895ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		.ident = "HP Pavilion N5430",
33995ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		.matches = {
34095ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
3418663fd6d0de7144c9e8455b733aeb38fe80788edBartlomiej Zolnierkiewicz			DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
34295ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		},
34395ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	},
34403e6f489b32c0e7877bfe48f5619db725edf1feaDaniel Exner	{
34503e6f489b32c0e7877bfe48f5619db725edf1feaDaniel Exner		.ident = "Toshiba Satellite S1800-814",
34603e6f489b32c0e7877bfe48f5619db725edf1feaDaniel Exner		.matches = {
34703e6f489b32c0e7877bfe48f5619db725edf1feaDaniel Exner			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
34803e6f489b32c0e7877bfe48f5619db725edf1feaDaniel Exner			DMI_MATCH(DMI_PRODUCT_NAME, "S1800-814"),
34903e6f489b32c0e7877bfe48f5619db725edf1feaDaniel Exner		},
35003e6f489b32c0e7877bfe48f5619db725edf1feaDaniel Exner	},
35195ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	{ }
35295ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz};
35395ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz
35495ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewiczstatic int ali_cable_override(struct pci_dev *pdev)
35595ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz{
35695ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	/* Fujitsu P2000 */
35795ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	if (pdev->subsystem_vendor == 0x10CF &&
35895ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	    pdev->subsystem_device == 0x10AF)
35995ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		return 1;
36095ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz
361d151456a71e2757da4169a6be2eb68ac115b05b0Bartlomiej Zolnierkiewicz	/* Mitac 8317 (Winbook-A) and relatives */
362d151456a71e2757da4169a6be2eb68ac115b05b0Bartlomiej Zolnierkiewicz	if (pdev->subsystem_vendor == 0x1071 &&
363d151456a71e2757da4169a6be2eb68ac115b05b0Bartlomiej Zolnierkiewicz	    pdev->subsystem_device == 0x8317)
364d151456a71e2757da4169a6be2eb68ac115b05b0Bartlomiej Zolnierkiewicz		return 1;
365d151456a71e2757da4169a6be2eb68ac115b05b0Bartlomiej Zolnierkiewicz
36695ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	/* Systems by DMI */
36795ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	if (dmi_check_system(cable_dmi_table))
36895ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		return 1;
36995ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz
37095ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	return 0;
37195ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz}
37295ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
374ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz *	ali_cable_detect	-	cable detection
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@hwif: IDE interface
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This checks if the controller and the cable are capable
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	of UDMA66 transfers. It doesn't check the drives.
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381f454cbe8cd38b6d447e74ddaf012017fea42717eBartlomiej Zolnierkiewiczstatic u8 ali_cable_detect(ide_hwif_t *hwif)
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
38336501650ec45b1db308c3b51886044863be2d762Bartlomiej Zolnierkiewicz	struct pci_dev *dev = to_pci_dev(hwif->dev);
38495ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	u8 cbl = ATA_CBL_PATA40, tmpbyte;
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (m5229_revision >= 0xC2) {
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
38895ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		 * m5229 80-pin cable detection (from Host View)
38995ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		 *
39095ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		 * 0x4a bit0 is 0 => primary channel has 80-pin
39195ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		 * 0x4a bit1 is 0 => secondary channel has 80-pin
39295ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		 *
39395ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		 * Certain laptops use short but suitable cables
39495ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		 * and don't implement the detect logic.
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
39695ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		if (ali_cable_override(dev))
39795ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz			cbl = ATA_CBL_PATA40_SHORT;
39895ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		else {
39995ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz			pci_read_config_byte(dev, 0x4a, &tmpbyte);
40095ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz			if ((tmpbyte & (1 << hwif->channel)) == 0)
40195ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz				cbl = ATA_CBL_PATA80;
40295ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz		}
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40595ba8c17bc57bf4666e9de2be715b69d9a1ba211Bartlomiej Zolnierkiewicz	return cbl;
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40803682411b1ccd38cbde2e9a6ab43884ff34fbefcAnton Vorontsov#ifndef CONFIG_SPARC64
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	init_hwif_ali15x3	-	Initialize the ALI IDE x86 stuff
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@hwif: interface to configure
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Obtain the IRQ tables for an ALi based IDE solution on the PC
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	class platforms. This part of the code isn't applicable to the
41503682411b1ccd38cbde2e9a6ab43884ff34fbefcAnton Vorontsov *	Sparc systems.
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
418c2f12589bfc4119f2c331ecea8cca4945ed48497Herbert Xustatic void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 ideic, inmir;
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	s8 irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				      1, 11, 0, 12, 0, 14, 0, 15 };
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int irq = -1;
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (isa_dev) {
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * read IDE interface control
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pci_read_config_byte(isa_dev, 0x58, &ideic);
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* bit0, bit1 */
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ideic = ideic & 0x03;
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* get IRQ for IDE Controller */
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((hwif->channel && ideic == 0x03) ||
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    (!hwif->channel && !ideic)) {
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * get SIRQ1 routing table
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pci_read_config_byte(isa_dev, 0x44, &inmir);
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			inmir = inmir & 0x0f;
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			irq = irq_routing_table[inmir];
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (hwif->channel && !(ideic & 0x01)) {
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * get SIRQ2 routing table
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pci_read_config_byte(isa_dev, 0x75, &inmir);
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			inmir = inmir & 0x0f;
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			irq = irq_routing_table[inmir];
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(irq >= 0)
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hwif->irq = irq;
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4556d1cee44361b8d06ccd1812e80448d86ae60dfe3Anton Vorontsov#else
4566d1cee44361b8d06ccd1812e80448d86ae60dfe3Anton Vorontsov#define init_hwif_ali15x3 NULL
45703682411b1ccd38cbde2e9a6ab43884ff34fbefcAnton Vorontsov#endif /* CONFIG_SPARC64 */
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	init_dma_ali15x3	-	set up DMA on ALi15x3
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@hwif: IDE interface
462b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz *	@d: IDE port info
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
464b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz *	Set up the DMA functionality on the ALi 15x3.
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
467b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewiczstatic int __devinit init_dma_ali15x3(ide_hwif_t *hwif,
468b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz				      const struct ide_port_info *d)
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
470b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz	struct pci_dev *dev = to_pci_dev(hwif->dev);
471b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz	unsigned long base = ide_pci_dma_base(hwif, d);
472b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz
473ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz	if (base == 0)
474ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz		return -1;
475ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz
476ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz	hwif->dma_base = base;
477ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz
478ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz	if (ide_pci_check_simplex(hwif, d) < 0)
479ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz		return -1;
480ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz
481ebb00fb55d0566bb3e81518122a57b4b3bedf1e4Bartlomiej Zolnierkiewicz	if (ide_pci_set_master(dev, d->name) < 0)
482b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz		return -1;
483b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz
4840ecdca26e556eae9668ce6de9554757dddb942efBartlomiej Zolnierkiewicz	if (!hwif->channel)
485b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz		outb(inb(base + 2) & 0x60, base + 2);
486b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz
487b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz	printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx\n",
488b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz			 hwif->name, base, base + 7);
489b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz
490b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz	if (ide_allocate_dma_engine(hwif))
491b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz		return -1;
492b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz
493b123f56e04c7c112f754f948198d1ea5a80e649dBartlomiej Zolnierkiewicz	return 0;
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
496ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewiczstatic const struct ide_port_ops ali_port_ops = {
497ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz	.set_pio_mode		= ali_set_pio_mode,
498ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz	.set_dma_mode		= ali_set_dma_mode,
499ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz	.udma_filter		= ali_udma_filter,
500ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz	.cable_detect		= ali_cable_detect,
501ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz};
502ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz
503f37afdaca711838b50ecd89b9c15fc745270d77cBartlomiej Zolnierkiewiczstatic const struct ide_dma_ops ali_dma_ops = {
504f37afdaca711838b50ecd89b9c15fc745270d77cBartlomiej Zolnierkiewicz	.dma_host_set		= ide_dma_host_set,
5058a4a5738ba499083cf4c5668895efe220b1946d3Bartlomiej Zolnierkiewicz	.dma_setup		= ide_dma_setup,
506f37afdaca711838b50ecd89b9c15fc745270d77cBartlomiej Zolnierkiewicz	.dma_start		= ide_dma_start,
507653bcf5292a9ac4ffc07315198f0ef995e0646a8Bartlomiej Zolnierkiewicz	.dma_end		= ide_dma_end,
508f37afdaca711838b50ecd89b9c15fc745270d77cBartlomiej Zolnierkiewicz	.dma_test_irq		= ide_dma_test_irq,
509f37afdaca711838b50ecd89b9c15fc745270d77cBartlomiej Zolnierkiewicz	.dma_lost_irq		= ide_dma_lost_irq,
5108a4a5738ba499083cf4c5668895efe220b1946d3Bartlomiej Zolnierkiewicz	.dma_check		= ali_dma_check,
51122117d6eaac50d366d9013c88318a869ea4d8739Bartlomiej Zolnierkiewicz	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
512592b5315219881c6c0af4785f96456ad2043193aSergei Shtylyov	.dma_sff_read_status	= ide_dma_sff_read_status,
5135e37bdc081a980dd0d669e6387bcf15ca9666f81Bartlomiej Zolnierkiewicz};
5145e37bdc081a980dd0d669e6387bcf15ca9666f81Bartlomiej Zolnierkiewicz
5158562043606430185cad26d085d46adcc7ad67fd1Bartlomiej Zolnierkiewiczstatic const struct ide_port_info ali15x3_chipset __devinitdata = {
516ced3ec8aa7d0fa3300187ee47c144a22ccfc974eBartlomiej Zolnierkiewicz	.name		= DRV_NAME,
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.init_chipset	= init_chipset_ali15x3,
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.init_hwif	= init_hwif_ali15x3,
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.init_dma	= init_dma_ali15x3,
520ac95beedf8bc97b24f9540d4da9952f07221c023Bartlomiej Zolnierkiewicz	.port_ops	= &ali_port_ops,
5213f023b0138b7db21bac0074b3d5ca2854372c6ffSergei Shtylyov	.dma_ops	= &sff_dma_ops,
5224099d14322149c7a467e4997b87be4ba8eb78697Bartlomiej Zolnierkiewicz	.pio_mask	= ATA_PIO5,
5235f8b6c34854a966fe5eb7241fde0419d47d5d408Bartlomiej Zolnierkiewicz	.swdma_mask	= ATA_SWDMA2,
5245f8b6c34854a966fe5eb7241fde0419d47d5d408Bartlomiej Zolnierkiewicz	.mwdma_mask	= ATA_MWDMA2,
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	alim15x3_init_one	-	set up an ALi15x3 IDE controller
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev: PCI device to set up
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Perform the actual set up for an ALi15x3 that has been found by the
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	hot plug layer.
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
537039788e1532368eeca1071a873c14e03920cdf38Bartlomiej Zolnierkiewicz	struct ide_port_info d = ali15x3_chipset;
5388ac2b42a45896641ed292deaf038a1d2703d85a6Bartlomiej Zolnierkiewicz	u8 rev = dev->revision, idx = id->driver_data;
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
540283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz	/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
541283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz	if (rev <= 0xC4)
542283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz		d.host_flags |= IDE_HFLAG_NO_LBA48_DMA;
543283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz
544283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz	if (rev >= 0x20) {
545283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz		if (rev == 0x20)
546283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz			d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
547283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz
548283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz		if (rev < 0xC2)
549283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz			d.udma_mask = ATA_UDMA2;
550283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz		else if (rev == 0xC2 || rev == 0xC3)
551283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz			d.udma_mask = ATA_UDMA4;
552283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz		else if (rev == 0xC4)
553283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz			d.udma_mask = ATA_UDMA5;
554283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz		else
555283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz			d.udma_mask = ATA_UDMA6;
5565e37bdc081a980dd0d669e6387bcf15ca9666f81Bartlomiej Zolnierkiewicz
5575e37bdc081a980dd0d669e6387bcf15ca9666f81Bartlomiej Zolnierkiewicz		d.dma_ops = &ali_dma_ops;
5586d36b95fe2cc5655e96da42eaf19f1aa341c6856Bartlomiej Zolnierkiewicz	} else {
5596d36b95fe2cc5655e96da42eaf19f1aa341c6856Bartlomiej Zolnierkiewicz		d.host_flags |= IDE_HFLAG_NO_DMA;
5606d36b95fe2cc5655e96da42eaf19f1aa341c6856Bartlomiej Zolnierkiewicz
5616d36b95fe2cc5655e96da42eaf19f1aa341c6856Bartlomiej Zolnierkiewicz		d.mwdma_mask = d.swdma_mask = 0;
562283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz	}
563283283070f2607ed759563613c044f96f1546834Bartlomiej Zolnierkiewicz
5648ac2b42a45896641ed292deaf038a1d2703d85a6Bartlomiej Zolnierkiewicz	if (idx == 0)
5658ac2b42a45896641ed292deaf038a1d2703d85a6Bartlomiej Zolnierkiewicz		d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX;
5668ac2b42a45896641ed292deaf038a1d2703d85a6Bartlomiej Zolnierkiewicz
5676cdf6eb357c2681596b7b1672b92396ba82333d4Bartlomiej Zolnierkiewicz	return ide_pci_init_one(dev, &d, NULL);
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5719cbcc5e3c5d2d0355fed22d00762fd764c81a383Bartlomiej Zolnierkiewiczstatic const struct pci_device_id alim15x3_pci_tbl[] = {
5729cbcc5e3c5d2d0355fed22d00762fd764c81a383Bartlomiej Zolnierkiewicz	{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 },
5738ac2b42a45896641ed292deaf038a1d2703d85a6Bartlomiej Zolnierkiewicz	{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 1 },
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ 0, },
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl);
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
578a9ab09e26055a76295548ca36ec00de2f4367d32Bartlomiej Zolnierkiewiczstatic struct pci_driver alim15x3_pci_driver = {
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name		= "ALI15x3_IDE",
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.id_table	= alim15x3_pci_tbl,
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.probe		= alim15x3_init_one,
5828ee3f3b69d9c37f86a45862f53451699ec77fe12Bartlomiej Zolnierkiewicz	.remove		= ide_pci_remove,
583feb22b7f8e62b1b987a3a1dbad95af767a1df832Bartlomiej Zolnierkiewicz	.suspend	= ide_pci_suspend,
584feb22b7f8e62b1b987a3a1dbad95af767a1df832Bartlomiej Zolnierkiewicz	.resume		= ide_pci_resume,
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
58782ab1eeceba6705cd5a8815c48eb03af1dada744Bartlomiej Zolnierkiewiczstatic int __init ali15x3_ide_init(void)
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
589a9ab09e26055a76295548ca36ec00de2f4367d32Bartlomiej Zolnierkiewicz	return ide_pci_register_driver(&alim15x3_pci_driver);
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5928ee3f3b69d9c37f86a45862f53451699ec77fe12Bartlomiej Zolnierkiewiczstatic void __exit ali15x3_ide_exit(void)
5938ee3f3b69d9c37f86a45862f53451699ec77fe12Bartlomiej Zolnierkiewicz{
59495964018d53f479529dfdc2b46fe30c0a14a00e0Hannes Eder	pci_unregister_driver(&alim15x3_pci_driver);
5958ee3f3b69d9c37f86a45862f53451699ec77fe12Bartlomiej Zolnierkiewicz}
5968ee3f3b69d9c37f86a45862f53451699ec77fe12Bartlomiej Zolnierkiewicz
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(ali15x3_ide_init);
5988ee3f3b69d9c37f86a45862f53451699ec77fe12Bartlomiej Zolnierkiewiczmodule_exit(ali15x3_ide_exit);
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6003c8cc8df5a67a539cd185026e6b6f49b576869baBartlomiej ZolnierkiewiczMODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz");
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
603