safe to say N. (As of 1.3.9x kernels, this driver's minor numbers
start at 0 instead of 32.)
+Cyclades-Z interrupt mode operation (EXPERIMENTAL)
+CONFIG_CYZ_INTR
+ The Cyclades-Z family of multiport cards allows 2 (two) driver
+ op modes: polling and interrupt. In polling mode, the driver will
+ check the status of the Cyclades-Z ports every certain amount of
+ time (which is called polling cycle and is configurable). In
+ interrupt mode, it will use an interrupt line (IRQ) in order to check
+ the status of the Cyclades-Z ports. The default op mode is polling.
+ If unsure, say N.
+
Stallion multiport serial support
CONFIG_STALDRV
Stallion cards give you many serial ports. You would need something
S: Maintained
IDE DRIVER [GENERAL]
-P: Mark Lord
-M: mlord@pobox.com
+P: Andre Hedrick
+M: andre@linux-ide.org
L: linux-kernel@vger.rutgers.edu
-S: Maintained
+W: http://linux.kernel.org/pub/linux/kernel/people/hedrick/
+S: Supported
IDE/ATAPI CDROM DRIVER
P: Jens Axboe
-M: axboe@image.dk
+M: axboe@suse.de
L: linux-kernel@vger.rutgers.edu
W: http://www.kernel.dk
S: Maintained
* This requires special handling here.
*/
switch (hd->major) {
+ case IDE5_MAJOR:
+ unit += 2;
+ case IDE4_MAJOR:
+ unit += 2;
case IDE3_MAJOR:
unit += 2;
case IDE2_MAJOR:
struct partition *p;
unsigned long first_sector, first_size, this_sector, this_size;
int mask = (1 << hd->minor_shift) - 1;
+ int loopct = 0; /* number of links followed
+ without finding a data partition */
int i;
first_sector = hd->part[MINOR(dev)].start_sect;
this_sector = first_sector;
while (1) {
+ if (++loopct > 100)
+ return;
if ((current_minor & mask) == 0)
return;
if (!(bh = bread(dev,0,1024)))
add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
current_minor++;
+ loopct = 0;
if ((current_minor & mask) == 0)
goto done;
}
* to trition.c and added UDMA to current DMA support.
* update Promise Ultra33 and added AEC6210U/UF UDMA cards.
* add configuration flag to allow booting of either card.
+ * Version 5.53.5 Fixed chipset identifiers.
+ * Version 5.53.6 Added Aladdin IV/V M5229 chipset support.
+ * Version 5.53.7 Added HPT343 basic support with everything at PIO 0.
+ * This is regardless of DMA capabilties.
*
* Some additional driver compile-time options are in ide.h
*
#define IS_PROMISE_DRIVE (0) /* auto-NULLs out Promise code */
#endif /* CONFIG_BLK_DEV_PROMISE */
-static const byte ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
-static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
-static const byte default_irqs[MAX_HWIFS] = {14, 15, 11, 10};
+static const byte ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, IDE5_MAJOR};
+static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160};
+static const byte default_irqs[MAX_HWIFS] = {14, 15, 11, 10, 8, 12};
static int idebus_parameter; /* holds the "idebus=" parameter */
static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
goto kill_rq;
}
block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0;
+
#if FAKE_FDISK_FOR_EZDRIVE
+ /* Yecch - this will shift the entire interval,
+ possibly killing some innocent following sector */
if (block == 0 && drive->remap_0_to_1)
block = 1; /* redirect MBR access to EZ-Drive partn table */
#endif /* FAKE_FDISK_FOR_EZDRIVE */
+
((ide_hwgroup_t *)hwif->hwgroup)->drive = drive;
+
#if (DISK_RECOVERY_TIME > 0)
while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME);
#endif
}
#endif
+#if MAX_HWIFS > 4
+static void do_ide4_request (void) /* invoked with cli() */
+{
+ do_hwgroup_request (ide_hwifs[4].hwgroup);
+}
+#endif
+
+#if MAX_HWIFS > 5
+static void do_ide5_request (void) /* invoked with cli() */
+{
+ do_hwgroup_request (ide_hwifs[5].hwgroup);
+}
+#endif
+
static void timer_expiry (unsigned long data)
{
ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
argbuf[3] = args[3];
}
if (!(err = verify_area(VERIFY_WRITE,(void *)arg, argsize))) {
+ if ((args[0] == WIN_SETFEATURES) &&
+ (args[1] > 66) &&
+ (args[2] == 3) &&
+ ((drive->id->word93 & 0x2000) == 0)) {
+ printk("%s: Speed warnings UDMA 3/4 is not functional.\n", drive->name);
+ goto abort_speed;
+ }
rq.buffer = argbuf;
err = ide_do_drive_cmd(drive, &rq, ide_wait);
memcpy_tofs((void *)arg, argbuf, argsize);
}
+abort_speed:
if (argsize > 4)
kfree(argbuf);
}
}
drive->media = ide_disk;
+
/* Extract geometry if we did not already have one for the drive */
if (!drive->present) {
drive->present = 1;
capacity/2048L, id->buf_size/2,
drive->bios_cyl, drive->bios_head, drive->bios_sect);
if (drive->using_dma) {
- if ((id->field_valid & 4) && (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
- printk(", UDMA"); /* UDMA BIOS-enabled! */
+ if ((id->field_valid & 4) && (id->word93 & 0x2000) &&
+ (id->dma_ultra & (id->dma_ultra >> 11) & 3)) {
+ printk(", UDMA(66)"); /* UDMA BIOS-enabled! */
+ } else if ((id->field_valid & 4) &&
+ (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
+ printk(", UDMA(33)"); /* UDMA BIOS-enabled! */
} else if (id->field_valid & 4) {
printk(", (U)DMA"); /* Can be BIOS-enabled! */
} else {
* The only "perfect" way to handle this would be to modify the setup.[cS] code
* to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
* for us during initialization. I have the necessary docs -- any takers? -ml
+ * [I did this. But the result is more suited for user space. -aeb]
+ *
+ * Unfortunately the above is far too optimistic. One of the problems is that
+ * drives 1 and 2 may be SCSI disks (even when IDE disks are present), so that
+ * the geometry we read here from BIOS is attributed to the wrong disks.
+ * Eventually the routine below should be removed.
*/
static void probe_cmos_for_drives (ide_hwif_t *hwif)
{
printk("%s ", msg);
+#endif
+
tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63;
drive->bios_sect = 63;
if (xparm > 1) {
drive->bios_head = xparm;
drive->bios_cyl = tracks / drive->bios_head;
} else {
+ heads = (xparm == -1) ? ez_head_vals : dm_head_vals;
while (drive->bios_cyl >= 1024) {
drive->bios_head = *heads;
drive->bios_cyl = tracks / drive->bios_head;
if (0 == *++heads)
break;
}
-#if FAKE_FDISK_FOR_EZDRIVE
- if (xparm == -1) {
- drive->remap_0_to_1 = 1;
- msg = "0->1";
- } else
-#endif /* FAKE_FDISK_FOR_EZDRIVE */
if (xparm == 1) {
drive->sect0 = 63;
drive->bios_cyl = (tracks - 1) / drive->bios_head;
- msg = "+63";
+ printk("[remap +63] ");
}
- printk("[remap %s] ", msg);
}
drive->part[0].nr_sects = current_capacity(drive);
printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect);
save_flags(flags);
cli();
for (index = 0; !pcibios_find_device (vendor, device, index, &bus, &fn); ++index) {
- init (bus, fn + func_adj);
+ if ((vendor == PCI_VENDOR_ID_TTI) &&
+ (device == PCI_DEVICE_ID_TTI_HPT343) && (func_adj)) {
+ unsigned short pcicmd = 0;
+
+ pcibios_read_config_word(bus, fn, PCI_COMMAND, &pcicmd);
+ if (pcicmd & PCI_COMMAND_MEMORY)
+ init (bus, fn);
+ else
+ return;
+ } else {
+ init (bus, fn + func_adj);
+ }
}
restore_flags(flags);
}
*/
#ifdef CONFIG_BLK_DEV_OFFBOARD
ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, &ide_init_triton, 0);
+ ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, &ide_init_triton, 0);
ide_probe_pci (PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, &ide_init_triton, 0);
+ ide_probe_pci (PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343, &ide_init_triton, 1);
#endif /* CONFIG_BLK_DEV_OFFBOARD */
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1);
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0);
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0);
ide_probe_pci (PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, &ide_init_triton, 0);
ide_probe_pci (PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, &ide_init_triton, 0);
+ ide_probe_pci (PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, &ide_init_triton, 0);
#ifndef CONFIG_BLK_DEV_OFFBOARD
ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, &ide_init_triton, 0);
+ ide_probe_pci (PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, &ide_init_triton, 0);
ide_probe_pci (PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, &ide_init_triton, 0);
#endif /* CONFIG_BLK_DEV_OFFBOARD */
+ ide_probe_pci (PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343, &ide_init_triton, 0);
#endif /* CONFIG_BLK_DEV_TRITON */
}
#endif /* CONFIG_PCI */
#endif
#if MAX_HWIFS > 3
case IDE3_MAJOR: rfn = &do_ide3_request; break;
+#endif
+#if MAX_HWIFS > 4
+ case IDE4_MAJOR: rfn = &do_ide4_request; break;
+#endif
+#if MAX_HWIFS > 5
+ case IDE5_MAJOR: rfn = &do_ide5_request; break;
#endif
default:
printk("%s: request_fn NOT DEFINED\n", hwif->name);
#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */
#define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */
#ifndef MAX_HWIFS
-#define MAX_HWIFS 4 /* an arbitrary, but realistic limit */
+#define MAX_HWIFS 6 /* an arbitrary, but realistic limit */
#endif
#define SECTOR_WORDS (512 / 4) /* number of 32bit words per sector */
typedef enum { ide_unknown, ide_generic, ide_triton,
ide_cmd640, ide_dtc2278, ide_ali14xx,
ide_qd6580, ide_umc8672, ide_ht6560b,
- ide_promise, ide_udma }
+ ide_promise, ide_hpt343, ide_udma,
+ ide_ultra66 }
hwif_chipset_t;
typedef struct hwif_s {
case FLOPPY_MAJOR:
case IDE2_MAJOR:
case IDE3_MAJOR:
+ case IDE4_MAJOR:
+ case IDE5_MAJOR:
/*
* The scsi disk and cdrom drivers completely remove the request
* from the queue when they start processing an entry. For this
* linux/drivers/block/triton.c Version 1.13 Aug 12, 1996
* Version 1.13a June 1998 - new chipsets
* Version 1.13b July 1998 - DMA blacklist
+ * Version 1.14 June 22, 1999
*
+ * Copyright (c) 1998-1999 Andre Hedrick
* Copyright (c) 1995-1996 Mark Lord
* May be copied or modified under the terms of the GNU General Public License
*/
#include <asm/io.h>
#include <asm/dma.h>
+#include <asm/irq.h>
#include "ide.h"
#undef DISPLAY_TRITON_TIMINGS /* define this to display timings */
#undef DISPLAY_APOLLO_TIMINGS /* define this for extensive debugging information */
+#undef DISPLAY_ALI15X3_TIMINGS /* define this for extensive debugging information */
-#if defined(CONFIG_PROC_FS) && defined(DISPLAY_APOLLO_TIMINGS)
+#if defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
+#ifdef DISPLAY_APOLLO_TIMINGS
#include <linux/via_ide_dma.h>
#endif
+#ifdef DISPLAY_ALI15X3_TIMINGS
+#include <linux/ali_ide_dma.h>
+#endif
+#endif
/*
* good_dma_drives() lists the model names (from "hdparm -i")
#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES))
#define DEFAULT_BMIBA 0xe800 /* in case BIOS did not init it */
#define DEFAULT_BMCRBA 0xcc00 /* VIA's default value */
+#define DEFAULT_BMALIBA 0xd400 /* ALI's default value */
/*
* dma_intr() is the handler for disk read/write DMA interrupts
const char **list;
struct hd_driveid *id = drive->id;
+ if (HWIF(drive)->chipset == ide_hpt343) {
+ drive->using_dma = 0; /* no DMA */
+ return 1; /* DMA disabled */
+ }
+
if (id && (id->capability & 1)) {
/* Consult the list of known "bad" drives */
list = bad_dma_drives;
return 1; /* DMA disabled */
}
}
- /* Enable DMA on any drive that has mode 2 UltraDMA enabled */
- if (id->field_valid & 4) /* UltraDMA */
- if ((id->dma_ultra & 0x404) == 0x404) {
+ /* Enable DMA on any drive that has mode 4 or 2 UltraDMA enabled */
+ if (id->field_valid & 4) { /* UltraDMA */
+ /* Enable DMA on any drive that has mode 4 UltraDMA enabled */
+ if (((id->dma_ultra & 0x1010) == 0x1010) &&
+ (id->word93 & 0x2000) &&
+ (HWIF(drive)->chipset == ide_ultra66)) {
+ drive->using_dma = 1;
+ return 0; /* DMA enabled */
+ } else
+ /* Enable DMA on any drive that has mode 2 UltraDMA enabled */
+ if ((id->dma_ultra & 0x404) == 0x404) {
drive->using_dma = 1;
return 0; /* DMA enabled */
}
+ }
/* Enable DMA on any drive that has mode2 DMA enabled */
if (id->field_valid & 2) /* regular DMA */
- if ((id->dma_mword & 0x404) == 0x404) {
+ if ((id->dma_mword & 0x404) == 0x404) {
drive->using_dma = 1;
return 0; /* DMA enabled */
}
return (0);
}
+static int setup_aladdin (byte bus, byte fn)
+{
+ byte confreg0 = 0, confreg1 = 0, progif = 0;
+ int errors = 0;
+
+ if (pcibios_read_config_byte(bus, fn, 0x50, &confreg1))
+ goto veryspecialsettingserror;
+ if (!(confreg1 & 0x02))
+ if (pcibios_write_config_byte(bus, fn, 0x50, confreg1 | 0x02))
+ goto veryspecialsettingserror;
+
+ if (pcibios_read_config_byte(bus, fn, 0x09, &progif))
+ goto veryspecialsettingserror;
+ if (!(progif & 0x40)) {
+ /*
+ * The way to enable them is to set progif
+ * writable at 0x4Dh register, and set bit 6
+ * of progif to 1:
+ */
+ if (pcibios_read_config_byte(bus, fn, 0x4d, &confreg0))
+ goto veryspecialsettingserror;
+ if (confreg0 & 0x80)
+ if (pcibios_write_config_byte(bus, fn, 0x4d, confreg0 & ~0x80))
+ goto veryspecialsettingserror;
+ if (pcibios_write_config_byte(bus, fn, 0x09, progif | 0x40))
+ goto veryspecialsettingserror;
+ if (confreg0 & 0x80)
+ if (pcibios_write_config_byte(bus, fn, 0x4d, confreg0))
+ errors++;
+ }
+
+ if ((pcibios_read_config_byte(bus, fn, 0x09, &progif)) || (!(progif & 0x40)))
+ goto veryspecialsettingserror;
+
+ printk("ide: ALI15X3: enabled read of IDE channels state (en/dis-abled) %s.\n",
+ errors ? "with Error(s)" : "Succeeded" );
+ return 1;
+veryspecialsettingserror:
+ printk("ide: ALI15X3: impossible to enable read of IDE channels state (en/dis-abled)!\n");
+ return 0;
+}
+
+void set_promise_hpt343_extra (unsigned short device, unsigned int bmiba)
+{
+ switch(device) {
+ case PCI_DEVICE_ID_PROMISE_20246:
+ if(!check_region((bmiba+16), 16))
+ request_region((bmiba+16), 16, "PDC20246");
+ break;
+ case PCI_DEVICE_ID_PROMISE_20262:
+ if (!check_region((bmiba+48), 48))
+ request_region((bmiba+48), 48, "PDC20262");
+ break;
+ case PCI_DEVICE_ID_TTI_HPT343:
+ if(!check_region((bmiba+16), 16))
+ request_region((bmiba+16), 16, "HPT343");
+ break;
+ default:
+ break;
+ }
+}
+
+#define HPT343_PCI_INIT_REG 0x80
+
/*
* ide_init_triton() prepares the IDE driver for DMA operation.
* This routine is called once, from ide.c during driver initialization,
*/
void ide_init_triton (byte bus, byte fn)
{
- int rc = 0, h;
- int dma_enabled = 0;
- unsigned short io[6], count = 0, step_count = 0;
+ byte bridgebus, bridgefn, bridgeset = 0, hpt34x_flag = 0;
+ unsigned char irq = 0;
+ int dma_enabled = 0, rc = 0, h;
+ unsigned short io[6], count = 0, step_count = 0, pass_count = 0;
unsigned short pcicmd, vendor, device, class;
unsigned int bmiba, timings, reg, tmp;
unsigned int addressbios = 0;
+ unsigned long flags;
+ unsigned index;
-#ifdef DISPLAY_APOLLO_TIMINGS
+#if defined(DISPLAY_APOLLO_TIMINGS) || defined(DISPLAY_ALI15X3_TIMINGS)
bmide_bus = bus;
bmide_fn = fn;
-#endif /* DISPLAY_APOLLO_TIMINGS */
+#endif /* DISPLAY_APOLLO_TIMINGS || DISPLAY_ALI15X3_TIMINGS */
/*
* We pick up the vendor, device, and class info for selecting the correct
pcibios_read_config_word (bus, fn, PCI_VENDOR_ID, &vendor);
pcibios_read_config_word (bus, fn, PCI_DEVICE_ID, &device);
pcibios_read_config_word (bus, fn, PCI_CLASS_DEVICE, &class);
+ pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq);
switch(vendor) {
case PCI_VENDOR_ID_INTEL:
- printk("ide: Intel 82371 (single FIFO) DMA Bus Mastering IDE ");
- break;
+ printk("ide: Intel 82371 ");
+ switch(device) {
+ case PCI_DEVICE_ID_INTEL_82371_0:
+ printk("PIIX (single FIFO) ");
+ break;
+ case PCI_DEVICE_ID_INTEL_82371SB_1:
+ printk("PIIX3 (dual FIFO) ");
+ break;
+ case PCI_DEVICE_ID_INTEL_82371AB:
+ printk("PIIX4 (dual FIFO) ");
+ break;
+ default:
+ printk(" (unknown) 0x%04x ", device);
+ break;
+ }
+ printk("DMA Bus Mastering IDE ");
+ break;
case PCI_VENDOR_ID_SI:
printk("ide: SiS 5513 (dual FIFO) DMA Bus Mastering IDE ");
break;
case PCI_VENDOR_ID_VIA:
- printk("ide: VIA VT82C586B (split FIFO) UDMA Bus Mastering IDE ");
- break;
+ printk("ide: VIA VT82C586B (split FIFO) UDMA Bus Mastering IDE ");
+ break;
+ case PCI_VENDOR_ID_TTI:
+ /*PCI_CLASS_STORAGE_UNKNOWN == class */
+ if (device == PCI_DEVICE_ID_TTI_HPT343) {
+ pcibios_write_config_byte(bus, fn, HPT343_PCI_INIT_REG, 0x00);
+ pcibios_read_config_word(bus, fn, PCI_COMMAND, &pcicmd);
+ hpt34x_flag = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
+#if 1
+ if (!hpt34x_flag) {
+ save_flags(flags);
+ cli();
+ pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd & ~PCI_COMMAND_IO);
+ pcibios_read_config_dword(bus, fn, PCI_BASE_ADDRESS_4, &bmiba);
+ pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_0, bmiba | 0x20);
+ pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_1, bmiba | 0x34);
+ pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_2, bmiba | 0x28);
+ pcibios_write_config_dword(bus, fn, PCI_BASE_ADDRESS_3, bmiba | 0x3c);
+ pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd);
+ bmiba = 0;
+ restore_flags(flags);
+ }
+#endif
+ pcibios_write_config_byte(bus, fn, PCI_LATENCY_TIMER, 0x20);
+ goto hpt343_jump_in;
+ } else {
+ printk("ide: HPTXXX did == 0x%04X unsupport chipset error.\n", device);
+ return;
+ }
case PCI_VENDOR_ID_PROMISE:
- /* PCI_CLASS_STORAGE_RAID == class */
/*
* I have been able to make my Promise Ultra33 UDMA card change class.
* It has reported as both PCI_CLASS_STORAGE_RAID and PCI_CLASS_STORAGE_IDE.
* correction if needed.
* PDC20246 (primary) PDC20247 (secondary) IDE hwif's.
*
+ * PDC20262 Promise Ultra66 UDMA.
+ *
* Note that Promise "stories,fibs,..." about this device not being
* capable of ATAPI and AT devices.
*/
- if (PCI_CLASS_STORAGE_RAID == class) {
- unsigned char irq1 = 0, irq2 = 0;
- pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq1);
- pcibios_read_config_byte (bus, fn, (PCI_INTERRUPT_LINE)|0x80, &irq2);
- if (irq1 != irq2) {
- pcibios_write_config_byte(bus, fn, (PCI_INTERRUPT_LINE)|0x80, irq1);
+ if (class != PCI_CLASS_STORAGE_IDE) {
+ unsigned char irq_mirror = 0;
+
+ pcibios_read_config_byte(bus, fn, (PCI_INTERRUPT_LINE)|0x80, &irq_mirror);
+ if (irq != irq_mirror) {
+ pcibios_write_config_byte(bus, fn, (PCI_INTERRUPT_LINE)|0x80, irq);
}
}
case PCI_VENDOR_ID_ARTOP:
* 0x6000 range. If they are setup in the 0xef00 range it is reported.
* WHY??? got me.........
*/
+hpt343_jump_in:
printk("ide: %s UDMA Bus Mastering ",
- (vendor == PCI_VENDOR_ID_ARTOP) ? "AEC6210" : "PDC20246");
+ (device == PCI_DEVICE_ID_ARTOP_ATP850UF) ? "AEC6210" :
+ (device == PCI_DEVICE_ID_PROMISE_20246) ? "PDC20246" :
+ (device == PCI_DEVICE_ID_PROMISE_20262) ? "PDC20262" :
+ (hpt34x_flag && (device == PCI_DEVICE_ID_TTI_HPT343)) ? "HPT345" :
+ (device == PCI_DEVICE_ID_TTI_HPT343) ? "HPT343" : "UNKNOWN");
pcibios_read_config_dword(bus, fn, PCI_ROM_ADDRESS, &addressbios);
if (addressbios) {
pcibios_write_config_byte(bus, fn, PCI_ROM_ADDRESS, addressbios | PCI_ROM_ADDRESS_ENABLE);
io[count++] = tmp & PCI_BASE_ADDRESS_IO_MASK;
}
break;
+ case PCI_VENDOR_ID_AL:
+ save_flags(flags);
+ cli();
+ for (index = 0; !pcibios_find_device (PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, index, &bridgebus, &bridgefn); ++index) {
+ bridgeset = setup_aladdin(bus, fn);
+ }
+ restore_flags(flags);
+ printk("ide: ALI15X3 (dual FIFO) DMA Bus Mastering IDE ");
+ break;
default:
return;
}
break;
} else {
printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
- if (inb(((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA)) != 0xff || !try_again)
+ if (inb(((vendor == PCI_VENDOR_ID_AL) ? DEFAULT_BMALIBA :
+ (vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA :
+ DEFAULT_BMIBA)) != 0xff || !try_again)
break;
- printk("ide: setting BM-DMA base register to 0x%04x\n", ((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA));
+ printk("ide: setting BM-DMA base register to 0x%04x\n",
+ ((vendor == PCI_VENDOR_ID_AL) ? DEFAULT_BMALIBA :
+ (vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA :
+ DEFAULT_BMIBA));
if ((rc = pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd&~1)))
goto quit;
- rc = pcibios_write_config_dword(bus, fn, 0x20, ((vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA : DEFAULT_BMIBA)|1);
+ rc = pcibios_write_config_dword(bus, fn, 0x20,
+ ((vendor == PCI_VENDOR_ID_AL) ? DEFAULT_BMALIBA :
+ (vendor == PCI_VENDOR_ID_VIA) ? DEFAULT_BMCRBA :
+ DEFAULT_BMIBA)|1);
if (pcibios_write_config_word(bus, fn, PCI_COMMAND, pcicmd|5) || rc)
goto quit;
}
if ((rc = pcibios_read_config_dword(bus, fn,
(vendor == PCI_VENDOR_ID_PROMISE) ? 0x50 :
(vendor == PCI_VENDOR_ID_ARTOP) ? 0x54 :
+ (vendor == PCI_VENDOR_ID_SI) ? 0x48 :
+ (vendor == PCI_VENDOR_ID_AL) ? 0x08 :
0x40, &timings)))
goto quit;
/*
- * We do a vendor check since the Ultra33 and AEC6210
+ * We do a vendor check since the Ultra33/66 and AEC6210
* holds their timings in a different location.
*/
+#if 0
printk("ide: timings == %08x\n", timings);
-
+#endif
/*
* The switch preserves some stuff that was original.
*/
goto quit;
}
break;
+ case PCI_VENDOR_ID_AL:
+ timings <<= 16;
+ timings >>= 24;
+ if (!(timings & 0x30)) {
+ printk("ide: ALI15X3: neither port is enabled\n");
+ goto quit;
+ }
+ break;
case PCI_VENDOR_ID_SI:
+ timings <<= 8;
+ timings >>= 24;
+ if (!(timings & 0x06)) {
+ printk("ide: SIS5513: neither port is enabled\n");
+ goto quit;
+ }
+ break;
case PCI_VENDOR_ID_PROMISE:
+ printk(" (U)DMA Burst Bit %sABLED " \
+ "Primary %s Mode " \
+ "Secondary %s Mode.\n",
+ (inb(bmiba + 0x001f) & 1) ? "EN" : "DIS",
+ (inb(bmiba + 0x001a) & 1) ? "MASTER" : "PCI",
+ (inb(bmiba + 0x001b) & 1) ? "MASTER" : "PCI" );
+#if 0
+ if (!(inb(bmiba + 0x001f) & 1)) {
+ outb(inb(bmiba + 0x001f)|0x01, (bmiba + 0x001f));
+ printk(" (U)DMA Burst Bit Forced %sABLED.\n",
+ (inb(bmiba + 0x001f) & 1) ? "EN" : "DIS");
+ }
+#endif
+ break;
case PCI_VENDOR_ID_ARTOP:
+ case PCI_VENDOR_ID_TTI:
default:
break;
}
*/
for (h = 0; h < MAX_HWIFS; ++h) {
ide_hwif_t *hwif = &ide_hwifs[h];
+ byte channel = ((h == 1) || (h == 3) || (h == 5)) ? 1 : 0;
/*
* This prevents the first contoller from accidentally
* initalizing the hwif's that it does not use and block
* an off-board ide-pci from getting in the game.
*/
- if (step_count >= 2) {
+ if ((step_count >= 2) || (pass_count >= 2)) {
goto quit;
}
+
+#if 0
+ if (hwif->chipset == ide_unknown)
+ printk("ide: index == %d channel(%d)\n", h, channel);
+#endif
+
#ifdef CONFIG_BLK_DEV_OFFBOARD
/*
* This is a forced override for the onboard ide controller
* for offboard UDMA upgrades with hard disks, but saving
* the onboard DMA2 controllers for CDROMS, TAPES, ZIPS, etc...
*/
- if ((vendor == PCI_VENDOR_ID_INTEL) ||
- (vendor == PCI_VENDOR_ID_SI) ||
- (vendor == PCI_VENDOR_ID_VIA)) {
- if (h == 2) {
- hwif->io_base = 0x1f0;
- hwif->ctl_port = 0x3f6;
- hwif->irq = 14;
- hwif->noprobe = 0;
- }
- if (h == 3) {
- hwif->io_base = 0x170;
- hwif->ctl_port = 0x376;
- hwif->irq = 15;
- hwif->noprobe = 0;
- }
+ if (((vendor == PCI_VENDOR_ID_INTEL) ||
+ (vendor == PCI_VENDOR_ID_SI) ||
+ (vendor == PCI_VENDOR_ID_VIA) ||
+ (vendor == PCI_VENDOR_ID_AL)) && (h >= 2)) {
+ hwif->io_base = channel ? 0x170 : 0x1f0;
+ hwif->ctl_port = channel ? 0x376 : 0x3f6;
+ hwif->irq = channel ? 15 : 14;
+ hwif->noprobe = 0;
}
#endif /* CONFIG_BLK_DEV_OFFBOARD */
/*
byte s_clks, r_clks;
unsigned short devid;
#endif /* DISPLAY_TRITON_TIMINGS */
+ pass_count++;
if (hwif->io_base == 0x1f0) {
time = timings & 0xffff;
if ((time & 0x8000) == 0) /* interface enabled? */
print_triton_drive_flags (1, (time >> 4) & 0xf);
#endif /* DISPLAY_TRITON_TIMINGS */
} else if (vendor == PCI_VENDOR_ID_SI) {
+ pass_count++;
if (hwif->io_base == 0x1f0) {
+ if ((timings & 0x02) == 0)
+ continue;
hwif->chipset = ide_triton;
if (dma_enabled)
init_triton_dma(hwif, bmiba);
step_count++;
} else if (hwif->io_base == 0x170) {
+ if ((timings & 0x04) == 0)
+ continue;
hwif->chipset = ide_triton;
if (dma_enabled)
init_triton_dma(hwif, bmiba + 8);
} else {
continue;
}
- } else if(vendor == PCI_VENDOR_ID_VIA) {
+ } else if (vendor == PCI_VENDOR_ID_VIA) {
+ pass_count++;
if (hwif->io_base == 0x1f0) {
- if((timings & 0x02) == 0)
+ if ((timings & 0x02) == 0)
continue;
hwif->chipset = ide_triton;
if (dma_enabled)
#endif /* DISPLAY_APOLLO_TIMINGS */
step_count++;
} else if (hwif->io_base == 0x170) {
- if((timings & 0x01) == 0)
+ if ((timings & 0x01) == 0)
continue;
hwif->chipset = ide_triton;
if (dma_enabled)
} else {
continue;
}
+ } else if (vendor == PCI_VENDOR_ID_AL) {
+ byte ideic, inmir;
+ byte irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6,
+ 1, 11, 0, 12, 0, 14, 0, 15 };
+
+ if (bridgeset) {
+ pcibios_read_config_byte(bridgebus, bridgefn, 0x58, &ideic);
+ ideic = ideic & 0x03;
+ if ((channel && ideic == 0x03) || (!channel && !ideic)) {
+ pcibios_read_config_byte(bridgebus, bridgefn, 0x44, &inmir);
+ inmir = inmir & 0x0f;
+ hwif->irq = irq_routing_table[inmir];
+ } else if (channel && !(ideic & 0x01)) {
+ pcibios_read_config_byte(bridgebus, bridgefn, 0x75, &inmir);
+ inmir = inmir & 0x0f;
+ hwif->irq = irq_routing_table[inmir];
+ }
+ }
+ pass_count++;
+ if (hwif->io_base == 0x1f0) {
+ if ((timings & 0x20) == 0)
+ continue;
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba);
+ outb(inb(bmiba+2) & 0x60, bmiba+2);
+ if (inb(bmiba+2) & 0x80)
+ printk("ALI15X3: simplex device: DMA forced\n");
+#ifdef DISPLAY_ALI15X3_TIMINGS
+ proc_register_dynamic(&proc_root, &ali_proc_entry);
+#endif /* DISPLAY_ALI15X3_TIMINGS */
+ step_count++;
+ } else if (hwif->io_base == 0x170) {
+ if ((timings & 0x10) == 0)
+ continue;
+ hwif->chipset = ide_triton;
+ if (dma_enabled)
+ init_triton_dma(hwif, bmiba + 8);
+ outb(inb(bmiba+10) & 0x60, bmiba+10);
+ if (inb(bmiba+10) & 0x80)
+ printk("ALI15X3: simplex device: DMA forced\n");
+ step_count++;
+ } else {
+ continue;
+ }
} else if ((vendor == PCI_VENDOR_ID_PROMISE) ||
- (vendor == PCI_VENDOR_ID_ARTOP)) {
- /*
- * This silly tmp = h routine allows an off-board ide-pci card to
- * be booted as primary hwifgroup, provided that the onboard
- * controllers are disabled. If they are active, then we wait our
- * turn for hwif assignment.
- */
- unsigned char irq = 0;
- pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &irq);
- if ((h == 0) || (h == 1)) {
- tmp = h * 2;
+ (vendor == PCI_VENDOR_ID_ARTOP) ||
+ (vendor == PCI_VENDOR_ID_TTI)) {
+ pass_count++;
+ if (vendor == PCI_VENDOR_ID_TTI) {
+ if ((!hpt34x_flag) && (h < 2)) {
+ goto quit;
+ } else if (hpt34x_flag) {
+ hwif->io_base = channel ? (bmiba + 0x28) : (bmiba + 0x20);
+ hwif->ctl_port = channel ? (bmiba + 0x3e) : (bmiba + 0x36);
+ } else {
+ goto io_temps;
+ }
} else {
- tmp = (h - 2) * 2;
+io_temps:
+ tmp = channel ? 2 : 0;
+ hwif->io_base = io[tmp];
+ hwif->ctl_port = io[tmp + 1] + 2;
}
- hwif->io_base = io[tmp];
- hwif->ctl_port = io[tmp + 1] + 2;
hwif->irq = irq;
hwif->noprobe = 0;
- if (vendor == PCI_VENDOR_ID_ARTOP) {
+ if (device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
hwif->serialized = 1;
}
+ if ((vendor == PCI_VENDOR_ID_PROMISE) ||
+ (vendor == PCI_VENDOR_ID_TTI)) {
+ set_promise_hpt343_extra(device, bmiba);
+ }
+
if (dma_enabled) {
- if (!check_region(bmiba, 8)) {
- hwif->chipset = ide_udma;
+ if ((!check_region(bmiba, 8)) && (!channel)) {
+ hwif->chipset = ((vendor == PCI_VENDOR_ID_TTI) && !hpt34x_flag) ? ide_hpt343 :
+ (device == PCI_DEVICE_ID_PROMISE_20262) ? ide_ultra66 : ide_udma;
init_triton_dma(hwif, bmiba);
step_count++;
- } else if (!check_region((bmiba + 0x08), 8)) {
- if ((vendor == PCI_VENDOR_ID_PROMISE) &&
- (!check_region(bmiba+16, 16))) {
- request_region(bmiba+16, 16, "PDC20246");
- }
- hwif->chipset = ide_udma;
+ } else if ((!check_region((bmiba + 0x08), 8)) && (channel)) {
+ hwif->chipset = ((vendor == PCI_VENDOR_ID_TTI) && !hpt34x_flag) ? ide_hpt343 :
+ (device == PCI_DEVICE_ID_PROMISE_20262) ? ide_ultra66 : ide_udma;
init_triton_dma(hwif, bmiba + 8);
step_count++;
} else {
fi
bool 'Digiboard PC/Xx Support' CONFIG_DIGI
tristate 'Cyclades async mux support' CONFIG_CYCLADES
+if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_CYCLADES" != "n" ]; then
+ bool ' Cyclades-Z interrupt mode operation (EXPERIMENTAL)' CONFIG_CYZ_INTR
+fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate 'Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m
fi
--- /dev/null
+#
+# Character device configuration
+#
+mainmenu_option next_comment
+comment 'Character devices'
+
+tristate 'Standard/generic serial support' CONFIG_SERIAL
+if [ "$CONFIG_SERIAL" != "n" ]; then
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool ' PCI serial support (EXPERIMENTAL)' CONFIG_SERIAL_PCI
+ fi
+fi
+bool 'Digiboard PC/Xx Support' CONFIG_DIGI
+tristate 'Cyclades async mux support' CONFIG_CYCLADES
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ dep_tristate 'Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m
+fi
+bool 'Stallion multiport serial support' CONFIG_STALDRV
+if [ "$CONFIG_STALDRV" = "y" ]; then
+ tristate ' Stallion EasyIO or EC8/32 support' CONFIG_STALLION
+ tristate ' Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION
+fi
+tristate 'SDL RISCom/8 card support' CONFIG_RISCOM8
+tristate 'Parallel printer support' CONFIG_PRINTER
+tristate 'Specialix IO8+ card support' CONFIG_SPECIALIX
+if [ "$CONFIG_SPECIALIX" = "y" -o "$CONFIG_SPECIALIX" = "m" ]; then
+ bool ' Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS
+fi
+
+
+bool 'Mouse Support (not serial mice)' CONFIG_MOUSE
+if [ "$CONFIG_MOUSE" = "y" ]; then
+ tristate ' ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE
+ tristate ' Logitech busmouse support' CONFIG_BUSMOUSE
+ tristate ' Microsoft busmouse support' CONFIG_MS_BUSMOUSE
+ tristate ' PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+ if [ "$CONFIG_PSMOUSE" != "n" ]; then
+ bool ' C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
+ fi
+fi
+
+bool 'Support for user misc device modules' CONFIG_UMISC
+
+bool 'QIC-02 tape support' CONFIG_QIC02_TAPE
+if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
+ bool ' Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF
+ if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
+ comment 'Edit configuration parameters in ./include/linux/tpqic02.h!'
+ else
+ comment 'Setting runtime QIC-02 configuration is done with qic02conf'
+ comment 'from the tpqic02-support package. It is available at'
+ comment 'ftp://titus.cfw.com/pub/Linux/util/'
+ fi
+fi
+
+tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE
+if [ "$CONFIG_FTAPE" != "n" ]; then
+ comment 'Set IObase/IRQ/DMA for ftape in ./drivers/char/ftape/Makefile'
+fi
+
+if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then
+ bool 'Tadpole ANA H8 Support' CONFIG_H8
+fi
+bool 'Watchdog Timer Support' CONFIG_WATCHDOG
+if [ "$CONFIG_WATCHDOG" != "n" ]; then
+ bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
+ tristate ' WDT Watchdog timer' CONFIG_WDT
+ if [ "$CONFIG_WDT" != "n" ]; then
+ bool ' WDT501 features' CONFIG_WDT_501
+ if [ "$CONFIG_WDT_501" = "y" ]; then
+ bool ' Fan Tachometer' CONFIG_WDT_501_FAN
+ fi
+ fi
+ tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG
+ tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
+fi
+bool 'Enhanced Real Time Clock Support' CONFIG_RTC
+endmenu
#define BLOCKMOVE
#define Z_WAKE
static char rcsid[] =
-"$Revision: 2.1.2.1 $$Date: 1999/04/08 16:17:18 $";
+"$Revision: 2.1.2.4 $$Date: 1999/07/12 18:00:24 $";
/*
* linux/drivers/char/cyclades.c
* extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
* and then fixed as suggested by Michael K. Johnson 12/12/92.
*
- * This version does not support shared irq's.
+ * This version supports shared IRQ's (only for PCI boards).
*
* This module exports the following rs232 io functions:
* int cy_init(void);
* void cleanup_module(void);
*
* $Log: cyclades.c,v $
+ * Revision 2.1.2.4 1999/07/12 18:00:24 ivan
+ * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control
+ * switching from working properly;
+ * The driver now only prints IRQ info for the Cyclades-Z if it's
+ * configured to work in interrupt mode;
+ *
+ * Revision 2.1.2.3 1999/06/28 11:05:57 ivan
+ * Added support for interrupt mode operation for the Z cards;
+ * Removed the driver inactivity control for the Z;
+ * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when
+ * the Z firmware is not loaded yet;
+ * Replaced the "manual" Z Tx flush buffer by a call to a FW command of
+ * same functionality;
+ * Implemented workaround for IRQ setting loss on the PCI configuration
+ * registers after a PCI bridge EEPROM reload (affects PLX9060 only);
+ *
+ * Revision 2.1.2.2 1999/05/21 17:18:05 ivan
+ * Added support to shared IRQ's (only for PCI boards);
+ * Added support for Cobalt Qube2 systems;
+ * IRQ [de]allocation scheme revisited;
+ * Included a PCI bridge reset and EEPROM reload in the board
+ * initialization code (for both Y and Z series).
+ *
* Revision 2.1.2.1 1999/04/08 16:17:18 ivan
* cy_wait_until_sent function revisited;
* Module usage counter scheme revisited;
constant in the definition below. No other change is necessary to
support more boards/ports. */
-#define NR_PORTS 128
+#define NR_PORTS 256
#define ZE_V1_NPORTS 64
#define ZO_V1 0
#include <linux/proc_fs.h>
#endif
+#ifdef CONFIG_COBALT_27
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#define CACHED_TO_UNCACHED(x) (((unsigned long)(x) & \
+ (unsigned long)0x1fffffff) + KSEG1)
+#endif
+
#define __initfunc(__arginit) __arginit
#define copy_from_user memcpy_fromfs
#define copy_to_user memcpy_tofs
struct tty_driver cy_serial_driver, cy_callout_driver;
+#ifndef CONFIG_COBALT_27
static volatile int cy_irq_triggered;
static volatile int cy_triggered;
static int cy_wild_int_mask;
};
#define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
+#endif /* CONFIG_COBALT_27 */
+
/* This is the per-card data structure containing address, irq, number of
channels, etc. This driver supports a maximum of NR_CARDS cards.
*/
static struct termios *serial_termios[NR_PORTS];
static struct termios *serial_termios_locked[NR_PORTS];
-/* This is the per-irq data structure,
- it maps an irq to the corresponding card */
-
-static struct cyclades_card *IRQ_cards[16];
-
-
/*
* tmp_buf is used as a temporary buffer by serial_write. We need to
* lock it in case the copy_from_user blocks while swapping in a page,
static void cy_start(struct tty_struct *);
static void set_line_char(struct cyclades_port *);
+#ifndef CONFIG_COBALT_27
static void cy_probe(int, void *, struct pt_regs *);
-static void cyz_poll(unsigned long);
+#endif /* CONFIG_COBALT_27 */
#ifdef CY_SHOW_STATUS
static void show_status(int);
#endif
};
#endif
+#ifndef CONFIG_CYZ_INTR
+static void cyz_poll(unsigned long);
+
/* The Cyclades-Z polling cycle is defined by this variable */
static long cyz_polling_cycle = CZ_DEF_POLL;
cyz_timerlist = {
NULL, NULL, 0, 0, cyz_poll
};
+#endif /* CONFIG_CYZ_INTR */
/**************************************************
error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
return 0;
} /* serial_paranoia_check */
-
+#ifndef CONFIG_COBALT_27
/* The following diagnostic routines allow the driver to spew
information on the screen, even (especially!) during interrupts.
*/
static void CP32(long data)
{ CP16((data>>16) & 0xffff); CP16(data & 0xffff); }/* CP32 */
#endif
-
+#endif /* CONFIG_COBALT_27 */
/*
* This routine is used by the interrupt handler to schedule
return(0);
} /* cyy_issue_cmd */
+#ifndef CONFIG_COBALT_27 /* ISA interrupt detection code */
+
static int probe_ready;
/*
return;
} /* cy_probe */
+#endif /* CONFIG_COBALT_27 */
+
/* The real interrupt service routine is called
whenever the card wants its hand held--chars
received, out buffer empty, modem change, etc.
int mdm_change;
int mdm_status;
- if((cinfo = IRQ_cards[irq]) == 0){
+ if((cinfo = (struct cyclades_card *)dev_id) == 0){
#ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: spurious interrupt %d\n\r", irq);
+ printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
#endif
return; /* spurious interrupt */
}
}
if (status & CySRReceive) { /* reception interrupt */
#ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: rcvd intr, chip %d\n\r", chip);
+ printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
#endif
/* determine the channel & change to that context */
save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
TTY_OVERRUN;
*tty->flip.char_buf_ptr++ = 0;
/* If the flip buffer itself is
- overflowing, we still loose
+ overflowing, we still lose
the next incoming character.
*/
if(tty->flip.count
is empty, we know we can always stuff a dozen
characters. */
#ifdef CY_DEBUG_INTERRUPTS
-printk("cy_interrupt: xmit intr, chip %d\n\r", chip);
+ printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
#endif
/* determine the channel & change to that context */
} /* cyz_update_channel */
#endif
-
+#ifdef CONFIG_CYZ_INTR
static void
cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+ struct tty_struct *tty;
+ struct cyclades_card *cinfo;
+ struct cyclades_port *info;
+ static volatile struct FIRM_ID *firm_id;
+ static volatile struct ZFW_CTRL *zfw_ctrl;
+ static volatile struct BOARD_CTRL *board_ctrl;
+ static volatile struct CH_CTRL *ch_ctrl;
+ static volatile struct BUF_CTRL *buf_ctrl;
+ uclong channel;
+ ucchar cmd;
+ uclong param;
+ uclong hw_ver, fw_ver;
+ char data;
+ volatile int char_count, special_count;
+#ifdef BLOCKMOVE
+ int small_count;
+#endif
+ volatile uclong tx_put, tx_get, tx_bufsize;
+ volatile uclong rx_put, rx_get, rx_bufsize;
+
+ if((cinfo = (struct cyclades_card *)dev_id) == 0){
+#ifdef CY_DEBUG_INTERRUPTS
+ printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
+#endif
+ return; /* spurious interrupt */
+ }
+
+ firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
+ if (!ISZLOADED(*cinfo)) {
+#ifdef CY_DEBUG_INTERRUPTS
+ printk("cyz_interrupt: board not yet loaded (INT %d).\n\r", irq);
+#endif
+ return;
+ }
+
+ zfw_ctrl = (struct ZFW_CTRL *)
+ (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ board_ctrl = &(zfw_ctrl->board_ctrl);
+ fw_ver = cy_readl(&board_ctrl->fw_version);
+ hw_ver = cy_readl(&((struct RUNTIME_9060 *)
+ (cinfo->ctl_addr))->mail_box_0);
+
+ while(cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) {
+ special_count = 0;
+ info = &cy_port[channel + cinfo->first_line];
+ if((tty = info->tty) == 0) continue;
+ ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
+ buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
+
+ switch(cmd){
+ case C_CM_PR_ERROR:
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+ *tty->flip.char_buf_ptr++ = 0;
+ special_count++;
+ break;
+ case C_CM_FR_ERROR:
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+ *tty->flip.char_buf_ptr++ = 0;
+ special_count++;
+ break;
+ case C_CM_RXBRK:
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+ *tty->flip.char_buf_ptr++ = 0;
+ special_count++;
+ break;
+ case C_CM_MDCD:
+ if (info->flags & ASYNC_CHECK_CD){
+ if ((fw_ver > 241 ?
+ ((u_long)param) :
+ cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
+ /* SP("Open Wakeup\n"); */
+ cy_sched_event(info,
+ Cy_EVENT_OPEN_WAKEUP);
+ }else if(!((info->flags
+ & ASYNC_CALLOUT_ACTIVE)
+ &&(info->flags
+ & ASYNC_CALLOUT_NOHUP))){
+ /* SP("Hangup\n"); */
+ cy_sched_event(info,
+ Cy_EVENT_HANGUP);
+ }
+ }
+ break;
+ case C_CM_MCTS:
+ if (info->flags & ASYNC_CTS_FLOW) {
+ if(info->tty->hw_stopped){
+ if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
+ /* cy_start isn't used because...
+ HW flow is handled by the board */
+ /* SP("Write Wakeup\n"); */
+ cy_sched_event(info,
+ Cy_EVENT_WRITE_WAKEUP);
+ }
+ }else{
+ if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
+ /* cy_stop isn't used because
+ HW flow is handled by the board */
+ /* SP("Write stop\n"); */
+ }
+ }
+ }
+ break;
+ case C_CM_MRI:
+ break;
+ case C_CM_MDSR:
+ break;
+#ifdef Z_WAKE
+ case C_CM_IOCTLW:
+ cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+ break;
+#endif
+ case C_CM_RXHIWM:
+ case C_CM_RXNNDT:
+ /* Reception Interrupt */
+#ifdef CY_DEBUG_INTERRUPTS
+ printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r",
+ info->card, channel);
+#endif
+
+ rx_get = cy_readl(&buf_ctrl->rx_get);
+ rx_put = cy_readl(&buf_ctrl->rx_put);
+ rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
+ if (rx_put >= rx_get)
+ char_count = rx_put - rx_get;
+ else
+ char_count = rx_put - rx_get + rx_bufsize;
+
+ if ( char_count ){
+
+#ifdef CY_ENABLE_MONITORING
+ info->mon.int_count++;
+ info->mon.char_count += char_count;
+ if (char_count > info->mon.char_max)
+ info->mon.char_max = char_count;
+ info->mon.char_last = char_count;
+#endif
+ info->idle_stats.recv_bytes += char_count;
+ info->idle_stats.recv_idle = jiffies;
+ if( tty == 0){
+ /* flush received characters */
+ rx_get = (rx_get + char_count) & (rx_bufsize - 1);
+ /* SP("-"); */
+ info->rflush_count++;
+ }else{
+#ifdef BLOCKMOVE
+ /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
+ for performance, but because of buffer boundaries, there
+ may be several steps to the operation */
+ while(0 < (small_count
+ = cy_min((rx_bufsize - rx_get),
+ cy_min((TTY_FLIPBUF_SIZE - tty->flip.count),
+ char_count)))){
+
+ memcpy_fromio(tty->flip.char_buf_ptr,
+ (char *)(cinfo->base_addr
+ + cy_readl(&buf_ctrl->rx_bufaddr)
+ + rx_get),
+ small_count);
+
+ tty->flip.char_buf_ptr += small_count;
+ memset(tty->flip.flag_buf_ptr,
+ TTY_NORMAL,
+ small_count);
+ tty->flip.flag_buf_ptr += small_count;
+ rx_get = (rx_get + small_count) & (rx_bufsize - 1);
+ char_count -= small_count;
+ tty->flip.count += small_count;
+ }
+#else
+ while(char_count--){
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE){
+ break;
+ }
+ data = cy_readb(cinfo->base_addr +
+ cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
+ rx_get = (rx_get + 1) & (rx_bufsize - 1);
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+ *tty->flip.char_buf_ptr++ = data;
+ }
+#endif
+ queue_task(&tty->flip.tqueue, &tq_timer);
+ }
+ /* Update rx_get */
+ cy_writel(&buf_ctrl->rx_get, rx_get);
+ }
+ break;
+ case C_CM_TXBEMPTY:
+ case C_CM_TXLOWWM:
+ case C_CM_INTBACK:
+ /* Transmission Interrupt */
+#ifdef CY_DEBUG_INTERRUPTS
+ printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r",
+ info->card, channel);
+#endif
+
+ tx_get = cy_readl(&buf_ctrl->tx_get);
+ tx_put = cy_readl(&buf_ctrl->tx_put);
+ tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
+ if (tx_put >= tx_get)
+ char_count = tx_get - tx_put - 1 + tx_bufsize;
+ else
+ char_count = tx_get - tx_put - 1;
+
+ if ( char_count ){
+
+ if( tty == 0 ){
+ goto ztxdone;
+ }
+
+ if(info->x_char) { /* send special char */
+ data = info->x_char;
+
+ cy_writeb((cinfo->base_addr +
+ cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
+ tx_put = (tx_put + 1) & (tx_bufsize - 1);
+ info->x_char = 0;
+ char_count--;
+ }
+#ifdef BLOCKMOVE
+ while(0 < (small_count
+ = cy_min((tx_bufsize - tx_put),
+ cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
+ cy_min(info->xmit_cnt, char_count))))){
+
+ memcpy_toio((char *)(cinfo->base_addr
+ + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
+ &info->xmit_buf[info->xmit_tail],
+ small_count);
+
+ tx_put = (tx_put + small_count) & (tx_bufsize - 1);
+ char_count -= small_count;
+ info->xmit_cnt -= small_count;
+ info->xmit_tail =
+ (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
+ }
+#else
+ while (info->xmit_cnt && char_count){
+ data = info->xmit_buf[info->xmit_tail];
+ info->xmit_cnt--;
+ info->xmit_tail =
+ (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
+
+ cy_writeb(cinfo->base_addr +
+ cy_readl(&buf_ctrl->tx_bufaddr) + tx_put,
+ data);
+ tx_put = (tx_put + 1) & (tx_bufsize - 1);
+ char_count--;
+ }
+
+#endif
+ ztxdone:
+ if (info->xmit_cnt < WAKEUP_CHARS) {
+ cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+ }
+ /* Update tx_put */
+ cy_writel(&buf_ctrl->tx_put, tx_put);
+ }
+ break;
+ case C_CM_FATAL:
+ /* should do something with this !!! */
+ break;
+ }
+ if(special_count){
+ queue_task(&tty->flip.tqueue, &tq_timer);
+ }
+ }
+
+ return;
} /* cyz_interrupt */
+#else /* CONFIG_CYZ_INTR */
static void
cyz_poll(unsigned long arg)
firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
if (!ISZLOADED(*cinfo)) {
- cinfo->inact_ctrl = 0;
continue;
}
hw_ver = cy_readl(&((struct RUNTIME_9060 *)
(cinfo->ctl_addr))->mail_box_0);
- /* Enables the firmware inactivity control */
- if ((fw_ver > 0x00000310L) && (!cinfo->inact_ctrl)) {
- param = cyz_issue_cmd( &cy_card[card], 0L, C_CM_TINACT, 0L);
- cinfo->inact_ctrl = 1;
- }
-
while(cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1){
char_count = 0;
info = &cy_port[ channel + cinfo->first_line ];
}
/* poll every 40 ms */
cyz_timerlist.expires = jiffies + cyz_polling_cycle;
-
- /* refresh inactivity counter */
- if (cinfo->inact_ctrl) {
- cy_writel(&board_ctrl->inactivity, (uclong) ZF_TINACT);
- }
}
add_timer(&cyz_timerlist);
return;
} /* cyz_poll */
+#endif /* CONFIG_CYZ_INTR */
/********** End of block of Cyclades-Z specific code *********/
/***********************************************************/
cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
#ifdef Z_WAKE
- cy_writel(&ch_ctrl[channel].intr_enable,
- C_IN_MDCD|C_IN_MCTS|C_IN_IOCTLW);
+#ifdef CONFIG_CYZ_INTR
+ cy_writel(&ch_ctrl[channel].intr_enable,
+ C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
+ C_IN_IOCTLW|
+ C_IN_MDCD|C_IN_MCTS);
#else
- cy_writel(&ch_ctrl[channel].intr_enable,
+ cy_writel(&ch_ctrl[channel].intr_enable,
+ C_IN_IOCTLW|
C_IN_MDCD|C_IN_MCTS);
-#endif
+#endif /* CONFIG_CYZ_INTR */
+#else
+#ifdef CONFIG_CYZ_INTR
+ cy_writel(&ch_ctrl[channel].intr_enable,
+ C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
+ C_IN_MDCD|C_IN_MCTS);
+#else
+ cy_writel(&ch_ctrl[channel].intr_enable,
+ C_IN_MDCD|C_IN_MCTS);
+#endif /* CONFIG_CYZ_INTR */
+#endif /* Z_WAKE */
+
retval = cyz_issue_cmd( &cy_card[card],
channel, C_CM_IOCTL, 0L); /* was C_CM_RESET */
if (retval != 0){
cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
restore_flags(flags);
} else {
+#ifdef CONFIG_CYZ_INTR
+ int retval;
+
+ save_flags(flags); cli();
+ retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 0L);
+ if (retval != 0){
+ printk("cyc:start_xmit retval was %x\n", retval);
+ }
+ restore_flags(flags);
+#else /* CONFIG_CYZ_INTR */
/* Don't have to do anything at this time */
+#endif /* CONFIG_CYZ_INTR */
}
} /* start_xmit */
-
/*
* This routine shuts down a serial port; interrupts are disabled,
* and DTR is dropped if the hangup on close termio flag is on.
} else {
printk("Cyclades-Z firmware not yet loaded\n");
}
+ MOD_DEC_USE_COUNT;
return -ENODEV;
}
+#ifdef CONFIG_CYZ_INTR
+ else {
+ /* In case this Z board is operating in interrupt mode, its
+ interrupts should be enabled as soon as the first open happens
+ to one of its ports. */
+ if (!cy_card[info->card].intr_enabled) {
+ retval = cyz_issue_cmd(&cy_card[info->card],
+ 0, C_CM_IRQ_ENBL, 0L);
+ if (retval != 0){
+ printk("cyc:IRQ enable retval was %x\n", retval);
+ }
+ cy_card[info->card].intr_enabled = 1;
+ }
+ }
+#endif /* CONFIG_CYZ_INTR */
}
#ifdef CY_DEBUG_OTHER
printk("cyc:cy_open ttyC%d\n", info->line); /* */
case CYGETCD1400VER:
ret_val = info->chip_rev;
break;
+#ifndef CONFIG_CYZ_INTR
case CYZSETPOLLCYCLE:
cyz_polling_cycle = (arg * HZ) / 1000;
ret_val = 0;
case CYZGETPOLLCYCLE:
ret_val = (cyz_polling_cycle * 1000) / HZ;
break;
+#endif /* CONFIG_CYZ_INTR */
case CYSETWAIT:
info->closing_wait = (unsigned short)arg * HZ/100;
ret_val = 0;
printk("cyc:cy_set_termios ttyC%d\n", info->line);
#endif
- if (tty->termios->c_cflag == old_termios->c_cflag)
+ if ((tty->termios->c_cflag == old_termios->c_cflag) &&
+ ((tty->termios->c_iflag & IXON) == (old_termios->c_iflag & IXON)))
return;
set_line_char(info);
return;
} /* cy_set_termios */
-
-/*
- * void (*set_ldisc)(struct tty_struct *tty);
- *
- * This routine allows the tty driver to be notified when the
- * device's termios settings have changed.
- *
- */
-
-
/* This routine is called by the upper-layer tty layer to signal
that incoming characters should be throttled because the input
buffers are close to full.
cy_flush_buffer(struct tty_struct *tty)
{
struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, channel;
+ int card, channel, retval;
unsigned long flags;
#ifdef CY_DEBUG_IO
if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board
buffers as well */
- static volatile struct FIRM_ID *firm_id;
- static volatile struct ZFW_CTRL *zfw_ctrl;
- static volatile struct CH_CTRL *ch_ctrl;
- static volatile struct BUF_CTRL *buf_ctrl;
-
- firm_id = (struct FIRM_ID *)(cy_card[card].base_addr + ID_ADDRESS);
- zfw_ctrl = (struct ZFW_CTRL *) (cy_card[card].base_addr +
- cy_readl(&firm_id->zfwctrl_addr));
- ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
- buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-
- while (cy_readl(&buf_ctrl->tx_get) != cy_readl(&buf_ctrl->tx_put))
- cy_writel(&buf_ctrl->tx_put, cy_readl(&buf_ctrl->tx_get));
+ retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
+ if (retval != 0) {
+ printk("cyc: flush_buffer retval was %x\n", retval);
+ }
}
wake_up_interruptible(&tty->write_wait);
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
return chip_number;
} /* cyy_init_card */
+#ifndef CONFIG_COBALT_27
/*
* ---------------------------------------------------------------------
* cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
/* allocate IRQ */
if(request_irq(cy_isa_irq, cyy_interrupt,
- SA_INTERRUPT, "cyclomY", NULL))
+ SA_INTERRUPT, "Cyclom-Y", &cy_card[j]))
{
printk("Cyclom-Y/ISA found at 0x%lx ",
(unsigned long) cy_isa_address);
cy_card[j].bus_index = 0;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = cy_isa_nchan/4;
- IRQ_cards[cy_isa_irq] = &cy_card[j];
nboard++;
/* print message */
return(nboard);
} /* cy_detect_isa */
+#endif /* CONFIG_COBALT_27 */
+
+static void plx_init(uclong addr, uclong initctl)
+{
+ /* Reset PLX */
+ cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
+ udelay(100L);
+ cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
+
+ /* Reload Config. Registers from EEPROM */
+ cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
+ udelay(100L);
+ cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
+}
/*
* ---------------------------------------------------------------------
cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
+ if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
+ printk(" Warning: PCI I/O bit incorrectly set. "
+ "Ignoring it...\n");
+ cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+ }
+
#if defined(__alpha__)
if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0 & PAGE_MASK,
PAGE_ALIGN(CyPCI_Yctl))
+ (cy_pci_addr0 & (PAGE_SIZE-1));
+#ifndef CONFIG_COBALT_27
if ((ulong)cy_pci_addr2 >= 0x100000) /* above 1M? */
+#endif /* CONFIG_COBALT_27 */
cy_pci_addr2 = (ulong) ioremap(cy_pci_addr2, CyPCI_Ywin);
#endif
/* allocate IRQ */
if(request_irq(cy_pci_irq, cyy_interrupt,
- SA_INTERRUPT, "cyclomY", NULL))
+ SA_SHIRQ, "Cyclom-Y", &cy_card[j]))
{
printk("Cyclom-Y/PCI found at 0x%lx ",
(ulong) cy_pci_addr2);
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = cy_pci_nchan/4;
- IRQ_cards[cy_pci_irq] = &cy_card[j];
/* enable interrupts in the PCI interface */
plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
switch (plx_ver) {
case PLX_9050:
+ plx_init(cy_pci_addr0, 0x50);
+
cy_writew(cy_pci_addr0+0x4c,
cy_readw(cy_pci_addr0+0x4c)|0x0040);
break;
case PLX_9080:
default: /* Old boards, use PLX_9060 */
+ plx_init(cy_pci_addr0, 0x6c);
+ /* For some yet unknown reason, once the PLX9060 reloads
+ the EEPROM, the IRQ is lost and, thus, we have to
+ re-write it to the PCI config. registers.
+ This will remain here until we find a permanent fix. */
+ pcibios_write_config_byte(cyy_bus, cyy_dev_fn,
+ PCI_INTERRUPT_LINE, cy_pci_irq);
+
cy_writew(cy_pci_addr0+0x68,
cy_readw(cy_pci_addr0+0x68)|0x0900);
break;
(ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
#endif
cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
+
#if !defined(__alpha__)
cy_pci_addr0 = (unsigned int) ioremap(
cy_pci_addr0 & PAGE_MASK,
PAGE_ALIGN(CyPCI_Zctl))
+ (cy_pci_addr0 & (PAGE_SIZE-1));
#endif
+
+ plx_init(cy_pci_addr0, 0x6c);
+ /* For some yet unknown reason, once the PLX9060 reloads
+ the EEPROM, the IRQ is lost and, thus, we have to
+ re-write it to the PCI config. registers.
+ This will remain here until we find a permanent fix. */
+ pcibios_write_config_byte(cyy_bus, cyy_dev_fn,
+ PCI_INTERRUPT_LINE, cy_pci_irq);
+
mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
cy_pci_addr0)->mail_box_0);
cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
+
+ if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
+ printk(" Warning: PCI I/O bit incorrectly set. "
+ "Ignoring it...\n");
+ cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+ }
if (mailbox == ZE_V1) {
#if !defined(__alpha__)
cy_pci_addr2 = (unsigned int) ioremap(
return(i);
}
+#ifdef CONFIG_CYZ_INTR
/* allocate IRQ only if board has an IRQ */
- if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
- if(request_irq(cy_pci_irq,cyz_interrupt,
- SA_INTERRUPT,"cyclomZ",NULL))
+ if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
+ if(request_irq(cy_pci_irq, cyz_interrupt,
+ SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
{
printk("Could not allocate IRQ%d ",
cy_pci_irq);
return(i);
}
}
+#endif /* CONFIG_CYZ_INTR */
/* set cy_card */
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = -1;
- IRQ_cards[cy_pci_irq] = &cy_card[j];
/* print message */
+#ifdef CONFIG_CYZ_INTR
/* don't report IRQ if board is no IRQ */
- if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
+ if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
j+1,(ulong)cy_pci_addr2,
(ulong)(cy_pci_addr2 + CyPCI_Zwin - 1),
(int)cy_pci_irq);
- }else{
+ else
+#endif /* CONFIG_CYZ_INTR */
printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
j+1,(ulong)cy_pci_addr2,
(ulong)(cy_pci_addr2 + CyPCI_Zwin - 1));
- }
+
printk("%d channels starting from port %d.\n",
cy_pci_nchan,cy_next_channel);
+#ifdef CONFIG_CYZ_INTR
+ /* Enable interrupts on the PLX chip */
+ cy_writew(cy_pci_addr0+0x68,
+ cy_readw(cy_pci_addr0+0x68)|0x0900);
+#endif /* CONFIG_CYZ_INTR */
cy_next_channel += cy_pci_nchan;
}
}
(ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n");
#endif
- /* The following clears the firmware id word. This ensures
- that the driver will not attempt to talk to the board
- until it has been properly initialized.
- */
PAUSE
/* This must be the new Cyclades-Ze/PCI. */
cy_pci_nchan = ZE_V1_NPORTS;
return(i);
}
+#ifdef CONFIG_CYZ_INTR
/* allocate IRQ only if board has an IRQ */
- if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
- if(request_irq(cy_pci_irq,cyz_interrupt,
- SA_INTERRUPT,"cyclomZ",NULL))
+ if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
+ if(request_irq(cy_pci_irq, cyz_interrupt,
+ SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
{
printk("Could not allocate IRQ%d ",
cy_pci_irq);
return(i);
}
}
+#endif /* CONFIG_CYZ_INTR */
/* set cy_card */
cy_card[j].base_addr = cy_pci_addr2;
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = -1;
- IRQ_cards[cy_pci_irq] = &cy_card[j];
/* print message */
+#ifdef CONFIG_CYZ_INTR
/* don't report IRQ if board is no IRQ */
- if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
+ if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
j+1,(ulong)cy_pci_addr2,
(ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1),
(int)cy_pci_irq);
- }else{
+ else
+#endif /* CONFIG_CYZ_INTR */
printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
j+1,(ulong)cy_pci_addr2,
(ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1));
- }
+
printk("%d channels starting from port %d.\n",
cy_pci_nchan,cy_next_channel);
+#ifdef CONFIG_CYZ_INTR
+ /* Enable interrupts on the PLX chip */
+ cy_writew(cy_pci_addr0+0x68,
+ cy_readw(cy_pci_addr0+0x68)|0x0900);
+#endif /* CONFIG_CYZ_INTR */
cy_next_channel += cy_pci_nchan;
}
if (ZeIndex != 0) {
init_bh(CYCLADES_BH, do_cyclades_bh);
- for (i = 0; i < 16; i++) {
- IRQ_cards[i] = 0;
- }
-
for (i = 0; i < NR_CARDS; i++) {
/* base_addr=0 indicates board not found */
cy_card[i].base_addr = 0;
availability of cy_card and cy_port data structures and updating
the cy_next_channel. */
+#ifndef CONFIG_COBALT_27
/* look for isa boards */
cy_isa_nboard = cy_detect_isa();
+#endif /* CONFIG_COBALT_27 */
/* look for pci boards */
cy_pci_nboard = cy_detect_pci();
mailbox = cy_readl(&((struct RUNTIME_9060 *)
cy_card[board].ctl_addr)->mail_box_0);
nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
+ cinfo->intr_enabled = 0;
for (port = cinfo->first_line ;
port < cinfo->first_line + nports;
port++)
}
}
}
-
- if ( number_z_boards && !cyz_timeron){
- cyz_timeron++;
+
+#ifndef CONFIG_CYZ_INTR
+ if (number_z_boards && !cyz_timeron){
+ cyz_timeron++;
cyz_timerlist.expires = jiffies + 1;
add_timer(&cyz_timerlist);
#ifdef CY_PCI_DEBUG
printk("Cyclades-Z polling initialized\n");
#endif
}
+#endif /* CONFIG_CYZ_INTR */
#if defined(CONFIG_PROC_FS) && !defined(MODULE)
proc_register_dynamic(&proc_root, &cyclades_proc_entry);
int i;
unsigned long flags;
+#ifndef CONFIG_CYZ_INTR
if (cyz_timeron){
cyz_timeron = 0;
del_timer(&cyz_timerlist);
}
+#endif /* CONFIG_CYZ_INTR */
save_flags(flags); cli();
for (i = 0; i < NR_CARDS; i++) {
if (cy_card[i].base_addr != 0
+#ifndef CONFIG_CYZ_INTR
+ && cy_card[i].num_chips != -1 /* not a Z card */
+#endif /* CONFIG_CYZ_INTR */
&& cy_card[i].irq)
{
- free_irq(cy_card[i].irq,NULL);
+ free_irq(cy_card[i].irq, &cy_card[i]);
}
}
} /* cleanup_module */
void
cy_setup(char *str, int *ints)
{
+#ifndef CONFIG_COBALT_27
int i, j;
for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
cy_isa_addresses[i++] = (unsigned char *)(ints[j]);
}
}
+#endif /* CONFIG_COBALT_27 */
} /* cy_setup */
#endif
if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
bool ' 3COM ISA, EISA and PCI cards' CONFIG_NET_VENDOR_3COM
if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
- tristate ' 3c501 support' CONFIG_EL1
- tristate ' 3c503 support' CONFIG_EL2
+ tristate ' 3c501 "EtherLink" support' CONFIG_EL1
+ tristate ' 3c503 "EtherLink II" support' CONFIG_EL2
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate ' 3c505 (EXPERIMENTAL) support' CONFIG_ELPLUS
- tristate ' 3c507 (EXPERIMENTAL) support' CONFIG_EL16
+ tristate ' 3c505 "EtherLink Plus" (EXPERIMENTAL) support' CONFIG_ELPLUS
+ tristate ' 3c507 "EtherLink 16" (EXPERIMENTAL) support' CONFIG_EL16
fi
- tristate ' 3c509/3c579 support' CONFIG_EL3
- tristate ' 3c515 ISA Fast EtherLink' CONFIG_3C515
+ tristate ' 3c509/3c579 "EtherLink III" support' CONFIG_EL3
+ tristate ' 3c515 ISA "Fast EtherLink"' CONFIG_3C515
tristate ' 3c590/3c900 series (592/595/597/900/905) "Vortex/Boomerang" support' CONFIG_VORTEX
fi
bool ' Western Digital/SMC ISA and EISA cards' CONFIG_NET_VENDOR_SMC
DEVICE( MOTOROLA, MOTOROLA_MPC106,"MPC106 Grackle"),
DEVICE( MOTOROLA, MOTOROLA_RAVEN, "Raven"),
DEVICE( PROMISE, PROMISE_20246, "IDE UltraDMA/33"),
+ DEVICE( PROMISE, PROMISE_20262, "IDE UltraDMA/66"),
DEVICE( PROMISE, PROMISE_5300, "DC5030"),
DEVICE( N9, N9_I128, "Imagine 128"),
DEVICE( N9, N9_I128_2, "Imagine 128v2"),
DEVICE( WINBOND, WINBOND_82C105, "SL82C105"),
DEVICE( WINBOND, WINBOND_83C553, "W83C553"),
DEVICE( DATABOOK, DATABOOK_87144, "DB87144"),
- DEVICE( PLX, PLX_SPCOM200, "SPCom 200 PCI serial I/O"),
- DEVICE( PLX, PLX_9050, "PLX9050 PCI <-> IOBus Bridge"),
+ DEVICE( PLX, PLX_SPCOM200, "SPCom 200 PCI serial I/O"),
+ DEVICE( PLX, PLX_9050, "PLX9050 PCI <-> IOBus Bridge"),
DEVICE( PLX, PLX_9080, "PCI9080 I2O"),
DEVICE( MADGE, MADGE_MK2, "Smart 16/4 BM Mk2 Ringnode"),
DEVICE( 3COM, 3COM_3C339, "3C339 TokenRing"),
DEVICE( AL, AL_M1523, "M1523"),
DEVICE( AL, AL_M1531, "M1531 Aladdin IV"),
DEVICE( AL, AL_M1533, "M1533 Aladdin IV"),
+ DEVICE( AL, AL_M1541, "M1541 Aladdin V"),
+ DEVICE( AL, AL_M1543, "M1543 Aladdin V"),
DEVICE( AL, AL_M3307, "M3307 MPEG-1 decoder"),
DEVICE( AL, AL_M4803, "M4803"),
DEVICE( AL, AL_M5219, "M5219"),
DEVICE( AL, AL_M5229, "M5229 TXpro"),
DEVICE( AL, AL_M5237, "M5237 USB"),
+ DEVICE( AL, AL_M7101, "M7101 PMU"),
DEVICE( SURECOM, SURECOM_NE34, "NE-34PCI LAN"),
DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_NM2070, "Magicgraph NM2070"),
DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_128V, "MagicGraph 128V"),
DEVICE( S3, S3_ViRGE_MXP, "ViRGE/MX+"),
DEVICE( S3, S3_ViRGE_MXPMV, "ViRGE/MX+MV"),
DEVICE( S3, S3_SONICVIBES, "SonicVibes"),
- DEVICE( DCI, DCI_PCCOM4, "PC COM PCI Bus 4 port serial Adapter"),
+ DEVICE( DCI, DCI_PCCOM4, "PC COM PCI Bus 4 port serial Adapter"),
DEVICE( INTEL, INTEL_82375, "82375EB"),
BRIDGE( INTEL, INTEL_82424, "82424ZX Saturn", 0x00),
DEVICE( INTEL, INTEL_82378, "82378IB"),
#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
+/* Amount to offset dynamic executables, such as glibc 2.x's ld.so when
+ * used from command line.
+ * Loading at 0x00000000 is not appropriate since it means
+ * null-pointer-dereferences are not caught. (and obstructs vm86 use.)
+ * Loading low in general is bad for ld.so, since it or the heap may
+ * collide with the second executable it loads.
+ * Loading near MMAP_SEARCH_START is even worse, since the heap will
+ * start after the executable, and quickly be occluded by shared
+ * libraries, etc.
+ * So we load in the top third of virtual memory.
+ */
+#define DYNAMIC_BIAS PAGE_ALIGN((TASK_SIZE/3)*2)
+
static struct linux_binfmt elf_format =
{
#ifndef MODULE
current->mm->end_code = 0;
current->mm->start_mmap = ELF_START_MMAP;
current->mm->mmap = NULL;
- elf_entry = (unsigned long) elf_ex.e_entry;
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
bprm->p = setup_arg_pages(bprm->p, bprm);
current->mm->start_stack = bprm->p;
+ /* Bias dynamic executables so they are not loaded at
+ * 0x00000000. See comment at DYNAMIC_BIAS define.
+ */
+ if (elf_ex.e_type == ET_DYN)
+ {
+ for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
+ elf_ppnt->p_vaddr += DYNAMIC_BIAS;
+ }
+ elf_ex.e_entry += DYNAMIC_BIAS;
+ }
+
+ elf_entry = (unsigned long) elf_ex.e_entry;
+
/* Now we do a little grungy work by mmaping the ELF image into
the correct location in memory. At this point, we assume that
the image should be loaded at fixed address, not at a variable
*/
if (sb->u.ext2_sb.s_loaded_block_bitmaps > 0 &&
sb->u.ext2_sb.s_block_bitmap_number[0] == block_group &&
- sb->u.ext2_sb.s_block_bitmap[block_group]) {
+ sb->u.ext2_sb.s_block_bitmap[0]) {
slot = 0;
}
/*
return sock->ops->sendmsg(sock, &msg, len, nonblock, flags);
}
+struct data_callback {
+ struct tq_struct cb;
+ struct sock *sk;
+};
+/*
+ * N.B. What happens if we're in here when the socket closes??
+ */
static void
-smb_data_callback(struct sock *sk, int len)
+found_data(struct sock *sk)
{
- struct socket *sock = sk->socket;
+ /*
+ * FIXME: copied from sock_def_readable, it should be a call to
+ * server->data_ready();
+ */
+ if (!sk->dead) {
+ wake_up_interruptible(sk->sleep);
+ sock_wake_async(sk->socket, 1);
+ }
+}
- if (!sk->dead)
+static void
+smb_data_callback(void *ptr)
+{
+ struct data_callback *job = ptr;
+ struct socket *sock = job->sk->socket;
+
+ if (!job->sk->dead)
{
unsigned char peek_buf[4];
int result;
set_fs(fs);
if (result != -EAGAIN)
- {
- wake_up_interruptible(sk->sleep);
- }
+ found_data(job->sk);
}
+ kfree(ptr);
}
+static void
+smb_data_ready(struct sock *sk, int len)
+{
+ struct data_callback *job;
+ job = kmalloc(sizeof(struct data_callback), GFP_ATOMIC);
+ if (job == 0) {
+ printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n");
+ found_data(sk);
+ return;
+ }
+ job->cb.next = NULL;
+ job->cb.sync = 0;
+ job->cb.routine = smb_data_callback;
+ job->cb.data = job;
+ job->sk = sk;
+ queue_task(&job->cb, &tq_scheduler);
+ }
int
smb_catch_keepalive(struct smb_server *server)
struct file *file;
struct inode *inode;
struct socket *sock;
+ void *data_ready;
struct sock *sk;
if ((server == NULL)
DDPRINTK("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
(unsigned int) (sk->data_ready),
(unsigned int) (server->data_ready));
-
- if (sk->data_ready == smb_data_callback)
- {
- printk("smb_catch_keepalive: already done\n");
+ /*
+ * Install the callback atomically to avoid races ...
+ */
+ data_ready = xchg(&sk->data_ready, smb_data_ready);
+ if (data_ready != smb_data_ready)
+ {
+ server->data_ready = data_ready;
+ return 0;
+ } else {
+ printk("smb_catch_keepalive: already done\n");
return -EINVAL;
}
- server->data_ready = sk->data_ready;
- sk->data_ready = smb_data_callback;
- return 0;
}
int
struct file *file;
struct inode *inode;
struct socket *sock;
+ void *data_ready;
struct sock *sk;
if ((server == NULL)
"server->data_ready == NULL\n");
return -EINVAL;
}
- if (sk->data_ready != smb_data_callback)
+ /*
+ * Restore the original callback atomically to avoid races ...
+ */
+ data_ready = xchg(&sk->data_ready, server->data_ready);
+ server->data_ready = NULL;
+ if (data_ready != smb_data_ready)
{
printk("smb_dont_catch_keepalive: "
- "sk->data_callback != smb_data_callback\n");
+ "sk->data_ready != smb_data_ready\n");
return -EINVAL;
}
DDPRINTK("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
(unsigned int) (sk->data_ready),
(unsigned int) (server->data_ready));
-
- sk->data_ready = server->data_ready;
- server->data_ready = NULL;
return 0;
}
--- /dev/null
+/* Aladdin 5229 timings display header file for triton.c.
+ Copyright (c) 1998-99 Michel Aubry
+ Copyright (c) 1999 Andre Hedrick
+*/
+
+
+static int ali_get_info(char *, char **, off_t, int, int);
+
+static struct proc_dir_entry ali_proc_entry = {
+ 0, 3, "ali", S_IFREG | S_IRUGO, 1, 0, 0, 0, 0, ali_get_info
+};
+
+/* we save bus, function of chipset here for further debug use */
+static byte bmide_bus, bmide_fn;
+
+static char *fifo[4] = {
+ "FIFO Off",
+ "FIFO On ",
+ "DMA mode",
+ "PIO mode"
+};
+
+static char *udmaT[8] = {
+ "1.5T",
+ " 2T",
+ "2.5T",
+ " 3T",
+ "3.5T",
+ " 4T",
+ " 6T",
+ " 8T"
+};
+
+char *channel_status[8] = {
+ "OK ",
+ "busy ",
+ "DRQ ",
+ "DRQ busy ",
+ "error ",
+ "error busy ",
+ "error DRQ ",
+ "error DRQ busy"
+};
+
+static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int dummy)
+{
+ byte reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1;
+ unsigned int bibma;
+ byte c0, c1;
+ byte rev, tmp;
+ char *p = buffer;
+ char *q;
+
+ /* fetch rev. */
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x08, &rev);
+ if (rev >= 0xc1) /* M1543C or newer */
+ udmaT[7] = " ???";
+ else
+ fifo[3] = " ??? ";
+
+ /* first fetch bibma: */
+ pcibios_read_config_dword(bmide_bus, bmide_fn, 0x20, &bibma);
+ bibma = (bibma & 0xfff0) ;
+ /*
+ * at that point bibma+0x2 et bibma+0xa are byte
+ * registers to investigate:
+ */
+ c0 = inb((unsigned short)bibma + 0x02);
+ c1 = inb((unsigned short)bibma + 0x0a);
+
+ p += sprintf(p,
+ "\n Ali M15x3 Chipset.\n");
+ p += sprintf(p,
+ " ------------------\n");
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x78, ®53h);
+ p += sprintf(p, "PCI Clock: %d.\n", reg53h);
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x53, ®53h);
+ p += sprintf(p,
+ "CD_ROM FIFO:%s, CD_ROM DMA:%s\n",
+ (reg53h & 0x02) ? "Yes" : "No ",
+ (reg53h & 0x01) ? "Yes" : "No " );
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x74, ®53h);
+ p += sprintf(p,
+ "FIFO Status: contains %d Words, runs%s%s\n\n",
+ (reg53h & 0x3f),
+ (reg53h & 0x40) ? " OVERWR" : "",
+ (reg53h & 0x80) ? " OVERRD." : "." );
+
+ p += sprintf(p,
+ "-------------------primary channel-------------------secondary channel---------\n\n");
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x09, ®53h);
+ p += sprintf(p,
+ "channel status: %s %s\n",
+ (reg53h & 0x20) ? "On " : "Off",
+ (reg53h & 0x10) ? "On " : "Off" );
+
+ p += sprintf(p,
+ "both channels togth: %s %s\n",
+ (c0&0x80) ? "No " : "Yes",
+ (c1&0x80) ? "No " : "Yes" );
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x76, ®53h);
+ p += sprintf(p,
+ "Channel state: %s %s\n",
+ channel_status[reg53h & 0x07],
+ channel_status[(reg53h & 0x70) >> 4] );
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x58, ®5xh);
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5c, ®5yh);
+ p += sprintf(p,
+ "Add. Setup Timing: %dT %dT\n",
+ (reg5xh & 0x07) ? (reg5xh & 0x07) : 8,
+ (reg5yh & 0x07) ? (reg5yh & 0x07) : 8 );
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x59, ®5xh);
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5d, ®5yh);
+ p += sprintf(p,
+ "Command Act. Count: %dT %dT\n"
+ "Command Rec. Count: %dT %dT\n\n",
+ (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
+ (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8,
+ (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
+ (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 );
+
+ p += sprintf(p,
+ "----------------drive0-----------drive1------------drive0-----------drive1------\n\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 " );
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x54, ®5xh);
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x55, ®5yh);
+ q = "FIFO threshold: %2d Words %2d Words %2d Words %2d Words\n";
+ if (rev < 0xc1) {
+ if ((rev == 0x20) && (pcibios_read_config_byte(bmide_bus, bmide_fn, 0x4f, &tmp), (tmp &= 0x20))) {
+ p += sprintf(p, q, 8, 8, 8, 8);
+ } else {
+ p += sprintf(p, q,
+ (reg5xh & 0x03) + 12,
+ ((reg5xh & 0x30)>>4) + 12,
+ (reg5yh & 0x03) + 12,
+ ((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 );
+ }
+
+#if 0
+ p += sprintf(p,
+ "FIFO threshold: %2d Words %2d Words %2d Words %2d Words\n",
+ (reg5xh & 0x03) + 12,
+ ((reg5xh & 0x30)>>4) + 12,
+ (reg5yh & 0x03) + 12,
+ ((reg5yh & 0x30)>>4) + 12 );
+#endif
+
+ p += sprintf(p,
+ "FIFO mode: %s %s %s %s\n",
+ fifo[((reg5xh & 0x0c) >> 2)],
+ fifo[((reg5xh & 0xc0) >> 6)],
+ fifo[((reg5yh & 0x0c) >> 2)],
+ fifo[((reg5yh & 0xc0) >> 6)] );
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5a, ®5xh);
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5b, ®5xh1);
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5e, ®5yh);
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x5f, ®5yh1);
+
+ p += sprintf(p,/*
+ "------------------drive0-----------drive1------------drive0-----------drive1------\n")*/
+ "Dt RW act. Cnt %dT %dT %dT %dT\n"
+ "Dt RW rec. Cnt %2dT %2dT %2dT %2dT\n\n",
+ (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8,
+ (reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8,
+ (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8,
+ (reg5yh1 & 0x70) ? ((reg5yh1 & 0x70) >> 4) : 8,
+ (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16,
+ (reg5xh1 & 0x0f) ? (reg5xh1 & 0x0f) : 16,
+ (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16,
+ (reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 );
+
+ p += sprintf(p,
+ "-----------------------------------UDMA Timings--------------------------------\n\n");
+
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x56, ®5xh);
+ pcibios_read_config_byte(bmide_bus, bmide_fn, 0x57, ®5yh);
+ p += sprintf(p,
+ "UDMA: %s %s %s %s\n"
+ "UDMA timings: %s %s %s %s\n\n",
+ (reg5xh & 0x08) ? "OK" : "No",
+ (reg5xh & 0x80) ? "OK" : "No",
+ (reg5yh & 0x08) ? "OK" : "No",
+ (reg5yh & 0x80) ? "OK" : "No",
+ udmaT[(reg5xh & 0x07)],
+ udmaT[(reg5xh & 0x70) >> 4],
+ udmaT[reg5yh & 0x07],
+ udmaT[(reg5yh & 0x70) >> 4] );
+
+ return p-buffer; /* => must be less than 4k! */
+}
+
/****************** ****************** *******************/
#endif
+/* Per card data structure */
+struct cyclades_card {
+ long base_addr;
+ long ctl_addr;
+ int irq;
+ int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */
+ int first_line; /* minor number of first channel on card */
+ int bus_index; /* address shift - 0 for ISA, 1 for PCI */
+ int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */
+};
+struct cyclades_chip {
+ int filler;
+};
#ifdef __KERNEL__
#define cy_readw(port) readw(port)
#define cy_readl(port) readl(port)
-/* Per card data structure */
-
-struct cyclades_card {
- long base_addr;
- long ctl_addr;
- int irq;
- int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */
- int first_line; /* minor number of first channel on card */
- int bus_index; /* address shift - 0 for ISA, 1 for PCI */
- int inact_ctrl; /* FW Inactivity control - 0 disabled, 1 enabled */
-};
-
-struct cyclades_chip {
- int filler;
-};
-
/*
* This is our internal structure for each serial port's state.
*
int xmit_cnt;
int default_threshold;
int default_timeout;
- struct tq_struct tqueue;
+ unsigned long jiffies[3];
+ unsigned long rflush_count;
struct termios normal_termios;
struct termios callout_termios;
+ struct cyclades_monitor mon;
+ struct cyclades_idle_stats idle_stats;
+ struct tq_struct tqueue;
struct wait_queue *open_wait;
struct wait_queue *close_wait;
struct wait_queue *shutdown_wait;
- struct cyclades_monitor mon;
- unsigned long jiffies[3];
- unsigned long rflush_count;
- struct cyclades_idle_stats idle_stats;
};
/*
#define DAC960_MAJOR 48 /* 48..55 */
#define RISCOM8_CALLOUT_MAJOR 49
#define MKISS_MAJOR 55
+
+#define IDE4_MAJOR 56
+#define IDE5_MAJOR 57
+
#define APBLOCK_MAJOR 60 /* AP1000 Block device */
#define DDV_MAJOR 61 /* AP1000 DDV block device */
#define PCI_VENDOR_ID_PROMISE 0x105a
#define PCI_DEVICE_ID_PROMISE_20246 0x4d33
+#define PCI_DEVICE_ID_PROMISE_20262 0x4d38
#define PCI_DEVICE_ID_PROMISE_5300 0x5300
#define PCI_VENDOR_ID_N9 0x105d
#define PCI_DEVICE_ID_DATABOOK_87144 0xb106
#define PCI_VENDOR_ID_PLX 0x10b5
-#define PCI_DEVICE_ID_PLX_9050 0x9050
+#define PCI_DEVICE_ID_PLX_9050 0x9050
#define PCI_DEVICE_ID_PLX_9080 0x9080
#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103
#define PCI_DEVICE_ID_AL_M1523 0x1523
#define PCI_DEVICE_ID_AL_M1531 0x1531
#define PCI_DEVICE_ID_AL_M1533 0x1533
+#define PCI_DEVICE_ID_AL_M1541 0x1541
+#define PCI_DEVICE_ID_AL_M1543 0x1543
#define PCI_DEVICE_ID_AL_M3307 0x3307
#define PCI_DEVICE_ID_AL_M4803 0x5215
#define PCI_DEVICE_ID_AL_M5219 0x5219
{ "hdf", 0x2140 },
{ "hdg", 0x2200 },
{ "hdh", 0x2240 },
+ { "hdi", 0x3800 },
+ { "hdj", 0x3840 },
+ { "hdk", 0x3900 },
+ { "hdl", 0x3940 },
{ "sda", 0x0800 },
{ "sdb", 0x0810 },
{ "sdc", 0x0820 },