patch-2.3.99-pre3 linux/drivers/ide/cmd64x.c
Next file: linux/drivers/ide/cs5530.c
Previous file: linux/drivers/ide/cmd640.c
Back to the patch index
Back to the overall index
- Lines: 326
- Date:
Wed Mar 22 17:18:43 2000
- Orig file:
v2.3.99-pre2/linux/drivers/ide/cmd64x.c
- Orig date:
Sun Mar 19 18:35:30 2000
diff -u --recursive --new-file v2.3.99-pre2/linux/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
@@ -1,5 +1,7 @@
/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16
*
+ * linux/drivers/ide/cmd64x.c Version 1.21 Mar. 18, 2000
+ *
* cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
* Note, this driver is not used at all on other systems because
* there the "BIOS" has done all of the following already.
@@ -116,19 +118,27 @@
p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
p += sprintf(p, " %sabled %sabled\n",
- (reg72&0x80) ? "dis" : " en", (reg7a&0x80) ? "dis" : " en");
+ (reg72&0x80)?"dis":" en",(reg7a&0x80)?"dis":" en");
p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
p += sprintf(p, "DMA enabled: %s %s %s %s\n",
- (reg72&0x20) ? "yes" : "no ", (reg72&0x40) ? "yes" : "no ", (reg7a&0x20) ? "yes" : "no ", (reg7a&0x40) ? "yes" : "no " );
+ (reg72&0x20)?"yes":"no ",(reg72&0x40)?"yes":"no ",(reg7a&0x20)?"yes":"no ",(reg7a&0x40)?"yes":"no ");
p += sprintf(p, "DMA Mode: %s(%s) %s(%s) %s(%s) %s(%s)\n",
(reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO",
- (reg72&0x20)?(((reg73&0x15)==0x15)?"4":((reg73&0x25)==0x25)?"3":((reg73&0x10)==0x10)?"2":((reg73&0x20)==0x20)?"1":((reg73&0x30)==0x30)?"0":"X"):"?",
+ (reg72&0x20)?( ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"):
+ ((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"):
+ ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"):"X"):"?",
(reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO",
- (reg72&0x40)?(((reg73&0x4A)==0x4A)?"4":((reg73&0x8A)==0x8A)?"3":((reg73&0x40)==0x40)?"2":((reg73&0x80)==0x80)?"1":((reg73&0xC0)==0xC0)?"0":"X"):"?",
+ (reg72&0x40)?( ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"):
+ ((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"):
+ ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"):"X"):"?",
(reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO",
- (reg7a&0x20)?(((reg7b&0x15)==0x15)?"4":((reg7b&0x25)==0x25)?"3":((reg7b&0x10)==0x10)?"2":((reg7b&0x20)==0x20)?"1":((reg7b&0x30)==0x30)?"0":"X"):"?",
+ (reg7a&0x20)?( ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"):
+ ((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"):
+ ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"):"X"):"?",
(reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO",
- (reg7a&0x40)?(((reg7b&0x4A)==0x4A)?"4":((reg7b&0x8A)==0x8A)?"3":((reg7b&0x40)==0x40)?"2":((reg7b&0x80)==0x80)?"1":((reg7b&0xC0)==0xC0)?"0":"X"):"?" );
+ (reg7a&0x40)?( ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"):
+ ((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"):
+ ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"):"X"):"?" );
p += sprintf(p, "PIO Mode: %s %s %s %s\n",
"?", "?", "?", "?");
@@ -155,6 +165,22 @@
return p-buffer; /* => must be less than 4k! */
}
+
+#if 0
+static char * cmd64x_chipset_data (char *buf, struct pci_dev *dev)
+{
+ char *p = buf;
+ p += sprintf(p, "thingy stuff\n");
+ return (char *)p;
+}
+static int __init cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+ char *p = buffer;
+ p = cmd64x_chipset_data(buffer, bmide_dev);
+ return p-buffer; /* hoping it is less than 4K... */
+}
+#endif
+
#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
byte cmd64x_proc = 0;
@@ -305,76 +331,60 @@
setup_count, active_count, recovery_count);
}
+static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+ byte speed= 0x00;
+ byte set_pio= ide_get_best_pio_mode(drive, 4, 5, NULL);
+
+ cmd64x_tuneproc(drive, set_pio);
+ speed = XFER_PIO_0 + set_pio;
+ if (set_speed)
+ (void) ide_config_drive_speed(drive, speed);
+}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
static int tune_chipset_for_dma (ide_drive_t *drive, byte speed)
{
-#if 0
- struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- unsigned long dma_base = hwif->dma_base;
byte unit = (drive->select.b.unit & 0x01);
+ int err = 0;
- u8 reg72 = 0, reg73 = 0; /* primary */
- u8 reg7a = 0, reg7b = 0; /* secondary */
- u8 pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
- u8 pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0;
- u8 regU = (hwif->channel) ? 2 : 0;
- u8 regD = (hwif->channel) ? 2 : 0;
-
- (void) pci_read_config_byte(dev, BMIDESR0, ®72);
- (void) pci_read_config_byte(dev, UDIDETCR0, ®73);
- (void) pci_read_config_byte(dev, BMIDESR1, ®7a);
- (void) pci_read_config_byte(dev, UDIDETCR1, ®7b);
+ u8 pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
+ u8 pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0;
+ u8 regU = 0;
+ u8 regD = 0;
+
+ (void) pci_read_config_byte(dev, pciD, ®D);
+ (void) pci_read_config_byte(dev, pciU, ®U);
+ regD &= ~(unit ? 0x40 : 0x20);
+ regU &= ~(unit ? 0xCA : 0x35);
+ (void) pci_write_config_byte(dev, pciD, regD);
+ (void) pci_write_config_byte(dev, pciU, regU);
+ (void) pci_read_config_byte(dev, pciD, ®D);
+ (void) pci_read_config_byte(dev, pciU, ®U);
switch(speed) {
- case XFER_UDMA_4:
- pciU = unit ? 0x4A : 0x15;
- case XFER_UDMA_3:
- pciU = unit ? 0x8A : 0x25;
- case XFER_UDMA_2:
- pciU = unit ? 0x42 : 0x11;
- case XFER_UDMA_1:
- pciU = unit ? 0x82 : 0x21;
- case XFER_UDMA_0:
- pciU = unit ? 0xC2 : 0x31
-(reg73&0x15)?"4":(reg73&0x25)?"3":(reg73&0x11)?"2":(reg73&0x21)?"1":(reg73&0x31)?"0":"X",
-(reg73&0x4A)?"4":(reg73&0x8A)?"3":(reg73&0x42)?"2":(reg73&0x82)?"1":(reg73&0xC2)?"0":"X",
-(reg7b&0x15)?"4":(reg7b&0x25)?"3":(reg7b&0x11)?"2":(reg7b&0x21)?"1":(reg7b&0x31)?"0":"X",
-(reg7b&0x4A)?"4":(reg7b&0x8A)?"3":(reg7b&0x42)?"2":(reg7b&0x82)?"1":(reg7b&0xC2)?"0":"X",
-
- case XFER_MW_DMA_2:
- pciD = unit ? 0x40 : 0x10;
- case XFER_MW_DMA_1:
- pciD = unit ? 0x80 : 0x20;
- case XFER_MW_DMA_0:
- pciD = unit ? 0xC0 : 0x30;
- case XFER_SW_DMA_2:
- case XFER_SW_DMA_1:
- case XFER_SW_DMA_0:
-(reg73&0x10)?"2":(reg73&0x20)?"1":(reg73&0x30)?"0":"X",
-(reg73&0x40)?"2":(reg73&0x80)?"1":(reg73&0xC0)?"0":"X",
-(reg7b&0x10)?"2":(reg7b&0x20)?"1":(reg7b&0x30)?"0":"X",
-(reg7b&0x40)?"2":(reg7b&0x80)?"1":(reg7b&0xC0)?"0":"X" );
-
+ case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break;
+ case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break;
+ case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break;
+ case XFER_UDMA_1: regU |= (unit ? 0x82 : 0x21); break;
+ case XFER_UDMA_0: regU |= (unit ? 0xC2 : 0x31); break;
+ case XFER_MW_DMA_2: regD |= (unit ? 0x40 : 0x10); break;
+ case XFER_MW_DMA_1: regD |= (unit ? 0x80 : 0x20); break;
+ case XFER_MW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break;
+ case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break;
+ case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break;
+ case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break;
default:
return 1;
}
+ (void) pci_write_config_byte(dev, pciU, regU);
+ err = ide_config_drive_speed(drive, speed);
+ regD |= (unit ? 0x40 : 0x20);
+ (void) pci_write_config_byte(dev, pciD, regD);
- (void) ide_config_drive_speed(drive, speed);
- outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-#endif
- return 0;
-}
-
-static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed)
-{
- byte speed = 0x00;
- byte set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL);
-
- cmd64x_tuneproc(drive, set_pio);
- speed = XFER_PIO_0 + set_pio;
- if (set_speed)
- (void) ide_config_drive_speed(drive, speed);
+ return err;
}
static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
@@ -382,21 +392,17 @@
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- unsigned long dma_base = hwif->dma_base;
- byte unit = (drive->select.b.unit & 0x01);
byte speed = 0x00;
byte set_pio = 0x00;
- byte udma_timing_bits = 0x00;
byte udma_33 = ((rev >= 0x05) || (ultra_66)) ? 1 : 0;
byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
- /* int drive_number = ((hwif->channel ? 2 : 0) + unit); */
int rval;
switch(dev->device) {
- case PCI_DEVICE_ID_CMD_643:
- case PCI_DEVICE_ID_CMD_646:
case PCI_DEVICE_ID_CMD_648:
+ case PCI_DEVICE_ID_CMD_646:
+ case PCI_DEVICE_ID_CMD_643:
default:
break;
}
@@ -416,22 +422,16 @@
* in the 646U2.
* So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
*/
-
if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) {
speed = XFER_UDMA_4;
- udma_timing_bits = 0x10; /* 2 clock */
} else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) {
speed = XFER_UDMA_3;
- udma_timing_bits = 0x20; /* 3 clock */
} else if ((id->dma_ultra & 0x0004) && (udma_33)) {
speed = XFER_UDMA_2;
- udma_timing_bits = 0x10; /* 2 clock */
} else if ((id->dma_ultra & 0x0002) && (udma_33)) {
speed = XFER_UDMA_1;
- udma_timing_bits = 0x20; /* 3 clock */
} else if ((id->dma_ultra & 0x0001) && (udma_33)) {
speed = XFER_UDMA_0;
- udma_timing_bits = 0x30; /* 4 clock */
} else if (id->dma_mword & 0x0004) {
speed = XFER_MW_DMA_2;
} else if (id->dma_mword & 0x0002) {
@@ -453,27 +453,6 @@
if (set_pio)
return ((int) ide_dma_off_quietly);
-#if 1
- /*
- * This the alternate access method. :-(
- * The correct method is to directly setup the pci-config space.
- */
- (void) ide_config_drive_speed(drive, speed);
- outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-
- if (speed >= XFER_UDMA_0) {
- byte udma_ctrl = inb(dma_base + 3);
- /* Put this channel into UDMA mode. */
- udma_ctrl |= (1 << unit);
- udma_ctrl &= ~(0x04 << unit);
- if (udma_66)
- udma_ctrl |= (0x04 << unit);
- udma_ctrl &= ~(0x30 << (unit * 2));
- udma_ctrl |= (udma_timing_bits << (unit * 2));
- outb(udma_ctrl, dma_base+3);
- }
-#endif
-
if (tune_chipset_for_dma(drive, speed))
return ((int) ide_dma_off);
@@ -500,17 +479,14 @@
class_rev &= 0xff;
switch(dev->device) {
+ case PCI_DEVICE_ID_CMD_648:
+ can_ultra_66 = 1;
case PCI_DEVICE_ID_CMD_643:
- can_ultra_33 = 1;
- can_ultra_66 = 0;
+ can_ultra_33 = 1;
break;
case PCI_DEVICE_ID_CMD_646:
- can_ultra_33 = (class_rev >= 0x05) ? 1 : 0;
- can_ultra_66 = 0;
- break;
- case PCI_DEVICE_ID_CMD_648:
- can_ultra_33 = 1;
- can_ultra_66 = 1;
+ can_ultra_33 = (class_rev >= 0x05) ? 1 : 0;
+ can_ultra_66 = 0;
break;
default:
return hwif->dmaproc(ide_dma_off, drive);
@@ -595,6 +571,7 @@
/* Other cases are done by generic IDE-DMA code. */
return cmd64x_dmaproc(func, drive);
}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name)
{
@@ -604,9 +581,11 @@
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
-#if 0
- if (dev->resource[PCI_ROM_RESOURCE].start)
+#ifdef __i386__
+ if (dev->resource[PCI_ROM_RESOURCE].start) {
pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
+ printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
+ }
#endif
switch(dev->device) {
@@ -702,7 +681,9 @@
if (!hwif->dma_base)
return;
+#ifdef CONFIG_BLK_DEV_IDEDMA
switch(dev->device) {
+ case PCI_DEVICE_ID_CMD_648:
case PCI_DEVICE_ID_CMD_643:
hwif->dmaproc = &cmd64x_dmaproc;
break;
@@ -714,10 +695,8 @@
hwif->dmaproc = &cmd64x_dmaproc;
}
break;
- case PCI_DEVICE_ID_CMD_648:
- hwif->dmaproc = &cmd64x_dmaproc;
- break;
default:
break;
}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)