## Automatically generated incremental diff ## From: linux-2.0.39-pre4 ## To: linux-2.0.39-pre5 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.0.39-pre4/Documentation/Configure.help linux-2.0.39-pre5/Documentation/Configure.help --- linux-2.0.39-pre4/Documentation/Configure.help 2003-08-15 15:04:57.000000000 -0700 +++ linux-2.0.39-pre5/Documentation/Configure.help 2003-08-15 15:04:57.000000000 -0700 @@ -4195,6 +4195,16 @@ 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 diff -urN linux-2.0.39-pre4/drivers/block/genhd.c linux-2.0.39-pre5/drivers/block/genhd.c --- linux-2.0.39-pre4/drivers/block/genhd.c 1999-06-13 10:21:00.000000000 -0700 +++ linux-2.0.39-pre5/drivers/block/genhd.c 2003-08-15 15:04:57.000000000 -0700 @@ -76,6 +76,10 @@ * 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: @@ -158,6 +162,8 @@ 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; @@ -165,6 +171,8 @@ this_sector = first_sector; while (1) { + if (++loopct > 100) + return; if ((current_minor & mask) == 0) return; if (!(bh = bread(dev,0,1024))) @@ -209,6 +217,7 @@ add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p)); current_minor++; + loopct = 0; if ((current_minor & mask) == 0) goto done; } diff -urN linux-2.0.39-pre4/drivers/block/ide.c linux-2.0.39-pre5/drivers/block/ide.c --- linux-2.0.39-pre4/drivers/block/ide.c 2003-08-15 15:04:57.000000000 -0700 +++ linux-2.0.39-pre5/drivers/block/ide.c 2003-08-15 15:04:57.000000000 -0700 @@ -283,6 +283,10 @@ * 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 * @@ -328,9 +332,9 @@ #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 */ @@ -1596,11 +1600,16 @@ 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 @@ -1763,6 +1772,20 @@ } #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; @@ -2322,10 +2345,18 @@ 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); } @@ -2557,6 +2588,7 @@ } drive->media = ide_disk; + /* Extract geometry if we did not already have one for the drive */ if (!drive->present) { drive->present = 1; @@ -2650,8 +2682,12 @@ 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 { @@ -2915,6 +2951,12 @@ * 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) { @@ -3380,30 +3422,26 @@ 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); @@ -3570,7 +3608,18 @@ 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); } @@ -3605,17 +3654,22 @@ */ #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 */ @@ -3662,6 +3716,12 @@ #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); return (hwif->present = 0); diff -urN linux-2.0.39-pre4/drivers/block/ide.h linux-2.0.39-pre5/drivers/block/ide.h --- linux-2.0.39-pre4/drivers/block/ide.h 1999-06-13 10:21:00.000000000 -0700 +++ linux-2.0.39-pre5/drivers/block/ide.h 2003-08-15 15:04:57.000000000 -0700 @@ -145,7 +145,7 @@ #define PARTN_MASK ((1< #include +#include #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 #include +#ifdef DISPLAY_APOLLO_TIMINGS #include #endif +#ifdef DISPLAY_ALI15X3_TIMINGS +#include +#endif +#endif /* * good_dma_drives() lists the model names (from "hdparm -i") @@ -90,6 +99,7 @@ #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 @@ -194,6 +204,11 @@ 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; @@ -204,15 +219,24 @@ 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 */ } @@ -363,6 +387,70 @@ 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, @@ -370,17 +458,20 @@ */ 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 @@ -392,19 +483,61 @@ 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. @@ -414,15 +547,17 @@ * 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: @@ -436,8 +571,13 @@ * 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); @@ -460,6 +600,15 @@ 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; } @@ -491,12 +640,20 @@ 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; } @@ -509,14 +666,17 @@ 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. */ @@ -533,9 +693,39 @@ 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; } @@ -545,15 +735,22 @@ */ 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 @@ -562,21 +759,14 @@ * 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 */ /* @@ -592,6 +782,7 @@ 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? */ @@ -637,12 +828,17 @@ 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); @@ -650,9 +846,10 @@ } 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) @@ -664,7 +861,7 @@ #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) @@ -675,41 +872,91 @@ } 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 { diff -urN linux-2.0.39-pre4/drivers/char/Config.in linux-2.0.39-pre5/drivers/char/Config.in --- linux-2.0.39-pre4/drivers/char/Config.in 2003-08-15 15:04:57.000000000 -0700 +++ linux-2.0.39-pre5/drivers/char/Config.in 2003-08-15 15:04:57.000000000 -0700 @@ -12,6 +12,9 @@ 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 diff -urN linux-2.0.39-pre4/drivers/char/cyclades.c linux-2.0.39-pre5/drivers/char/cyclades.c --- linux-2.0.39-pre4/drivers/char/cyclades.c 1999-06-13 10:21:00.000000000 -0700 +++ linux-2.0.39-pre5/drivers/char/cyclades.c 2003-08-15 15:04:57.000000000 -0700 @@ -1,7 +1,7 @@ #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 @@ -21,7 +21,7 @@ * 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); @@ -31,6 +31,29 @@ * 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; @@ -518,7 +541,7 @@ 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 @@ -600,6 +623,14 @@ #include #endif +#ifdef CONFIG_COBALT_27 +#include +#include + +#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 @@ -636,6 +667,7 @@ 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; @@ -663,6 +695,8 @@ }; #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. */ @@ -681,12 +715,6 @@ 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, @@ -791,8 +819,9 @@ 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 @@ -813,6 +842,9 @@ }; #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; @@ -821,6 +853,7 @@ cyz_timerlist = { NULL, NULL, 0, 0, cyz_poll }; +#endif /* CONFIG_CYZ_INTR */ /************************************************** error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long)); @@ -862,7 +895,7 @@ 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. */ @@ -895,7 +928,7 @@ 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 @@ -1009,6 +1042,8 @@ return(0); } /* cyy_issue_cmd */ +#ifndef CONFIG_COBALT_27 /* ISA interrupt detection code */ + static int probe_ready; /* @@ -1204,6 +1239,8 @@ 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. @@ -1227,9 +1264,9 @@ 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 */ } @@ -1261,7 +1298,7 @@ } 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<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 @@ -1389,7 +1426,7 @@ 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 */ @@ -1687,12 +1724,285 @@ } /* 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) @@ -1726,7 +2036,6 @@ firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS); if (!ISZLOADED(*cinfo)) { - cinfo->inact_ctrl = 0; continue; } @@ -1737,12 +2046,6 @@ 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 ]; @@ -1984,17 +2287,13 @@ } /* 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 *********/ /***********************************************************/ @@ -2103,12 +2402,27 @@ 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){ @@ -2171,11 +2485,21 @@ cy_readb(base_addr+(CySRER<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); /* */ @@ -4139,6 +4479,7 @@ case CYGETCD1400VER: ret_val = info->chip_rev; break; +#ifndef CONFIG_CYZ_INTR case CYZSETPOLLCYCLE: cyz_polling_cycle = (arg * HZ) / 1000; ret_val = 0; @@ -4146,6 +4487,7 @@ 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; @@ -4254,7 +4596,8 @@ 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); @@ -4272,16 +4615,6 @@ 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. @@ -4483,7 +4816,7 @@ 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 @@ -4501,19 +4834,10 @@ 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)) @@ -4639,6 +4963,7 @@ return chip_number; } /* cyy_init_card */ +#ifndef CONFIG_COBALT_27 /* * --------------------------------------------------------------------- * cy_detect_isa() - Probe for Cyclom-Y/ISA boards. @@ -4699,7 +5024,7 @@ /* 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); @@ -4715,7 +5040,6 @@ 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 */ @@ -4730,6 +5054,20 @@ 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); +} /* * --------------------------------------------------------------------- @@ -4800,6 +5138,12 @@ 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, ", @@ -4817,7 +5161,9 @@ 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 @@ -4855,7 +5201,7 @@ /* 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); @@ -4871,13 +5217,14 @@ 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; @@ -4886,6 +5233,14 @@ 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; @@ -4921,15 +5276,31 @@ (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( @@ -5009,10 +5380,11 @@ 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); @@ -5021,6 +5393,7 @@ return(i); } } +#endif /* CONFIG_CYZ_INTR */ /* set cy_card */ @@ -5030,22 +5403,28 @@ 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; } } @@ -5065,10 +5444,6 @@ (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; @@ -5093,10 +5468,11 @@ 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); @@ -5105,6 +5481,7 @@ return(i); } } +#endif /* CONFIG_CYZ_INTR */ /* set cy_card */ cy_card[j].base_addr = cy_pci_addr2; @@ -5113,22 +5490,28 @@ 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) { @@ -5299,10 +5682,6 @@ 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; @@ -5315,8 +5694,10 @@ 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(); @@ -5348,6 +5729,7 @@ 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++) @@ -5471,15 +5853,17 @@ } } } - - 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); @@ -5504,10 +5888,12 @@ 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(); @@ -5521,9 +5907,12 @@ 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 */ @@ -5532,6 +5921,7 @@ void cy_setup(char *str, int *ints) { +#ifndef CONFIG_COBALT_27 int i, j; for (i = 0 ; i < NR_ISA_ADDRS ; i++) { @@ -5542,6 +5932,7 @@ cy_isa_addresses[i++] = (unsigned char *)(ints[j]); } } +#endif /* CONFIG_COBALT_27 */ } /* cy_setup */ #endif diff -urN linux-2.0.39-pre4/drivers/net/Config.in linux-2.0.39-pre5/drivers/net/Config.in --- linux-2.0.39-pre4/drivers/net/Config.in 2003-08-15 15:04:57.000000000 -0700 +++ linux-2.0.39-pre5/drivers/net/Config.in 2003-08-15 15:04:57.000000000 -0700 @@ -54,14 +54,14 @@ 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 diff -urN linux-2.0.39-pre4/drivers/pci/pci.c linux-2.0.39-pre5/drivers/pci/pci.c --- linux-2.0.39-pre4/drivers/pci/pci.c 1999-06-13 10:21:02.000000000 -0700 +++ linux-2.0.39-pre5/drivers/pci/pci.c 2003-08-15 15:04:57.000000000 -0700 @@ -210,6 +210,7 @@ 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"), @@ -271,8 +272,8 @@ 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"), @@ -297,11 +298,14 @@ 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"), @@ -489,7 +493,7 @@ 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"), diff -urN linux-2.0.39-pre4/fs/binfmt_elf.c linux-2.0.39-pre5/fs/binfmt_elf.c --- linux-2.0.39-pre4/fs/binfmt_elf.c 2003-08-15 15:04:57.000000000 -0700 +++ linux-2.0.39-pre5/fs/binfmt_elf.c 2003-08-15 15:04:57.000000000 -0700 @@ -55,6 +55,19 @@ #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 @@ -557,7 +570,6 @@ 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 */ @@ -565,6 +577,19 @@ 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 diff -urN linux-2.0.39-pre4/fs/ext2/balloc.c linux-2.0.39-pre5/fs/ext2/balloc.c --- linux-2.0.39-pre4/fs/ext2/balloc.c 2003-08-15 15:04:57.000000000 -0700 +++ linux-2.0.39-pre5/fs/ext2/balloc.c 2003-08-15 15:04:57.000000000 -0700 @@ -205,7 +205,7 @@ */ 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; } /* diff -urN linux-2.0.39-pre4/fs/smbfs/sock.c linux-2.0.39-pre5/fs/smbfs/sock.c --- linux-2.0.39-pre4/fs/smbfs/sock.c 1997-09-15 10:02:41.000000000 -0700 +++ linux-2.0.39-pre5/fs/smbfs/sock.c 2003-08-15 15:04:57.000000000 -0700 @@ -64,12 +64,33 @@ 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; @@ -101,11 +122,27 @@ 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) @@ -113,6 +150,7 @@ struct file *file; struct inode *inode; struct socket *sock; + void *data_ready; struct sock *sk; if ((server == NULL) @@ -143,15 +181,18 @@ 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 @@ -160,6 +201,7 @@ struct file *file; struct inode *inode; struct socket *sock; + void *data_ready; struct sock *sk; if ((server == NULL) @@ -191,18 +233,20 @@ "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; } diff -urN linux-2.0.39-pre4/include/linux/ali_ide_dma.h linux-2.0.39-pre5/include/linux/ali_ide_dma.h --- linux-2.0.39-pre4/include/linux/ali_ide_dma.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.0.39-pre5/include/linux/ali_ide_dma.h 2003-08-15 15:04:57.000000000 -0700 @@ -0,0 +1,210 @@ +/* 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! */ +} + diff -urN linux-2.0.39-pre4/include/linux/cyclades.h linux-2.0.39-pre5/include/linux/cyclades.h --- linux-2.0.39-pre4/include/linux/cyclades.h 1999-06-13 10:21:04.000000000 -0700 +++ linux-2.0.39-pre5/include/linux/cyclades.h 2003-08-15 15:04:57.000000000 -0700 @@ -490,7 +490,20 @@ /****************** ****************** *******************/ #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__ @@ -508,22 +521,6 @@ #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. * @@ -567,16 +564,16 @@ 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; }; /* diff -urN linux-2.0.39-pre4/include/linux/major.h linux-2.0.39-pre5/include/linux/major.h --- linux-2.0.39-pre4/include/linux/major.h 1999-06-13 10:21:04.000000000 -0700 +++ linux-2.0.39-pre5/include/linux/major.h 2003-08-15 15:04:57.000000000 -0700 @@ -68,6 +68,10 @@ #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 */ diff -urN linux-2.0.39-pre4/include/linux/pci.h linux-2.0.39-pre5/include/linux/pci.h --- linux-2.0.39-pre4/include/linux/pci.h 1999-06-13 10:21:04.000000000 -0700 +++ linux-2.0.39-pre5/include/linux/pci.h 2003-08-15 15:04:57.000000000 -0700 @@ -451,6 +451,7 @@ #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 @@ -558,7 +559,7 @@ #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 @@ -593,6 +594,8 @@ #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 diff -urN linux-2.0.39-pre4/init/main.c linux-2.0.39-pre5/init/main.c --- linux-2.0.39-pre4/init/main.c 1999-06-13 10:21:04.000000000 -0700 +++ linux-2.0.39-pre5/init/main.c 2003-08-15 15:04:57.000000000 -0700 @@ -653,6 +653,10 @@ { "hdf", 0x2140 }, { "hdg", 0x2200 }, { "hdh", 0x2240 }, + { "hdi", 0x3800 }, + { "hdj", 0x3840 }, + { "hdk", 0x3900 }, + { "hdl", 0x3940 }, { "sda", 0x0800 }, { "sdb", 0x0810 }, { "sdc", 0x0820 }, diff -urN linux-2.0.39-pre4/MAINTAINERS linux-2.0.39-pre5/MAINTAINERS --- linux-2.0.39-pre4/MAINTAINERS 2003-08-15 15:04:57.000000000 -0700 +++ linux-2.0.39-pre5/MAINTAINERS 2003-08-15 15:04:57.000000000 -0700 @@ -251,14 +251,15 @@ 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