diff options
| author | Martin Dalecki <dalecki@evision-ventures.com> | 2002-06-12 20:58:38 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-06-12 20:58:38 -0700 |
| commit | eccec1ce128684498d3edf986cd77638c21ab4e7 (patch) | |
| tree | fab267f4aef8603a0ce8ff29cb3b6e9613beac4c | |
| parent | ded80dca303d9282faaa24f32be1bf15bdce2df8 (diff) | |
[PATCH] 2.5.21 IDE 88
- Bunch of cleanups by Bartlomiej (accounts for over a half of the patch):
cmd64x.c:
- kill SPLIT_BYTE() macro
- kill wrappers for cmd64x_config_drive_for_dma()
- misc cleanups
cy82c693.c:
- kill obsolete comments
- clean cy82c693_tune_drive() and calc_clk()
- misc cleanups
hpt34x.c:
- kill obsolete comment
- kill SPLIT_BYTE()
- kill hpt34x_clear_chipset()
- simplify hpt34x_tune_drive()
hpt366.c:
- kill hpt_min_rev()
- kill redundant hpt368_tune_chipset() and hpt374_tune_chipset()
- fix badlists checking in config_chipset_for_dma()
- misc cleanups
pdc202xx.c:
- clean registers decoding
- clean pdc202xx_tune_chipset()
- kill pdc202xx_udma_irq_status(), use generic udma_pci_irq_status()
- rationalize pdc202xx_reset()
- kill UDMA_SPEED_FLAG() and PDC_CLOCK() macros,
do it right by defining constants PDC_UDMA and PDC_CLK
- kill init_high_16() inline, no need to hide internals
- clean pdc202xx_init_chipset()
- split ata66_pdc202xx() and pdc202xx_init_chipset()
- clean config_chipset_for_dma()
- misc cleanups
- Fix plug in of CF cards. The previously used sub device driver attach method
lookup was entirely hosed.
- Enforce indentation style on ide-cs.c. Enable debugging there. (Makes the
patch quite big...)
| -rw-r--r-- | drivers/ide/cmd64x.c | 131 | ||||
| -rw-r--r-- | drivers/ide/cy82c693.c | 170 | ||||
| -rw-r--r-- | drivers/ide/hpt34x.c | 86 | ||||
| -rw-r--r-- | drivers/ide/hpt366.c | 121 | ||||
| -rw-r--r-- | drivers/ide/ide-cs.c | 660 | ||||
| -rw-r--r-- | drivers/ide/ide-taskfile.c | 3 | ||||
| -rw-r--r-- | drivers/ide/main.c | 43 | ||||
| -rw-r--r-- | drivers/ide/pdc202xx.c | 366 | ||||
| -rw-r--r-- | include/linux/ide.h | 1 |
9 files changed, 699 insertions, 882 deletions
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index d254363590f2..429a28866677 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -7,8 +7,7 @@ * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Note, this driver is not used at all on other systems because * there the "BIOS" has done all of the following already. - * Due to massive hardware bugs, UltraDMA is only supported - * on the 646U2 and not on the 646U. + * Due to massive hardware bugs, UDMA is not supported on the 646U. * * Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be> * Copyright (C) 1998 David S. Miller <davem@redhat.com> @@ -28,10 +27,6 @@ #include "ata-timing.h" #include "pcihost.h" -#ifndef SPLIT_BYTE -#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) -#endif - #define CMD_DEBUG 0 #if CMD_DEBUG @@ -186,6 +181,7 @@ static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted) * I copied all this complicated stuff from cmd640.c and made a few minor changes. * For now I am just going to pray that it is correct. */ + /* FIXME: try to use generic ata-timings library --bkz */ recovery_time = t->cycle - (t->setup + t->active); clock_time = 1000000 / system_bus_speed; @@ -256,9 +252,7 @@ static int cmd64x_ratemask(struct ata_device *drive) case 0x07: case 0x05: map |= XFER_UDMA; - case 0x03: - case 0x01: - default: + default: /* 0x03, 0x01 */ break; } } @@ -272,13 +266,12 @@ static int cmd64x_ratemask(struct ata_device *drive) return map; } -static byte cmd680_taskfile_timing(struct ata_channel *hwif) +static u8 cmd680_taskfile_timing(struct ata_channel *ch) { - struct pci_dev *dev = hwif->pci_dev; - byte addr_mask = (hwif->unit) ? 0xB2 : 0xA2; - unsigned short timing; + u8 addr_mask = (ch->unit) ? 0xB2 : 0xA2; + u16 timing; - pci_read_config_word(dev, addr_mask, &timing); + pci_read_config_word(ch->pci_dev, addr_mask, &timing); switch (timing) { case 0x10c1: return 4; @@ -290,12 +283,12 @@ static byte cmd680_taskfile_timing(struct ata_channel *hwif) } } -static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted) +static void cmd680_tuneproc(struct ata_device *drive, u8 mode_wanted) { struct ata_channel *hwif = drive->channel; struct pci_dev *dev = hwif->pci_dev; - byte drive_pci; - unsigned short speedt; + u8 drive_pci; + u16 speedt; switch (drive->dn) { case 0: drive_pci = 0xA4; break; @@ -320,25 +313,23 @@ static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted) pci_write_config_word(dev, drive_pci, speedt); } -static void config_cmd64x_chipset_for_pio(struct ata_device *drive, byte set_speed) +static void config_cmd64x_chipset_for_pio(struct ata_device *drive, u8 set_speed) { - byte speed = 0x00; - byte set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; + u8 set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; cmd64x_tuneproc(drive, set_pio); - speed = XFER_PIO_0 + set_pio; if (set_speed) - (void) ide_config_drive_speed(drive, speed); + (void) ide_config_drive_speed(drive, XFER_PIO_0 + set_pio); } -static void config_cmd680_chipset_for_pio(struct ata_device *drive, byte set_speed) +static void config_cmd680_chipset_for_pio(struct ata_device *drive, u8 set_speed) { struct ata_channel *hwif = drive->channel; struct pci_dev *dev = hwif->pci_dev; u8 unit = (drive->select.b.unit & 0x01); u8 addr_mask = (hwif->unit) ? 0x84 : 0x80; - u8 speed = 0x00; - u8 mode_pci = 0x00; + u8 speed; + u8 mode_pci; u8 channel_timings = cmd680_taskfile_timing(hwif); u8 set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; @@ -375,8 +366,7 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed) u8 unit = (drive->select.b.unit & 0x01); u8 pciU = (hwif->unit) ? UDIDETCR1 : UDIDETCR0; u8 pciD = (hwif->unit) ? BMIDESR1 : BMIDESR0; - u8 regU = 0; - u8 regD = 0; + u8 regU, regD; if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0)) return 1; @@ -390,6 +380,7 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed) (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); + /* FIXME: get unit checking out of here --bkz */ switch(speed) { case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; @@ -406,12 +397,13 @@ static int cmd64x_tune_chipset(struct ata_device *drive, byte speed) #else switch(speed) { #endif /* CONFIG_BLK_DEV_IDEDMA */ - case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; - case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; - case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break; - case XFER_PIO_1: cmd64x_tuneproc(drive, 1); break; - case XFER_PIO_0: cmd64x_tuneproc(drive, 0); break; - + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + cmd64x_tuneproc(drive, speed - XFER_PIO_0); + break; default: return 1; } @@ -436,12 +428,9 @@ static int cmd680_tune_chipset(struct ata_device *drive, byte speed) struct pci_dev *dev = hwif->pci_dev; u8 addr_mask = (hwif->unit) ? 0x84 : 0x80; u8 unit = (drive->select.b.unit & 0x01); - u8 dma_pci = 0; - u8 udma_pci = 0; - u8 mode_pci = 0; - u8 scsc = 0; - u16 ultra = 0; - u16 multi = 0; + u8 dma_pci, udma_pci; + u8 mode_pci, scsc; + u16 ultra, multi; pci_read_config_byte(dev, addr_mask, &mode_pci); pci_read_config_byte(dev, 0x8A, &scsc); @@ -515,11 +504,13 @@ speed_break : multi = 0x2208; break; #endif /* CONFIG_BLK_DEV_IDEDMA */ - case XFER_PIO_4: cmd680_tuneproc(drive, 4); break; - case XFER_PIO_3: cmd680_tuneproc(drive, 3); break; - case XFER_PIO_2: cmd680_tuneproc(drive, 2); break; - case XFER_PIO_1: cmd680_tuneproc(drive, 1); break; - case XFER_PIO_0: cmd680_tuneproc(drive, 0); break; + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + cmd680_tuneproc(drive, speed - XFER_PIO_0); + break; default: return 1; } @@ -570,7 +561,7 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma) return !drive->channel->speedproc(drive, mode); } -static int cmd64x_config_drive_for_dma(struct ata_device *drive) +static int cmd6xx_udma_setup(struct ata_device *drive) { struct hd_driveid *id = drive->id; struct ata_channel *hwif = drive->channel; @@ -627,11 +618,6 @@ no_dma_set: return 0; } -static int cmd680_udma_setup(struct ata_device *drive) -{ - return cmd64x_config_drive_for_dma(drive); -} - static int cmd64x_udma_stop(struct ata_device *drive) { struct ata_channel *ch = drive->channel; @@ -680,11 +666,10 @@ static int cmd64x_udma_irq_status(struct ata_device *drive) return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ } -static int cmd64x_udma_setup(struct ata_device *drive) -{ - return cmd64x_config_drive_for_dma(drive); -} - +/* + * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old + * event order for DMA transfers. + */ static int cmd646_1_udma_stop(struct ata_device *drive) { struct ata_channel *ch = drive->channel; @@ -699,14 +684,6 @@ static int cmd646_1_udma_stop(struct ata_device *drive) return (dma_stat & 7) != 4; /* verify good DMA status */ } -/* - * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old - * event order for DMA transfers. - */ -static int cmd646_1_udma_setup(struct ata_device *drive) -{ - return cmd64x_config_drive_for_dma(drive); -} #endif static int cmd680_busproc(struct ata_device * drive, int state) @@ -808,10 +785,7 @@ static unsigned int cmd64x_pci_init(struct pci_dev *dev) } printk("\n"); break; - case PCI_DEVICE_ID_CMD_648: - case PCI_DEVICE_ID_CMD_649: - break; - default: + default: /* 648, 649 */ break; } @@ -863,8 +837,8 @@ static unsigned int __init cmd64x_init_chipset(struct pci_dev *dev) static unsigned int cmd680_ata66(struct ata_channel *hwif) { - byte ata66 = 0; - byte addr_mask = (hwif->unit) ? 0xB0 : 0xA0; + u8 ata66; + u8 addr_mask = (hwif->unit) ? 0xB0 : 0xA0; pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66); return (ata66 & 0x01) ? 1 : 0; @@ -872,8 +846,8 @@ static unsigned int cmd680_ata66(struct ata_channel *hwif) static unsigned int cmd64x_ata66(struct ata_channel *hwif) { - byte ata66 = 0; - byte mask = (hwif->unit) ? 0x02 : 0x01; + u8 ata66; + u8 mask = (hwif->unit) ? 0x02 : 0x01; pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66); return (ata66 & mask) ? 1 : 0; @@ -881,8 +855,7 @@ static unsigned int cmd64x_ata66(struct ata_channel *hwif) static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif) { - struct pci_dev *dev = hwif->pci_dev; - if (dev->device == PCI_DEVICE_ID_CMD_680) + if (hwif->pci_dev->device == PCI_DEVICE_ID_CMD_680) return cmd680_ata66(hwif); return cmd64x_ata66(hwif); } @@ -890,7 +863,7 @@ static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif) static void __init cmd64x_init_channel(struct ata_channel *hwif) { struct pci_dev *dev = hwif->pci_dev; - unsigned int class_rev; + u32 class_rev; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; @@ -903,7 +876,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) hwif->busproc = cmd680_busproc; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) - hwif->udma_setup = cmd680_udma_setup; + hwif->udma_setup = cmd6xx_udma_setup; #endif hwif->resetproc = cmd680_reset; hwif->speedproc = cmd680_tune_chipset; @@ -914,7 +887,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) case PCI_DEVICE_ID_CMD_643: #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { - hwif->udma_setup = cmd64x_udma_setup; + hwif->udma_setup = cmd6xx_udma_setup; hwif->udma_stop = cmd64x_udma_stop; hwif->udma_irq_status = cmd64x_udma_irq_status; } @@ -926,11 +899,10 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) hwif->chipset = ide_cmd646; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { + hwif->udma_setup = cmd6xx_udma_setup; if (class_rev == 0x01) { - hwif->udma_setup = cmd646_1_udma_setup; hwif->udma_stop = cmd646_1_udma_stop; } else { - hwif->udma_setup = cmd64x_udma_setup; hwif->udma_stop = cmd64x_udma_stop; hwif->udma_irq_status = cmd64x_udma_irq_status; } @@ -1007,9 +979,8 @@ int __init init_cmd64x(void) { int i; - for (i = 0; i < ARRAY_SIZE(chipsets); ++i) { + for (i = 0; i < ARRAY_SIZE(chipsets); ++i) ata_register_chipset(&chipsets[i]); - } return 0; } diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 3855f8a98ddb..194cd2d3cfbd 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -21,12 +21,9 @@ * hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA * - this is my first linux driver, so there's probably a lot of room * for optimizations and bug fixing, so feel free to do it. - * - use idebus=xx parameter to set PCI bus speed - needed to calc - * timings for PIO modes (default will be 40) - * - if using PIO mode it's a good idea to set the PIO mode and - * 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda * - I had some problems with my IBM DHEA with PIO modes < 2 * (lost interrupts) ????? + * FIXME: probably because we set wrong timings for 8bit --bkz * - first tests with DMA look okay, they seem to work, but there is a * problem with sound - the BusMaster IDE TimeOut should fixed this * @@ -83,6 +80,9 @@ /* here are the offset definitions for the registers */ #define CY82_IDE_CMDREG 0x04 #define CY82_IDE_ADDRSETUP 0x48 + +#define CYPRESS_TIMINGS 0x4C + #define CY82_IDE_MASTER_IOR 0x4C #define CY82_IDE_MASTER_IOW 0x4D #define CY82_IDE_SLAVE_IOR 0x4E @@ -105,19 +105,20 @@ #define CY82C963_MIN_BUS_SPEED 25 #define CY82C963_MAX_BUS_SPEED 33 -/* the struct for the PIO mode timings */ +/* the struct for the PIO mode timings (in clocks) */ typedef struct pio_clocks_s { - byte address_time; /* Address setup (clocks) */ - byte time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */ - byte time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */ - byte time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */ + u8 address_time; /* Address setup */ + /* 0xF0=Active/data, 0x0F=Recovery */ + u8 time_16r; /* 16bit IOR */ + u8 time_16w; /* 16bit IOW */ + u8 time_8; /* 8bit */ } pio_clocks_t; /* * calc clocks using bus_speed * returns (rounded up) time in bus clocks for time in ns */ -static int calc_clk (int time, int bus_speed) +static u8 calc_clk(int time, int bus_speed) { int clocks; @@ -129,7 +130,7 @@ static int calc_clk (int time, int bus_speed) if (clocks > 0x0F) clocks = 0x0F; - return clocks; + return (u8)clocks; } /* @@ -140,7 +141,8 @@ static int calc_clk (int time, int bus_speed) * for mode 3 and 4 drives 8 and 16-bit timings are the same * */ -static void compute_clocks (byte pio, pio_clocks_t *p_pclk) +/* FIXME: use generic ata-timings library --bkz */ +static void compute_clocks(u8 pio, pio_clocks_t *p_pclk) { struct ata_timing *t; int clk1, clk2; @@ -149,34 +151,33 @@ static void compute_clocks (byte pio, pio_clocks_t *p_pclk) /* we don't check against CY82C693's min and max speed, * so you can play with the idebus=xx parameter + * FIXME: warn about going out of specification --bkz */ if (pio > CY82C693_MAX_PIO) pio = CY82C693_MAX_PIO; - /* let's calc the address setup time clocks */ - p_pclk->address_time = (byte)calc_clk(t->setup, system_bus_speed); + /* address setup */ + p_pclk->address_time = calc_clk(t->setup, system_bus_speed); - /* let's calc the active and recovery time clocks */ + /* active */ clk1 = calc_clk(t->active, system_bus_speed); - /* calc recovery timing */ - clk2 = t->cycle - t->active - t->setup; - - clk2 = calc_clk(clk2, system_bus_speed); + /* FIXME: check why not t->cycle - t->active ? --bkz */ + /* recovery */ + clk2 = calc_clk(t->cycle - t->active - t->setup, system_bus_speed); - clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */ + clk1 = (clk1 << 4) | clk2; /* combine active and recovery clocks */ /* note: we use the same values for 16bit IOR and IOW * those are all the same, since I don't have other * timings than those from ata-timing.h */ + p_pclk->time_16w = p_pclk->time_16r = clk1; - p_pclk->time_16r = (byte)clk1; - p_pclk->time_16w = (byte)clk1; - + /* FIXME: ugh... --bkz */ /* what are good values for 8bit ?? */ - p_pclk->time_8 = (byte)clk1; + p_pclk->time_8 = clk1; } #ifdef CONFIG_BLK_DEV_IDEDMA @@ -276,7 +277,9 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio) struct pci_dev *dev = hwif->pci_dev; pio_clocks_t pclk; unsigned int addrCtrl; + u8 ior, iow, bit8; + /* FIXME: probaly broken --bkz */ /* select primary or secondary channel */ if (hwif->index > 0) { /* drive is on the secondary channel */ dev = pci_find_slot(dev->bus->number, dev->devfn+1); @@ -286,40 +289,41 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio) } } + if (drive->select.b.unit == 0) { + ior = CY82_IDE_MASTER_IOR; + iow = CY82_IDE_MASTER_IOW; + bit8 = CY82_IDE_MASTER_8BIT; + } else { + ior = CY82_IDE_SLAVE_IOR; + iow = CY82_IDE_SLAVE_IOW; + bit8 = CY82_IDE_SLAVE_8BIT; + } + #if CY82C693_DEBUG_LOGS /* for debug let's show the register values */ - if (drive->select.b.unit == 0) { - /* - * get master drive registers - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - addrCtrl &= 0x0F; - - /* now let's get the remaining registers */ - pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r); - pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w); - pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8); - } else { - /* - * set slave drive registers - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + /* + * get address setup control register + * mine master or slave data + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); + if (drive->select.b.unit == 0) + addrCtrl &= 0x0F; + else { addrCtrl &= 0xF0; addrCtrl >>= 4; - - /* now let's get the remaining registers */ - pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r); - pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w); - pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8); } - printk (KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); + /* now let's get the remaining registers */ + pci_read_config_byte(dev, ior, &pclk.time_16r); + pci_read_config_byte(dev, iow, &pclk.time_16w); + pci_read_config_byte(dev, bit8, &pclk.time_8); + + printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X," + " ior=0x%X, iow=0x%X, 8bit=0x%X)\n", + drive->name, hwif->unit, drive->select.b.unit, + addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); #endif /* CY82C693_DEBUG_LOGS */ /* first let's calc the pio modes */ @@ -331,65 +335,37 @@ static void cy82c693_tune_drive(struct ata_device *drive, byte pio) compute_clocks(pio, &pclk); /* let's calc the values for this PIO mode */ - /* now let's write the clocks registers */ + /* + * set address setup control register + */ + pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); if (drive->select.b.unit == 0) { - /* - * set master drive - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - - addrCtrl &= (~0xF); + addrCtrl &= (~0x0F); addrCtrl |= (unsigned int)pclk.address_time; - pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); - - /* now let's set the remaining registers */ - pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r); - pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w); - pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8); - - addrCtrl &= 0xF; } else { - /* - * set slave drive - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - addrCtrl &= (~0xF0); addrCtrl |= ((unsigned int)pclk.address_time<<4); - pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); - - /* now let's set the remaining registers */ - pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r); - pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w); - pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8); - - addrCtrl >>= 4; - addrCtrl &= 0xF; } + pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); + + /* now let's set the remaining registers */ + pci_write_config_byte(dev, ior, pclk.time_16r); + pci_write_config_byte(dev, iow, pclk.time_16w); + pci_write_config_byte(dev, bit8, pclk.time_8); #if CY82C693_DEBUG_INFO - printk (KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); -#endif /* CY82C693_DEBUG_INFO */ + printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X," + " ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, + hwif->unit, drive->select.b.unit, addrCtrl, + pclk.time_16r, pclk.time_16w, pclk.time_8); +#endif } -/* - * this function is called during init and is used to setup the cy82c693 chip - */ -/* - * FIXME! "pci_init_cy82c693" really should replace - * the "init_cy82c693_chip", it is the correct location to tinker/setup - * the device prior to INIT. - */ - static unsigned int __init pci_init_cy82c693(struct pci_dev *dev) { #ifdef CY82C693_SETDMA_CLOCK - byte data; -#endif /* CY82C693_SETDMA_CLOCK */ + u8 data; +#endif /* write info about this verion of the driver */ printk (KERN_INFO CY82_VERSION "\n"); @@ -402,7 +378,7 @@ static unsigned int __init pci_init_cy82c693(struct pci_dev *dev) #if CY82C693_DEBUG_INFO printk (KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", dev->name, data); -#endif /* CY82C693_DEBUG_INFO */ +#endif /* * for some reason sometimes the DMA controller diff --git a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c index 8dd23001cd24..4aeb0b7afb58 100644 --- a/drivers/ide/hpt34x.c +++ b/drivers/ide/hpt34x.c @@ -5,19 +5,7 @@ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * - * - * 00:12.0 Unknown mass storage controller: - * Triones Technologies, Inc. - * Unknown device 0003 (rev 01) - * - * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010) - * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030) - * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010) - * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030) - * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070) - * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0) - * - * ide-pci.c reference + * ide-pci.c reference: * * Since there are two cards that report almost identically, * the only discernable difference is the values reported in pcicmd. @@ -45,53 +33,34 @@ #include "ata-timing.h" #include "pcihost.h" -#ifndef SPLIT_BYTE -# define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) -#endif - #define HPT343_DEBUG_DRIVE_INFO 0 -static void hpt34x_clear_chipset(struct ata_device *drive) -{ - unsigned int reg1 = 0, tmp1 = 0; - unsigned int reg2 = 0, tmp2 = 0; - - pci_read_config_dword(drive->channel->pci_dev, 0x44, ®1); - pci_read_config_dword(drive->channel->pci_dev, 0x48, ®2); - tmp1 = ((0x00 << (3 * drive->dn)) | (reg1 & ~(7 << (3 * drive->dn)))); - tmp2 = (reg2 & ~(0x11 << drive->dn)); - pci_write_config_dword(drive->channel->pci_dev, 0x44, tmp1); - pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2); -} - -static int hpt34x_tune_chipset(struct ata_device *drive, byte speed) +static int hpt34x_tune_chipset(struct ata_device *drive, u8 speed) { - byte hi_speed, lo_speed; - unsigned int reg1 = 0, tmp1 = 0; - unsigned int reg2 = 0, tmp2 = 0; - - SPLIT_BYTE(speed, hi_speed, lo_speed); - - if (hi_speed & 7) { - hi_speed = (hi_speed & 4) ? 0x01 : 0x10; - } else { - lo_speed <<= 5; - lo_speed >>= 5; - } + struct pci_dev *dev = drive->channel->pci_dev; + u8 udma = 0, pio = 0; + u32 reg1, reg2, tmp1, tmp2; + + if (speed >= XFER_UDMA_0) + udma = 0x01; + else if (speed >= XFER_SW_DMA_0) + udma = 0x10; + else + pio = speed & 7; - pci_read_config_dword(drive->channel->pci_dev, 0x44, ®1); - pci_read_config_dword(drive->channel->pci_dev, 0x48, ®2); - tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); - tmp2 = ((hi_speed << drive->dn) | reg2); - pci_write_config_dword(drive->channel->pci_dev, 0x44, tmp1); - pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2); + pci_read_config_dword(dev, 0x44, ®1); + pci_read_config_dword(dev, 0x48, ®2); + tmp1 = (pio << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))); + tmp2 = (udma << drive->dn) | (reg2 & ~(0x11 << drive->dn)); + pci_write_config_dword(dev, 0x44, tmp1); + pci_write_config_dword(dev, 0x48, tmp2); #if HPT343_DEBUG_DRIVE_INFO printk("%s: %02x drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ " (0x%02x 0x%02x) 0x%04x\n", drive->name, speed, drive->dn, reg1, tmp1, reg2, tmp2, - hi_speed, lo_speed, err); + udma, pio, err); #endif drive->current_speed = speed; @@ -103,7 +72,7 @@ static void config_chipset_for_pio(struct ata_device *drive) unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; unsigned short xfer_pio = drive->id->eide_pio_modes; - byte timing, speed, pio; + u8 timing, speed, pio; pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; @@ -135,19 +104,9 @@ static void config_chipset_for_pio(struct ata_device *drive) (void) hpt34x_tune_chipset(drive, speed); } -static void hpt34x_tune_drive(struct ata_device *drive, byte pio) +static void hpt34x_tune_drive(struct ata_device *drive, u8 pio) { - byte speed; - - switch(pio) { - case 4: speed = XFER_PIO_4;break; - case 3: speed = XFER_PIO_3;break; - case 2: speed = XFER_PIO_2;break; - case 1: speed = XFER_PIO_1;break; - default: speed = XFER_PIO_0;break; - } - hpt34x_clear_chipset(drive); - (void) hpt34x_tune_chipset(drive, speed); + (void) hpt34x_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4)); } #ifdef CONFIG_BLK_DEV_IDEDMA @@ -168,7 +127,6 @@ static int config_chipset_for_dma(struct ata_device *drive, u8 udma) if (mode < XFER_SW_DMA_0) return 0; - hpt34x_clear_chipset(drive); return !hpt34x_tune_chipset(drive, mode); } diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index a46993786585..8a739c4f7058 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -476,8 +476,6 @@ static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = { #define F_LOW_PCI_50 0x2d #define F_LOW_PCI_66 0x42 -static unsigned int hpt_min_rev(struct pci_dev *dev, int rev); - static int check_in_drive_lists(struct ata_device *drive, const char **list) { struct hd_driveid *id = drive->id; @@ -515,29 +513,24 @@ static unsigned int hpt_revision(struct pci_dev *dev) return class_rev; } -static unsigned int hpt_min_rev(struct pci_dev *dev, int rev) -{ - return (hpt_revision(dev) >= rev) ? 1 : 0; -} - static int hpt3xx_ratemask(struct ata_device *drive) { - struct pci_dev *dev = drive->channel->pci_dev; + u32 rev = hpt_revision(drive->channel->pci_dev); int map = XFER_UDMA; - if (hpt_min_rev(dev, 8)) { /* HPT374 */ + if (rev >= 8) { /* HPT374 */ if (HPT374_ALLOW_ATA133_6) map |= XFER_UDMA_133; map |= (XFER_UDMA_100 | XFER_UDMA_66); - } else if (hpt_min_rev(dev, 5)) { /* HPT372 */ + } else if (rev >= 5) { /* HPT372 */ if (HPT372_ALLOW_ATA133_6) map |= XFER_UDMA_133; map |= (XFER_UDMA_100 | XFER_UDMA_66); - } else if (hpt_min_rev(dev, 4)) { /* HPT370A */ + } else if (rev >= 4) { /* HPT370A */ if (HPT370_ALLOW_ATA100_5) map |= XFER_UDMA_100; map |= XFER_UDMA_66; - } else if (hpt_min_rev(dev, 3)) { /* HPT370 */ + } else if (rev >= 3) { /* HPT370 */ if (HPT370_ALLOW_ATA100_5) map |= XFER_UDMA_100; map |= XFER_UDMA_66; @@ -600,11 +593,6 @@ static void hpt366_tune_chipset(struct ata_device *drive, u8 speed) pci_write_config_dword(dev, regtime, reg2); } -static void hpt368_tune_chipset(struct ata_device *drive, u8 speed) -{ - hpt366_tune_chipset(drive, speed); -} - static void hpt370_tune_chipset(struct ata_device *drive, u8 speed) { u8 regfast = (drive->channel->unit) ? 0x55 : 0x51; @@ -674,31 +662,24 @@ static void hpt372_tune_chipset(struct ata_device *drive, u8 speed) pci_write_config_dword(dev, drive_pci, list_conf); } -static void hpt374_tune_chipset(struct ata_device *drive, u8 speed) -{ - hpt372_tune_chipset(drive, speed); -} - static int hpt3xx_tune_chipset(struct ata_device *drive, u8 speed) { - struct pci_dev *dev = drive->channel->pci_dev; + u32 rev; if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0)) return -1; - if (hpt_min_rev(dev, 7)) { - hpt374_tune_chipset(drive, speed); - } else if (hpt_min_rev(dev, 5)) { + rev = hpt_revision(drive->channel->pci_dev); + + if (rev >= 5) { hpt372_tune_chipset(drive, speed); - } else if (hpt_min_rev(dev, 3)) { + } else if (rev >= 3) { hpt370_tune_chipset(drive, speed); - } else if (hpt_min_rev(dev, 2)) { - hpt368_tune_chipset(drive, speed); } else { hpt366_tune_chipset(drive, speed); } drive->current_speed = speed; - return ((int) ide_config_drive_speed(drive, speed)); + return ide_config_drive_speed(drive, speed); } static void config_chipset_for_pio(struct ata_device *drive) @@ -755,13 +736,15 @@ static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio) #ifdef CONFIG_BLK_DEV_IDEDMA static int config_chipset_for_dma(struct ata_device *drive) { - struct pci_dev *dev = drive->channel->pci_dev; int map; + u32 rev; u8 mode; if (drive->type != ATA_DISK) return 0; + rev = hpt_revision(drive->channel->pci_dev); + /* FIXME: check SWDMA modes --bkz */ map = hpt3xx_ratemask(drive) | XFER_MWDMA; mode = ata_timing_mode(drive, map); @@ -770,7 +753,7 @@ static int config_chipset_for_dma(struct ata_device *drive) bad_ata100_5 is for HPT370/370A, bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368 */ - if (mode == XFER_UDMA_5 && hpt_min_rev(dev, 5)) { + if (mode == XFER_UDMA_5 && rev < 5) { if (check_in_drive_lists(drive, bad_ata100_5)) { /* FIXME: make XFER_UDMA_66/100/133 independent of XFER_UDMA --bkz */ @@ -779,7 +762,7 @@ static int config_chipset_for_dma(struct ata_device *drive) mode = ata_timing_mode(drive, map); } } - if (mode == XFER_UDMA_4 && hpt_min_rev(dev, 3)) { + if (mode == XFER_UDMA_4 && rev < 3) { if (check_in_drive_lists(drive, bad_ata66_4)) { if (drive->id->dma_ultra & 0x0008) { mode = XFER_UDMA_3; @@ -790,14 +773,14 @@ static int config_chipset_for_dma(struct ata_device *drive) } } } - if (mode == XFER_UDMA_3 && hpt_min_rev(dev, 3)) { + if (mode == XFER_UDMA_3 && rev < 3) { if (check_in_drive_lists(drive, bad_ata66_3)) { map &= ~XFER_UDMA_66; map |= XFER_UDMA; mode = ata_timing_mode(drive, map); } } - if (check_in_drive_lists(drive, bad_ata33) && hpt_min_rev(dev, 3)) + if (check_in_drive_lists(drive, bad_ata33) && rev < 3) mode = ata_timing_mode(drive, XFER_MWDMA); return !hpt3xx_tune_chipset(drive, mode); @@ -823,7 +806,8 @@ static void hpt3xx_maskproc(struct ata_device *drive) struct ata_channel *ch = drive->channel; if (drive->quirk_list) { - if (hpt_min_rev(dev, 3)) { + u32 rev = hpt_revision(dev); + if (rev >= 3) { u8 reg5a; pci_read_config_byte(dev, 0x5a, ®5a); if ((reg5a & 0x10) >> 4) @@ -892,15 +876,16 @@ no_dma_set: static void hpt366_udma_irq_lost(struct ata_device *drive) { + struct pci_dev *dev = drive->channel->pci_dev; u8 reg50h, reg52h, reg5ah; - pci_read_config_byte(drive->channel->pci_dev, 0x50, ®50h); - pci_read_config_byte(drive->channel->pci_dev, 0x52, ®52h); - pci_read_config_byte(drive->channel->pci_dev, 0x5a, ®5ah); + pci_read_config_byte(dev, 0x50, ®50h); + pci_read_config_byte(dev, 0x52, ®52h); + pci_read_config_byte(dev, 0x5a, ®5ah); printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n", drive->name, __FUNCTION__, reg50h, reg52h, reg5ah); if (reg5ah & 0x10) - pci_write_config_byte(drive->channel->pci_dev, 0x5a, reg5ah & ~0x10); + pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10); } static void do_udma_start(struct ata_device *drive) @@ -1127,7 +1112,7 @@ static void __init hpt37x_init(struct pci_dev *dev) { int adjust, i; u16 freq; - u32 pll; + u32 pll, rev = hpt_revision(dev); u8 reg5bh; /* @@ -1144,9 +1129,9 @@ static void __init hpt37x_init(struct pci_dev *dev) freq &= 0x1FF; if (freq < 0x9c) { pll = F_LOW_PCI_33; - if (hpt_min_rev(dev, 7)) { + if (rev >= 7) { dev->sysdata = (void *) thirty_three_base_hpt374; - } else if (hpt_min_rev(dev, 5)) { + } else if (rev >= 5) { dev->sysdata = (void *) thirty_three_base_hpt372; } else { dev->sysdata = (void *) thirty_three_base_hpt370; @@ -1156,10 +1141,10 @@ static void __init hpt37x_init(struct pci_dev *dev) pll = F_LOW_PCI_40; } else if (freq < 0xc8) { pll = F_LOW_PCI_50; - if (hpt_min_rev(dev, 7)) { + if (rev >= 7) { // dev->sysdata = (void *) fifty_base_hpt374; BUG(); - } else if (hpt_min_rev(dev, 5)) { + } else if (rev >= 5) { dev->sysdata = (void *) fifty_base_hpt372; } else { dev->sysdata = (void *) fifty_base_hpt370; @@ -1167,10 +1152,10 @@ static void __init hpt37x_init(struct pci_dev *dev) printk("HPT37X: using 50MHz PCI clock\n"); } else { pll = F_LOW_PCI_66; - if (hpt_min_rev(dev, 7)) { + if (rev >= 7) { // dev->sysdata = (void *) sixty_six_base_hpt374; BUG(); - } else if (hpt_min_rev(dev, 5)) { + } else if (rev >= 5) { dev->sysdata = (void *) sixty_six_base_hpt372; } else { dev->sysdata = (void *) sixty_six_base_hpt370; @@ -1213,10 +1198,10 @@ static void __init hpt37x_init(struct pci_dev *dev) pci_write_config_dword(dev, 0x5c, pll & ~0x100); pci_write_config_byte(dev, 0x5b, 0x21); - if (hpt_min_rev(dev, 7)) { + if (rev >= 7) { // dev->sysdata = (void *) fifty_base_hpt374; BUG(); - } else if (hpt_min_rev(dev, 5)) { + } else if (rev >= 5) { dev->sysdata = (void *) fifty_base_hpt372; } else { dev->sysdata = (void *) fifty_base_hpt370; @@ -1269,6 +1254,7 @@ static void __init hpt366_init(struct pci_dev *dev) static unsigned int __init hpt366_init_chipset(struct pci_dev *dev) { + u32 rev = hpt_revision(dev); u8 test; if (dev->resource[PCI_ROM_RESOURCE].start) @@ -1290,7 +1276,7 @@ static unsigned int __init hpt366_init_chipset(struct pci_dev *dev) if (test != 0x08) pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); - if (hpt_min_rev(dev, 3)) + if (rev >= 3) hpt37x_init(dev); else hpt366_init(dev); @@ -1315,6 +1301,7 @@ static unsigned int __init hpt366_ata66_check(struct ata_channel *ch) static void __init hpt366_init_channel(struct ata_channel *ch) { struct pci_dev *dev = ch->pci_dev; + u32 rev = hpt_revision(dev); ch->tuneproc = hpt3xx_tune_drive; ch->speedproc = hpt3xx_tune_chipset; @@ -1330,7 +1317,7 @@ static void __init hpt366_init_channel(struct ata_channel *ch) #ifdef CONFIG_BLK_DEV_IDEDMA if (ch->dma_base) { - if (hpt_min_rev(dev, 3)) { + if (rev >= 3) { u8 reg5ah; pci_read_config_byte(dev, 0x5a, ®5ah); if (reg5ah & 0x10) /* interrupt force enable */ @@ -1343,45 +1330,33 @@ static void __init hpt366_init_channel(struct ata_channel *ch) ch->resetproc = hpt3xx_reset; ch->busproc = hpt370_busproc; - if (hpt_min_rev(dev, 7)) { + if (rev >= 5) { ch->udma_stop = hpt374_udma_stop; - ch->udma_setup = hpt3xx_udma_setup; - } else if (hpt_min_rev(dev, 5)) { - ch->udma_stop = hpt374_udma_stop; - ch->udma_setup = hpt3xx_udma_setup; - } else if (hpt_min_rev(dev, 3)) { + } else { /* rev >= 3 */ ch->udma_start = hpt370_udma_start; ch->udma_stop = hpt370_udma_stop; ch->udma_timeout = hpt370_udma_timeout; ch->udma_irq_lost = hpt370_udma_irq_lost; - ch->udma_setup = hpt3xx_udma_setup; } - } else if (hpt_min_rev(dev, 2)) { - ch->udma_irq_lost = hpt366_udma_irq_lost; -// ch->resetproc = hpt3xx_reset; -// ch->busproc = hpt3xx_tristate; - ch->udma_setup = hpt3xx_udma_setup; } else { ch->udma_irq_lost = hpt366_udma_irq_lost; // ch->resetproc = hpt3xx_reset; // ch->busproc = hpt3xx_tristate; - ch->udma_setup = hpt3xx_udma_setup; } + ch->udma_setup = hpt3xx_udma_setup; + if (!noautodma) ch->autodma = 1; else ch->autodma = 0; ch->highmem = 1; - } else { + } else +#endif + { ch->autodma = 0; ch->drives[0].autotune = 1; ch->drives[1].autotune = 1; } -#else - ch->drives[0].autotune = 1; - ch->drives[1].autotune = 1; - ch->autodma = 0; -#endif } static void __init hpt366_init_dma(struct ata_channel *ch, unsigned long dmabase) @@ -1390,10 +1365,9 @@ static void __init hpt366_init_dma(struct ata_channel *ch, unsigned long dmabase u8 dma_old = inb(dmabase + 2); u8 dma_new = dma_old; u8 primary = ch->unit ? 0x4b : 0x43; - u8 secondary = primary + 4; pci_read_config_byte(ch->pci_dev, primary, &masterdma); - pci_read_config_byte(ch->pci_dev, secondary, &slavedma); + pci_read_config_byte(ch->pci_dev, primary + 4, &slavedma); if (masterdma & 0x30) dma_new |= 0x20; @@ -1447,9 +1421,8 @@ int __init init_hpt366(void) { int i; - for (i = 0; i < ARRAY_SIZE(chipsets); ++i) { + for (i = 0; i < ARRAY_SIZE(chipsets); ++i) ata_register_chipset(&chipsets[i]); - } return 0; } diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index 0d1c45864bff..c919b166723d 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c @@ -1,5 +1,5 @@ -/*====================================================================== - +/**** vi:set ts=8 sts=8 sw=8:************************************************ + * A driver for PCMCIA IDE/ATA disk cards ide_cs.c 1.26 1999/11/16 02:10:49 @@ -28,8 +28,8 @@ and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. - -======================================================================*/ + * + */ #include <linux/module.h> #include <linux/kernel.h> @@ -54,12 +54,12 @@ #include <pcmcia/ds.h> #include <pcmcia/cisreg.h> +#define PCMCIA_DEBUG 100 #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -static char *version = -"ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)"; +static const char *version = "ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -81,23 +81,23 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ static const char ide_major[] = { - IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, + IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, #ifdef IDE4_MAJOR - IDE4_MAJOR, IDE5_MAJOR + IDE4_MAJOR, IDE5_MAJOR #endif }; typedef struct ide_info_t { - dev_link_t link; - int ndev; - dev_node_t node; - int hd; + dev_link_t link; + int ndev; + dev_node_t node; + int hd; } ide_info_t; -static void ide_config(dev_link_t *link); +static void ide_config(dev_link_t * link); static void ide_release(u_long arg); static int ide_event(event_t event, int priority, - event_callback_args_t *args); + event_callback_args_t * args); static dev_info_t dev_info = "ide-cs"; @@ -110,8 +110,11 @@ static dev_link_t *dev_list = NULL; static void cs_error(client_handle_t handle, int func, int ret) { - error_info_t err = { func, ret }; - CardServices(ReportError, handle, &err); + error_info_t err = { func, ret }; + + DEBUG(0, "cs_error\n"); + + CardServices(ReportError, handle, &err); } /*====================================================================== @@ -124,56 +127,58 @@ static void cs_error(client_handle_t handle, int func, int ret) static dev_link_t *ide_attach(void) { - ide_info_t *info; - dev_link_t *link; - client_reg_t client_reg; - int i, ret; - - DEBUG(0, "ide_attach()\n"); - - /* Create new ide device */ - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) return NULL; - memset(info, 0, sizeof(*info)); - link = &info->link; link->priv = info; - - link->release.function = &ide_release; - link->release.data = (u_long)link; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = 3; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; - if (irq_list[0] == -1) - link->irq.IRQInfo2 = irq_mask; - else - for (i = 0; i < 4; i++) - link->irq.IRQInfo2 |= 1 << irq_list[i]; - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - client_reg.dev_info = &dev_info; - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; - client_reg.EventMask = - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | - CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | - CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; - client_reg.event_handler = &ide_event; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - ret = CardServices(RegisterClient, &link->handle, &client_reg); - if (ret != CS_SUCCESS) { - cs_error(link->handle, RegisterClient, ret); - ide_detach(link); - return NULL; - } - - return link; -} /* ide_attach */ + ide_info_t *info; + dev_link_t *link; + client_reg_t client_reg; + int i, ret; + + DEBUG(0, "ide_attach\n"); + + /* Create new ide device */ + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return NULL; + memset(info, 0, sizeof(*info)); + link = &info->link; + link->priv = info; + + link->release.function = &ide_release; + link->release.data = (u_long) link; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = 3; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &ide_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != CS_SUCCESS) { + cs_error(link->handle, RegisterClient, ret); + ide_detach(link); + return NULL; + } + + return link; +} /* ide_attach */ /*====================================================================== @@ -184,34 +189,35 @@ static dev_link_t *ide_attach(void) ======================================================================*/ -static void ide_detach(dev_link_t *link) +static void ide_detach(dev_link_t * link) { - dev_link_t **linkp; - int ret; - - DEBUG(0, "ide_detach(0x%p)\n", link); - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; + dev_link_t **linkp; + int ret; + + DEBUG(0, "ide_detach(0x%p)\n", link); - del_timer(&link->release); - if (link->state & DEV_CONFIG) - ide_release((u_long)link); - - if (link->handle) { - ret = CardServices(DeregisterClient, link->handle); - if (ret != CS_SUCCESS) - cs_error(link->handle, DeregisterClient, ret); - } - - /* Unlink, free device structure */ - *linkp = link->next; - kfree(link->priv); - -} /* ide_detach */ + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) + break; + if (*linkp == NULL) + return; + + del_timer(&link->release); + if (link->state & DEV_CONFIG) + ide_release((u_long) link); + + if (link->handle) { + ret = CardServices(DeregisterClient, link->handle); + if (ret != CS_SUCCESS) + cs_error(link->handle, DeregisterClient, ret); + } + + /* Unlink, free device structure */ + *linkp = link->next; + kfree(link->priv); + +} /* ide_detach */ /*====================================================================== @@ -227,199 +233,224 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed #define CFG_CHECK(fn, args...) \ if (CardServices(fn, args) != 0) goto next_entry -int idecs_register (int arg1, int arg2, int irq) +int idecs_register(int arg1, int arg2, int irq) { - hw_regs_t hw; - ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL); - hw.irq = irq; - hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */ + hw_regs_t hw; - return ide_register_hw(&hw); + DEBUG(0, "idecs_register\n"); + + ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, + NULL); + hw.irq = irq; + hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */ + + return ide_register_hw(&hw); } -void ide_config(dev_link_t *link) +void ide_config(dev_link_t * link) { - client_handle_t handle = link->handle; - ide_info_t *info = link->priv; - tuple_t tuple; - u_short buf[128]; - cisparse_t parse; - config_info_t conf; - cistpl_cftable_entry_t *cfg = &parse.cftable_entry; - cistpl_cftable_entry_t dflt = { 0 }; - int i, pass, last_ret, last_fn, hd=-1, io_base, ctl_base; - - DEBUG(0, "ide_config(0x%p)\n", link); - - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleOffset = 0; tuple.TupleDataMax = 255; - tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CONFIG; - CS_CHECK(GetFirstTuple, handle, &tuple); - CS_CHECK(GetTupleData, handle, &tuple); - CS_CHECK(ParseTuple, handle, &tuple, &parse); - link->conf.ConfigBase = parse.config.base; - link->conf.Present = parse.config.rmask[0]; - - /* Configure card */ - link->state |= DEV_CONFIG; - - /* Not sure if this is right... look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, handle, &conf); - link->conf.Vcc = conf.Vcc; - - pass = io_base = ctl_base = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, handle, &tuple); - while (1) { - CFG_CHECK(GetTupleData, handle, &tuple); - CFG_CHECK(ParseTuple, handle, &tuple, &parse); - - /* Check for matching Vcc, unless we're desperate */ - if (!pass) { - if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { - if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) - goto next_entry; - } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { - if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) - goto next_entry; - } - } - - if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = - cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; - else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = - dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; - - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->conf.ConfigIndex = cfg->index; - link->io.BasePort1 = io->win[0].base; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - if (io->nwin == 2) { - link->io.NumPorts1 = 8; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = 1; - CFG_CHECK(RequestIO, link->handle, &link->io); - io_base = link->io.BasePort1; - ctl_base = link->io.BasePort2; - } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { - link->io.NumPorts1 = io->win[0].len; - link->io.NumPorts2 = 0; - CFG_CHECK(RequestIO, link->handle, &link->io); - io_base = link->io.BasePort1; - ctl_base = link->io.BasePort1+0x0e; - } else goto next_entry; - /* If we've got this far, we're done */ - break; + client_handle_t handle = link->handle; + ide_info_t *info = link->priv; + tuple_t tuple; + u_short buf[128]; + cisparse_t parse; + config_info_t conf; + cistpl_cftable_entry_t *cfg = &parse.cftable_entry; + cistpl_cftable_entry_t dflt = { 0 }; + int i, pass, last_ret, last_fn, hd = -1, io_base, ctl_base; + + DEBUG(0, "ide_config(0x%p)\n", link); + + tuple.TupleData = (cisdata_t *) buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, handle, &tuple); + CS_CHECK(GetTupleData, handle, &tuple); + CS_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Not sure if this is right... look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, handle, &conf); + link->conf.Vcc = conf.Vcc; + + pass = io_base = ctl_base = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, handle, &tuple); + while (1) { + CFG_CHECK(GetTupleData, handle, &tuple); + CFG_CHECK(ParseTuple, handle, &tuple, &parse); + + /* Check for matching Vcc, unless we're desperate */ + if (!pass) { + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != + cfg->vcc.param[CISTPL_POWER_VNOM] / + 10000) + goto next_entry; + } else if (dflt.vcc. + present & (1 << CISTPL_POWER_VNOM)) { + if (conf.Vcc != + dflt.vcc.param[CISTPL_POWER_VNOM] / + 10000) + goto next_entry; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp1 = link->conf.Vpp2 = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) + link->conf.Vpp1 = link->conf.Vpp2 = + dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = + (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->conf.ConfigIndex = cfg->index; + link->io.BasePort1 = io->win[0].base; + link->io.IOAddrLines = + io->flags & CISTPL_IO_LINES_MASK; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = + IO_DATA_PATH_WIDTH_8; + if (io->nwin == 2) { + link->io.NumPorts1 = 8; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = 1; + CFG_CHECK(RequestIO, link->handle, + &link->io); + io_base = link->io.BasePort1; + ctl_base = link->io.BasePort2; + } else if ((io->nwin == 1) + && (io->win[0].len >= 16)) { + link->io.NumPorts1 = io->win[0].len; + link->io.NumPorts2 = 0; + CFG_CHECK(RequestIO, link->handle, + &link->io); + io_base = link->io.BasePort1; + ctl_base = link->io.BasePort1 + 0x0e; + } else + goto next_entry; + /* If we've got this far, we're done */ + break; + } + + next_entry: + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + dflt = *cfg; + if (pass) { + CS_CHECK(GetNextTuple, handle, &tuple); + } else if (CardServices(GetNextTuple, handle, &tuple) != 0) { + CS_CHECK(GetFirstTuple, handle, &tuple); + memset(&dflt, 0, sizeof(dflt)); + pass++; + } } - - next_entry: - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; - if (pass) { - CS_CHECK(GetNextTuple, handle, &tuple); - } else if (CardServices(GetNextTuple, handle, &tuple) != 0) { - CS_CHECK(GetFirstTuple, handle, &tuple); - memset(&dflt, 0, sizeof(dflt)); - pass++; + + CS_CHECK(RequestIRQ, handle, &link->irq); + CS_CHECK(RequestConfiguration, handle, &link->conf); + + /* deal with brain dead IDE resource management */ + release_region(link->io.BasePort1, link->io.NumPorts1); + if (link->io.NumPorts2) + release_region(link->io.BasePort2, link->io.NumPorts2); + + /* retry registration in case device is still spinning up */ + for (i = 0; i < 10; i++) { + if (ctl_base) + outb(0x02, ctl_base); /* Set nIEN = disable device interrupts */ + hd = idecs_register(io_base, ctl_base, + link->irq.AssignedIRQ); + if (hd >= 0) + break; + if (link->io.NumPorts1 == 0x20) { + if (ctl_base) + outb(0x02, ctl_base + 0x10); + hd = idecs_register(io_base + 0x10, + ctl_base + 0x10, + link->irq.AssignedIRQ); + if (hd >= 0) { + io_base += 0x10; + ctl_base += 0x10; + break; + } + } + __set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); } - } - - CS_CHECK(RequestIRQ, handle, &link->irq); - CS_CHECK(RequestConfiguration, handle, &link->conf); - - /* deal with brain dead IDE resource management */ - release_region(link->io.BasePort1, link->io.NumPorts1); - if (link->io.NumPorts2) - release_region(link->io.BasePort2, link->io.NumPorts2); - - /* retry registration in case device is still spinning up */ - for (i = 0; i < 10; i++) { - if (ctl_base) - outb(0x02, ctl_base); /* Set nIEN = disable device interrupts */ - hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); - if (hd >= 0) break; - if (link->io.NumPorts1 == 0x20) { - if (ctl_base) - outb(0x02, ctl_base+0x10); - hd = idecs_register(io_base+0x10, ctl_base+0x10, - link->irq.AssignedIRQ); - if (hd >= 0) { - io_base += 0x10; ctl_base += 0x10; - break; - } + + if (hd < 0) { + printk(KERN_NOTICE + "ide_cs: ide_register() at 0x%03x & 0x%03x" + ", irq %u failed\n", io_base, ctl_base, + link->irq.AssignedIRQ); + goto failed; } - __set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); - } - - if (hd < 0) { - printk(KERN_NOTICE "ide_cs: ide_register() at 0x%03x & 0x%03x" - ", irq %u failed\n", io_base, ctl_base, - link->irq.AssignedIRQ); - goto failed; - } - - MOD_INC_USE_COUNT; - info->ndev = 1; - sprintf(info->node.dev_name, "hd%c", 'a'+(hd*2)); - info->node.major = ide_major[hd]; - info->node.minor = 0; - info->hd = hd; - link->dev = &info->node; - printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n", - info->node.dev_name, link->conf.Vcc/10, link->conf.Vcc%10, - link->conf.Vpp1/10, link->conf.Vpp1%10); - - link->state &= ~DEV_CONFIG_PENDING; - return; - -cs_failed: - cs_error(link->handle, last_fn, last_ret); -failed: - ide_release((u_long)link); - -} /* ide_config */ + + MOD_INC_USE_COUNT; + info->ndev = 1; + sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2)); + info->node.major = ide_major[hd]; + info->node.minor = 0; + info->hd = hd; + link->dev = &info->node; + printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n", + info->node.dev_name, link->conf.Vcc / 10, + link->conf.Vcc % 10, link->conf.Vpp1 / 10, + link->conf.Vpp1 % 10); + + link->state &= ~DEV_CONFIG_PENDING; + return; + + cs_failed: + cs_error(link->handle, last_fn, last_ret); + failed: + ide_release((u_long) link); + +} /* ide_config */ /*====================================================================== After a card is removed, ide_release() will unregister the net device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. - + ======================================================================*/ void ide_release(u_long arg) { - dev_link_t *link = (dev_link_t *)arg; - ide_info_t *info = link->priv; - - DEBUG(0, "ide_release(0x%p)\n", link); - - if (info->ndev) { - ide_unregister(&ide_hwifs[info->hd]); - MOD_DEC_USE_COUNT; - } - - request_region(link->io.BasePort1, link->io.NumPorts1,"ide-cs"); - if (link->io.NumPorts2) - request_region(link->io.BasePort2, link->io.NumPorts2,"ide-cs"); - - info->ndev = 0; - link->dev = NULL; - - CardServices(ReleaseConfiguration, link->handle); - CardServices(ReleaseIO, link->handle, &link->io); - CardServices(ReleaseIRQ, link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; - -} /* ide_release */ + dev_link_t *link = (dev_link_t *) arg; + ide_info_t *info = link->priv; + + DEBUG(0, "ide_release(0x%p)\n", link); + + if (info->ndev) { + ide_unregister(&ide_hwifs[info->hd]); + MOD_DEC_USE_COUNT; + } + + request_region(link->io.BasePort1, link->io.NumPorts1, "ide-cs"); + if (link->io.NumPorts2) + request_region(link->io.BasePort2, link->io.NumPorts2, + "ide-cs"); + + info->ndev = 0; + link->dev = NULL; + + CardServices(ReleaseConfiguration, link->handle); + CardServices(ReleaseIO, link->handle, &link->io); + CardServices(ReleaseIRQ, link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; + +} /* ide_release */ /*====================================================================== @@ -427,66 +458,67 @@ void ide_release(u_long arg) stuff to run after an event is received. A CARD_REMOVAL event also sets some flags to discourage the ide drivers from talking to the ports. - + ======================================================================*/ -int ide_event(event_t event, int priority, - event_callback_args_t *args) +int ide_event(event_t event, int priority, event_callback_args_t * args) { - dev_link_t *link = args->client_data; + dev_link_t *link = args->client_data; - DEBUG(1, "ide_event(0x%06x)\n", event); - - switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) - mod_timer(&link->release, jiffies + HZ/20); - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - ide_config(link); - break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - if (link->state & DEV_CONFIG) - CardServices(ReleaseConfiguration, link->handle); - break; - case CS_EVENT_PM_RESUME: - link->state &= ~DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_CARD_RESET: - if (DEV_OK(link)) - CardServices(RequestConfiguration, link->handle, &link->conf); - break; - } - return 0; -} /* ide_event */ + DEBUG(1, "ide_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) + mod_timer(&link->release, jiffies + HZ / 20); + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + ide_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) + CardServices(ReleaseConfiguration, link->handle); + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (DEV_OK(link)) + CardServices(RequestConfiguration, link->handle, + &link->conf); + break; + } + return 0; +} /* ide_event */ /*====================================================================*/ static int __init init_ide_cs(void) { - servinfo_t serv; - DEBUG(0, "%s\n", version); - CardServices(GetCardServicesInfo, &serv); - if (serv.Revision != CS_RELEASE_CODE) { - printk(KERN_NOTICE "ide_cs: Card Services release " - "does not match!\n"); - return -1; - } - register_pccard_driver(&dev_info, &ide_attach, &ide_detach); - return 0; + servinfo_t serv; + DEBUG(0, "%s\n", version); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "ide_cs: Card Services release " + "does not match!\n"); + return -1; + } + register_pccard_driver(&dev_info, &ide_attach, &ide_detach); + + return 0; } static void __exit exit_ide_cs(void) { - DEBUG(0, "ide_cs: unloading\n"); - unregister_pccard_driver(&dev_info); - while (dev_list != NULL) - ide_detach(dev_list); + DEBUG(0, "ide_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) + ide_detach(dev_list); } module_init(init_ide_cs); diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index e7cd124ec003..14f6f6cfb372 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -176,6 +176,9 @@ int drive_is_ready(struct ata_device *drive) return 1; /* drive ready: *might* be interrupting */ } +/* + * FIXME: Channel lock should be held on entry. + */ ide_startstop_t ata_taskfile(struct ata_device *drive, struct ata_taskfile *ar, struct request *rq) { diff --git a/drivers/ide/main.c b/drivers/ide/main.c index ca3fe84a1503..deb7ca8d1099 100644 --- a/drivers/ide/main.c +++ b/drivers/ide/main.c @@ -325,7 +325,6 @@ void ide_driver_module(void) int i; /* Don't reinit the probe if there is already one channel detected. */ - for (i = 0; i < MAX_HWIFS; ++i) { if (ide_hwifs[i].present) goto revalidate; @@ -565,33 +564,12 @@ static int subdriver_match(struct ata_channel *channel, struct ata_operations *o if (drive->present && !drive->driver) { (*ops->attach)(drive); if (drive->driver != NULL) - count++; + ++count; } } return count; } -static struct ata_operations * subdriver_iterator(struct ata_operations *prev) -{ - struct ata_operations *tmp; - unsigned long flags; - - spin_lock_irqsave(&ata_drivers_lock, flags); - - /* Restart from beginning if current ata_operations was deallocated, - or if prev is NULL. */ - for(tmp = ata_drivers; tmp != prev && tmp; tmp = tmp->next); - if (!tmp) - tmp = ata_drivers; - else - tmp = tmp->next; - - spin_unlock_irqrestore(&ata_drivers_lock, flags); - - return tmp; - -} - /* * Register an IDE interface, specifing exactly the registers etc * Set initializing=1 iff calling before probes have taken place. @@ -601,7 +579,6 @@ int ide_register_hw(hw_regs_t *hw) int h; int retry = 1; struct ata_channel *ch; - struct ata_operations *subdriver; do { for (h = 0; h < MAX_HWIFS; ++h) { @@ -639,12 +616,20 @@ found: } /* Look up whatever there is a subdriver, which will serve this - * device. + * device and execute the attach method it is providing. */ - subdriver = NULL; - while ((subdriver = subdriver_iterator(subdriver))) { - if (subdriver_match(ch, subdriver) > 0) - break; + { + struct ata_operations *tmp; + unsigned long flags; + + struct ata_operations *sd = NULL; + + spin_lock_irqsave(&ata_drivers_lock, flags); + for(tmp = ata_drivers; tmp; tmp = tmp->next) { + if (subdriver_match(ch, tmp) > 0) + break; + } + spin_unlock_irqrestore(&ata_drivers_lock, flags); } return (initializing || ch->present) ? h : -1; diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c index e39249907b43..aeeaf22f9865 100644 --- a/drivers/ide/pdc202xx.c +++ b/drivers/ide/pdc202xx.c @@ -3,6 +3,11 @@ * linux/drivers/ide/pdc202xx.c Version 0.30 May. 28, 2002 * * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2002 Bartlomiej Zolnierkiewicz + * + * Portions Copyright (C) 1999 Promise Technology, Inc. + * Author: Frank Tiernan (frankt@promise.com) + * * May be copied or modified under the terms of the GNU General Public License * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this @@ -24,12 +29,6 @@ * */ -/* - * Portions Copyright (C) 1999 Promise Technology, Inc. - * Author: Frank Tiernan (frankt@promise.com) - * Released under terms of General Public License - */ - #include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> @@ -61,9 +60,10 @@ #define IORDY_EN 0x20 /* PIO: IOREADY */ #define PREFETCH_EN 0x10 /* PIO: PREFETCH */ - -#define PDC_CLOCK(high_16) IN_BYTE(high_16 + 0x11) -#define UDMA_SPEED_FLAG(high_16) IN_BYTE(high_16 + 0x001f) +#define PDC_CLK 0x11 +#define PDC_PRIMARY 0x1a +#define PDC_SECONDARY 0x1b +#define PDC_UDMA 0x1f #if PDC202XX_DECODE_REGISTER_INFO @@ -78,23 +78,12 @@ static struct pdc_bit_messages pdc_reg_A[] = { { 0x20, "IORDY_EN" }, { 0x10, "PREFETCH_EN" }, /* PA3-PA0 - PIO "A" timing */ - { 0x08, "PA3" }, - { 0x04, "PA2" }, - { 0x02, "PA1" }, - { 0x01, "PA0" } }; static struct pdc_bit_messages pdc_reg_B[] = { /* MB2-MB0 - DMA "B" timing */ - { 0x80, "MB2" }, - { 0x40, "MB1" }, - { 0x20, "MB0" }, { 0x10, "PIO_FORCED/PB4" }, /* PIO_FORCE 1:0 */ /* PB3-PB0 - PIO "B" timing */ - { 0x08, "PB3" }, /* PIO flow Control mode */ - { 0x04, "PB2" }, /* PIO 4 */ - { 0x02, "PB1" }, /* PIO 3 half */ - { 0x01, "PB0" } /* PIO 3 other half */ }; static struct pdc_bit_messages pdc_reg_C[] = { @@ -103,10 +92,6 @@ static struct pdc_bit_messages pdc_reg_C[] = { { 0x20, "DMAR_EN" }, { 0x10, "DMAW_EN" }, /* MC3-MC0 - DMA "C" timing */ - { 0x08, "MC3" }, - { 0x04, "MC2" }, - { 0x02, "MC1" }, - { 0x01, "MC0" } }; static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits) @@ -115,7 +100,7 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits) printk(KERN_DEBUG " { "); - for (i = 0; i < 8; i++, msgs++) + for (i = 0; i < ARRAY_SIZE(msgs); i++, msgs++) if (bits & msgs->mask) printk(KERN_DEBUG "%s ", msgs->msg); @@ -123,13 +108,6 @@ static void pdc_dump_bits(struct pdc_bit_messages *msgs, byte bits) } #endif /* PDC202XX_DECODE_REGISTER_INFO */ - -static inline int init_high_16 (struct pci_dev *dev) -{ - return pci_resource_start(dev, 4); -} - - int check_in_drive_lists(struct ata_device *drive) { static const char *pdc_quirk_drives[] = { @@ -179,14 +157,11 @@ static int pdc202xx_ratemask(struct ata_device *drive) static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) { - struct ata_channel *hwif = drive->channel; - struct pci_dev *dev = hwif->pci_dev; - - unsigned int drive_conf; - byte drive_pci, AP, BP, CP; - byte TA = 0, TB = 0, TC = 0; + struct pci_dev *dev = drive->channel->pci_dev; + u32 drive_conf; + u8 drive_pci, AP, BP, CP, DP, TA = 0, TB, TC = 0; - if (drive->dn > 3) + if (drive->dn > 3) /* FIXME: remove this --bkz */ return -1; drive_pci = 0x60 + (drive->dn << 2); @@ -195,37 +170,12 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) return -1; pci_read_config_dword(dev, drive_pci, &drive_conf); - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); - -#ifdef CONFIG_BLK_DEV_IDEDMA - if (speed >= XFER_SW_DMA_0) { - if ((BP & 0xF0) && (CP & 0x0F)) { - /* clear DMA modes of upper 842 bits of B Register */ - /* clear PIO forced mode upper 1 bit of B Register */ - pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0); - /* clear DMA modes of lower 8421 bits of C Register */ - pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F); - } - } else -#endif /* CONFIG_BLK_DEV_IDEDMA */ - { - if ((AP & 0x0F) || (BP & 0x07)) { - /* clear PIO modes of lower 8421 bits of A Register */ - pci_write_config_byte(dev, (drive_pci), AP & ~0x0F); - /* clear PIO modes of lower 421 bits of B Register */ - pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07); - } - } - - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + pci_read_config_byte(dev, drive_pci, &AP); + pci_read_config_byte(dev, drive_pci + 1, &BP); + pci_read_config_byte(dev, drive_pci + 2, &CP); switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA - /* case XFER_UDMA_6: */ case XFER_UDMA_5: case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; @@ -249,20 +199,20 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) #ifdef CONFIG_BLK_DEV_IDEDMA if (speed >= XFER_SW_DMA_0) { - pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); - pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); + pci_write_config_byte(dev, drive_pci + 1, (BP & ~0xf0) | TB); + pci_write_config_byte(dev, drive_pci + 2, (CP & ~0x0f) | TC); } else -#endif /* CONFIG_BLK_DEV_IDEDMA */ +#endif { - pci_write_config_byte(dev, (drive_pci), AP|TA); - pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); + pci_write_config_byte(dev, drive_pci, (AP & ~0x0f) | TA); + pci_write_config_byte(dev, drive_pci + 1, (BP & ~0x07) | TB); } #if PDC202XX_DECODE_REGISTER_INFO - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); - pci_read_config_byte(dev, (drive_pci)|0x03, &DP); + pci_read_config_byte(dev, drive_pci, &AP); + pci_read_config_byte(dev, drive_pci + 1, &BP); + pci_read_config_byte(dev, drive_pci + 2, &CP); + pci_read_config_byte(dev, drive_pci + 3, &DP); printk(KERN_DEBUG "AP(%x): PIO(A) = %d\n", AP, AP & 0x0f); pdc_dump_bits(pdc_reg_A, AP); @@ -298,7 +248,6 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed) OUT_BYTE(value, reg); \ mdelay(delay); - static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed) { struct ata_channel *hwif = drive->channel; @@ -306,7 +255,7 @@ static int pdc202xx_new_tune_chipset(struct ata_device *drive, byte speed) unsigned long indexreg = (hwif->dma_base + 1); unsigned long datareg = (hwif->dma_base + 3); #else - unsigned long high_16 = init_high_16(hwif->pci_dev); + u32 high_16 = pci_resource_start(hwif->pci_dev, 4); unsigned long indexreg = high_16 + (hwif->unit ? 0x09 : 0x01); unsigned long datareg = (indexreg + 2); #endif /* CONFIG_BLK_DEV_IDEDMA */ @@ -431,23 +380,19 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma) struct ata_channel *hwif = drive->channel; struct hd_driveid *mate_id = hwif->drives[!(drive->dn%2)].id; struct pci_dev *dev = hwif->pci_dev; - unsigned long high_16 = init_high_16(dev); - unsigned long dma_base = hwif->dma_base; - unsigned long indexreg = dma_base + 1; - unsigned long datareg = dma_base + 3; + u32 high_16 = pci_resource_start(dev, 4); + u32 dma_base = hwif->dma_base; + u32 indexreg = dma_base + 1; + u32 datareg = dma_base + 3; byte adj = (drive->dn%2) ? 0x08 : 0x00; - byte jumpbit = 0; - unsigned int drive_conf; - byte drive_pci = 0, AP, tmp, mode = -1; - byte CLKSPD = 0; - /* primary - second bit, secondary - fourth bit */ - byte mask = hwif->unit ? 0x08 : 0x02; + u8 jumpbit; + u32 drive_conf; + u8 drive_pci = 0, AP, tmp, mode = -1; + u8 CLKSPD, mask = hwif->unit ? 0x08 : 0x02; int map; - byte needs_80w = ((id->dma_ultra & 0x0008) || - (id->dma_ultra & 0x0010) || - (id->dma_ultra & 0x0020) || - (id->dma_ultra & 0x0040)); + /* UDMA 3, 4, 5 and 6 */ + u8 needs_80w = (id->dma_ultra & 0x0078); switch(dev->device) { case PCI_DEVICE_ID_PROMISE_20267: @@ -456,52 +401,44 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma) case PCI_DEVICE_ID_PROMISE_20246: jumpbit = 0; break; - default: /* chipsets newer then 20268 */ + default: /* chipsets newer then 20267 */ jumpbit = 1; break; } - if (!jumpbit) - CLKSPD = PDC_CLOCK(high_16); + /* FIXME: this check is wrong for 20246 --bkz */ + /* */ + if (needs_80w && !hwif->udma_four) { + printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name); + printk(KERN_INFO "%s: reduced to UDMA(33) mode.\n", drive->name); + } + + if (jumpbit) + goto chipset_is_set; + /* * Set the control register to use the 66Mhz system - * clock for UDMA 3/4 mode operation. If one drive on + * clock for UDMA 3/4 mode operations. If one drive on * a channel is U66 capable but the other isn't we * fall back to U33 mode. The BIOS INT 13 hooks turn - * the clock on then off for each read/write issued. I don't - * do that here because it would require modifying the - * kernel, seperating the fop routines from the kernel or - * somehow hooking the fops calls. It may also be possible to - * leave the 66Mhz clock on and readjust the timing - * parameters. + * the clock on then off for each read/write issued. + * We can do the same in device specific udma_start/stop() + * routines or better try to readjust timings. + * + * FIXME: move this to pdc202xx_tuneproc() + * right now you can't downgrade from U66 to U33 --bkz */ if (needs_80w) { - /* FIXME: this check is wrong for 20246 --bkz */ - if (!hwif->udma_four) { - printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name); - printk(KERN_WARNING "%s: reduced to UDMA(33) mode.\n", drive->name); - if (!jumpbit) - OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); - } - if (!jumpbit) { - if (mate_id) { /* check if mate is at least udma3 */ - if ((mate_id->dma_ultra & 0x0040) || - (mate_id->dma_ultra & 0x0020) || - (mate_id->dma_ultra & 0x0010) || - (mate_id->dma_ultra & 0x0008)) { - OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); - } else { - OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); - } - } else { /* single drive */ - OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); - } - } + CLKSPD = IN_BYTE(high_16 + PDC_CLK); + /* check cable and mate (must be at least udma3 capable) */ + if (!hwif->udma_four || + !mate_id || !(mate_id->dma_ultra & 0x0078)) + OUT_BYTE(CLKSPD & ~mask, high_16 + PDC_CLK); + else + /* cable ok, mate ok or single drive */ + OUT_BYTE(CLKSPD | mask, high_16 + PDC_CLK); } - if (jumpbit) - goto chipset_is_set; - if (drive->dn > 3) /* FIXME: remove this --bkz */ return 0; @@ -560,7 +497,7 @@ chipset_is_set: return 0; } - return !(hwif->speedproc(drive, mode)); + return !hwif->speedproc(drive, mode); } static int pdc202xx_udma_setup(struct ata_device *drive) @@ -614,14 +551,14 @@ no_dma_set: static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq) { struct ata_channel *ch = drive->channel; - unsigned long high_16 = init_high_16(ch->pci_dev); + u32 high_16 = pci_resource_start(ch->pci_dev, 4); unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00); if (drive->addressing) { unsigned long word_count = 0; - u8 clock = PDC_CLOCK(high_16); + u8 clock = IN_BYTE(high_16 + PDC_CLK); - outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + 0x11); + outb(clock|(ch->unit ? 0x08 : 0x02), high_16 + PDC_CLK); word_count = (rq->nr_sectors << 8); word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000; outl(word_count, atapi_reg); @@ -640,15 +577,15 @@ static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq) int pdc202xx_udma_stop(struct ata_device *drive) { struct ata_channel *ch = drive->channel; - unsigned long high_16 = init_high_16(ch->pci_dev); + u32 high_16 = pci_resource_start(ch->pci_dev, 4); unsigned long atapi_reg = high_16 + (ch->unit ? 0x24 : 0x00); unsigned long dma_base = ch->dma_base; u8 dma_stat, clock; if (drive->addressing) { outl(0, atapi_reg); /* zero out extra */ - clock = PDC_CLOCK(high_16); - OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + 0x11); + clock = IN_BYTE(high_16 + PDC_CLK); + OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + PDC_CLK); } drive->waiting_for_dma = 0; @@ -660,16 +597,6 @@ int pdc202xx_udma_stop(struct ata_device *drive) return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */ } -static int pdc202xx_udma_irq_status(struct ata_device *drive) -{ - struct ata_channel *ch = drive->channel; - u8 dma_stat; - - dma_stat = IN_BYTE(ch->dma_base + 2); - - return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ -} - static void pdc202xx_bug(struct ata_device *drive) { if (!drive->channel->resetproc) @@ -690,55 +617,51 @@ void pdc202xx_new_reset(struct ata_device *drive) drive->channel->unit ? "Secondary" : "Primary"); } -void pdc202xx_reset(struct ata_device *drive) +/* + * software host reset + * + * BIOS will set UDMA timing on if the drive supports it. + * The user may then want to turn it off. A bug is that + * that device cannot handle a downgrade in timing from + * UDMA to DMA. Disk accesses after issuing a set + * feature command will result in errors. + * + * A software reset leaves the timing registers intact, + * but resets the drives on both channels. + */ +static void pdc202xx_reset_host(struct pci_dev *dev) { - unsigned long high_16 = init_high_16(drive->channel->pci_dev); - byte udma_speed_flag = UDMA_SPEED_FLAG(high_16); + u32 high_16 = pci_resource_start(dev, 4); + u8 burst = IN_BYTE(high_16 + PDC_UDMA); - set_reg_and_wait(udma_speed_flag | 0x10, high_16 + 0x001f, 100); - set_reg_and_wait(udma_speed_flag & ~0x10, high_16 + 0x001f, 2000); /* 2 seconds ?! */ - printk("PDC202XX: %s channel reset.\n", - drive->channel->unit ? "Secondary" : "Primary"); + set_reg_and_wait(burst | 0x10, high_16 + PDC_UDMA, 100); + /* FIXME: 2 seconds ?! */ + set_reg_and_wait(burst & ~0x10, high_16 + PDC_UDMA, 2000); + printk(KERN_INFO "%s: device reseted.\n", dev->name); +} + +void pdc202xx_reset(struct ata_device *drive) +{ + struct ata_channel *ch = drive->channel; + printk(KERN_INFO "%s: channel needs reset.\n", ch->name); + pdc202xx_reset_host(ch->pci_dev); } -/* FIXME: should be splited for old & new chipsets --bkz */ static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev) { - unsigned long high_16 = init_high_16(dev); - byte udma_speed_flag = UDMA_SPEED_FLAG(high_16); - byte primary_mode = IN_BYTE(high_16 + 0x001a); - byte secondary_mode = IN_BYTE(high_16 + 0x001b); - byte newchip = 0; + u32 high_16 = pci_resource_start(dev, 4); + u8 burst = IN_BYTE(high_16 + PDC_UDMA); if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk("%s: ROM enabled at 0x%08lx\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start); } switch (dev->device) { - case PCI_DEVICE_ID_PROMISE_20275: - case PCI_DEVICE_ID_PROMISE_20276: - case PCI_DEVICE_ID_PROMISE_20269: - case PCI_DEVICE_ID_PROMISE_20268R: - case PCI_DEVICE_ID_PROMISE_20268: - newchip = 1; - break; case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_PROMISE_20265: case PCI_DEVICE_ID_PROMISE_20262: - /* - * software reset - this is required because the BIOS - * will set UDMA timing on if the drive supports it. - * The user may want to turn udma off. A bug is that - * that device cannot handle a downgrade in timing from - * UDMA to DMA. Disk accesses after issuing a set - * feature command will result in errors. - * - * A software reset leaves the timing registers intact, - * but resets the drives. - */ - set_reg_and_wait(udma_speed_flag | 0x10, high_16 + 0x001f, 100); - set_reg_and_wait(udma_speed_flag & ~0x10, high_16 + 0x001f, 2000); /* 2 seconds ?! */ + pdc202xx_reset_host(dev); break; default: /* FIXME: only checked for 20246 - is this right?, @@ -755,46 +678,44 @@ static unsigned int __init pdc202xx_init_chipset(struct pci_dev *dev) break; } - if (newchip) - goto fttk_tx_series; - - printk("%s: (U)DMA Burst Bit %sABLED " \ - "Primary %s Mode " \ - "Secondary %s Mode.\n", - dev->name, - (udma_speed_flag & 1) ? "EN" : "DIS", - (primary_mode & 1) ? "MASTER" : "PCI", - (secondary_mode & 1) ? "MASTER" : "PCI" ); - #ifdef CONFIG_PDC202XX_BURST - if (!(udma_speed_flag & 1)) { - printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", dev->name, udma_speed_flag, (udma_speed_flag|1)); - OUT_BYTE(udma_speed_flag|1, high_16 + 0x001f); - printk("%sCTIVE\n", (UDMA_SPEED_FLAG(high_16) & 1) ? "A" : "INA"); + if (!(burst & 1)) { + printk(KERN_INFO "%s: forcing (U)DMA BURST.\n", dev->name); + OUT_BYTE(burst | 1, high_16 + PDC_UDMA); } -#endif /* CONFIG_PDC202XX_BURST */ +#endif + printk(KERN_INFO "%s: (U)DMA BURST %sabled, " + "primary %s mode, secondary %s mode.\n", + dev->name, (burst & 1) ? "en" : "dis", + (IN_BYTE(high_16 + PDC_PRIMARY) & 1) ? "MASTER" : "PCI", + (IN_BYTE(high_16 + PDC_SECONDARY) & 1) ? "MASTER" : "PCI" ); -fttk_tx_series: return dev->irq; } -static unsigned int __init ata66_pdc202xx(struct ata_channel *hwif) +/* chipsets newer then 20267 */ +static unsigned int __init pdc202xx_tx_init_chipset(struct pci_dev *dev) { - unsigned short mask = (hwif->unit) ? (1<<11) : (1<<10); - unsigned short CIS; - - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_PROMISE_20275: - case PCI_DEVICE_ID_PROMISE_20276: - case PCI_DEVICE_ID_PROMISE_20269: - case PCI_DEVICE_ID_PROMISE_20268: - case PCI_DEVICE_ID_PROMISE_20268R: - OUT_BYTE(0x0b, (hwif->dma_base + 1)); - return (!(IN_BYTE((hwif->dma_base + 3)) & 0x04)); - default: - pci_read_config_word(hwif->pci_dev, 0x50, &CIS); - return (!(CIS & mask)); + if (dev->resource[PCI_ROM_RESOURCE].start) { + pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx.\n", dev->name, dev->resource[PCI_ROM_RESOURCE].start); } + return dev->irq; +} + +static unsigned int __init pdc202xx_ata66_check(struct ata_channel *ch) +{ + u16 CIS; + + pci_read_config_word(ch->pci_dev, 0x50, &CIS); + return !(CIS & (1 << (10 + ch->unit))); +} + +/* chipsets newer then 20267 */ +static unsigned int __init pdc202xx_tx_ata66_check(struct ata_channel *ch) +{ + OUT_BYTE(0x0b, ch->dma_base + 1); + return !(IN_BYTE(ch->dma_base + 3) & 0x04); } static void __init ide_init_pdc202xx(struct ata_channel *hwif) @@ -820,7 +741,6 @@ static void __init ide_init_pdc202xx(struct ata_channel *hwif) if (hwif->dma_base) { hwif->udma_start = pdc202xx_udma_start; hwif->udma_stop = pdc202xx_udma_stop; - hwif->udma_irq_status = pdc202xx_udma_irq_status; } #endif /* FIXME: check whether 20246 works with lba48 --bkz */ @@ -867,7 +787,7 @@ static struct ata_pci_device chipsets[] __initdata = { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20262, init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + ata66_check: pdc202xx_ata66_check, init_channel: ide_init_pdc202xx, #ifndef CONFIG_PDC202XX_FORCE enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, @@ -880,7 +800,7 @@ static struct ata_pci_device chipsets[] __initdata = { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20265, init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + ata66_check: pdc202xx_ata66_check, init_channel: ide_init_pdc202xx, #ifndef CONFIG_PDC202XX_FORCE enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, @@ -895,7 +815,7 @@ static struct ata_pci_device chipsets[] __initdata = { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20267, init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + ata66_check: pdc202xx_ata66_check, init_channel: ide_init_pdc202xx, #ifndef CONFIG_PDC202XX_FORCE enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, @@ -907,8 +827,8 @@ static struct ata_pci_device chipsets[] __initdata = { { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20268, - init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + init_chipset: pdc202xx_tx_init_chipset, + ata66_check: pdc202xx_tx_ata66_check, init_channel: ide_init_pdc202xx, bootable: OFF_BOARD, flags: ATA_F_IRQ | ATA_F_DMA @@ -920,8 +840,8 @@ static struct ata_pci_device chipsets[] __initdata = { { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20268R, - init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + init_chipset: pdc202xx_tx_init_chipset, + ata66_check: pdc202xx_tx_ata66_check, init_channel: ide_init_pdc202xx, bootable: OFF_BOARD, flags: ATA_F_IRQ | ATA_F_DMA @@ -929,8 +849,8 @@ static struct ata_pci_device chipsets[] __initdata = { { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20269, - init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + init_chipset: pdc202xx_tx_init_chipset, + ata66_check: pdc202xx_tx_ata66_check, init_channel: ide_init_pdc202xx, bootable: OFF_BOARD, flags: ATA_F_IRQ | ATA_F_DMA @@ -938,8 +858,8 @@ static struct ata_pci_device chipsets[] __initdata = { { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20275, - init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + init_chipset: pdc202xx_tx_init_chipset, + ata66_check: pdc202xx_tx_ata66_check, init_channel: ide_init_pdc202xx, bootable: OFF_BOARD, flags: ATA_F_IRQ | ATA_F_DMA @@ -947,8 +867,8 @@ static struct ata_pci_device chipsets[] __initdata = { { vendor: PCI_VENDOR_ID_PROMISE, device: PCI_DEVICE_ID_PROMISE_20276, - init_chipset: pdc202xx_init_chipset, - ata66_check: ata66_pdc202xx, + init_chipset: pdc202xx_tx_init_chipset, + ata66_check: pdc202xx_tx_ata66_check, init_channel: ide_init_pdc202xx, bootable: OFF_BOARD, flags: ATA_F_IRQ | ATA_F_DMA diff --git a/include/linux/ide.h b/include/linux/ide.h index bb1324b7f4f6..51fbd637a48a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -613,7 +613,6 @@ extern u8 ata_dump(struct ata_device *, struct request *, const char *); extern ide_startstop_t ata_error(struct ata_device *, struct request *rq, const char *); extern void ide_fixstring(char *s, const int bytecount, const int byteswap); -extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long); /* * This routine is called from the partition-table code in genhd.c |
