1669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/*
2669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * pata_pdc202xx_old.c 	- Promise PDC202xx PATA for new ATA layer
3669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *			  (C) 2005 Red Hat Inc
4ab77163008c596aad9624ceab190d840c0143fa8Alan Cox *			  Alan Cox <alan@lxorguk.ukuu.org.uk>
5a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz *			  (C) 2007,2009,2010 Bartlomiej Zolnierkiewicz
6669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
7669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Based in part on linux/drivers/ide/pci/pdc202xx_old.c
8669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
9669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * First cut with LBA48/ATAPI
10669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
11669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * TODO:
1206b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox *	Channel interlock/reset on both required ?
13669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */
1485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
15669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/kernel.h>
16669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/module.h>
17669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/pci.h>
18669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/init.h>
19669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/blkdev.h>
20669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/delay.h>
21669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <scsi/scsi_host.h>
22669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/libata.h>
23669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
24669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#define DRV_NAME "pata_pdc202xx_old"
2506b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox#define DRV_VERSION "0.4.3"
26669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
27a0fcdc0259e98d1c16d96baea9ba8a8603e41791Jeff Garzikstatic int pdc2026x_cable_detect(struct ata_port *ap)
28669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
29669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
30669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	u16 cis;
3185cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
32669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_read_config_word(pdev, 0x50, &cis);
33669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	if (cis & (1 << (10 + ap->port_no)))
34a0ac38f16045f90dbbcd265b638cd7254c53aa65Alan Cox		return ATA_CBL_PATA40;
35a0ac38f16045f90dbbcd265b638cd7254c53aa65Alan Cox	return ATA_CBL_PATA80;
36669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
37669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
38750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewiczstatic void pdc202xx_exec_command(struct ata_port *ap,
39a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz				  const struct ata_taskfile *tf)
40a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz{
41a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz	DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
42a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz
43a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz	iowrite8(tf->command, ap->ioaddr.command_addr);
44a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz	ndelay(400);
45a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz}
46a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz
47606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyovstatic bool pdc202xx_irq_check(struct ata_port *ap)
48606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov{
49606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
50606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	unsigned long master	= pci_resource_start(pdev, 4);
51606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	u8 sc1d			= inb(master + 0x1d);
52606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov
53606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	if (ap->port_no) {
54606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		/*
55606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		 * bit 7: error, bit 6: interrupting,
56606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		 * bit 5: FIFO full, bit 4: FIFO empty
57606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		 */
58606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		return sc1d & 0x40;
59606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	} else	{
60606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		/*
61606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		 * bit 3: error, bit 2: interrupting,
62606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		 * bit 1: FIFO full, bit 0: FIFO empty
63606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		 */
64606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov		return sc1d & 0x04;
65606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	}
66606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov}
67606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov
68669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/**
69ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox *	pdc202xx_configure_piomode	-	set chip PIO timing
70669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@ap: ATA interface
71669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@adev: ATA device
72669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@pio: PIO mode
73669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
74669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	Called to do the PIO mode setup. Our timing registers are shared
75669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	so a configure_dmamode call will undo any work we do here and vice
76669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	versa
77669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */
7885cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
79ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
80669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
81669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
8263ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz	int port = 0x60 + 8 * ap->port_no + 4 * adev->devno;
83669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	static u16 pio_timing[5] = {
84669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		0x0913, 0x050C , 0x0308, 0x0206, 0x0104
85669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	};
86669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	u8 r_ap, r_bp;
87669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
88669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_read_config_byte(pdev, port, &r_ap);
89669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_read_config_byte(pdev, port + 1, &r_bp);
90669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	r_ap &= ~0x3F;	/* Preserve ERRDY_EN, SYNC_IN */
9163ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz	r_bp &= ~0x1F;
92669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	r_ap |= (pio_timing[pio] >> 8);
93669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	r_bp |= (pio_timing[pio] & 0xFF);
9485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
95669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	if (ata_pio_need_iordy(adev))
96669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		r_ap |= 0x20;	/* IORDY enable */
97669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	if (adev->class == ATA_DEV_ATA)
98669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		r_ap |= 0x10;	/* FIFO enable */
99669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_write_config_byte(pdev, port, r_ap);
100669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_write_config_byte(pdev, port + 1, r_bp);
101669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
102669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
103669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/**
104ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox *	pdc202xx_set_piomode	-	set initial PIO mode data
105669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@ap: ATA interface
106669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@adev: ATA device
107669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
108669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	Called to do the PIO mode setup. Our timing registers are shared
109669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	but we want to set the PIO timing by default.
110669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */
11185cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
112ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void pdc202xx_set_piomode(struct ata_port *ap, struct ata_device *adev)
113669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
114ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox	pdc202xx_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
115669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
116669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
117669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/**
118ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox *	pdc202xx_configure_dmamode	-	set DMA mode in chip
119669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@ap: ATA interface
120669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@adev: ATA device
121669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
122669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	Load DMA cycle times into the chip ready for a DMA transfer
123669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	to occur.
124669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */
12585cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
126ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
127669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
128669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
12963ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz	int port = 0x60 + 8 * ap->port_no + 4 * adev->devno;
130669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	static u8 udma_timing[6][2] = {
131669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{ 0x60, 0x03 },	/* 33 Mhz Clock */
132669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{ 0x40, 0x02 },
133669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{ 0x20, 0x01 },
134669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{ 0x40, 0x02 },	/* 66 Mhz Clock */
135669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{ 0x20, 0x01 },
13685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik		{ 0x20, 0x01 }
137669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	};
13863ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz	static u8 mdma_timing[3][2] = {
13963ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz		{ 0xe0, 0x0f },
14006b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox		{ 0x60, 0x04 },
14106b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox		{ 0x60, 0x03 },
14263ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz	};
143669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	u8 r_bp, r_cp;
14485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
145669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_read_config_byte(pdev, port + 1, &r_bp);
146669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_read_config_byte(pdev, port + 2, &r_cp);
14785cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
14863ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz	r_bp &= ~0xE0;
149669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	r_cp &= ~0x0F;
15085cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
151669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	if (adev->dma_mode >= XFER_UDMA_0) {
152669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		int speed = adev->dma_mode - XFER_UDMA_0;
153669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		r_bp |= udma_timing[speed][0];
154669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		r_cp |= udma_timing[speed][1];
15585cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
156669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	} else {
157669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		int speed = adev->dma_mode - XFER_MW_DMA_0;
15863ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz		r_bp |= mdma_timing[speed][0];
15963ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz		r_cp |= mdma_timing[speed][1];
160669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	}
161669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_write_config_byte(pdev, port + 1, r_bp);
162669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	pci_write_config_byte(pdev, port + 2, r_cp);
16385cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
164669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
165669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
166669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/**
167669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	pdc2026x_bmdma_start		-	DMA engine begin
168669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@qc: ATA command
169669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
170669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	In UDMA3 or higher we have to clock switch for the duration of the
171669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	DMA transfer sequence.
17206b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox *
17306b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox *	Note: The host lock held by the libata layer protects
17406b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox *	us from two channels both trying to set DMA bits at once
175669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */
17685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
177669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
178669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
179669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct ata_port *ap = qc->ap;
180669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct ata_device *adev = qc->dev;
181669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct ata_taskfile *tf = &qc->tf;
182669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	int sel66 = ap->port_no ? 0x08: 0x02;
183669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
1840d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo	void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr;
1850d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo	void __iomem *clock = master + 0x11;
1860d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo	void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no);
18785cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
188669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	u32 len;
18985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
190669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	/* Check we keep host level locking here */
1916ad58b245a543461bd55d51b8303f555419687b2Bartlomiej Zolnierkiewicz	if (adev->dma_mode > XFER_UDMA_2)
1920d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo		iowrite8(ioread8(clock) | sel66, clock);
193669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	else
1940d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo		iowrite8(ioread8(clock) & ~sel66, clock);
195669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
19685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik	/* The DMA clocks may have been trashed by a reset. FIXME: make conditional
197669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	   and move to qc_issue ? */
198ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox	pdc202xx_set_dmamode(ap, qc->dev);
199669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
200669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	/* Cases the state machine will not complete correctly without help */
2010dc36888d4422140f9eaf50f24953ec109f750a3Tejun Heo	if ((tf->flags & ATA_TFLAG_LBA48) ||  tf->protocol == ATAPI_PROT_DMA) {
2025e5188108bcf9ab2e6f87b4b54924354040b0aa7Alan Cox		len = qc->nbytes / 2;
20385cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
204669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		if (tf->flags & ATA_TFLAG_WRITE)
205669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			len |= 0x06000000;
206669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		else
207669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			len |= 0x05000000;
20885cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
2090d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo		iowrite32(len, atapi_reg);
210669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	}
21185cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
21285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik	/* Activate DMA */
213669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	ata_bmdma_start(qc);
214669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
215669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
216669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/**
217669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	pdc2026x_bmdma_end		-	DMA engine stop
218669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@qc: ATA command
219669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
220669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	After a DMA completes we need to put the clock back to 33MHz for
221669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	PIO timings.
22206b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox *
22306b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox *	Note: The host lock held by the libata layer protects
22406b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox *	us from two channels both trying to set DMA bits at once
225669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */
22685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
227669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
228669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
229669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct ata_port *ap = qc->ap;
230669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct ata_device *adev = qc->dev;
231669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	struct ata_taskfile *tf = &qc->tf;
23285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
233669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	int sel66 = ap->port_no ? 0x08: 0x02;
234669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	/* The clock bits are in the same register for both channels */
2350d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo	void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr;
2360d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo	void __iomem *clock = master + 0x11;
2370d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo	void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no);
23885cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
239669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	/* Cases the state machine will not complete correctly */
2400dc36888d4422140f9eaf50f24953ec109f750a3Tejun Heo	if (tf->protocol == ATAPI_PROT_DMA || (tf->flags & ATA_TFLAG_LBA48)) {
2410d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo		iowrite32(0, atapi_reg);
2420d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo		iowrite8(ioread8(clock) & ~sel66, clock);
243669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	}
244669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	/* Flip back to 33Mhz for PIO */
2456ad58b245a543461bd55d51b8303f555419687b2Bartlomiej Zolnierkiewicz	if (adev->dma_mode > XFER_UDMA_2)
2460d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo		iowrite8(ioread8(clock) & ~sel66, clock);
247669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	ata_bmdma_stop(qc);
24836906d9beab941452cad406cc03f05cc78671256Alan Cox	pdc202xx_set_piomode(ap, adev);
249669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
250669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
251669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/**
252669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	pdc2026x_dev_config	-	device setup hook
253669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	@adev: newly found device
254669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *
255669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	Perform chip specific early setup. We need to lock the transfer
256669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	sizes to 8bit to avoid making the state engine on the 2026x cards
257669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik *	barf.
258669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */
25985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
260cd0d3bbcdd650651b7ccfaf55d107e3fc237d95aAlan Coxstatic void pdc2026x_dev_config(struct ata_device *adev)
261669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
262669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	adev->max_sectors = 256;
263669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
264669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
26536906d9beab941452cad406cc03f05cc78671256Alan Coxstatic int pdc2026x_port_start(struct ata_port *ap)
26636906d9beab941452cad406cc03f05cc78671256Alan Cox{
26736906d9beab941452cad406cc03f05cc78671256Alan Cox	void __iomem *bmdma = ap->ioaddr.bmdma_addr;
26836906d9beab941452cad406cc03f05cc78671256Alan Cox	if (bmdma) {
26936906d9beab941452cad406cc03f05cc78671256Alan Cox		/* Enable burst mode */
27036906d9beab941452cad406cc03f05cc78671256Alan Cox		u8 burst = ioread8(bmdma + 0x1f);
27136906d9beab941452cad406cc03f05cc78671256Alan Cox		iowrite8(burst | 0x01, bmdma + 0x1f);
27236906d9beab941452cad406cc03f05cc78671256Alan Cox	}
273c7087652e1890a3feef35b30ee1d4be68e1932cdTejun Heo	return ata_bmdma_port_start(ap);
27436906d9beab941452cad406cc03f05cc78671256Alan Cox}
27536906d9beab941452cad406cc03f05cc78671256Alan Cox
276aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox/**
277aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *	pdc2026x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command
278aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *	@qc: Metadata associated with taskfile to check
279aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *
280aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *	Just say no - not supported on older Promise.
281aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *
282aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *	LOCKING:
283aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *	None (inherited from caller).
284aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *
285aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *	RETURNS: 0 when ATAPI DMA can be used
286aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox *		 1 otherwise
287aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox */
288aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox
289aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Coxstatic int pdc2026x_check_atapi_dma(struct ata_queued_cmd *qc)
290aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox{
291aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox	return 1;
292aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox}
293aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox
294ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic struct scsi_host_template pdc202xx_sht = {
29568d1d07b510bb57a504588adc2bd2758adea0965Tejun Heo	ATA_BMDMA_SHT(DRV_NAME),
296669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik};
297669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
298669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic struct ata_port_operations pdc2024x_port_ops = {
299029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.inherits		= &ata_bmdma_port_ops,
300029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo
301029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.cable_detect		= ata_cable_40wire,
302029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.set_piomode		= pdc202xx_set_piomode,
303029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.set_dmamode		= pdc202xx_set_dmamode,
304a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz
305750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewicz	.sff_exec_command	= pdc202xx_exec_command,
306606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	.sff_irq_check		= pdc202xx_irq_check,
30785cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik};
308669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
309669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic struct ata_port_operations pdc2026x_port_ops = {
310029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.inherits		= &pdc2024x_port_ops,
311029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo
312029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.check_atapi_dma	= pdc2026x_check_atapi_dma,
313029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.bmdma_start		= pdc2026x_bmdma_start,
314029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.bmdma_stop		= pdc2026x_bmdma_stop,
315029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo
316029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.cable_detect		= pdc2026x_cable_detect,
317029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.dev_config		= pdc2026x_dev_config,
318029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo
319029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo	.port_start		= pdc2026x_port_start,
320750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewicz
321750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewicz	.sff_exec_command	= pdc202xx_exec_command,
322606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov	.sff_irq_check		= pdc202xx_irq_check,
32385cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik};
324669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
325ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
326669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
3271626aeb881236c8cb022b5e4ca594146a951d669Tejun Heo	static const struct ata_port_info info[3] = {
328669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{
3291d2808fd3d2d5d2c0483796a0f443d1cb3f11367Jeff Garzik			.flags = ATA_FLAG_SLAVE_POSS,
33014bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø			.pio_mask = ATA_PIO4,
33114bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø			.mwdma_mask = ATA_MWDMA2,
332669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			.udma_mask = ATA_UDMA2,
333669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			.port_ops = &pdc2024x_port_ops
33485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik		},
335669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{
3361d2808fd3d2d5d2c0483796a0f443d1cb3f11367Jeff Garzik			.flags = ATA_FLAG_SLAVE_POSS,
33714bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø			.pio_mask = ATA_PIO4,
33814bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø			.mwdma_mask = ATA_MWDMA2,
339669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			.udma_mask = ATA_UDMA4,
340669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			.port_ops = &pdc2026x_port_ops
341669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		},
342669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		{
3431d2808fd3d2d5d2c0483796a0f443d1cb3f11367Jeff Garzik			.flags = ATA_FLAG_SLAVE_POSS,
34414bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø			.pio_mask = ATA_PIO4,
34514bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø			.mwdma_mask = ATA_MWDMA2,
346669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			.udma_mask = ATA_UDMA5,
347669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik			.port_ops = &pdc2026x_port_ops
348669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		}
34985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
350669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	};
3511626aeb881236c8cb022b5e4ca594146a951d669Tejun Heo	const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
35285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik
353669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	if (dev->device == PCI_DEVICE_ID_PROMISE_20265) {
354669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		struct pci_dev *bridge = dev->bus->self;
355669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		/* Don't grab anything behind a Promise I2O RAID */
356669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		if (bridge && bridge->vendor == PCI_VENDOR_ID_INTEL) {
357b447916e2b8c80f37aa88512ea39a05d5d11507dJeff Garzik			if (bridge->device == PCI_DEVICE_ID_INTEL_I960)
358669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik				return -ENODEV;
359b447916e2b8c80f37aa88512ea39a05d5d11507dJeff Garzik			if (bridge->device == PCI_DEVICE_ID_INTEL_I960RM)
360669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik				return -ENODEV;
361669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik		}
362669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik	}
3631c5afdf7a629d2e77de8dd043b97a33dcd7e6dfaTejun Heo	return ata_pci_bmdma_init_one(dev, ppi, &pdc202xx_sht, NULL, 0);
364669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
365669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
366ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic const struct pci_device_id pdc202xx[] = {
3672d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
3682d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
3692d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 },
3702d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2 },
3712d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik	{ PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2 },
3722d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik
3732d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik	{ },
374669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik};
375669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
376ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic struct pci_driver pdc202xx_pci_driver = {
3772d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik	.name 		= DRV_NAME,
378ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox	.id_table	= pdc202xx,
379ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox	.probe 		= pdc202xx_init_one,
38062d64ae0ec76360736c9dc4ca2067ae8de0ba9f2Alan Cox	.remove		= ata_pci_remove_one,
381438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#ifdef CONFIG_PM
38262d64ae0ec76360736c9dc4ca2067ae8de0ba9f2Alan Cox	.suspend	= ata_pci_device_suspend,
38362d64ae0ec76360736c9dc4ca2067ae8de0ba9f2Alan Cox	.resume		= ata_pci_device_resume,
384438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#endif
385669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik};
386669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
387ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic int __init pdc202xx_init(void)
388669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
389ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox	return pci_register_driver(&pdc202xx_pci_driver);
390669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
391669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
392ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void __exit pdc202xx_exit(void)
393669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{
394ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox	pci_unregister_driver(&pdc202xx_pci_driver);
395669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}
396669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
397669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_AUTHOR("Alan Cox");
398669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267");
399669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_LICENSE("GPL");
400ada406c8246b0792afe4d7f8ae7606093052de87Alan CoxMODULE_DEVICE_TABLE(pci, pdc202xx);
401669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_VERSION(DRV_VERSION);
402669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik
403ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxmodule_init(pdc202xx_init);
404ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxmodule_exit(pdc202xx_exit);
405