diff options
Diffstat (limited to 'drivers/ide/pci/ns87415.c')
| -rw-r--r-- | drivers/ide/pci/ns87415.c | 115 | 
1 files changed, 58 insertions, 57 deletions
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 45ba71a7182..5cd2b32ff0e 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -28,10 +28,6 @@   */  #include <asm/superio.h> -static unsigned long superio_ide_status[2]; -static unsigned long superio_ide_select[2]; -static unsigned long superio_ide_dma_status[2]; -  #define SUPERIO_IDE_MAX_RETRIES 25  /* Because of a defect in Super I/O, all reads of the PCI DMA status  @@ -40,27 +36,28 @@ static unsigned long superio_ide_dma_status[2];   */  static u8 superio_ide_inb (unsigned long port)  { -	if (port == superio_ide_status[0] || -	    port == superio_ide_status[1] || -	    port == superio_ide_select[0] || -	    port == superio_ide_select[1] || -	    port == superio_ide_dma_status[0] || -	    port == superio_ide_dma_status[1]) { -		u8 tmp; -		int retries = SUPERIO_IDE_MAX_RETRIES; +	u8 tmp; +	int retries = SUPERIO_IDE_MAX_RETRIES; -		/* printk(" [ reading port 0x%x with retry ] ", port); */ +	/* printk(" [ reading port 0x%x with retry ] ", port); */ -		do { -			tmp = inb(port); -			if (tmp == 0) -				udelay(50); -		} while (tmp == 0 && retries-- > 0); +	do { +		tmp = inb(port); +		if (tmp == 0) +			udelay(50); +	} while (tmp == 0 && retries-- > 0); -		return tmp; -	} +	return tmp; +} -	return inb(port); +static u8 superio_read_status(ide_hwif_t *hwif) +{ +	return superio_ide_inb(hwif->io_ports.status_addr); +} + +static u8 superio_read_sff_dma_status(ide_hwif_t *hwif) +{ +	return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);  }  static void superio_tf_read(ide_drive_t *drive, ide_task_t *task) @@ -78,6 +75,8 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)  	/* be sure we're looking at the low order bits */  	outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); +	if (task->tf_flags & IDE_TFLAG_IN_FEATURE) +		tf->feature = inb(io_ports->feature_addr);  	if (task->tf_flags & IDE_TFLAG_IN_NSECT)  		tf->nsect  = inb(io_ports->nsect_addr);  	if (task->tf_flags & IDE_TFLAG_IN_LBAL) @@ -105,36 +104,32 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)  	}  } -static void __devinit superio_ide_init_iops (struct hwif_s *hwif) -{ -	struct pci_dev *pdev = to_pci_dev(hwif->dev); -	u32 base, dmabase; -	u8 port = hwif->channel, tmp; +static const struct ide_tp_ops superio_tp_ops = { +	.exec_command		= ide_exec_command, +	.read_status		= superio_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= superio_read_sff_dma_status, -	base = pci_resource_start(pdev, port * 2) & ~3; -	dmabase = pci_resource_start(pdev, 4) & ~3; - -	superio_ide_status[port] = base + 7; -	superio_ide_select[port] = base + 6; -	superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa); - -	/* Clear error/interrupt, enable dma */ -	tmp = superio_ide_inb(superio_ide_dma_status[port]); -	outb(tmp | 0x66, superio_ide_dma_status[port]); +	.set_irq		= ide_set_irq, -	hwif->tf_read = superio_tf_read; +	.tf_load		= ide_tf_load, +	.tf_read		= superio_tf_read, -	/* We need to override inb to workaround a SuperIO errata */ -	hwif->INB = superio_ide_inb; -} +	.input_data		= ide_input_data, +	.output_data		= ide_output_data, +}; -static void __devinit init_iops_ns87415(ide_hwif_t *hwif) +static void __devinit superio_init_iops(struct hwif_s *hwif)  { -	struct pci_dev *dev = to_pci_dev(hwif->dev); +	struct pci_dev *pdev = to_pci_dev(hwif->dev); +	u32 dma_stat; +	u8 port = hwif->channel, tmp; -	if (PCI_SLOT(dev->devfn) == 0xE) -		/* Built-in - assume it's under superio. */ -		superio_ide_init_iops(hwif); +	dma_stat = (pci_resource_start(pdev, 4) & ~3) + (!port ? 2 : 0xa); + +	/* Clear error/interrupt, enable dma */ +	tmp = superio_ide_inb(dma_stat); +	outb(tmp | 0x66, dma_stat);  }  #endif @@ -200,14 +195,14 @@ static int ns87415_dma_end(ide_drive_t *drive)  	u8 dma_stat = 0, dma_cmd = 0;  	drive->waiting_for_dma = 0; -	dma_stat = hwif->INB(hwif->dma_status); -	/* get dma command mode */ -	dma_cmd = hwif->INB(hwif->dma_command); +	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); +	/* get DMA command mode */ +	dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);  	/* stop DMA */ -	outb(dma_cmd & ~1, hwif->dma_command); +	outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);  	/* from ERRATA: clear the INTR & ERROR bits */ -	dma_cmd = hwif->INB(hwif->dma_command); -	outb(dma_cmd | 6, hwif->dma_command); +	dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); +	outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);  	/* and free any DMA resources */  	ide_destroy_dmatable(drive);  	/* verify good DMA status */ @@ -276,7 +271,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)  		outb(8, hwif->io_ports.ctl_addr);  		do {  			udelay(50); -			stat = hwif->INB(hwif->io_ports.status_addr); +			stat = hwif->tp_ops->read_status(hwif);                  	if (stat == 0xff)                          	break;          	} while ((stat & BUSY_STAT) && --timeout); @@ -291,7 +286,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)  	if (!hwif->dma_base)  		return; -	outb(0x60, hwif->dma_status); +	outb(0x60, hwif->dma_base + ATA_DMA_STATUS);  }  static const struct ide_port_ops ns87415_port_ops = { @@ -311,9 +306,6 @@ static const struct ide_dma_ops ns87415_dma_ops = {  static const struct ide_port_info ns87415_chipset __devinitdata = {  	.name		= "NS87415", -#ifdef CONFIG_SUPERIO -	.init_iops	= init_iops_ns87415, -#endif  	.init_hwif	= init_hwif_ns87415,  	.port_ops	= &ns87415_port_ops,  	.dma_ops	= &ns87415_dma_ops, @@ -323,7 +315,16 @@ static const struct ide_port_info ns87415_chipset __devinitdata = {  static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)  { -	return ide_setup_pci_device(dev, &ns87415_chipset); +	struct ide_port_info d = ns87415_chipset; + +#ifdef CONFIG_SUPERIO +	if (PCI_SLOT(dev->devfn) == 0xE) { +		/* Built-in - assume it's under superio. */ +		d.init_iops = superio_init_iops; +		d.tp_ops = &superio_tp_ops; +	} +#endif +	return ide_setup_pci_device(dev, &d);  }  static const struct pci_device_id ns87415_pci_tbl[] = {  |