diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-11-23 02:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-11-23 02:00:47 +0000 |
commit | 06615f62b17d7de6e12d2f5ec6b88cf30af08413 (patch) | |
tree | 8766f208847d4876a6db619aebbf54d53b76eb44 /drivers/ide | |
parent | fa9bdb574f4febb751848a685d9a9017e04e1d53 (diff) |
Merge with Linux 2.4.0-test10.
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/Config.in | 4 | ||||
-rw-r--r-- | drivers/ide/Makefile | 298 | ||||
-rw-r--r-- | drivers/ide/alim15x3.c | 10 | ||||
-rw-r--r-- | drivers/ide/buddha.c | 10 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-features.c | 5 | ||||
-rw-r--r-- | drivers/ide/ide-pci.c | 55 | ||||
-rw-r--r-- | drivers/ide/ide-proc.c | 24 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 34 | ||||
-rw-r--r-- | drivers/ide/ide.c | 18 | ||||
-rw-r--r-- | drivers/ide/osb4.c | 322 | ||||
-rw-r--r-- | drivers/ide/slc90e66.c | 382 | ||||
-rw-r--r-- | drivers/ide/via82cxxx.c | 8 |
13 files changed, 902 insertions, 272 deletions
diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in index d4687f703..4db04ef96 100644 --- a/drivers/ide/Config.in +++ b/drivers/ide/Config.in @@ -68,7 +68,9 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL dep_bool ' PROMISE PDC20246/PDC20262/PDC20267 support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX + dep_bool ' ServerWorks OSB4 chipset support' CONFIG_BLK_DEV_OSB4 $CONFIG_BLK_DEV_OSB4 dep_bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 + dep_bool ' SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 dep_bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' VIA82CXXX chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI fi @@ -154,9 +156,11 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_HPT366" = "y" -o \ "$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \ "$CONFIG_BLK_DEV_OPTI621" = "y" -o \ + "$CONFIG_BLK_DEV_OSB4" = "y" -o \ "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \ "$CONFIG_BLK_DEV_PIIX" = "y" -o \ "$CONFIG_BLK_DEV_SIS5513" = "y" -o \ + "$CONFIG_BLK_DEV_SLC90E66" = "y" -o \ "$CONFIG_BLK_DEV_SL82C105" = "y" -o \ "$CONFIG_BLK_DEV_VIA82CXXX" = "y" ]; then define_bool CONFIG_BLK_DEV_IDE_MODES y diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index cc8d4e870..d5b4b637e 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -1,14 +1,8 @@ # # Makefile for the kernel ata, atapi, and ide block device drivers. # -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definition is now inherited from the -# parent makefile. -# - +# 12 September 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> +# Rewritten to use lists instead of if-statements. # # Note : at this point, these files are compiled on all systems. # In the future, some of these should be built conditionally. @@ -19,219 +13,85 @@ MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) O_TARGET := idedriver.o -O_OBJS := ide-geometry.o -M_OBJS := -OX_OBJS := -MX_OBJS := - -ifeq ($(CONFIG_BLK_DEV_AEC62XX),y) -IDE_OBJS += aec62xx.o -endif - -ifeq ($(CONFIG_BLK_DEV_ALI14XX),y) -IDE_OBJS += ali14xx.o -endif - -ifeq ($(CONFIG_BLK_DEV_ALI15X3),y) -IDE_OBJS += alim15x3.o -endif - -ifeq ($(CONFIG_BLK_DEV_AMD7409),y) -IDE_OBJS += amd7409.o -endif - -ifeq ($(CONFIG_BLK_DEV_BUDDHA),y) -IDE_OBJS += buddha.o -endif - -ifeq ($(CONFIG_BLK_DEV_CMD640),y) -IDE_OBJS += cmd640.o -endif - -ifeq ($(CONFIG_BLK_DEV_CMD64X),y) -IDE_OBJS += cmd64x.o -endif - -ifeq ($(CONFIG_BLK_DEV_CS5530),y) -IDE_OBJS += cs5530.o -endif - -ifeq ($(CONFIG_BLK_DEV_CY82C693),y) -IDE_OBJS += cy82c693.o -endif - -ifeq ($(CONFIG_BLK_DEV_DTC2278),y) -IDE_OBJS += dtc2278.o -endif - -ifeq ($(CONFIG_BLK_DEV_FALCON_IDE),y) -IDE_OBJS += falconide.o -endif - -ifeq ($(CONFIG_BLK_DEV_GAYLE),y) -IDE_OBJS += gayle.o -endif - -ifeq ($(CONFIG_BLK_DEV_Q40IDE),y) -IDE_OBJS += q40ide.o -endif - -ifeq ($(CONFIG_BLK_DEV_HD),y) -O_OBJS += hd.o -endif - -ifeq ($(CONFIG_BLK_DEV_HPT34X),y) -IDE_OBJS += hpt34x.o -endif - -ifeq ($(CONFIG_BLK_DEV_HPT366),y) -IDE_OBJS += hpt366.o -endif - -ifeq ($(CONFIG_BLK_DEV_HT6560B),y) -IDE_OBJS += ht6560b.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDE_ICSIDE),y) -IDE_OBJS += icside.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDEDMA),y) -IDE_OBJS += ide-dma.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDEPCI),y) -IDE_OBJS += ide-pci.o -endif - -ifeq ($(CONFIG_BLK_DEV_ISAPNP),y) -IDE_OBJS += ide-pnp.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDE_PMAC),y) -IDE_OBJS += ide-pmac.o -endif - -ifeq ($(CONFIG_BLK_DEV_MAC_IDE),y) -IDE_OBJS += macide.o -endif - -ifeq ($(CONFIG_BLK_DEV_NS87415),y) -IDE_OBJS += ns87415.o -endif - -ifeq ($(CONFIG_BLK_DEV_OPTI621),y) -IDE_OBJS += opti621.o -endif - -ifeq ($(CONFIG_BLK_DEV_PDC202XX),y) -IDE_OBJS += pdc202xx.o -endif - -ifeq ($(CONFIG_BLK_DEV_PDC4030),y) -IDE_OBJS += pdc4030.o -endif - -ifeq ($(CONFIG_BLK_DEV_PIIX),y) -IDE_OBJS += piix.o -endif - -ifeq ($(CONFIG_BLK_DEV_QD6580),y) -IDE_OBJS += qd6580.o -endif - -ifeq ($(CONFIG_BLK_DEV_IDE_RAPIDE),y) -IDE_OBJS += rapide.o -endif - -ifeq ($(CONFIG_BLK_DEV_RZ1000),y) -IDE_OBJS += rz1000.o -endif - -ifeq ($(CONFIG_BLK_DEV_SIS5513),y) -IDE_OBJS += sis5513.o -endif - -ifeq ($(CONFIG_BLK_DEV_SL82C105),y) -IDE_OBJS += sl82c105.o -endif - -ifeq ($(CONFIG_BLK_DEV_TRM290),y) -IDE_OBJS += trm290.o -endif - -ifeq ($(CONFIG_BLK_DEV_UMC8672),y) -IDE_OBJS += umc8672.o -endif - -ifeq ($(CONFIG_BLK_DEV_VIA82CXXX),y) -IDE_OBJS += via82cxxx.o -endif - -### if CONFIG_BLK_DEV_IDE is n, IDE_OBJS will be ignored - -ifeq ($(CONFIG_PROC_FS),y) -IDE_OBJS += ide-proc.o -endif - -###Collect - -ifeq ($(CONFIG_BLK_DEV_IDE),y) - OX_OBJS += ide.o ide-features.o - O_OBJS += ide-probe.o $(IDE_OBJS) -else - ifeq ($(CONFIG_BLK_DEV_IDE),m) - MIX_OBJS += ide.o ide-features.o $(IDE_OBJS) - M_OBJS += ide-mod.o ide-probe-mod.o - endif -endif - -############ - -ifeq ($(CONFIG_BLK_DEV_IDECS),y) -O_OBJS += ide-cs.o -else - ifeq ($(CONFIG_BLK_DEV_IDECS),m) - M_OBJS += ide-cs.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_IDEDISK),y) -O_OBJS += ide-disk.o -else - ifeq ($(CONFIG_BLK_DEV_IDEDISK),m) - M_OBJS += ide-disk.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_IDECD),y) -O_OBJS += ide-cd.o -else - ifeq ($(CONFIG_BLK_DEV_IDECD),m) - M_OBJS += ide-cd.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_IDETAPE),y) -O_OBJS += ide-tape.o -else - ifeq ($(CONFIG_BLK_DEV_IDETAPE),m) - M_OBJS += ide-tape.o - endif -endif -ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),y) -O_OBJS += ide-floppy.o -else - ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),m) - M_OBJS += ide-floppy.o - endif -endif +obj-y := +obj-m := +ide-obj-y := + +ide-obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o +ide-obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o +ide-obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o +ide-obj-$(CONFIG_BLK_DEV_AMD7409) += amd7409.o +ide-obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o +ide-obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o +ide-obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o +ide-obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o +ide-obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o +ide-obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o +ide-obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o +ide-obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o +ide-obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o +ide-obj-$(CONFIG_BLK_DEV_HD) += hd.o +ide-obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o +ide-obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o +ide-obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o +ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o +ide-obj-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o +ide-obj-$(CONFIG_BLK_DEV_IDEPCI) += ide-pci.o +ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o +ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += ide-pmac.o +ide-obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o +ide-obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o +ide-obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o +ide-obj-$(CONFIG_BLK_DEV_OSB4) += osb4.o +ide-obj-$(CONFIG_BLK_DEV_PDC202XX) += pdc202xx.o +ide-obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o +ide-obj-$(CONFIG_BLK_DEV_PIIX) += piix.o +ide-obj-$(CONFIG_BLK_DEV_QD6580) += qd6580.o +ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o +ide-obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o +ide-obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o +ide-obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o +ide-obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o +ide-obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o +ide-obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o +ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o + +ide-obj-$(CONFIG_PROC_FS) += ide-proc.o + +export-objs := ide.o ide-features.o +list-multi := ide-mod.o ide-probe-mod.o +ide-mod-objs := $(export-objs) $(ide-obj-y) +ide-probe-mod-objs := ide-probe.o ide-geometry.o + +obj-$(CONFIG_BLK_DEV_IDE) += ide-mod.o ide-probe-mod.o +obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o +obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o +obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o +obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o +obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o + +# Extract lists of the multi-part drivers. +# The 'int-*' lists are the intermediate files used to build the multi's. +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + +# Take multi-part drivers out of obj-y and put components in. +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) + +# Translate to Rules.make lists. +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) +MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) include $(TOPDIR)/Rules.make -ide-mod.o: ide.o ide-features.o $(IDE_OBJS) - $(LD) $(LD_RFLAG) -r -o $@ ide.o ide-features.o $(IDE_OBJS) +ide-mod.o: $(ide-mod-objs) + $(LD) -r -o $@ $(ide-mod-objs) -ide-probe-mod.o: ide-probe.o ide-geometry.o - $(LD) $(LD_RFLAG) -r -o $@ ide-probe.o ide-geometry.o +ide-probe-mod.o: $(ide-probe-mod-objs) + $(LD) -r -o $@ $(ide-probe-mod-objs) diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 41768bb90..813aecd3b 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -171,11 +171,11 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count) ((reg5yh & 0x30)>>4) + 12 ); } } else { - p += sprintf(p, q, - (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4, - (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4, - (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4, - (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4 ); + int t1 = (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4; + int t2 = (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4; + int t3 = (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4; + int t4 = (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4; + p += sprintf(p, q, t1, t2, t3, t4); } #if 0 diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c index 710b6654d..7ef6f645a 100644 --- a/drivers/ide/buddha.c +++ b/drivers/ide/buddha.c @@ -117,19 +117,15 @@ static int __init find_buddha(void) buddha_num_hwifs = 0; while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { unsigned long board; - const char *name; - if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { + if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) buddha_num_hwifs = BUDDHA_NUM_HWIFS; - name = "Buddha IDE Interface"; - } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { + else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) buddha_num_hwifs = CATWEASEL_NUM_HWIFS; - name = "Catweasel IDE Interface and Floppy Controller"; - } else + else continue; board = z->resource.start; if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) continue; - strcpy(z->name, name); buddha_board = ZTWO_VADDR(board); /* write to BUDDHA_IRQ_MR to enable the board IRQ */ *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index ae9f62768..9d0fc8e74 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -64,8 +64,8 @@ static void idedisk_bswap_data (void *buffer, int wcount) u16 *p = buffer; while (wcount--) { - *p++ = *p << 8 | *p >> 8; - *p++ = *p << 8 | *p >> 8; + *p = *p << 8 | *p >> 8; p++; + *p = *p << 8 | *p >> 8; p++; } } diff --git a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c index fa765d76f..2dfef8bee 100644 --- a/drivers/ide/ide-features.c +++ b/drivers/ide/ide-features.c @@ -224,7 +224,8 @@ int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature) #ifndef CONFIG_IDEDMA_IVB if ((drive->id->hw_config & 0x6000) == 0) { #else /* !CONFIG_IDEDMA_IVB */ - if ((drive->id->hw_config & 0x2000) == 0) { + if (((drive->id->hw_config & 0x2000) == 0) || + ((drive->id->hw_config & 0x4000) == 0)) { #endif /* CONFIG_IDEDMA_IVB */ printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name); return 1; @@ -260,7 +261,7 @@ byte eighty_ninty_three (ide_drive_t *drive) #ifndef CONFIG_IDEDMA_IVB (drive->id->hw_config & 0x4000) && #endif /* CONFIG_IDEDMA_IVB */ - (drive->id->hw_config & 0x2000)) ? 1 : 0); + (drive->id->hw_config & 0x6000)) ? 1 : 0); } /* diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c index 561b1c3cf..f1304a4a0 100644 --- a/drivers/ide/ide-pci.c +++ b/drivers/ide/ide-pci.c @@ -72,6 +72,8 @@ #define DEVID_CS5530 ((ide_pci_devid_t){PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE}) #define DEVID_AMD7403 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7403}) #define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409}) +#define DEVID_SLC90E66 ((ide_pci_devid_t){PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1}) +#define DEVID_OSB4 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE}) #define IDE_IGNORE ((void *)-1) @@ -205,6 +207,19 @@ extern void ide_init_opti621(ide_hwif_t *); #define INIT_OPTI621 NULL #endif +#ifdef CONFIG_BLK_DEV_OSB4 +extern unsigned int pci_init_osb4(struct pci_dev *, const char *); +extern unsigned int ata66_osb4(ide_hwif_t *); +extern void ide_init_osb4(ide_hwif_t *); +#define PCI_OSB4 &pci_init_osb4 +#define ATA66_OSB4 &ata66_osb4 +#define INIT_OSB4 &ide_init_osb4 +#else +#define PCI_OSB4 NULL +#define ATA66_OSB4 NULL +#define INIT_OSB4 NULL +#endif + #ifdef CONFIG_BLK_DEV_PDC202XX extern unsigned int pci_init_pdc202xx(struct pci_dev *, const char *); extern unsigned int ata66_pdc202xx(ide_hwif_t *); @@ -253,6 +268,19 @@ extern void ide_init_sis5513(ide_hwif_t *); #define INIT_SIS5513 NULL #endif +#ifdef CONFIG_BLK_DEV_SLC90E66 +extern unsigned int pci_init_slc90e66(struct pci_dev *, const char *); +extern unsigned int ata66_slc90e66(ide_hwif_t *); +extern void ide_init_slc90e66(ide_hwif_t *); +#define PCI_SLC90E66 &pci_init_slc90e66 +#define ATA66_SLC90E66 &ata66_slc90e66 +#define INIT_SLC90E66 &ide_init_slc90e66 +#else +#define PCI_SLC90E66 NULL +#define ATA66_SLC90E66 NULL +#define INIT_SLC90E66 NULL +#endif + #ifdef CONFIG_BLK_DEV_SL82C105 extern void ide_init_sl82c105(ide_hwif_t *); extern void ide_dmacapable_sl82c105(ide_hwif_t *, unsigned long); @@ -351,6 +379,8 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_CS5530, "CS5530", PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AMD7403, "AMD7403", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AMD7409, "AMD7409", PCI_AMD7409, ATA66_AMD7409, INIT_AMD7409, DMA_AMD7409, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, + {DEVID_SLC90E66,"SLC90E66", PCI_SLC90E66, ATA66_SLC90E66, INIT_SLC90E66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_OSB4, "ServerWorks OSB4", PCI_OSB4, ATA66_OSB4, INIT_OSB4, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; /* @@ -466,7 +496,7 @@ static int __init ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) */ for (reg = 0; reg < 4; reg++) { struct resource *res = dev->resource + reg; - if (!(res->flags & PCI_BASE_ADDRESS_SPACE_IO)) + if ((res->flags & IORESOURCE_IO) == 0) continue; if (!res->start) { printk("%s: Missing I/O address #%d\n", name, reg); @@ -493,11 +523,16 @@ static void __init ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t * byte tmp = 0; ide_hwif_t *hwif, *mate = NULL; unsigned int class_rev; - int pci_class_ide; #ifdef CONFIG_IDEDMA_AUTO autodma = 1; #endif + +#if 1 /* what do do with this useful tool ??? */ + if (pci_enable_device(dev)) + return; +#endif + check_if_enabled: if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) { printk("%s: error accessing PCI regs\n", d->name); @@ -539,8 +574,7 @@ check_if_enabled: * Can we trust the reported IRQ? */ pciirq = dev->irq; - pci_class_ide = ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE); - if (!pci_class_ide) { + if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) { printk("%s: not 100%% native mode: will probe irqs later\n", d->name); /* * This allows offboard ide-pci cards the enable a BIOS, @@ -550,17 +584,11 @@ check_if_enabled: */ pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : ide_special_settings(dev, d->name); } else if (tried_config) { - printk(KERN_INFO "%s: will probe irqs later\n", d->name); + printk("%s: will probe irqs later\n", d->name); pciirq = 0; } else if (!pciirq) { - if (pci_class_ide) { - /* this is the normal path for most IDE devices */ - if (d->init_chipset) - pciirq = d->init_chipset(dev, d->name); - else - printk(KERN_INFO "%s standard IDE storage device detected\n", d->name); - } else - printk(KERN_WARNING "%s: bad irq (0): will probe later\n", d->name); + printk("%s: bad irq (%d): will probe later\n", d->name, pciirq); + pciirq = 0; } else { if (d->init_chipset) (void) d->init_chipset(dev, d->name); @@ -656,6 +684,7 @@ check_if_enabled: IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_OSB4) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name); if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 4bb181241..56e8a9593 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -101,6 +101,10 @@ int (*hpt34x_display_info)(char *, char **, off_t, int) = NULL; extern byte hpt366_proc; int (*hpt366_display_info)(char *, char **, off_t, int) = NULL; #endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_OSB4 +extern byte osb4_proc; +int (*osb4_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_OSB4 */ #ifdef CONFIG_BLK_DEV_PDC202XX extern byte pdc202xx_proc; int (*pdc202xx_display_info)(char *, char **, off_t, int) = NULL; @@ -113,6 +117,10 @@ int (*piix_display_info)(char *, char **, off_t, int) = NULL; extern byte sis_proc; int (*sis_display_info)(char *, char **, off_t, int) = NULL; #endif /* CONFIG_BLK_DEV_SIS5513 */ +#ifdef CONFIG_BLK_DEV_SLC90E66 +extern byte slc90e66_proc; +int (*slc90e66_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_SLC90E66 */ #ifdef CONFIG_BLK_DEV_VIA82CXXX extern byte via_proc; int (*via_display_info)(char *, char **, off_t, int) = NULL; @@ -829,6 +837,10 @@ void proc_ide_create(void) if ((hpt366_display_info) && (hpt366_proc)) create_proc_info_entry("hpt366", 0, proc_ide_root, hpt366_display_info); #endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_OSB4 + if ((osb4_display_info) && (osb4_proc)) + create_proc_info_entry("osb4", 0, proc_ide_root, osb4_display_info); +#endif /* CONFIG_BLK_DEV_OSB4 */ #ifdef CONFIG_BLK_DEV_PDC202XX if ((pdc202xx_display_info) && (pdc202xx_proc)) create_proc_info_entry("pdc202xx", 0, proc_ide_root, pdc202xx_display_info); @@ -841,6 +853,10 @@ void proc_ide_create(void) if ((sis_display_info) && (sis_proc)) create_proc_info_entry("sis", 0, proc_ide_root, sis_display_info); #endif /* CONFIG_BLK_DEV_SIS5513 */ +#ifdef CONFIG_BLK_DEV_SLC90E66 + if ((slc90e66_display_info) && (slc90e66_proc)) + create_proc_info_entry("slc90e66", 0, proc_ide_root, slc90e66_display_info); +#endif /* CONFIG_BLK_DEV_SLC90E66 */ #ifdef CONFIG_BLK_DEV_VIA82CXXX if ((via_display_info) && (via_proc)) create_proc_info_entry("via", 0, proc_ide_root, via_display_info); @@ -881,6 +897,10 @@ void proc_ide_destroy(void) if ((hpt366_display_info) && (hpt366_proc)) remove_proc_entry("ide/hpt366",0); #endif /* CONFIG_BLK_DEV_HPT366 */ +#ifdef CONFIG_BLK_DEV_OSB4 + if ((osb4_display_info) && (osb4_proc)) + remove_proc_entry("ide/osb4",0); +#endif /* CONFIG_BLK_DEV_OSB4 */ #ifdef CONFIG_BLK_DEV_PDC202XX if ((pdc202xx_display_info) && (pdc202xx_proc)) remove_proc_entry("ide/pdc202xx",0); @@ -893,6 +913,10 @@ void proc_ide_destroy(void) if ((sis_display_info) && (sis_proc)) remove_proc_entry("ide/sis", 0); #endif /* CONFIG_BLK_DEV_SIS5513 */ +#ifdef CONFIG_BLK_DEV_SLC90E66 + if ((slc90e66_display_info) && (slc90e66_proc)) + remove_proc_entry("ide/slc90e66",0); +#endif /* CONFIG_BLK_DEV_SLC90E66 */ #ifdef CONFIG_BLK_DEV_VIA82CXXX if ((via_display_info) && (via_proc)) remove_proc_entry("ide/via",0); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index f36dbd8ff..079353425 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -3126,8 +3126,11 @@ static void idetape_create_load_unload_cmd (ide_drive_t *drive, idetape_pc_t *pc idetape_init_pc (pc); pc->c[0] = IDETAPE_LOAD_UNLOAD_CMD; pc->c[4] = cmd; - if (tape->onstream) + if (tape->onstream) { pc->c[1] = 1; + if (cmd == !IDETAPE_LU_LOAD_MASK) + pc->c[4] = 4; + } set_bit (PC_WAIT_FOR_DSC, &pc->flags); pc->callback = &idetape_pc_callback; } @@ -3239,12 +3242,18 @@ static void idetape_create_locate_cmd (ide_drive_t *drive, idetape_pc_t *pc, uns pc->callback = &idetape_pc_callback; } -static void idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int prevent) +static int idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int prevent) { + idetape_tape_t *tape = drive->driver_data; + + if (!tape->capabilities.lock) + return 0; + idetape_init_pc(pc); pc->c[0] = IDETAPE_PREVENT_CMD; pc->c[4] = prevent; pc->callback = &idetape_pc_callback; + return 1; } static int __idetape_discard_read_pipeline (ide_drive_t *drive) @@ -5017,13 +5026,15 @@ static int idetape_mtioctop (ide_drive_t *drive,short mt_op,int mt_count) } } case MTLOCK: - idetape_create_prevent_cmd(drive, &pc, 1); + if (!idetape_create_prevent_cmd(drive, &pc, 1)) + return 0; retval = idetape_queue_pc_tail (drive,&pc); if (retval) return retval; tape->door_locked = DOOR_EXPLICITLY_LOCKED; return 0; case MTUNLOCK: - idetape_create_prevent_cmd(drive, &pc, 0); + if (!idetape_create_prevent_cmd(drive, &pc, 0)) + return 0; retval = idetape_queue_pc_tail (drive,&pc); if (retval) return retval; tape->door_locked = DOOR_UNLOCKED; @@ -5262,10 +5273,11 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp) clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags); if (tape->chrdev_direction == idetape_direction_none) { - idetape_create_prevent_cmd(drive, &pc, 1); - if (!idetape_queue_pc_tail (drive,&pc)) { - if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) - tape->door_locked = DOOR_LOCKED; + if (idetape_create_prevent_cmd(drive, &pc, 1)) { + if (!idetape_queue_pc_tail (drive,&pc)) { + if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) + tape->door_locked = DOOR_LOCKED; + } } idetape_analyze_headers(drive); } @@ -5320,9 +5332,9 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) (void) idetape_rewind_tape (drive); if (tape->chrdev_direction == idetape_direction_none) { if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) { - idetape_create_prevent_cmd(drive, &pc, 0); - if (!idetape_queue_pc_tail (drive,&pc)) - tape->door_locked = DOOR_UNLOCKED; + if (idetape_create_prevent_cmd(drive, &pc, 0)) + if (!idetape_queue_pc_tail (drive,&pc)) + tape->door_locked = DOOR_UNLOCKED; } } clear_bit (IDETAPE_BUSY, &tape->flags); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 5d00083c3..32205cccc 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -163,12 +163,12 @@ static const byte ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR }; -static int idebus_parameter = 0; /* holds the "idebus=" parameter */ -static int system_bus_speed = 0; /* holds what we think is VESA/PCI bus speed */ +static int idebus_parameter; /* holds the "idebus=" parameter */ +static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ static int initializing; /* set while initializing built-in drivers */ #ifdef CONFIG_BLK_DEV_IDEPCI -static int ide_scan_direction = 0; /* THIS was formerly 2.2.x pci=reverse */ +static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ #endif /* CONFIG_BLK_DEV_IDEPCI */ #if defined(__mc68000__) || defined(CONFIG_APUS) @@ -176,14 +176,14 @@ static int ide_scan_direction = 0; /* THIS was formerly 2.2.x pci=reverse */ * ide_lock is used by the Atari code to obtain access to the IDE interrupt, * which is shared between several drivers. */ -static int ide_lock = 0; +static int ide_lock; #endif /* __mc68000__ || CONFIG_APUS */ /* * ide_modules keeps track of the available IDE chipset/probe/driver modules. */ -ide_module_t *ide_modules = NULL; -ide_module_t *ide_probe = NULL; +ide_module_t *ide_modules; +ide_module_t *ide_probe; /* * This is declared extern in ide.h, for access by other IDE modules: @@ -1509,7 +1509,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); if (!OK_STAT(stat, READY_STAT, BAD_STAT)) { /* Try to not flood the console with msgs */ - static unsigned long last_msgtime = 0, count = 0; + static unsigned long last_msgtime, count; ++count; if (0 < (signed long)(jiffies - (last_msgtime + HZ))) { last_msgtime = jiffies; @@ -3499,7 +3499,7 @@ EXPORT_SYMBOL(ide_spin_wait_hwgroup); /* * Probe module */ -devfs_handle_t ide_devfs_handle = NULL; +devfs_handle_t ide_devfs_handle; EXPORT_SYMBOL(ide_probe); EXPORT_SYMBOL(drive_is_flashcard); @@ -3561,7 +3561,7 @@ EXPORT_SYMBOL(system_bus_clock); */ int __init ide_init (void) { - static char banner_printed = 0; + static char banner_printed; int i; if (!banner_printed) { diff --git a/drivers/ide/osb4.c b/drivers/ide/osb4.c new file mode 100644 index 000000000..85b6cda9d --- /dev/null +++ b/drivers/ide/osb4.c @@ -0,0 +1,322 @@ +/* + * linux/drivers/block/osb4.c Version 0.2 17 Oct 2000 + * + * Copyright (C) 2000 Cobalt Networks, Inc. <asun@cobalt.com> + * May be copied or modified under the terms of the GNU General Public License + * + * interface borrowed from alim15x3.c: + * Copyright (C) 1998-2000 Michel Aubry, Maintainer + * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer + * + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> + * + * IDE support for the ServerWorks OSB4 IDE chipset + * + * here's the default lspci: + * + * 00:0f.1 IDE interface: ServerWorks: Unknown device 0211 (prog-if 8a [Master SecP PriP]) + * Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- + * Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- + * Latency: 255 + * Region 4: I/O ports at c200 + * 00: 66 11 11 02 05 01 00 02 00 8a 01 01 00 ff 80 00 + * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 20: 01 c2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 40: 99 99 99 99 ff ff ff ff 0c 0c 00 00 00 00 00 00 + * 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/hdreg.h> +#include <linux/ide.h> +#include <linux/init.h> + +#include <asm/delay.h> +#include <asm/io.h> + +#include "ide_modes.h" + +#define OSB4_DEBUG_DRIVE_INFO 0 + +#define DISPLAY_OSB4_TIMINGS + +#if defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static byte osb4_revision = 0; +static struct pci_dev *bmide_dev; + +static int osb4_get_info(char *, char **, off_t, int, int); +extern int (*osb4_display_info)(char *, char **, off_t, int, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); + +static int osb4_get_info (char *buffer, char **addr, off_t offset, int count, int dummy) +{ + char *p = buffer; + u32 bibma = pci_resource_start(bmide_dev, 4); + u16 reg56; + u8 c0 = 0, c1 = 0, reg54; + + pci_read_config_byte(bmide_dev, 0x54, ®54); + pci_read_config_word(bmide_dev, 0x56, ®56); + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, "\n ServerWorks OSB4 Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + 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 " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + (reg54 & 0x01) ? "yes" : "no ", + (reg54 & 0x02) ? "yes" : "no ", + (reg54 & 0x04) ? "yes" : "no ", + (reg54 & 0x08) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + (reg56 & 0x0002) ? "2" : ((reg56 & 0x0001) ? "1" : + ((reg56 & 0x000f) ? "X" : "0")), + (reg56 & 0x0020) ? "2" : ((reg56 & 0x0010) ? "1" : + ((reg56 & 0x00f0) ? "X" : "0")), + (reg56 & 0x0200) ? "2" : ((reg56 & 0x0100) ? "1" : + ((reg56 & 0x0f00) ? "X" : "0")), + (reg56 & 0x2000) ? "2" : ((reg56 & 0x1000) ? "1" : + ((reg56 & 0xf000) ? "X" : "0"))); + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte osb4_proc = 0; + +extern char *ide_xfer_verbose (byte xfer_rate); + +static void osb4_tune_drive (ide_drive_t *drive, byte pio) +{ + /* command/recover widths */ + byte timings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; + int port = HWIF(drive)->index ? 0x42 : 0x40; + + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + if (&HWIF(drive)->drives[0] == drive) /* master drive */ + port++; + pci_write_config_byte(HWIF(drive)->pci_dev, port, timings[pio]); +} + +#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_BLK_DEV_OSB4) +static int osb4_tune_chipset (ide_drive_t *drive, byte speed) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + byte is_slave = (&HWIF(drive)->drives[1] == drive) ? 1 : 0; + byte bit8, enable; + int err; + + /* clear udma register if we don't want udma */ + if (speed < XFER_UDMA_0) { + enable = 0x1 << (is_slave + (hwif->channel ? 2 : 0)); + pci_read_config_byte(dev, 0x54, &bit8); + pci_write_config_byte(dev, 0x54, bit8 & ~enable); + } + +#ifdef CONFIG_BLK_DEV_IDEDMA + if (speed >= XFER_MW_DMA_0) { + byte channel = hwif->channel ? 0x46 : 0x44; + if (!is_slave) + channel++; + + switch (speed) { + case XFER_MW_DMA_0: + bit8 = 0x77; + break; + case XFER_MW_DMA_1: + bit8 = 0x21; + break; + case XFER_MW_DMA_2: + default: + bit8 = 0x20; + break; + } + pci_write_config_byte(dev, channel, bit8); + } + + if (speed >= XFER_UDMA_0) { + byte channel = hwif->channel ? 0x57 : 0x56; + int slave = is_slave ? 4 : 0; + + pci_read_config_byte(dev, channel, &bit8); + bit8 &= ~(0xf << slave); + switch (speed) { + case XFER_UDMA_0: + break; + case XFER_UDMA_1: + bit8 |= 0x1 << slave; + break; + case XFER_UDMA_2: + default: + bit8 |= 0x2 << slave; + break; + } + pci_write_config_byte(dev, channel, bit8); + + enable = 0x1 << (is_slave + (hwif->channel ? 2 : 0)); + pci_read_config_byte(dev, 0x54, &bit8); + pci_write_config_byte(dev, 0x54, bit8 | enable); + } +#endif + +#if OSB4_DEBUG_DRIVE_INFO + printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); +#endif /* OSB4_DEBUG_DRIVE_INFO */ + if (!drive->init_speed) + drive->init_speed = speed; + err = ide_config_drive_speed(drive, speed); + drive->current_speed = speed; + return err; +} + +static int osb4_config_drive_for_dma (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + byte speed; + + byte udma_66 = eighty_ninty_three(drive); + /* need specs to figure out if osb4 is capable of ata/66/100 */ + int ultra100 = 0; + int ultra66 = 0; + int ultra = 1; + + if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra)) { + speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0008) && (ultra)) { + speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0004) && (ultra)) { + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (ultra)) { + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (ultra)) { + speed = XFER_UDMA_0; + } else if (id->dma_mword & 0x0004) { + speed = XFER_MW_DMA_2; + } else if (id->dma_mword & 0x0002) { + speed = XFER_MW_DMA_1; + } else if (id->dma_1word & 0x0004) { + speed = XFER_SW_DMA_2; + } else { + speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + } + + (void) osb4_tune_chipset(drive, speed); + + return ((int) ((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); +} + +static int osb4_dmaproc(ide_dma_action_t func, ide_drive_t *drive) +{ + switch (func) { + case ide_dma_check: + return ide_dmaproc((ide_dma_action_t) osb4_config_drive_for_dma(drive), drive); + default : + break; + } + /* Other cases are done by generic IDE-DMA code. */ + return ide_dmaproc(func, drive); +} +#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_BLK_DEV_OSB4) */ + +unsigned int __init pci_init_osb4 (struct pci_dev *dev, const char *name) +{ + u16 word; + byte bit8; + + pci_read_config_byte(dev, PCI_REVISION_ID, &osb4_revision); + + /* setup command register. just make sure that bus master and + * i/o ports are on. */ + pci_read_config_word(dev, PCI_COMMAND, &word); + if ((word & (PCI_COMMAND_MASTER | PCI_COMMAND_IO)) != + (PCI_COMMAND_MASTER | PCI_COMMAND_IO)) + pci_write_config_word(dev, PCI_COMMAND, word | + PCI_COMMAND_MASTER | PCI_COMMAND_IO); + + /* make sure that we're in pci native mode for both the primary + * and secondary channel. */ + pci_read_config_byte(dev, PCI_CLASS_PROG, &bit8); + if ((bit8 & 0x5) != 0x5) + pci_write_config_byte(dev, PCI_CLASS_PROG, bit8 | 0x5); + + /* setup up our latency. the default is 255 which is a bit large. + * set it to 64 instead. */ + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &bit8); + if (bit8 != 0x40) + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); + +#if defined(DISPLAY_OSB4_TIMINGS) && defined(CONFIG_PROC_FS) + if (!osb4_proc) { + osb4_proc = 1; + bmide_dev = dev; + osb4_display_info = &osb4_get_info; + } +#endif /* DISPLAY_OSB4_TIMINGS && CONFIG_PROC_FS */ + return 0; +} + +unsigned int __init ata66_osb4 (ide_hwif_t *hwif) +{ + return 0; +} + +void __init ide_init_osb4 (ide_hwif_t *hwif) +{ + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + + hwif->tuneproc = &osb4_tune_drive; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + if (!hwif->dma_base) + return; + +#ifndef CONFIG_BLK_DEV_IDEDMA + hwif->autodma = 0; +#else /* CONFIG_BLK_DEV_IDEDMA */ +#ifdef CONFIG_BLK_DEV_OSB4 + hwif->autodma = 1; + hwif->dmaproc = &osb4_dmaproc; + hwif->speedproc = &osb4_tune_chipset; +#endif /* CONFIG_BLK_DEV_OSB4 */ +#endif /* !CONFIG_BLK_DEV_IDEDMA */ +} diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c new file mode 100644 index 000000000..f8e6be4d0 --- /dev/null +++ b/drivers/ide/slc90e66.c @@ -0,0 +1,382 @@ +/* + * linux/drivers/ide/slc90e66.c Version 0.10 October 4, 2000 + * + * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> + * May be copied or modified under the terms of the GNU General Public License + * + * 00:07.1 IDE interface: EFAR Microsystems: + * Unknown device 9130 (prog-if 8a [Master SecP PriP]) + * Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- + * VGASnoop- ParErr- Stepping- SERR- FastB2B- + * Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium + * >TAbort- <TAbort- <MAbort- >SERR- <PERR- + * Latency: 64 + * Interrupt: pin A routed to IRQ 255 + * Region 4: I/O ports at 1050 + * + * 00: 55 10 30 91 05 00 00 02 00 8a 01 01 00 40 00 00 + * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 20: 51 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 30: 00 00 00 00 00 00 00 00 00 00 00 00 ff 01 00 00 + * 40: 37 e3 33 e3 b9 55 01 00 0d 00 04 22 00 00 00 00 + * 50: 00 00 ff a0 00 00 00 08 40 00 00 00 00 00 00 00 + * 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * + * This a look-a-like variation of the ICH0 PIIX4 Ultra-66, + * but this keeps the ISA-Bridge and slots alive. + * + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/hdreg.h> +#include <linux/ide.h> +#include <linux/delay.h> +#include <linux/init.h> + +#include <asm/io.h> + +#include "ide_modes.h" + +#define SLC90E66_DEBUG_DRIVE_INFO 0 + +#define DISPLAY_SLC90E66_TIMINGS + +#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int slc90e66_get_info(char *, char **, off_t, int); +extern int (*slc90e66_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + u32 bibma = pci_resource_start(bmide_dev, 4); + u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0; + u8 c0 = 0, c1 = 0; + u8 reg44 = 0, reg47 = 0, reg48 = 0, reg4a = 0, reg4b = 0; + + pci_read_config_word(bmide_dev, 0x40, ®40); + pci_read_config_word(bmide_dev, 0x42, ®42); + pci_read_config_byte(bmide_dev, 0x44, ®44); + pci_read_config_byte(bmide_dev, 0x47, ®47); + pci_read_config_byte(bmide_dev, 0x48, ®48); + pci_read_config_byte(bmide_dev, 0x4a, ®4a); + pci_read_config_byte(bmide_dev, 0x4b, ®4b); + + psitre = (reg40 & 0x4000) ? 1 : 0; + ssitre = (reg42 & 0x4000) ? 1 : 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb_p((unsigned short)bibma + 0x02); + c1 = inb_p((unsigned short)bibma + 0x0a); + + p += sprintf(p, " SLC90E66 Chipset.\n"); + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + p += sprintf(p, " %sabled %sabled\n", + (c0&0x80) ? "dis" : " en", + (c1&0x80) ? "dis" : " en"); + 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 " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + (reg48&0x01) ? "yes" : "no ", + (reg48&0x02) ? "yes" : "no ", + (reg48&0x04) ? "yes" : "no ", + (reg48&0x08) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + ((reg4a&0x04)==0x04) ? "4" : + ((reg4a&0x03)==0x03) ? "3" : + (reg4a&0x02) ? "2" : + (reg4a&0x01) ? "1" : + (reg4a&0x00) ? "0" : "X", + ((reg4a&0x40)==0x40) ? "4" : + ((reg4a&0x30)==0x30) ? "3" : + (reg4a&0x20) ? "2" : + (reg4a&0x10) ? "1" : + (reg4a&0x00) ? "0" : "X", + ((reg4b&0x04)==0x04) ? "4" : + ((reg4b&0x03)==0x03) ? "3" : + (reg4b&0x02) ? "2" : + (reg4b&0x01) ? "1" : + (reg4b&0x00) ? "0" : "X", + ((reg4b&0x40)==0x40) ? "4" : + ((reg4b&0x30)==0x30) ? "3" : + (reg4b&0x20) ? "2" : + (reg4b&0x10) ? "1" : + (reg4b&0x00) ? "0" : "X"); + + p += sprintf(p, "UDMA\n"); + p += sprintf(p, "DMA\n"); + p += sprintf(p, "PIO\n"); + +/* + * FIXME.... Add configuration junk data....blah blah...... + */ + + return p-buffer; /* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) */ + +/* + * Used to set Fifo configuration via kernel command line: + */ + +byte slc90e66_proc = 0; + +extern char *ide_xfer_verbose (byte xfer_rate); + +#ifdef CONFIG_BLK_DEV_IDEDMA +/* + * + */ +static byte slc90e66_dma_2_pio (byte xfer_rate) { + switch(xfer_rate) { + case XFER_UDMA_4: + case XFER_UDMA_3: + case XFER_UDMA_2: + case XFER_UDMA_1: + case XFER_UDMA_0: + case XFER_MW_DMA_2: + case XFER_PIO_4: + return 4; + case XFER_MW_DMA_1: + case XFER_PIO_3: + return 3; + case XFER_SW_DMA_2: + case XFER_PIO_2: + return 2; + case XFER_MW_DMA_0: + case XFER_SW_DMA_1: + case XFER_SW_DMA_0: + case XFER_PIO_1: + case XFER_PIO_0: + case XFER_PIO_SLOW: + default: + return 0; + } +} +#endif /* CONFIG_BLK_DEV_IDEDMA */ + +/* + * Based on settings done by AMI BIOS + * (might be usefull if drive is not registered in CMOS for any reason). + */ +static void slc90e66_tune_drive (ide_drive_t *drive, byte pio) +{ + unsigned long flags; + u16 master_data; + byte slave_data; + int is_slave = (&HWIF(drive)->drives[1] == drive); + int master_port = HWIF(drive)->index ? 0x42 : 0x40; + int slave_port = 0x44; + /* ISP RTC */ + byte timings[][2] = { { 0, 0 }, + { 0, 0 }, + { 1, 0 }, + { 2, 1 }, + { 2, 3 }, }; + + pio = ide_get_best_pio_mode(drive, pio, 5, NULL); + pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data); + if (is_slave) { + master_data = master_data | 0x4000; + if (pio > 1) + /* enable PPE, IE and TIME */ + master_data = master_data | 0x0070; + pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data); + slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0); + slave_data = slave_data | ((timings[pio][0] << 2) | (timings[pio][1] + << (HWIF(drive)->index ? 4 : 0))); + } else { + master_data = master_data & 0xccf8; + if (pio > 1) + /* enable PPE, IE and TIME */ + master_data = master_data | 0x0007; + master_data = master_data | (timings[pio][0] << 12) | + (timings[pio][1] << 8); + } + save_flags(flags); + cli(); + pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data); + if (is_slave) + pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data); + restore_flags(flags); +} + +#ifdef CONFIG_BLK_DEV_IDEDMA +static int slc90e66_tune_chipset (ide_drive_t *drive, byte speed) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + byte maslave = hwif->channel ? 0x42 : 0x40; + int a_speed = 7 << (drive->dn * 4); + int u_flag = 1 << drive->dn; + int u_speed = 0; + int err = 0; + int sitre; + short reg4042, reg44, reg48, reg4a; + + pci_read_config_word(dev, maslave, ®4042); + sitre = (reg4042 & 0x4000) ? 1 : 0; + pci_read_config_word(dev, 0x44, ®44); + pci_read_config_word(dev, 0x48, ®48); + pci_read_config_word(dev, 0x4a, ®4a); + + switch(speed) { + case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; + case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; + case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; + case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; + case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; + case XFER_MW_DMA_2: + case XFER_MW_DMA_1: + case XFER_SW_DMA_2: break; + default: return -1; + } + + if (speed >= XFER_UDMA_0) { + if (!(reg48 & u_flag)) + pci_write_config_word(dev, 0x48, reg48|u_flag); + if ((reg4a & u_speed) != u_speed) { + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + pci_read_config_word(dev, 0x4a, ®4a); + pci_write_config_word(dev, 0x4a, reg4a|u_speed); + } + } + if (speed < XFER_UDMA_0) { + if (reg48 & u_flag) + pci_write_config_word(dev, 0x48, reg48 & ~u_flag); + if (reg4a & a_speed) + pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); + } + + slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed)); + +#if SLC90E66_DEBUG_DRIVE_INFO + printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn); +#endif /* SLC90E66_DEBUG_DRIVE_INFO */ + if (!drive->init_speed) + drive->init_speed = speed; + err = ide_config_drive_speed(drive, speed); + drive->current_speed = speed; + return err; +} + +static int slc90e66_config_drive_for_dma (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + int ultra = 1; + byte speed = 0; + byte udma_66 = eighty_ninty_three(drive); + + if ((id->dma_ultra & 0x0010) && (ultra)) { + speed = (udma_66) ? XFER_UDMA_4 : XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0008) && (ultra)) { + speed = (udma_66) ? XFER_UDMA_3 : XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0004) && (ultra)) { + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (ultra)) { + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (ultra)) { + speed = XFER_UDMA_0; + } else if (id->dma_mword & 0x0004) { + speed = XFER_MW_DMA_2; + } else if (id->dma_mword & 0x0002) { + speed = XFER_MW_DMA_1; + } else if (id->dma_1word & 0x0004) { + speed = XFER_SW_DMA_2; + } else { + speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + } + + (void) slc90e66_tune_chipset(drive, speed); + + return ((int) ((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); +} + +static int slc90e66_dmaproc(ide_dma_action_t func, ide_drive_t *drive) +{ + switch (func) { + case ide_dma_check: + return ide_dmaproc((ide_dma_action_t) slc90e66_config_drive_for_dma(drive), drive); + default : + break; + } + /* Other cases are done by generic IDE-DMA code. */ + return ide_dmaproc(func, drive); +} +#endif /* CONFIG_BLK_DEV_IDEDMA */ + +unsigned int __init pci_init_slc90e66 (struct pci_dev *dev, const char *name) +{ +#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) + if (!slc90e66_proc) { + slc90e66_proc = 1; + bmide_dev = dev; + slc90e66_display_info = &slc90e66_get_info; + } +#endif /* DISPLAY_SLC90E66_TIMINGS && CONFIG_PROC_FS */ + return 0; +} + +unsigned int __init ata66_slc90e66 (ide_hwif_t *hwif) +{ +#if 1 + byte reg47 = 0, ata66 = 0; + byte mask = hwif->channel ? 0x02 : 0x01; + + pci_read_config_byte(hwif->pci_dev, 0x47, ®47); + + ata66 = (reg47 & mask) ? 1 : 0; +#else + byte ata66 = 0; +#endif + return ata66; +} + +void __init ide_init_slc90e66 (ide_hwif_t *hwif) +{ + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + + hwif->tuneproc = &slc90e66_tune_drive; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + if (!hwif->dma_base) + return; + +#ifndef CONFIG_BLK_DEV_IDEDMA + hwif->autodma = 0; +#else /* CONFIG_BLK_DEV_IDEDMA */ + hwif->autodma = 1; + hwif->dmaproc = &slc90e66_dmaproc; + hwif->speedproc = &slc90e66_tune_chipset; +#endif /* !CONFIG_BLK_DEV_IDEDMA */ +} diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 1c1b68ff2..566dcc4d5 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -1,5 +1,5 @@ /* - * $Id: via82cxxx.c,v 2.1d 2000/10/01 10:01:00 vojtech Exp $ + * $Id: via82cxxx.c,v 2.1e 2000/10/03 10:01:00 vojtech Exp $ * * Copyright (c) 2000 Vojtech Pavlik * @@ -192,7 +192,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) via_print("----------VIA BusMastering IDE Configuration----------------"); - via_print("Driver Version: 2.1d"); + via_print("Driver Version: 2.1e"); pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t); via_print("South Bridge: VIA %s rev %#x", via_isa_bridges[via_config].name, t); @@ -334,8 +334,8 @@ static int via_set_speed(ide_drive_t *drive, byte speed) */ switch(via_isa_bridges[via_config].speed) { - case XFER_UDMA_2: t = via_timing[i].udma ? (0xe0 | (FIT(via_timing[i].udma, 2, 5) - 2)) : 0x03; break; - case XFER_UDMA_4: t = via_timing[i].udma ? (0xe8 | (FIT(via_timing[i].udma, 2, 9) - 2)) : 0x0f; break; + case XFER_UDMA_2: t = via_timing[i].udma ? (0xe0 | (FIT(ENOUGH(via_timing[i].udma, T), 2, 5) - 2)) : 0x03; break; + case XFER_UDMA_4: t = via_timing[i].udma ? (0xe8 | (FIT(ENOUGH(via_timing[i].udma, T/2), 2, 9) - 2)) : 0x0f; break; } if (via_isa_bridges[via_config].speed != XFER_MW_DMA_2) |