Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6423407 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (34 commits)
  ide-cd: prevent null pointer deref via cdrom_newpc_intr
  ide: BUG() on unknown requests
  ide: filter out invalid DMA xfer mode changes in HDIO_DRIVE_CMD ioctl handler
  ide: do not access ide_drive_t 'drive_data' field directly
  sl82c105: implement test_irq() method
  siimage: implement test_irq() method
  pdc202xx_old: implement test_irq() method (take 2)
  cmd64x: implement test_irq() method
  cmd640: implement test_irq() method
  ide: move ack_intr() method into 'struct ide_port_ops' (take 2)
  ide: move IRQ clearing from ack_intr() method to clear_irq() method (take 2)
  siimage: use ide_dma_test_irq() (take 2)
  cmd64x: implement clear_irq() method (take 2)
  ide: call clear_irq() method in ide_timer_expiry()
  sgiioc4: coding style cleanup
  ide: don't enable IORDY at a probe time
  ide: IORDY handling fixes
  ata: add ata_id_pio_need_iordy() helper (v2)
  ide-tape: fix build issue
  ide: unify interrupt reason checking
  ...
parents 7f818906 39c58f37
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -185,8 +185,7 @@ static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
	timing = ide_timing_find_mode(XFER_PIO_0 + pio);
	BUG_ON(!timing);

	if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
	    !(ata_id_is_cfa(drive->id) && pio > 4))
	if (ide_pio_need_iordy(drive, pio))
		use_iordy = 1;

	apply_timings(chipselect, pio, timing, use_iordy);
+21 −19
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" };
     *  Check and acknowledge the interrupt status
     */

static int buddha_ack_intr(ide_hwif_t *hwif)
static int buddha_test_irq(ide_hwif_t *hwif)
{
    unsigned char ch;

@@ -109,21 +109,16 @@ static int buddha_ack_intr(ide_hwif_t *hwif)
    return 1;
}

static int xsurf_ack_intr(ide_hwif_t *hwif)
static void xsurf_clear_irq(ide_drive_t *drive)
{
    unsigned char ch;

    ch = z_readb(hwif->io_ports.irq_addr);
    /* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */
    z_writeb(0, hwif->io_ports.irq_addr);
    if (!(ch & 0x80))
	    return 0;
    return 1;
    /*
     * X-Surf needs 0 written to IRQ register to ensure ISA bit A11 stays at 0
     */
    z_writeb(0, drive->hwif->io_ports.irq_addr);
}

static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base,
				      unsigned long ctl, unsigned long irq_port,
				      ide_ack_intr_t *ack_intr)
				      unsigned long ctl, unsigned long irq_port)
{
	int i;

@@ -138,10 +133,19 @@ static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base,
	hw->io_ports.irq_addr = irq_port;

	hw->irq = IRQ_AMIGA_PORTS;
	hw->ack_intr = ack_intr;
}

static const struct ide_port_ops buddha_port_ops = {
	.test_irq		= buddha_test_irq,
};

static const struct ide_port_ops xsurf_port_ops = {
	.clear_irq		= xsurf_clear_irq,
	.test_irq		= buddha_test_irq,
};

static const struct ide_port_info buddha_port_info = {
	.port_ops		= &buddha_port_ops,
	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
	.irq_flags		= IRQF_SHARED,
	.chipset		= ide_generic,
@@ -161,6 +165,7 @@ static int __init buddha_init(void)
	while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
		unsigned long board;
		struct ide_hw hw[MAX_NUM_HWIFS], *hws[MAX_NUM_HWIFS];
		struct ide_port_info d = buddha_port_info;

		if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
			buddha_num_hwifs = BUDDHA_NUM_HWIFS;
@@ -171,6 +176,7 @@ static int __init buddha_init(void)
		} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) {
			buddha_num_hwifs = XSURF_NUM_HWIFS;
			type=BOARD_XSURF;
			d.port_ops = &xsurf_port_ops;
		} else 
			continue;
		
@@ -203,28 +209,24 @@ fail_base2:

		for (i = 0; i < buddha_num_hwifs; i++) {
			unsigned long base, ctl, irq_port;
			ide_ack_intr_t *ack_intr;

			if (type != BOARD_XSURF) {
				base = buddha_board + buddha_bases[i];
				ctl = base + BUDDHA_CONTROL;
				irq_port = buddha_board + buddha_irqports[i];
				ack_intr = buddha_ack_intr;
			} else {
				base = buddha_board + xsurf_bases[i];
				/* X-Surf has no CS1* (Control/AltStat) */
				ctl = 0;
				irq_port = buddha_board + xsurf_irqports[i];
				ack_intr = xsurf_ack_intr;
			}

			buddha_setup_ports(&hw[i], base, ctl, irq_port,
					   ack_intr);
			buddha_setup_ports(&hw[i], base, ctl, irq_port);

			hws[i] = &hw[i];
		}

		ide_host_add(&buddha_port_info, hws, i, NULL);
		ide_host_add(&d, hws, i, NULL);
	}

	return 0;
+13 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ static int cmd640_vlb;
#define ARTTIM23	0x57
#define   ARTTIM23_DIS_RA2	0x04
#define   ARTTIM23_DIS_RA3	0x08
#define   ARTTIM23_IDE23INTR	0x10
#define DRWTIM23	0x58
#define BRST		0x59

@@ -629,12 +630,24 @@ static void cmd640_init_dev(ide_drive_t *drive)
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
}

static int cmd640_test_irq(ide_hwif_t *hwif)
{
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	int irq_reg		= hwif->channel ? ARTTIM23 : CFR;
	u8  irq_stat, irq_mask	= hwif->channel ? ARTTIM23_IDE23INTR :
						  CFR_IDE01INTR;

	pci_read_config_byte(dev, irq_reg, &irq_stat);

	return (irq_stat & irq_mask) ? 1 : 0;
}

static const struct ide_port_ops cmd640_port_ops = {
	.init_dev		= cmd640_init_dev,
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
	.set_pio_mode		= cmd640_set_pio_mode,
#endif
	.test_irq		= cmd640_test_irq,
};

static int pci_conf1(void)
+32 −71
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 * Copyright (C) 1998		David S. Miller (davem@redhat.com)
 *
 * Copyright (C) 1999-2002	Andre Hedrick <andre@linux-ide.org>
 * Copyright (C) 2007		MontaVista Software, Inc. <source@mvista.com>
 * Copyright (C) 2007,2009	MontaVista Software, Inc. <source@mvista.com>
 */

#include <linux/module.h>
@@ -118,8 +118,9 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
	ide_hwif_t *hwif	= drive->hwif;
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	struct ide_timing *t	= ide_timing_find_mode(XFER_PIO_0 + pio);
	unsigned long setup_count;
	unsigned int cycle_time;
	u8 setup_count, arttim = 0;
	u8 arttim = 0;

	static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
	static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
@@ -140,10 +141,11 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
	if (hwif->channel) {
		ide_drive_t *pair = ide_get_pair_dev(drive);

		drive->drive_data = setup_count;
		ide_set_drivedata(drive, (void *)setup_count);

		if (pair)
			setup_count = max_t(u8, setup_count, pair->drive_data);
			setup_count = max_t(u8, setup_count,
					(unsigned long)ide_get_drivedata(pair));
	}

	if (setup_count > 5)		/* shouldn't actually happen... */
@@ -226,11 +228,11 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
		(void) pci_write_config_byte(dev, pciU, regU);
}

static int cmd648_dma_end(ide_drive_t *drive)
static void cmd648_clear_irq(ide_drive_t *drive)
{
	ide_hwif_t *hwif	= drive->hwif;
	unsigned long base	= hwif->dma_base - (hwif->channel * 8);
	int err			= ide_dma_end(drive);
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	unsigned long base	= pci_resource_start(dev, 4);
	u8  irq_mask		= hwif->channel ? MRDMODE_INTR_CH1 :
						  MRDMODE_INTR_CH0;
	u8  mrdmode		= inb(base + 1);
@@ -238,11 +240,9 @@ static int cmd648_dma_end(ide_drive_t *drive)
	/* clear the interrupt bit */
	outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask,
	     base + 1);

	return err;
}

static int cmd64x_dma_end(ide_drive_t *drive)
static void cmd64x_clear_irq(ide_drive_t *drive)
{
	ide_hwif_t *hwif	= drive->hwif;
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
@@ -250,62 +250,40 @@ static int cmd64x_dma_end(ide_drive_t *drive)
	u8  irq_mask		= hwif->channel ? ARTTIM23_INTR_CH1 :
						  CFR_INTR_CH0;
	u8  irq_stat		= 0;
	int err			= ide_dma_end(drive);

	(void) pci_read_config_byte(dev, irq_reg, &irq_stat);
	/* clear the interrupt bit */
	(void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask);

	return err;
}

static int cmd648_dma_test_irq(ide_drive_t *drive)
static int cmd648_test_irq(ide_hwif_t *hwif)
{
	ide_hwif_t *hwif	= drive->hwif;
	unsigned long base	= hwif->dma_base - (hwif->channel * 8);
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	unsigned long base	= pci_resource_start(dev, 4);
	u8 irq_mask		= hwif->channel ? MRDMODE_INTR_CH1 :
						  MRDMODE_INTR_CH0;
	u8 dma_stat		= inb(hwif->dma_base + ATA_DMA_STATUS);
	u8 mrdmode		= inb(base + 1);

#ifdef DEBUG
	printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n",
	       drive->name, dma_stat, mrdmode, irq_mask);
#endif
	if (!(mrdmode & irq_mask))
		return 0;
	pr_debug("%s: mrdmode: 0x%02x irq_mask: 0x%02x\n",
		 hwif->name, mrdmode, irq_mask);

	/* return 1 if INTR asserted */
	if (dma_stat & 4)
		return 1;

	return 0;
	return (mrdmode & irq_mask) ? 1 : 0;
}

static int cmd64x_dma_test_irq(ide_drive_t *drive)
static int cmd64x_test_irq(ide_hwif_t *hwif)
{
	ide_hwif_t *hwif	= drive->hwif;
	struct pci_dev *dev	= to_pci_dev(hwif->dev);
	int irq_reg		= hwif->channel ? ARTTIM23 : CFR;
	u8  irq_mask		= hwif->channel ? ARTTIM23_INTR_CH1 :
						  CFR_INTR_CH0;
	u8  dma_stat		= inb(hwif->dma_base + ATA_DMA_STATUS);
	u8  irq_stat		= 0;

	(void) pci_read_config_byte(dev, irq_reg, &irq_stat);

#ifdef DEBUG
	printk("%s: dma_stat: 0x%02x irq_stat: 0x%02x irq_mask: 0x%02x\n",
	       drive->name, dma_stat, irq_stat, irq_mask);
#endif
	if (!(irq_stat & irq_mask))
		return 0;

	/* return 1 if INTR asserted */
	if (dma_stat & 4)
		return 1;
	pr_debug("%s: irq_stat: 0x%02x irq_mask: 0x%02x\n",
		 hwif->name, irq_stat, irq_mask);

	return 0;
	return (irq_stat & irq_mask) ? 1 : 0;
}

/*
@@ -370,18 +348,17 @@ static u8 cmd64x_cable_detect(ide_hwif_t *hwif)
static const struct ide_port_ops cmd64x_port_ops = {
	.set_pio_mode		= cmd64x_set_pio_mode,
	.set_dma_mode		= cmd64x_set_dma_mode,
	.clear_irq		= cmd64x_clear_irq,
	.test_irq		= cmd64x_test_irq,
	.cable_detect		= cmd64x_cable_detect,
};

static const struct ide_dma_ops cmd64x_dma_ops = {
	.dma_host_set		= ide_dma_host_set,
	.dma_setup		= ide_dma_setup,
	.dma_start		= ide_dma_start,
	.dma_end		= cmd64x_dma_end,
	.dma_test_irq		= cmd64x_dma_test_irq,
	.dma_lost_irq		= ide_dma_lost_irq,
	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
	.dma_sff_read_status	= ide_dma_sff_read_status,
static const struct ide_port_ops cmd648_port_ops = {
	.set_pio_mode		= cmd64x_set_pio_mode,
	.set_dma_mode		= cmd64x_set_dma_mode,
	.clear_irq		= cmd648_clear_irq,
	.test_irq		= cmd648_test_irq,
	.cable_detect		= cmd64x_cable_detect,
};

static const struct ide_dma_ops cmd646_rev1_dma_ops = {
@@ -395,24 +372,12 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = {
	.dma_sff_read_status	= ide_dma_sff_read_status,
};

static const struct ide_dma_ops cmd648_dma_ops = {
	.dma_host_set		= ide_dma_host_set,
	.dma_setup		= ide_dma_setup,
	.dma_start		= ide_dma_start,
	.dma_end		= cmd648_dma_end,
	.dma_test_irq		= cmd648_dma_test_irq,
	.dma_lost_irq		= ide_dma_lost_irq,
	.dma_timer_expiry	= ide_dma_sff_timer_expiry,
	.dma_sff_read_status	= ide_dma_sff_read_status,
};

static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
	{	/* 0: CMD643 */
		.name		= DRV_NAME,
		.init_chipset	= init_chipset_cmd64x,
		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
		.port_ops	= &cmd64x_port_ops,
		.dma_ops	= &cmd64x_dma_ops,
		.host_flags	= IDE_HFLAG_CLEAR_SIMPLEX |
				  IDE_HFLAG_ABUSE_PREFETCH,
		.pio_mask	= ATA_PIO5,
@@ -423,8 +388,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
		.name		= DRV_NAME,
		.init_chipset	= init_chipset_cmd64x,
		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
		.port_ops	= &cmd64x_port_ops,
		.dma_ops	= &cmd648_dma_ops,
		.port_ops	= &cmd648_port_ops,
		.host_flags	= IDE_HFLAG_SERIALIZE |
				  IDE_HFLAG_ABUSE_PREFETCH,
		.pio_mask	= ATA_PIO5,
@@ -435,8 +399,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
		.name		= DRV_NAME,
		.init_chipset	= init_chipset_cmd64x,
		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
		.port_ops	= &cmd64x_port_ops,
		.dma_ops	= &cmd648_dma_ops,
		.port_ops	= &cmd648_port_ops,
		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
		.pio_mask	= ATA_PIO5,
		.mwdma_mask	= ATA_MWDMA2,
@@ -446,8 +409,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
		.name		= DRV_NAME,
		.init_chipset	= init_chipset_cmd64x,
		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
		.port_ops	= &cmd64x_port_ops,
		.dma_ops	= &cmd648_dma_ops,
		.port_ops	= &cmd648_port_ops,
		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
		.pio_mask	= ATA_PIO5,
		.mwdma_mask	= ATA_MWDMA2,
@@ -484,10 +446,9 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic
			 */
			if (dev->revision < 3) {
				d.enablebits[0].reg = 0;
				d.port_ops = &cmd64x_port_ops;
				if (dev->revision == 1)
					d.dma_ops = &cmd646_rev1_dma_ops;
				else
					d.dma_ops = &cmd64x_dma_ops;
			}
		}
	}
+15 −8
Original line number Diff line number Diff line
@@ -146,14 +146,16 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
	struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
	ide_drive_t *pair = ide_get_pair_dev(drive);
	int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
	unsigned long timings = (unsigned long)ide_get_drivedata(drive);
	u32 cast;
	u8 cmd_pio = pio;

	if (pair)
		cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));

	drive->drive_data &= (IDE_DRV_MASK << 8);
	drive->drive_data |= drv_timings[pio];
	timings &= (IDE_DRV_MASK << 8);
	timings |= drv_timings[pio];
	ide_set_drivedata(drive, (void *)timings);

	cs5536_program_dtc(drive, drv_timings[pio]);

@@ -186,6 +188,7 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)

	struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
	int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
	unsigned long timings = (unsigned long)ide_get_drivedata(drive);
	u32 etc;

	cs5536_read(pdev, ETC, &etc);
@@ -195,8 +198,9 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
		etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
	} else { /* MWDMA */
		etc &= ~(IDE_ETC_UDMA_MASK << dshift);
		drive->drive_data &= IDE_DRV_MASK;
		drive->drive_data |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
		timings &= IDE_DRV_MASK;
		timings |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
		ide_set_drivedata(drive, (void *)timings);
	}

	cs5536_write(pdev, ETC, etc);
@@ -204,9 +208,11 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)

static void cs5536_dma_start(ide_drive_t *drive)
{
	unsigned long timings = (unsigned long)ide_get_drivedata(drive);

	if (drive->current_speed < XFER_UDMA_0 &&
	    (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
		cs5536_program_dtc(drive, drive->drive_data >> 8);
	    (timings >> 8) != (timings & IDE_DRV_MASK))
		cs5536_program_dtc(drive, timings >> 8);

	ide_dma_start(drive);
}
@@ -214,10 +220,11 @@ static void cs5536_dma_start(ide_drive_t *drive)
static int cs5536_dma_end(ide_drive_t *drive)
{
	int ret = ide_dma_end(drive);
	unsigned long timings = (unsigned long)ide_get_drivedata(drive);

	if (drive->current_speed < XFER_UDMA_0 &&
	    (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
		cs5536_program_dtc(drive, drive->drive_data & IDE_DRV_MASK);
	    (timings >> 8) != (timings & IDE_DRV_MASK))
		cs5536_program_dtc(drive, timings & IDE_DRV_MASK);

	return ret;
}
Loading