The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: "Hank Yang" <hanky@promise.com.tw>
To: "Alan Cox" <alan@lxorguk.ukuu.org.uk>
Cc: <linux-kernel@vger.kernel.org>, <torvalds@transmeta.com>,
	"Linus Chen" <linusc@promise.com.tw>
Subject: Re: [PATCH] Submitting PROMISE IDE Controllers Driver Patch
Date: Fri, 8 Mar 2002 11:49:37 +0800	[thread overview]
Message-ID: <015101c1c654$454cad10$59cca8c0@hank> (raw)
In-Reply-To: <E16ixk4-0002D4-00@the-village.bc.nu>

[-- Attachment #1: Type: text/plain, Size: 803 bytes --]

Hi, Alan.

    Thank you for yours efforts to support this patch code.
    I sent our patch file as attachment for you reference.

    I saw the 'patch-2.4.19-pre2-ac3' and it has build-in Maxtor 48 bit lba
spec. Is these patch will be build into next kernel version 2.4.19?
Do you want us to make a patch for the 'patch-2.4.19-pre2-ac3'?

Best Regards
Hank Yang


> > Kernel Version: linux kernel 2.4.18
>
> The big IDE update is going into 2.4.19pre. Thats going to overlap with
this
> patch I suspect. You might want to cross check with 2.4.19pre3 when it
> appears and see how much you can remove.
> Other than that it looks pretty sound. Your mailer seems to have messed
> the tabs up so once 19pre3 appears and you've had a look at it can you
> send me a copy as an attachment ?
>
> Thanks
> Alan

[-- Attachment #2: ultra-2.4.18-submitting-ready.patch --]
[-- Type: application/octet-stream, Size: 43653 bytes --]

diff -urN linux-2.4.18.org/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.4.18.org/drivers/ide/ide-disk.c	Sat Dec 22 01:41:54 2001
+++ linux/drivers/ide/ide-disk.c	Wed Feb 27 23:54:46 2002
@@ -28,6 +28,11 @@
  *			added UDMA 3/4 reporting
  * Version 1.10		request queue changes, Ultra DMA 100
  */
+/*
+ * Support UltraDMA Mode 6 and 48 bit LBA Mode.
+ * Powered by PROMISE Technology, Inc. Portions Copyright (C)2001.
+ */
+#define PCI_VENDOR_ID_PROMISE	0x105a
 
 #define IDEDISK_VERSION	"1.10"
 
@@ -371,10 +376,22 @@
 		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
 	OUT_BYTE(0x00, IDE_FEATURE_REG);
 	OUT_BYTE(rq->nr_sectors,IDE_NSECTOR_REG);
+	if ((drive->id->command_set_2 & 0x0400) && HWIF(drive)->pci_devid.vid==PCI_VENDOR_ID_PROMISE) {
+		/* 48 bits data previous */
+		OUT_BYTE(rq->nr_sectors>>8, IDE_NSECTOR_REG);
+		OUT_BYTE(block>>24, IDE_SECTOR_REG);
+		OUT_BYTE(0x00, IDE_LCYL_REG);	//block only 32 bits
+		OUT_BYTE(0x00, IDE_HCYL_REG);
+		/* 48 bits data current */
+		OUT_BYTE(rq->nr_sectors, IDE_NSECTOR_REG);
+		OUT_BYTE(block, IDE_SECTOR_REG);
+		OUT_BYTE(block>>8, IDE_LCYL_REG);
+		OUT_BYTE(block>>16, IDE_HCYL_REG);
+		OUT_BYTE(drive->select.all,IDE_SELECT_REG);
 #ifdef CONFIG_BLK_DEV_PDC4030
-	if (drive->select.b.lba || IS_PDC4030_DRIVE) {
-#else /* !CONFIG_BLK_DEV_PDC4030 */
-	if (drive->select.b.lba) {
+	} else if (drive->select.b.lba || IS_PDC4030_DRIVE) {
+#else /* !CONFIG_BLK_DEV_PDC4030 */		
+	} else if (drive->select.b.lba) {
 #endif /* CONFIG_BLK_DEV_PDC4030 */
 #ifdef DEBUG
 		printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
@@ -413,7 +430,10 @@
 			return ide_started;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
-		OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
+		if ((drive->id->command_set_2 & 0x0400) && HWIF(drive)->pci_devid.vid==PCI_VENDOR_ID_PROMISE)
+			OUT_BYTE(drive->mult_count ? MULTI_READ_EXT : READ_EXT, IDE_COMMAND_REG);
+		else
+			OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
 		return ide_started;
 	}
 	if (rq->cmd == WRITE) {
@@ -422,7 +442,11 @@
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_write, drive)))
 			return ide_started;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-		OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, IDE_COMMAND_REG);
+		/* out 48 bits R/W command here */
+		if ((drive->id->command_set_2 & 0x0400) && HWIF(drive)->pci_devid.vid==PCI_VENDOR_ID_PROMISE)
+			OUT_BYTE(drive->mult_count ? MULTI_WRITE_EXT : WRITE_EXT, IDE_COMMAND_REG);
+		else
+			OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, IDE_COMMAND_REG);
 		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
 			printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name,
 				drive->mult_count ? "MULTWRITE" : "WRITE");
@@ -481,7 +505,7 @@
 static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
 {
 	if (drive->removable && !drive->usage) {
-		invalidate_bdev(inode->i_bdev, 0);
+		invalidate_buffers(inode->i_rdev);
 		if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL))
 			drive->doorlocking = 0;
 	}
@@ -508,12 +532,22 @@
 {
 	struct hd_driveid *id = drive->id;
 	unsigned long capacity = drive->cyl * drive->head * drive->sect;
+	int lba48=drive->id->command_set_2 & 0x0400;
+	unsigned long temp=0;
 
 	drive->select.b.lba = 0;
 
 	/* Determine capacity, and use LBA if the drive properly supports it */
 	if ((id->capability & 2) && lba_capacity_is_ok(id)) {
 		capacity = id->lba_capacity;
+		/* get 48 bits disk capacity if support */
+		if (lba48 && HWIF(drive)->pci_devid.vid==PCI_VENDOR_ID_PROMISE)
+		{
+			temp=id->words94_125[7];
+			temp<<=16;
+			temp|=id->words94_125[6];
+			capacity=temp;
+		}
 		drive->cyl = capacity / (drive->head * drive->sect);
 		drive->select.b.lba = 1;
 	}
@@ -769,7 +803,7 @@
 
 	/* Give size in megabytes (MB), not mebibytes (MiB). */
 	/* We compute the exact rounded value, avoiding overflow. */
-	printk (" (%ld MB)", (capacity - capacity/625 + 974)/1950);
+	printk (" (%ld GB)", ((capacity - capacity/625 + 974)/1950)/1024);
 
 	/* Only print cache size when it was specified */
 	if (id->buf_size)
diff -urN linux-2.4.18.org/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.4.18.org/drivers/ide/ide-dma.c	Mon Sep 10 01:43:02 2001
+++ linux/drivers/ide/ide-dma.c	Thu Feb 28 00:00:15 2002
@@ -75,6 +75,8 @@
  * ATA-66/100 and recovery functions, I forgot the rest......
  * SELECT_READ_WRITE(hwif,drive,func) for active tuning based on IO direction.
  *
+ * Support UltraDMA Mode 6 and 48 bit LBA Mode.
+ * Powered by PROMISE Technology, Inc. Portions Copyright (C)2001.
  */
 
 #include <linux/config.h>
@@ -101,6 +103,8 @@
 #define DEFAULT_BMCRBA	0xcc00	/* VIA's default value */
 #define DEFAULT_BMALIBA	0xd400	/* ALI's default value */
 
+#define CONFIG_BLK_DEV_IDEDMA_TIMEOUT 1	// By Promise
+
 extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);
 
 #ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
@@ -429,18 +433,22 @@
 	struct hd_driveid *id = drive->id;
 
 	if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-	    (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
-		if ((id->dma_ultra >> 13) & 1) {
-			printk(", UDMA(100)");	/* UDMA BIOS-enabled! */
+	    (id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
+	    	if ((id->dma_ultra >> 15) & 1) {
+			printk(", UDMA(166?)");	/* UDMA 7 BIOS-enabled! */
+	    	} else if ((id->dma_ultra >> 14) & 1) {
+			printk(", UDMA(133)");	/* UDMA 6 BIOS-enabled! */
+		} else if ((id->dma_ultra >> 13) & 1) {
+			printk(", UDMA(100)");	/* UDMA 5 BIOS-enabled! */
 		} else if ((id->dma_ultra >> 12) & 1) {
-			printk(", UDMA(66)");	/* UDMA BIOS-enabled! */
+			printk(", UDMA(66)");	/* UDMA 4 BIOS-enabled! */
 		} else {
 			printk(", UDMA(44)");	/* UDMA BIOS-enabled! */
 		}
 	} else if ((id->field_valid & 4) &&
 		   (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
 		if ((id->dma_ultra >> 10) & 1) {
-			printk(", UDMA(33)");	/* UDMA BIOS-enabled! */
+			printk(", UDMA(33)");	/* UDMA 2 BIOS-enabled! */
 		} else if ((id->dma_ultra >> 9) & 1) {
 			printk(", UDMA(25)");	/* UDMA BIOS-enabled! */
 		} else {
@@ -463,7 +471,11 @@
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive))
 			return hwif->dmaproc(ide_dma_off, drive);
-
+		
+		/* Enable DMA on any drive that has UltraDMA (mode 6/7) enabled */
+		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
+			if ((id->dma_ultra & (id->dma_ultra >> 14) & 3))
+				return hwif->dmaproc(ide_dma_on, drive);
 		/* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
 			if ((id->dma_ultra & (id->dma_ultra >> 11) & 7))
@@ -550,13 +562,18 @@
  */
 int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
-//	ide_hwgroup_t *hwgroup		= HWGROUP(drive);
 	ide_hwif_t *hwif		= HWIF(drive);
-	unsigned long dma_base		= hwif->dma_base;
+	unsigned long dma_base	= hwif->dma_base;
 	byte unit			= (drive->select.b.unit & 0x01);
 	unsigned int count, reading	= 0;
 	byte dma_stat;
-
+	int lba48			=drive->id->command_set_2 & 0x0400;
+	unsigned long high_16		= pci_resource_start(hwif->pci_dev, 4);
+	byte clock			=inb(high_16+0x11);
+	unsigned long atapi_port	=high_16+ 0x20 + (hwif->channel ? 0x04 : 0x00);
+	struct request *rq 		= HWGROUP(drive)->rq;
+	unsigned long word_count 	= 0;
+	
 	switch (func) {
 		case ide_dma_off:
 			printk("%s: DMA disabled\n", drive->name);
@@ -586,18 +603,39 @@
 #else /* !CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
 #endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
-			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+			if (lba48 && hwif->pci_devid.vid==PCI_VENDOR_ID_PROMISE)
+				OUT_BYTE(reading ? READ_DMA_EXT : WRITE_DMA_EXT, IDE_COMMAND_REG);
+			else
+				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
-			 * been issued to the drive, as per the BM-IDE spec.
-			 * The Promise Ultra33 doesn't work correctly when
-			 * we do this part before issuing the drive cmd.
-			 */
-			outb(inb(dma_base)|1, dma_base);		/* start DMA */
+			 * been issued to the drive, as per the BM-IDE spec. */
+			/* Enable ATAPI UDMA port for 48bit data on PDC20267 */
+			if (lba48 && hwif->pci_devid.vid==PCI_VENDOR_ID_PROMISE &&
+			   (hwif->pci_devid.did == PCI_DEVICE_ID_PROMISE_20267 || 
+			    hwif->pci_devid.did == PCI_DEVICE_ID_PROMISE_20265 ||
+			    hwif->pci_devid.did == PCI_DEVICE_ID_PROMISE_20262))
+			{
+				outb(clock|(hwif->channel ? 0x08:0x02), high_16 + 0x11);
+				word_count=(rq->nr_sectors << 8);
+				word_count=reading ? word_count | 0x05000000 : word_count | 0x06000000;
+				outl(word_count, atapi_port);
+			}  
+			outb(inb(dma_base)|1, dma_base);	/* start DMA */
 			return 0;
 		case ide_dma_end: /* returns 1 on error, 0 otherwise */
 			drive->waiting_for_dma = 0;
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+			/* Disable ATAPI UDMA port for 48bit data on PDC20267 */
+			if (lba48 && hwif->pci_devid.vid==PCI_VENDOR_ID_PROMISE &&
+			    (hwif->pci_devid.did == PCI_DEVICE_ID_PROMISE_20267 || 
+			     hwif->pci_devid.did == PCI_DEVICE_ID_PROMISE_20265 ||
+			     hwif->pci_devid.did == PCI_DEVICE_ID_PROMISE_20262))
+			{
+			    	outl(0, atapi_port);
+				clock=inb(high_16+0x11);
+				outb(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11);
+			}
 			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(dma_stat|6, dma_base+2);	/* clear the INTR & ERROR bits */
 			ide_destroy_dmatable(drive);	/* purge DMA mappings */
diff -urN linux-2.4.18.org/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c
--- linux-2.4.18.org/drivers/ide/ide-features.c	Sat Feb 10 03:40:02 2001
+++ linux/drivers/ide/ide-features.c	Thu Feb 28 00:04:42 2002
@@ -261,6 +261,9 @@
  */
 byte eighty_ninty_three (ide_drive_t *drive)
 {
+	if (HWIF(drive)->pci_devid.vid==0x105a)
+	    return(HWIF(drive)->udma_four);
+	/* PDC202XX: that's because some HDD will return wrong info */
 	return ((byte) ((HWIF(drive)->udma_four) &&
 #ifndef CONFIG_IDEDMA_IVB
 			(drive->id->hw_config & 0x4000) &&
diff -urN linux-2.4.18.org/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.4.18.org/drivers/ide/ide-pci.c	Fri Oct 26 04:53:47 2001
+++ linux/drivers/ide/ide-pci.c	Wed Feb 27 19:26:40 2002
@@ -11,6 +11,10 @@
  *  This module provides support for automatic detection and
  *  configuration of all PCI IDE interfaces present in a system.  
  */
+/* 
+ * Support PROMISE PDC20268/20269/20275 IDE Controller.
+ * Powered by PROMISE Technology, Inc. Portions Copyright (C)2001.
+ */ 
 
 #include <linux/config.h>
 #include <linux/types.h>
@@ -45,8 +49,9 @@
 #define DEVID_PDC20262	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262})
 #define DEVID_PDC20265	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265})
 #define DEVID_PDC20267	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267})
-#define DEVID_PDC20268  ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268})
-#define DEVID_PDC20268R ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R})
+#define DEVID_PDC20268	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268})
+#define DEVID_PDC20269	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269})
+#define DEVID_PDC20275	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275})
 #define DEVID_RZ1000	((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_RZ1000})
 #define DEVID_RZ1001	((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_RZ1001})
 #define DEVID_SAMURAI	((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_SAMURAI_IDE})
@@ -402,10 +407,8 @@
 	{DEVID_PDC20267,"PDC20267",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x50,0x02,0x02}, {0x50,0x04,0x04}},	OFF_BOARD,	48 },
 #endif
 	{DEVID_PDC20268,"PDC20268",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
-	/* Promise used a different PCI ident for the raid card apparently to try and
-	   prevent Linux detecting it and using our own raid code. We want to detect
-	   it for the ataraid drivers, so we have to list both here.. */
-	{DEVID_PDC20268R,"PDC20268",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
+	{DEVID_PDC20269,"PDC20269",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
+	{DEVID_PDC20275,"PDC20275",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	16 },
 	{DEVID_RZ1000,	"RZ1000",	NULL,		NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
 	{DEVID_RZ1001,	"RZ1001",	NULL,		NULL,		INIT_RZ1000,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
 	{DEVID_SAMURAI,	"SAMURAI",	NULL,		NULL,		INIT_SAMURAI,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
@@ -458,6 +461,8 @@
 		case PCI_DEVICE_ID_PROMISE_20265:
 		case PCI_DEVICE_ID_PROMISE_20267:
 		case PCI_DEVICE_ID_PROMISE_20268:
+		case PCI_DEVICE_ID_PROMISE_20269:
+		case PCI_DEVICE_ID_PROMISE_20275:
 		case PCI_DEVICE_ID_ARTOP_ATP850UF:
 		case PCI_DEVICE_ID_ARTOP_ATP860:
 		case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -586,6 +591,7 @@
 	ide_hwif_t *hwif, *mate = NULL;
 	unsigned int class_rev;
 	static int secondpdc = 0;
+	int new_chip=0;
 
 #ifdef CONFIG_IDEDMA_AUTO
 	if (!noautodma)
@@ -684,6 +690,10 @@
 	/*
 	 * Set up the IDE ports
 	 */
+	if ((IDE_PCI_DEVID_EQ(d->devid,DEVID_PDC20268)) ||
+	     (IDE_PCI_DEVID_EQ(d->devid,DEVID_PDC20269)) ||
+	     (IDE_PCI_DEVID_EQ(d->devid,DEVID_PDC20275)))
+	 	new_chip=1; 
 	for (port = 0; port <= 1; ++port) {
 		unsigned long base = 0, ctl = 0;
 		ide_pci_enablebit_t *e = &(d->enablebits[port]);
@@ -697,9 +707,9 @@
 			goto controller_ok;
 		if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262)) && (secondpdc++==1) && (port==1)  ) 
 			goto controller_ok;
-			
-		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val))
-			continue;	/* port not enabled */
+		if (!(new_chip))
+			if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val))
+				continue;	/* port not enabled */
 controller_ok:			
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev < 0x03))
 			return;
@@ -774,7 +784,8 @@
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268) ||
-		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20269) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20275) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) ||
diff -urN linux-2.4.18.org/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.4.18.org/drivers/ide/ide.c	Tue Feb 26 03:37:57 2002
+++ linux/drivers/ide/ide.c	Wed Feb 27 19:27:51 2002
@@ -716,7 +716,6 @@
 		}
 	}
 	hwgroup->poll_timeout = 0;	/* done polling */
-	return ide_stopped;
 }
 
 static void check_dma_crc (ide_drive_t *drive)
@@ -883,6 +882,7 @@
 {
 	unsigned long flags;
 	byte err = 0;
+	int lba48=(drive->id->command_set_2 & 0x0400);
 
 	__save_flags (flags);	/* local CPU only */
 	ide__sti();		/* local CPU only */
@@ -918,7 +918,16 @@
 			printk("}");
 			if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
 				byte cur = IN_BYTE(IDE_SELECT_REG);
-				if (cur & 0x40) {	/* using LBA? */
+				if ((lba48) && (HWIF(drive)->pci_devid.vid==0x105a)) { /* 48bit LBA? */
+					OUT_BYTE(0x88, IDE_CONTROL_REG);
+					cur = IN_BYTE(IDE_SECTOR_REG);
+					OUT_BYTE(0x08, IDE_CONTROL_REG);
+					printk(", LBAsect=%ld", (unsigned long)
+					(cur << 24)
+					 |(IN_BYTE(IDE_HCYL_REG)<<16)
+					 |(IN_BYTE(IDE_LCYL_REG)<<8)
+					 | IN_BYTE(IDE_SECTOR_REG));
+				} else if (cur & 0x40) {	/* using LBA? */
 					printk(", LBAsect=%ld", (unsigned long)
 					 ((cur&0xf)<<24)
 					 |(IN_BYTE(IDE_HCYL_REG)<<16)
@@ -3746,7 +3755,6 @@
 char *options = NULL;
 MODULE_PARM(options,"s");
 MODULE_LICENSE("GPL");
-
 static void __init parse_options (char *line)
 {
 	char *next = line;
diff -urN linux-2.4.18.org/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.4.18.org/drivers/ide/pdc202xx.c	Thu Nov 15 03:44:03 2001
+++ linux/drivers/ide/pdc202xx.c	Thu Feb 28 00:48:45 2002
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pdc202xx.c	Version 0.30	Mar. 18, 2000
+ *  linux/drivers/ide/pdc202xx.c	Version 0.32	Feb. 27, 2002
  *
  *  Copyright (C) 1998-2000	Andre Hedrick <andre@linux-ide.org>
  *  May be copied or modified under the terms of the GNU General Public License
@@ -12,7 +12,8 @@
  *  Promise Ultra66 cards with BIOS v1.11 this
  *  compiled into the kernel if you have more than one card installed.
  *
- *  Promise Ultra100 cards.
+ *  Promise Ultra Series cards.
+ *  Promise Ultra100TX2 & Ultra133TX2 cards.
  *
  *  The latest chipset code will support the following ::
  *  Three Ultra33 controllers and 12 drives.
@@ -21,13 +22,29 @@
  *
  *  UNLESS you enable "CONFIG_PDC202XX_BURST"
  *
- */
-
-/*
- *  Portions Copyright (C) 1999 Promise Technology, Inc.
- *  Author: Frank Tiernan (frankt@promise.com)
+ *  Version 1.20.b1 support PDC20268
+ *                  fix cable judge function
+ *  Version 1.20.b2 support ATA-133 PDC20269/75
+ *                  support UDMA Mode 6
+ *                  fix proc report information
+ *                  set ATA133 timing
+ *                  fix ultra dma bit 14 selectable
+ *                  support 32bit LBA
+ *  Version 1.20 b3 fix eighty_ninty_three()
+ *                  fix offset address 0x1c~0x1f
+ *  Version 1.20 b4 fix 48bit LBA HOB bit
+ *                  force rescan drive under PIO modes if need
+ *  Version 1.20.0.5 could be patched with ext3 filesystem code
+ *  Version 1.20.0.6 fix LBA48 drive running without promise controller
+ *                   fix LBA48 drive running under PIO modes
+ *
+ *  Portions Copyright (C) 1999-2002 Promise Technology, Inc.
+ *  Author: Frank Tiernan <frankt@promise.com>
+ *          Hank Yang <hanky@promise.com.tw> August.13.2001
  *  Released under terms of General Public License
  */
+#define VERSION	"1.20.0.6"
+#define VERDATE "2002-01-28"
 
 #include <linux/config.h>
 #include <linux/types.h>
@@ -65,41 +82,10 @@
 extern int (*pdc202xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 extern char *ide_media_verbose(ide_drive_t *);
 static struct pci_dev *bmide_dev;
-
-char *pdc202xx_pio_verbose (u32 drive_pci)
-{
-	if ((drive_pci & 0x000ff000) == 0x000ff000) return("NOTSET");
-	if ((drive_pci & 0x00000401) == 0x00000401) return("PIO 4");
-	if ((drive_pci & 0x00000602) == 0x00000602) return("PIO 3");
-	if ((drive_pci & 0x00000803) == 0x00000803) return("PIO 2");
-	if ((drive_pci & 0x00000C05) == 0x00000C05) return("PIO 1");
-	if ((drive_pci & 0x00001309) == 0x00001309) return("PIO 0");
-	return("PIO ?");
-}
-
-char *pdc202xx_dma_verbose (u32 drive_pci)
-{
-	if ((drive_pci & 0x00036000) == 0x00036000) return("MWDMA 2");
-	if ((drive_pci & 0x00046000) == 0x00046000) return("MWDMA 1");
-	if ((drive_pci & 0x00056000) == 0x00056000) return("MWDMA 0");
-	if ((drive_pci & 0x00056000) == 0x00056000) return("SWDMA 2");
-	if ((drive_pci & 0x00068000) == 0x00068000) return("SWDMA 1");
-	if ((drive_pci & 0x000BC000) == 0x000BC000) return("SWDMA 0");
-	return("PIO---");
-}
-
-char *pdc202xx_ultra_verbose (u32 drive_pci, u16 slow_cable)
-{
-	if ((drive_pci & 0x000ff000) == 0x000ff000)
-		return("NOTSET");
-	if ((drive_pci & 0x00012000) == 0x00012000)
-		return((slow_cable) ? "UDMA 2" : "UDMA 4");
-	if ((drive_pci & 0x00024000) == 0x00024000)
-		return((slow_cable) ? "UDMA 1" : "UDMA 3");
-	if ((drive_pci & 0x00036000) == 0x00036000)
-		return("UDMA 0");
-	return(pdc202xx_dma_verbose(drive_pci));
-}
+static struct hd_driveid *id[4];
+static int speed_rate[4];
+static int set_speed=0;
+static int new_chip=0;
 
 static char * pdc202xx_info (char *buf, struct pci_dev *dev)
 {
@@ -107,8 +93,8 @@
 
 	u32 bibma  = pci_resource_start(dev, 4);
 	u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0;
-	u16 reg50h = 0, pmask = (1<<10), smask = (1<<11);
-	u8 hi = 0, lo = 0, invalid_data_set = 0;
+	u16 reg50h = 0, word88=0;
+	int udmasel[4]={0,0,0,0}, piosel[4]={0,0,0,0}, i=0, hd=0;
 
         /*
          * at that point bibma+0x2 et bibma+0xa are byte registers
@@ -120,10 +106,6 @@
 	u8 sc11	= inb_p((unsigned short)bibma + 0x11);
 	u8 sc1a	= inb_p((unsigned short)bibma + 0x1a);
 	u8 sc1b	= inb_p((unsigned short)bibma + 0x1b);
-	u8 sc1c	= inb_p((unsigned short)bibma + 0x1c); 
-	u8 sc1d	= inb_p((unsigned short)bibma + 0x1d);
-	u8 sc1e	= inb_p((unsigned short)bibma + 0x1e);
-	u8 sc1f	= inb_p((unsigned short)bibma + 0x1f);
 
 	pci_read_config_word(dev, 0x50, &reg50h);
 	pci_read_config_dword(dev, 0x60, &reg60h);
@@ -131,45 +113,35 @@
 	pci_read_config_dword(dev, 0x68, &reg68h);
 	pci_read_config_dword(dev, 0x6c, &reg6ch);
 
+	p+=sprintf(p, "\nPROMISE Ultra series linux driver Ver %s %s Adapter: ", VERSION, VERDATE);
 	switch(dev->device) {
+		case PCI_DEVICE_ID_PROMISE_20275:
+			p += sprintf(p, "MBUltra133\n");
+			break;
+		case PCI_DEVICE_ID_PROMISE_20269:
+			p += sprintf(p, "Ultra133 TX2\n");
+			break;
 		case PCI_DEVICE_ID_PROMISE_20268:
-		case PCI_DEVICE_ID_PROMISE_20268R:
-			p += sprintf(p, "\n                                PDC20268 TX2 Chipset.\n");
-			invalid_data_set = 1;
+			p += sprintf(p, "Ultra100 TX2\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20267:
-			p += sprintf(p, "\n                                PDC20267 Chipset.\n");
+			p += sprintf(p, "Ultra100\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20265:
-			p += sprintf(p, "\n                                PDC20265 Chipset.\n");
+			p += sprintf(p, "Ultra100 on M/B\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20262:
-			p += sprintf(p, "\n                                PDC20262 Chipset.\n");
+			p += sprintf(p, "Ultra66\n");
 			break;
 		case PCI_DEVICE_ID_PROMISE_20246:
-			p += sprintf(p, "\n                                PDC20246 Chipset.\n");
+			p += sprintf(p, "Ultra33\n");
 			reg50h |= 0x0c00;
 			break;
 		default:
-			p += sprintf(p, "\n                                PDC202XX Chipset.\n");
+			p += sprintf(p, "Ultra Series\n");
 			break;
 	}
 
-	p += sprintf(p, "------------------------------- General Status ---------------------------------\n");
-	p += sprintf(p, "Burst Mode                           : %sabled\n", (sc1f & 0x01) ? "en" : "dis");
-	p += sprintf(p, "Host Mode                            : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal");
-	p += sprintf(p, "Bus Clocking                         : %s\n",
-		((sc1f & 0xC0) == 0xC0) ? "100 External" :
-		((sc1f & 0x80) == 0x80) ? "66 External" :
-		((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal");
-	p += sprintf(p, "IO pad select                        : %s mA\n",
-		((sc1c & 0x03) == 0x03) ? "10" :
-		((sc1c & 0x02) == 0x02) ? "8" :
-		((sc1c & 0x01) == 0x01) ? "6" :
-		((sc1c & 0x00) == 0x00) ? "4" : "??");
-	SPLIT_BYTE(sc1e, hi, lo);
-	p += sprintf(p, "Status Polling Period                : %d\n", hi);
-	p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo);
 	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
 	p += sprintf(p, "                %s                         %s\n",
 		(c0&0x80)?"disabled":"enabled ",
@@ -177,41 +149,33 @@
 	p += sprintf(p, "66 Clocking     %s                         %s\n",
 		(sc11&0x02)?"enabled ":"disabled",
 		(sc11&0x08)?"enabled ":"disabled");
-	p += sprintf(p, "           Mode %s                      Mode %s\n",
+	p += sprintf(p, "Mode            %s                         %s\n",
 		(sc1a & 0x01) ? "MASTER" : "PCI   ",
 		(sc1b & 0x01) ? "MASTER" : "PCI   ");
-	if (!(invalid_data_set))
-		p += sprintf(p, "                %s                     %s\n",
-			(sc1d & 0x08) ? "Error       " :
-			((sc1d & 0x05) == 0x05) ? "Not My INTR " :
-			(sc1d & 0x04) ? "Interrupting" :
-			(sc1d & 0x02) ? "FIFO Full   " :
-			(sc1d & 0x01) ? "FIFO Empty  " : "????????????",
-			(sc1d & 0x80) ? "Error       " :
-			((sc1d & 0x50) == 0x50) ? "Not My INTR " :
-			(sc1d & 0x40) ? "Interrupting" :
-			(sc1d & 0x20) ? "FIFO Full   " :
-			(sc1d & 0x10) ? "FIFO Empty  " : "????????????");
 	p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
 	p += sprintf(p, "DMA enabled:    %s              %s             %s               %s\n",
-		(c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no ");
-	if (!(invalid_data_set))
-		p += sprintf(p, "DMA Mode:       %s           %s          %s            %s\n",
-			pdc202xx_ultra_verbose(reg60h, (reg50h & pmask)),
-			pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)),
-			pdc202xx_ultra_verbose(reg68h, (reg50h & smask)),
-			pdc202xx_ultra_verbose(reg6ch, (reg50h & smask)));
-	if (!(invalid_data_set))
-		p += sprintf(p, "PIO Mode:       %s            %s           %s            %s\n",
-			pdc202xx_pio_verbose(reg60h),
-			pdc202xx_pio_verbose(reg64h),
-			pdc202xx_pio_verbose(reg68h),
-			pdc202xx_pio_verbose(reg6ch));
+		(id[0]!=NULL && (c0&0x20))?"yes":"no ",(id[1]!=NULL && (c0&0x40))?"yes":"no ",
+		(id[2]!=NULL && (c1&0x20))?"yes":"no ",(id[3]!=NULL && (c1&0x40))?"yes":"no ");
+	for(hd=0;hd<4;hd++)
+	{
+		if (id[hd]==NULL)
+			continue;
+		word88=id[hd]->dma_ultra;
+		for (i=7;i>=0;i--)
+			if (word88>>(i+8))
+			{
+				udmasel[hd]=i;	/* get select UDMA mode */
+				break;
+			}
+		piosel[hd]=(id[hd]->eide_pio_modes >= 0x02) ? 4 : 3;
+        }
+	p += sprintf(p, "UDMA Mode:      %d                %d               %d                 %d\n",
+		udmasel[0],udmasel[1],udmasel[2],udmasel[3]);
+	p += sprintf(p, "PIO Mode:       %d                %d               %d                 %d\n",
+		piosel[0],piosel[1],piosel[2],piosel[3]);
 #if 0
 	p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n");
 #endif
-	if (invalid_data_set)
-		p += sprintf(p, "--------------- Cannot Decode HOST ---------------\n");
 	return (char *)p;
 }
 
@@ -376,7 +340,21 @@
 	int			err;
 	byte			drive_pci, AP, BP, CP, DP;
 	byte			TA = 0, TB = 0, TC = 0;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	unsigned long indexreg	= (hwif->dma_base + 1);
+	unsigned long datareg	= (hwif->dma_base + 3);
+#else
+	struct pci_dev *dev	= hwif->pci_dev;
+	unsigned long high_16	= pci_resource_start(dev, 4);
+	unsigned long indexreg	= high_16 + (hwif->channel ? 0x09 : 0x01);
+	unsigned long datareg	= (indexreg + 2);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	byte thold		=0x10;
+	byte adj		=(drive->dn%2) ? 0x08 : 0x00;
+	int  i=0, j=hwif->channel ? 2:0;
 
+if (!(new_chip))
+{
 	switch (drive->dn) {
 		case 0: drive_pci = 0x60; break;
 		case 1: drive_pci = 0x64; break;
@@ -387,9 +365,6 @@
 
 	if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))	return -1;
 
-	if (dev->device == PCI_DEVICE_ID_PROMISE_20268)
-		goto skip_register_hell;
-
 	pci_read_config_dword(dev, drive_pci, &drive_conf);
 	pci_read_config_byte(dev, (drive_pci), &AP);
 	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
@@ -476,14 +451,158 @@
 	decode_registers(REG_C, CP);
 	decode_registers(REG_D, DP);
 #endif /* PDC202XX_DECODE_REGISTER_INFO */
-
-skip_register_hell:
-
+}
+	if (speed>=XFER_UDMA_6)
+		set_speed=1;	/* we need to set ATA133 timing */
 	if (!drive->init_speed)
 		drive->init_speed = speed;
+#if PDC202XX_DEBUG_DRIVE_INFO
+	printk("%s: Before set_feature = %s, word88 = %#x\n",
+		drive->name, ide_xfer_verbose(speed), drive->id->dma_ultra );
+#endif /* PDC202XX_DEBUG_DRIVE_INFO */
 	err = ide_config_drive_speed(drive, speed);
 	drive->current_speed = speed;
-
+#ifdef CONFIG_BLK_DEV_IDEDMA
+	/* Setting tHOLD bit to 0 if using UDMA mode 2 */
+	if ((speed==XFER_UDMA_2) && (new_chip))
+	{
+		outb(thold+adj,indexreg);
+		outb((inb(datareg)&0x7f),datareg);
+	}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	for (i=0;i<2;i++)
+		if (hwif->drives[i].present)
+	  	{
+	 		id[i+j]=hwif->drives[i].id;	/* get identify structs */
+	 		speed_rate[i+j]=speed;		/* get current speed */
+	 	}
+	if (new_chip && set_speed)
+	{
+		for (i=0; i<4; i++)
+		{
+			if (id[i]==NULL)
+				continue;
+			switch(speed_rate[i]){
+			case XFER_PIO_0:
+				outb(0x0c+adj, indexreg);
+				outb(0xfb, datareg);
+				outb(0x0d+adj, indexreg);
+				outb(0x2b, datareg);
+				outb(0x13+adj, indexreg);
+				outb(0xac, datareg);
+				break;
+			case XFER_PIO_1:
+				outb(0x0c+adj, indexreg);
+				outb(0x46, datareg);
+				outb(0x0d+adj, indexreg);
+				outb(0x29, datareg);
+				outb(0x13+adj, indexreg);
+				outb(0xa4, datareg);
+				break;
+			case XFER_PIO_2:
+				outb(0x0c+adj, indexreg);
+				outb(0x23, datareg);
+				outb(0x0d+adj, indexreg);
+				outb(0x26, datareg);
+				outb(0x13+adj, indexreg);
+				outb(0x64, datareg);
+				break;
+			case XFER_PIO_3:
+				outb(0x0c+adj, indexreg);
+				outb(0x27, datareg);
+				outb(0x0d+adj, indexreg);
+				outb(0x0d, datareg);
+				outb(0x13+adj, indexreg);
+				outb(0x35, datareg);
+				break;
+			case XFER_PIO_4:
+				outb(0x0c+adj, indexreg);
+				outb(0x23, datareg);
+				outb(0x0d+adj, indexreg);
+				outb(0x09, datareg);
+				outb(0x13+adj, indexreg);
+				outb(0x25, datareg);
+				break;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+			case XFER_MW_DMA_0:
+				outb(0x0e +adj, indexreg);
+				outb(0xdf, datareg);
+				outb(0x0f+adj, indexreg);
+				outb(0x5f, datareg);
+				break;
+			case XFER_MW_DMA_1:
+				outb(0x0e +adj, indexreg);
+				outb(0x6b, datareg);
+				outb(0x0f+adj, indexreg);
+				outb(0x27, datareg);
+				break;
+			case XFER_MW_DMA_2:
+				outb(0x0e +adj, indexreg);
+				outb(0x69, datareg);
+				outb(0x0f+adj, indexreg);
+				outb(0x25, datareg);
+				break;
+			case XFER_UDMA_0:
+				outb(0x10+adj, indexreg);
+				outb(0x4a, datareg);
+				outb(0x11+adj, indexreg);
+				outb(0x0f, datareg);
+				outb(0x12+adj, indexreg);
+				outb(0xd5, datareg);
+				break;
+			case XFER_UDMA_1:
+				outb(0x10+adj, indexreg);
+				outb(0x3a, datareg);
+				outb(0x11+adj, indexreg);
+				outb(0x0a, datareg);
+				outb(0x12+adj, indexreg);
+				outb(0xd0, datareg);
+					break;
+			case XFER_UDMA_2:
+				outb(0x10+adj, indexreg);
+				outb(0x2a, datareg);
+				outb(0x11+adj, indexreg);
+				outb(0x07, datareg);
+				outb(0x12+adj, indexreg);
+				outb(0xcd, datareg);
+				break;
+			case XFER_UDMA_3:
+				outb(0x10+adj, indexreg);
+				outb(0x1a, datareg);
+				outb(0x11+adj, indexreg);
+				outb(0x05, datareg);
+				outb(0x12+adj, indexreg);
+				outb(0xcd, datareg);
+				break;
+			case XFER_UDMA_4:
+				outb(0x10+adj, indexreg);
+				outb(0x1a, datareg);
+				outb(0x11+adj, indexreg);
+				outb(0x03, datareg);
+				outb(0x12+adj, indexreg);
+				outb(0xcd, datareg);
+				break;
+			case XFER_UDMA_5:
+				outb(0x10+adj, indexreg);
+				outb(0x1a, datareg);
+				outb(0x11+adj, indexreg);
+				outb(0x02, datareg);
+				outb(0x12+adj, indexreg);
+				outb(0xcb, datareg);
+				break;
+			case XFER_UDMA_6:
+				outb(0x10+adj, indexreg);
+				outb(0x1a, datareg);
+				outb(0x11+adj, indexreg);
+				outb(0x01, datareg);
+				outb(0x12+adj, indexreg);
+				outb(0xcb, datareg);
+				break;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+			default:	break;
+			}
+		}
+	}
 #if PDC202XX_DEBUG_DRIVE_INFO
 	printk("%s: %s drive%d 0x%08x ",
 		drive->name, ide_xfer_verbose(speed),
@@ -519,22 +638,38 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
 {
-	struct hd_driveid *id	= drive->id;
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	unsigned long high_16   = pci_resource_start(dev, 4);
-	unsigned long dma_base  = hwif->dma_base;
-	byte unit		= (drive->select.b.unit & 0x01);
+	struct hd_driveid *id		= drive->id;
+	ide_hwif_t *hwif		= HWIF(drive);
+	struct pci_dev *dev		= hwif->pci_dev;
+	unsigned long high_16   	= pci_resource_start(dev, 4);
+	unsigned long dma_base  	= hwif->dma_base;
+	unsigned long indexreg		= dma_base+1;
+	unsigned long datareg		= indexreg+2;
+	byte unit			= (drive->select.b.unit & 0x01);
+	byte	iordy			= 0x13;
+	byte	adj			= (drive->dn%2) ? 0x08 : 0x00;
+	byte 	cable			= 0;
 
 	unsigned int		drive_conf;
-	byte			drive_pci;
+	byte			drive_pci = 0;
 	byte			test1, test2, speed = -1;
 	byte			AP;
 	unsigned short		EP;
 	byte CLKSPD		= IN_BYTE(high_16 + 0x11);
-	byte udma_33		= ultra ? (inb(high_16 + 0x001f) & 1) : 0;
+	byte udma_33		= ultra;
 	byte udma_66		= ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0;
-	byte udma_100		= (((dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20267) || (dev->device == PCI_DEVICE_ID_PROMISE_20268)) && udma_66) ? 1 : 0;
+	byte udma_100		= (((dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
+				    (dev->device == PCI_DEVICE_ID_PROMISE_20267) ||
+				     new_chip) && udma_66) ? 1 : 0;
+	byte udma_133		= (((dev->device == PCI_DEVICE_ID_PROMISE_20269) ||
+				    (dev->device == PCI_DEVICE_ID_PROMISE_20275))
+				     && udma_100) ? 1 : 0;
+	byte mask		= hwif->channel ? 0x08 : 0x02;
+	unsigned short c_mask	= hwif->channel ? (1<<11) : (1<<10);
+	byte ultra_66		= ((id->dma_ultra & 0x0010) || 
+			           (id->dma_ultra & 0x0008)) ? 1 : 0;
+	byte ultra_100		= ((id->dma_ultra & 0x0020) || (ultra_66)) ? 1 : 0;
+	byte ultra_133		= ((id->dma_ultra & 0x0040) || (ultra_100)) ? 1 : 0;
 
 	/*
 	 * Set the control register to use the 66Mhz system
@@ -548,21 +683,18 @@
 	 * leave the 66Mhz clock on and readjust the timing
 	 * parameters.
 	 */
-
-	byte mask		= hwif->channel ? 0x08 : 0x02;
-	unsigned short c_mask	= hwif->channel ? (1<<11) : (1<<10);
-	byte ultra_66		= ((id->dma_ultra & 0x0010) ||
-				   (id->dma_ultra & 0x0008)) ? 1 : 0;
-	byte ultra_100		= ((id->dma_ultra & 0x0020) ||
-				   (id->dma_ultra & 0x0010) ||
-				   (id->dma_ultra & 0x0008)) ? 1 : 0;
-
-	if (dev->device == PCI_DEVICE_ID_PROMISE_20268)
-		goto jump_pci_mucking;
-
-	pci_read_config_word(dev, 0x50, &EP);
-
-	if (((ultra_66) || (ultra_100)) && (EP & c_mask)) {
+	
+	if (new_chip)
+	{
+		outb(0x0b,indexreg);
+		cable=(inb(datareg)&0x04);	/* check 80pin cable? */
+	}
+	else {
+		pci_read_config_word(dev, 0x50, &EP);
+		cable=(EP & c_mask);		/* check 80pin cable? */
+	}	
+	
+	if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) {
 #ifdef DEBUG
 		printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary");
 		printk("         Switching to Ultra33 mode.\n");
@@ -570,14 +702,19 @@
 		/* Primary   : zero out second bit */
 		/* Secondary : zero out fourth bit */
 		OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
+		printk("Warning: %s channel requires an 80-pin cable for operation.\n",
+			hwif->channel ? "Secondary":"Primary");
+		printk("%s reduced to Ultra33 mode.\n", drive->name);
+		udma_66=0;	udma_100=0;	udma_133=0;
 	} else {
-		if ((ultra_66) || (ultra_100)) {
+		if ((ultra_66) || (ultra_100) || (ultra_133)) {
 			/*
 			 * check to make sure drive on same channel
 			 * is u66 capable
 			 */
 			if (hwif->drives[!(drive->dn%2)].id) {
-				if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) ||
+				if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0040) ||
+				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) ||
 				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) ||
 				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) {
 					OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
@@ -589,7 +726,8 @@
 			}
 		}
 	}
-
+    if (!(new_chip))
+    {
 	switch(drive->dn) {
 		case 0:	drive_pci = 0x60;
 			pci_read_config_dword(dev, drive_pci, &drive_conf);
@@ -639,10 +777,18 @@
 	pci_read_config_byte(dev, (drive_pci), &AP);
 	if (drive->media == ide_disk)	/* PREFETCH_EN */
 		pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
-
-jump_pci_mucking:
-
-	if ((id->dma_ultra & 0x0020) && (udma_100))	speed = XFER_UDMA_5;
+    }
+    else
+    {
+    	if (drive->media != ide_disk)	return ide_dma_off_quietly;
+	if (id->capability & 4)	/* IORDY_EN & PREFETCH_EN*/
+	{
+		outb(iordy+adj, indexreg);
+		outb((inb(datareg)|0x03), datareg);
+	}
+    }
+    	if ((id->dma_ultra & 0x0040) && (udma_133))	speed = XFER_UDMA_6;
+	else if ((id->dma_ultra & 0x0020) && (udma_100))	speed = XFER_UDMA_5;
 	else if ((id->dma_ultra & 0x0010) && (udma_66))	speed = XFER_UDMA_4;
 	else if ((id->dma_ultra & 0x0008) && (udma_66))	speed = XFER_UDMA_3;
 	else if ((id->dma_ultra & 0x0004) && (udma_33))	speed = XFER_UDMA_2;
@@ -656,7 +802,7 @@
 	else if (id->dma_1word & 0x0001)		speed = XFER_SW_DMA_0;
 	else {
 		/* restore original pci-config space */
-		if (dev->device != PCI_DEVICE_ID_PROMISE_20268)
+		if (!(new_chip))
 			pci_write_config_dword(dev, drive_pci, drive_conf);
 		return ide_dma_off_quietly;
 	}
@@ -664,11 +810,13 @@
 	outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
 	(void) pdc202xx_tune_chipset(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
+	
+	return ((int)	((id->dma_ultra >> 14) & 3) ? ide_dma_on :
+			((id->dma_ultra >> 11) & 7) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
 			((id->dma_mword >> 8) & 7) ? ide_dma_on : 
 			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+			ide_dma_off_quietly);
 }
 
 static int config_drive_xfer_rate (ide_drive_t *drive)
@@ -685,7 +833,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x007F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive, 1);
 				if ((id->field_valid & 2) &&
@@ -757,6 +905,13 @@
 		case ide_dma_timeout:
 			if (HWIF(drive)->resetproc != NULL)
 				HWIF(drive)->resetproc(drive);
+			break;
+		/*
+		case ide_dma_off:
+			printk("PDC202XX: Force DMA keep on.\n");
+			return (0);
+			//func=ide_dma_check;	// Fix me!!
+		*/
 		default:
 			break;
 	}
@@ -766,13 +921,12 @@
 
 void pdc202xx_reset (ide_drive_t *drive)
 {
-	unsigned long high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);
-	byte udma_speed_flag	= inb(high_16 + 0x001f);
-
-	OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
-	mdelay(100);
-	OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
-	mdelay(2000);		/* 2 seconds ?! */
+	outb(0x04,IDE_CONTROL_REG);
+	mdelay(1000);
+	outb(0x00,IDE_CONTROL_REG);
+	mdelay(1000);
+	printk("PDC202XX: %s channel reset.\n",
+		 HWIF(drive)->channel ? "Secondary":"Primary");
 }
 
 unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
@@ -784,6 +938,9 @@
 
 	if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
 	    (dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
+	    (dev->device == PCI_DEVICE_ID_PROMISE_20268) ||
+	    (dev->device == PCI_DEVICE_ID_PROMISE_20269) ||
+	    (dev->device == PCI_DEVICE_ID_PROMISE_20275) ||
 	    (dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
 		/*
 		 * software reset -  this is required because the bios
@@ -800,6 +957,10 @@
 		OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
 		mdelay(2000);	/* 2 seconds ?! */
 	}
+	if ((dev->device == PCI_DEVICE_ID_PROMISE_20268) ||
+	    (dev->device == PCI_DEVICE_ID_PROMISE_20269) ||
+	    (dev->device == PCI_DEVICE_ID_PROMISE_20275))
+	        	new_chip=1;
 
 	if (dev->resource[PCI_ROM_RESOURCE].start) {
 		pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
@@ -813,7 +974,7 @@
 		if ((irq != irq2) &&
 		    (dev->device != PCI_DEVICE_ID_PROMISE_20265) &&
 		    (dev->device != PCI_DEVICE_ID_PROMISE_20267) &&
-		    (dev->device != PCI_DEVICE_ID_PROMISE_20268)) {
+		    !(new_chip)) {
 			pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq);	/* 0xbc */
 			printk("%s: pci-config space interrupt mirror fixed.\n", name);
 		}
@@ -866,10 +1027,19 @@
 	unsigned short mask = (hwif->channel) ? (1<<11) : (1<<10);
 	unsigned short CIS;
 
-	pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
-	return ((CIS & mask) ? 0 : 1);
+	 switch(hwif->pci_dev->device) {
+		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20269:
+		case PCI_DEVICE_ID_PROMISE_20268:
+			OUT_BYTE(0x0b, (hwif->dma_base + 1));
+			return (!(IN_BYTE((hwif->dma_base + 3)) & 0x04));
+			/* check 80pin cable */
+		default:
+			pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
+			return (!(CIS & mask));
+			/* check 80pin cable */
+	}
 }
-
 void __init ide_init_pdc202xx (ide_hwif_t *hwif)
 {
 	hwif->tuneproc	= &pdc202xx_tune_drive;
@@ -878,6 +1048,9 @@
 
 	if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
 	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
+	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20268) ||
+	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20269) ||
+	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20275) ||
 	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
 		hwif->resetproc	= &pdc202xx_reset;
 	}
diff -urN linux-2.4.18.org/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux-2.4.18.org/include/linux/hdreg.h	Fri Nov 23 03:46:18 2001
+++ linux/include/linux/hdreg.h	Wed Feb 27 19:54:12 2002
@@ -81,6 +81,14 @@
 
 #define WIN_SMART		0xB0	/* self-monitoring and reporting */
 
+/* Additianal command for 48 Bit LBA */
+#define READ_EXT		0x24
+#define WRITE_EXT		0x34
+#define MULTI_READ_EXT		0x29
+#define MULTI_WRITE_EXT		0x39
+#define READ_DMA_EXT		0x25
+#define WRITE_DMA_EXT		0x35
+
 /* Additional drive command codes used by ATAPI devices. */
 #define WIN_PIDENTIFY		0xA1	/* identify ATAPI device	*/
 #define WIN_SRST		0x08	/* ATAPI soft reset command */
diff -urN linux-2.4.18.org/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- linux-2.4.18.org/include/linux/pci_ids.h	Tue Feb 26 03:38:13 2002
+++ linux/include/linux/pci_ids.h	Wed Feb 27 19:45:18 2002
@@ -603,7 +603,6 @@
 #define PCI_DEVICE_ID_PROMISE_20246	0x4d33
 #define PCI_DEVICE_ID_PROMISE_20262	0x4d38
 #define PCI_DEVICE_ID_PROMISE_20268	0x4d68
-#define PCI_DEVICE_ID_PROMISE_20268R	0x6268
 #define PCI_DEVICE_ID_PROMISE_20269	0x4d69
 #define PCI_DEVICE_ID_PROMISE_20275	0x1275
 #define PCI_DEVICE_ID_PROMISE_5300	0x5300

  reply	other threads:[~2002-03-08  3:51 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-03-07  9:01 [PATCH] Submitting PROMISE IDE Controllers Driver Patch Hank Yang
2002-03-07 10:23 ` Arjan van de Ven
2002-03-08  1:45   ` Hank Yang
2002-03-08  2:10     ` Alan Cox
2002-03-08  3:01       ` Hank Yang
2002-03-08  8:19         ` Martin Dalecki
2002-03-08  8:23           ` arjan
2002-03-08  8:35             ` Martin Dalecki
2002-03-08  8:50               ` Arjan van de Ven
2002-03-08  9:14                 ` Martin Dalecki
2002-03-08 13:12                 ` Alan Cox
2002-03-08 19:25                 ` Kelsey Hudson
2002-03-09 13:25                   ` Martin Dalecki
2002-03-08 13:25         ` Alan Cox
2002-03-13  7:35           ` Hank Yang
2002-03-13  7:45             ` Arjan van de Ven
2002-03-08  2:54     ` Kelsey Hudson
2002-03-08  7:54     ` Arjan van de Ven
2002-03-08  8:12     ` Martin Dalecki
2002-03-07 13:15 ` Alan Cox
2002-03-08  3:49   ` Hank Yang [this message]
2002-03-08 13:14     ` Alan Cox
2002-03-13  6:52       ` Hank Yang
2002-03-13 16:39         ` Alan Cox
2002-05-22  9:38           ` Hank Yang
     [not found]           ` <039701c20892$3940ca30$c0cca8c0@promise.com.tw>
2002-05-31 14:33             ` [PATCH] Submitting PROMISE IDE " Alan Cox
2002-06-03  3:51               ` [PATCH] 2.4.19pre9 in pdc202xx.c bug Hank Yang
2002-06-03 15:48                 ` Alan Cox
2002-06-06  2:31                   ` Hank Yang
2002-06-06 12:17                     ` Alan Cox
     [not found] ` <3C876199.5000107@evision-ventures.com>
2002-03-08  2:00   ` [PATCH] Submitting PROMISE IDE Controllers Driver Patch Hank Yang
  -- strict thread matches above, loose matches on Subject: below --
2002-03-10 14:23 Ed Tomlinson
2002-03-10 14:47 ` Alan Cox
2002-03-11  9:56   ` benh
     [not found] <200203071331.g27DVi211087@sunrise.pg.gda.pl>
2002-03-07 13:36 ` Andrzej Krzysztofowicz
2002-03-07  6:46 Hank Yang
2002-03-09 21:23 ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='015101c1c654$454cad10$59cca8c0@hank' \
    --to=hanky@promise.com.tw \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linusc@promise.com.tw \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox