diff options
| -rw-r--r-- | drivers/ide/arm/icside.c | 2 | ||||
| -rw-r--r-- | drivers/ide/h8300/ide-h8300.c | 26 | ||||
| -rw-r--r-- | drivers/ide/ide-atapi.c | 13 | ||||
| -rw-r--r-- | drivers/ide/ide-cd.c | 12 | ||||
| -rw-r--r-- | drivers/ide/ide-dma.c | 12 | ||||
| -rw-r--r-- | drivers/ide/ide-floppy.c | 8 | ||||
| -rw-r--r-- | drivers/ide/ide-io.c | 32 | ||||
| -rw-r--r-- | drivers/ide/ide-iops.c | 122 | ||||
| -rw-r--r-- | drivers/ide/ide-lib.c | 2 | ||||
| -rw-r--r-- | drivers/ide/ide-probe.c | 53 | ||||
| -rw-r--r-- | drivers/ide/ide-tape.c | 8 | ||||
| -rw-r--r-- | drivers/ide/ide-taskfile.c | 29 | ||||
| -rw-r--r-- | drivers/ide/ide.c | 2 | ||||
| -rw-r--r-- | drivers/ide/legacy/falconide.c | 27 | ||||
| -rw-r--r-- | drivers/ide/legacy/q40ide.c | 27 | ||||
| -rw-r--r-- | drivers/ide/mips/au1xxx-ide.c | 29 | ||||
| -rw-r--r-- | drivers/ide/pci/ns87415.c | 50 | ||||
| -rw-r--r-- | drivers/ide/pci/scc_pata.c | 29 | ||||
| -rw-r--r-- | drivers/ide/pci/sgiioc4.c | 18 | ||||
| -rw-r--r-- | drivers/ide/ppc/pmac.c | 21 | ||||
| -rw-r--r-- | drivers/ide/setup-pci.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/ide-scsi.c | 7 | ||||
| -rw-r--r-- | include/linux/ide.h | 52 | 
23 files changed, 358 insertions, 225 deletions
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 0fd01d630f1..0283d162f7f 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -382,7 +382,7 @@ static void icside_dma_timeout(ide_drive_t *drive)  	if (icside_dma_test_irq(drive))  		return; -	ide_dump_status(drive, "DMA timeout", hwif->read_status(hwif)); +	ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));  	icside_dma_end(drive);  } diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 0795d655491..84644e15053 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -155,6 +155,21 @@ static void h8300_output_data(ide_drive_t *drive, struct request *rq,  	mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);  } +static const struct ide_tp_ops h8300_tp_ops = { +	.exec_command		= ide_exec_command, +	.read_status		= ide_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= ide_read_sff_dma_status, + +	.set_irq		= ide_set_irq, + +	.tf_load		= h8300_tf_load, +	.tf_read		= h8300_tf_read, + +	.input_data		= h8300_input_data, +	.output_data		= h8300_output_data, +}; +  #define H8300_IDE_GAP (2)  static inline void hw_setup(hw_regs_t *hw) @@ -169,16 +184,8 @@ static inline void hw_setup(hw_regs_t *hw)  	hw->chipset = ide_generic;  } -static inline void hwif_setup(ide_hwif_t *hwif) -{ -	hwif->tf_load = h8300_tf_load; -	hwif->tf_read = h8300_tf_read; - -	hwif->input_data  = h8300_input_data; -	hwif->output_data = h8300_output_data; -} -  static const struct ide_port_info h8300_port_info = { +	.tp_ops			= &h8300_tp_ops,  	.host_flags		= IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA,  }; @@ -205,7 +212,6 @@ static int __init h8300_ide_init(void)  		return -ENOENT;  	index = hwif->index; -	hwif_setup(hwif);  	idx[0] = index; diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f17a00ccbe9..6789b81ea78 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -22,6 +22,7 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,  	void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))  {  	ide_hwif_t *hwif = drive->hwif; +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	xfer_func_t *xferfunc;  	unsigned int temp;  	u16 bcount; @@ -35,7 +36,7 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,  	}  	/* Clear the interrupt */ -	stat = hwif->read_status(hwif); +	stat = tp_ops->read_status(hwif);  	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {  		if (hwif->dma_ops->dma_end(drive) || @@ -140,7 +141,7 @@ cmd_finished:  					if (pc->sg)  						io_buffers(drive, pc, temp, 0);  					else -						hwif->input_data(drive, NULL, +						tp_ops->input_data(drive, NULL,  							pc->cur_pos, temp);  					printk(KERN_ERR "%s: transferred %d of "  							"%d bytes\n", @@ -157,9 +158,9 @@ cmd_finished:  			debug_log("The device wants to send us more data than "  				  "expected - allowing transfer\n");  		} -		xferfunc = hwif->input_data; +		xferfunc = tp_ops->input_data;  	} else -		xferfunc = hwif->output_data; +		xferfunc = tp_ops->output_data;  	if ((drive->media == ide_floppy && !scsi && !pc->buf) ||  	    (drive->media == ide_tape && !scsi && pc->bh) || @@ -188,7 +189,7 @@ static u8 ide_read_ireason(ide_drive_t *drive)  	memset(&task, 0, sizeof(task));  	task.tf_flags = IDE_TFLAG_IN_NSECT; -	drive->hwif->tf_read(drive, &task); +	drive->hwif->tp_ops->tf_read(drive, &task);  	return task.tf.nsect & 3;  } @@ -249,7 +250,7 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,  	/* Send the actual packet */  	if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0) -		hwif->output_data(drive, NULL, pc->c, 12); +		hwif->tp_ops->output_data(drive, NULL, pc->c, 12);  	return ide_started;  } diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 563a380d0e7..d9798ca433b 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -285,7 +285,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)  	int stat, err, sense_key;  	/* check for errors */ -	stat = hwif->read_status(hwif); +	stat = hwif->tp_ops->read_status(hwif);  	if (stat_ret)  		*stat_ret = stat; @@ -590,7 +590,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,  		cmd_len = ATAPI_MIN_CDB_BYTES;  	/* send the command to the device */ -	hwif->output_data(drive, NULL, rq->cmd, cmd_len); +	hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);  	/* start the DMA if need be */  	if (info->dma) @@ -627,7 +627,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,  		 * Some drives (ASUS) seem to tell us that status info is  		 * available.  Just get it and ignore.  		 */ -		(void)hwif->read_status(hwif); +		(void)hwif->tp_ops->read_status(hwif);  		return 0;  	} else {  		/* drive wants a command packet, or invalid ireason... */ @@ -990,10 +990,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)  	if (ireason == 0) {  		write = 1; -		xferfunc = hwif->output_data; +		xferfunc = hwif->tp_ops->output_data;  	} else {  		write = 0; -		xferfunc = hwif->input_data; +		xferfunc = hwif->tp_ops->input_data;  	}  	/* transfer data */ @@ -1200,7 +1200,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,  		if (info->cd_flags & IDE_CD_FLAG_SEEKING) {  			ide_hwif_t *hwif = drive->hwif;  			unsigned long elapsed = jiffies - info->start_seek; -			int stat = hwif->read_status(hwif); +			int stat = hwif->tp_ops->read_status(hwif);  			if ((stat & SEEK_STAT) != SEEK_STAT) {  				if (elapsed < IDECD_SEEK_TIMEOUT) { diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index e72112efab9..be99d463dcc 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -104,7 +104,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)  	u8 stat = 0, dma_stat = 0;  	dma_stat = hwif->dma_ops->dma_end(drive); -	stat = hwif->read_status(hwif); +	stat = hwif->tp_ops->read_status(hwif);  	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {  		if (!dma_stat) { @@ -335,7 +335,7 @@ static int config_drive_for_dma (ide_drive_t *drive)  static int dma_timer_expiry (ide_drive_t *drive)  {  	ide_hwif_t *hwif	= HWIF(drive); -	u8 dma_stat		= hwif->read_sff_dma_status(hwif); +	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);  	printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n",  		drive->name, dma_stat); @@ -370,7 +370,7 @@ void ide_dma_host_set(ide_drive_t *drive, int on)  {  	ide_hwif_t *hwif	= HWIF(drive);  	u8 unit			= (drive->select.b.unit & 0x01); -	u8 dma_stat		= hwif->read_sff_dma_status(hwif); +	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);  	if (on)  		dma_stat |= (1 << (5 + unit)); @@ -482,7 +482,7 @@ int ide_dma_setup(ide_drive_t *drive)  		outb(reading, hwif->dma_base + ATA_DMA_CMD);  	/* read DMA status for INTR & ERROR flags */ -	dma_stat = hwif->read_sff_dma_status(hwif); +	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);  	/* clear INTR & ERROR flags */  	if (mmio) @@ -551,7 +551,7 @@ int __ide_dma_end (ide_drive_t *drive)  	}  	/* get DMA status */ -	dma_stat = hwif->read_sff_dma_status(hwif); +	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);  	if (mmio)  		/* clear the INTR & ERROR bits */ @@ -574,7 +574,7 @@ EXPORT_SYMBOL(__ide_dma_end);  int ide_dma_test_irq(ide_drive_t *drive)  {  	ide_hwif_t *hwif	= HWIF(drive); -	u8 dma_stat		= hwif->read_sff_dma_status(hwif); +	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);  	/* return 1 if INTR asserted */  	if ((dma_stat & 4) == 4) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 6f5294cfff2..62be2b27f23 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -247,9 +247,9 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,  		data = bvec_kmap_irq(bvec, &flags);  		if (direction) -			hwif->output_data(drive, NULL, data, count); +			hwif->tp_ops->output_data(drive, NULL, data, count);  		else -			hwif->input_data(drive, NULL, data, count); +			hwif->tp_ops->input_data(drive, NULL, data, count);  		bvec_kunmap_irq(data, &flags);  		bcount -= count; @@ -402,7 +402,7 @@ static int idefloppy_transfer_pc(ide_drive_t *drive)  	idefloppy_floppy_t *floppy = drive->driver_data;  	/* Send the actual packet */ -	drive->hwif->output_data(drive, NULL, floppy->pc->c, 12); +	drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12);  	/* Timeout for the packet command */  	return IDEFLOPPY_WAIT_CMD; @@ -954,7 +954,7 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)  		u8 stat;  		local_irq_save(flags); -		stat = hwif->read_status(hwif); +		stat = hwif->tp_ops->read_status(hwif);  		local_irq_restore(flags);  		progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index bbd7bd4c48e..a896a283f27 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -330,7 +330,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)  			tf->error = err;  			tf->status = stat; -			drive->hwif->tf_read(drive, task); +			drive->hwif->tp_ops->tf_read(drive, task);  			if (task->tf_flags & IDE_TFLAG_DYN)  				kfree(task); @@ -381,7 +381,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8  		if (err == ABRT_ERR) {  			if (drive->select.b.lba &&  			    /* some newer drives don't support WIN_SPECIFY */ -			    hwif->read_status(hwif) == WIN_SPECIFY) +			    hwif->tp_ops->read_status(hwif) == WIN_SPECIFY)  				return ide_stopped;  		} else if ((err & BAD_CRC) == BAD_CRC) {  			/* UDMA crc error, just retry the operation */ @@ -407,7 +407,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8  		return ide_stopped;  	} -	if (hwif->read_status(hwif) & (BUSY_STAT | DRQ_STAT)) +	if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))  		rq->errors |= ERROR_RESET;  	if ((rq->errors & ERROR_RESET) == ERROR_RESET) { @@ -434,9 +434,9 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u  		/* add decoding error stuff */  	} -	if (hwif->read_status(hwif) & (BUSY_STAT | DRQ_STAT)) +	if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))  		/* force an abort */ -		hwif->exec_command(hwif, WIN_IDLEIMMEDIATE); +		hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE);  	if (rq->errors >= ERROR_MAX) {  		ide_kill_rq(drive, rq); @@ -710,7 +710,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,  #ifdef DEBUG   	printk("%s: DRIVE_CMD (null)\n", drive->name);  #endif -	ide_end_drive_cmd(drive, hwif->read_status(hwif), +	ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif),  			  ide_read_error(drive));   	return ide_stopped; @@ -755,7 +755,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)  		if (rc)  			printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);  		SELECT_DRIVE(drive); -		hwif->set_irq(hwif, 1); +		hwif->tp_ops->set_irq(hwif, 1);  		rc = ide_wait_not_busy(hwif, 100000);  		if (rc)  			printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); @@ -1042,7 +1042,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)  			 * quirk_list may not like intr setups/cleanups  			 */  			if (drive->quirk_list != 1) -				hwif->set_irq(hwif, 0); +				hwif->tp_ops->set_irq(hwif, 0);  		}  		hwgroup->hwif = hwif;  		hwgroup->drive = drive; @@ -1142,7 +1142,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)  		printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);  		(void)hwif->dma_ops->dma_end(drive);  		ret = ide_error(drive, "dma timeout error", -				hwif->read_status(hwif)); +				hwif->tp_ops->read_status(hwif));  	} else {  		printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);  		hwif->dma_ops->dma_timeout(drive); @@ -1267,7 +1267,7 @@ void ide_timer_expiry (unsigned long data)  				} else  					startstop =  					ide_error(drive, "irq timeout", -						  hwif->read_status(hwif)); +						  hwif->tp_ops->read_status(hwif));  			}  			drive->service_time = jiffies - drive->service_start;  			spin_lock_irq(&ide_lock); @@ -1323,7 +1323,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)  	 */  	do {  		if (hwif->irq == irq) { -			stat = hwif->read_status(hwif); +			stat = hwif->tp_ops->read_status(hwif);  			if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {  				/* Try to not flood the console with msgs */ @@ -1414,7 +1414,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)  			 * Whack the status register, just in case  			 * we have a leftover pending IRQ.  			 */ -			(void)hwif->read_status(hwif); +			(void)hwif->tp_ops->read_status(hwif);  #endif /* CONFIG_BLK_DEV_IDEPCI */  		}  		spin_unlock_irqrestore(&ide_lock, flags); @@ -1531,9 +1531,9 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)  	task.tf.lbah    = (bcount >> 8) & 0xff;  	ide_tf_dump(drive->name, &task.tf); -	hwif->set_irq(hwif, 1); +	hwif->tp_ops->set_irq(hwif, 1);  	SELECT_MASK(drive, 0); -	hwif->tf_load(drive, &task); +	hwif->tp_ops->tf_load(drive, &task);  }  EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load); @@ -1545,9 +1545,9 @@ void ide_pad_transfer(ide_drive_t *drive, int write, int len)  	while (len > 0) {  		if (write) -			hwif->output_data(drive, NULL, buf, min(4, len)); +			hwif->tp_ops->output_data(drive, NULL, buf, min(4, len));  		else -			hwif->input_data(drive, NULL, buf, min(4, len)); +			hwif->tp_ops->input_data(drive, NULL, buf, min(4, len));  		len -= 4;  	}  } diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c9d15be4c48..07da5fb9eaf 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -68,7 +68,7 @@ void SELECT_DRIVE (ide_drive_t *drive)  	memset(&task, 0, sizeof(task));  	task.tf_flags = IDE_TFLAG_OUT_DEVICE; -	drive->hwif->tf_load(drive, &task); +	drive->hwif->tp_ops->tf_load(drive, &task);  }  void SELECT_MASK(ide_drive_t *drive, int mask) @@ -79,39 +79,43 @@ void SELECT_MASK(ide_drive_t *drive, int mask)  		port_ops->maskproc(drive, mask);  } -static void ide_exec_command(ide_hwif_t *hwif, u8 cmd) +void ide_exec_command(ide_hwif_t *hwif, u8 cmd)  {  	if (hwif->host_flags & IDE_HFLAG_MMIO)  		writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);  	else  		outb(cmd, hwif->io_ports.command_addr);  } +EXPORT_SYMBOL_GPL(ide_exec_command); -static u8 ide_read_status(ide_hwif_t *hwif) +u8 ide_read_status(ide_hwif_t *hwif)  {  	if (hwif->host_flags & IDE_HFLAG_MMIO)  		return readb((void __iomem *)hwif->io_ports.status_addr);  	else  		return inb(hwif->io_ports.status_addr);  } +EXPORT_SYMBOL_GPL(ide_read_status); -static u8 ide_read_altstatus(ide_hwif_t *hwif) +u8 ide_read_altstatus(ide_hwif_t *hwif)  {  	if (hwif->host_flags & IDE_HFLAG_MMIO)  		return readb((void __iomem *)hwif->io_ports.ctl_addr);  	else  		return inb(hwif->io_ports.ctl_addr);  } +EXPORT_SYMBOL_GPL(ide_read_altstatus); -static u8 ide_read_sff_dma_status(ide_hwif_t *hwif) +u8 ide_read_sff_dma_status(ide_hwif_t *hwif)  {  	if (hwif->host_flags & IDE_HFLAG_MMIO)  		return readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));  	else  		return inb(hwif->dma_base + ATA_DMA_STATUS);  } +EXPORT_SYMBOL_GPL(ide_read_sff_dma_status); -static void ide_set_irq(ide_hwif_t *hwif, int on) +void ide_set_irq(ide_hwif_t *hwif, int on)  {  	u8 ctl = ATA_DEVCTL_OBS; @@ -127,8 +131,9 @@ static void ide_set_irq(ide_hwif_t *hwif, int on)  	else  		outb(ctl, hwif->io_ports.ctl_addr);  } +EXPORT_SYMBOL_GPL(ide_set_irq); -static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) +void ide_tf_load(ide_drive_t *drive, ide_task_t *task)  {  	ide_hwif_t *hwif = drive->hwif;  	struct ide_io_ports *io_ports = &hwif->io_ports; @@ -180,8 +185,9 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)  		tf_outb((tf->device & HIHI) | drive->select.all,  			 io_ports->device_addr);  } +EXPORT_SYMBOL_GPL(ide_tf_load); -static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) +void ide_tf_read(ide_drive_t *drive, ide_task_t *task)  {  	ide_hwif_t *hwif = drive->hwif;  	struct ide_io_ports *io_ports = &hwif->io_ports; @@ -241,6 +247,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)  			tf->hob_lbah    = tf_inb(io_ports->lbah_addr);  	}  } +EXPORT_SYMBOL_GPL(ide_tf_read);  /*   * Some localbus EIDE interfaces require a special access sequence @@ -263,8 +270,8 @@ static void ata_vlb_sync(unsigned long port)   * so if an odd len is specified, be sure that there's at least one   * extra byte allocated for the buffer.   */ -static void ata_input_data(ide_drive_t *drive, struct request *rq, -			   void *buf, unsigned int len) +void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, +		    unsigned int len)  {  	ide_hwif_t *hwif = drive->hwif;  	struct ide_io_ports *io_ports = &hwif->io_ports; @@ -304,12 +311,13 @@ static void ata_input_data(ide_drive_t *drive, struct request *rq,  			insw(data_addr, buf, len / 2);  	}  } +EXPORT_SYMBOL_GPL(ide_input_data);  /*   * This is used for most PIO data transfers *to* the IDE interface   */ -static void ata_output_data(ide_drive_t *drive, struct request *rq, -			    void *buf, unsigned int len) +void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, +		     unsigned int len)  {  	ide_hwif_t *hwif = drive->hwif;  	struct ide_io_ports *io_ports = &hwif->io_ports; @@ -347,22 +355,7 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq,  			outsw(data_addr, buf, len / 2);  	}  } - -void default_hwif_transport(ide_hwif_t *hwif) -{ -	hwif->exec_command	  = ide_exec_command; -	hwif->read_status	  = ide_read_status; -	hwif->read_altstatus	  = ide_read_altstatus; -	hwif->read_sff_dma_status = ide_read_sff_dma_status; - -	hwif->set_irq	  = ide_set_irq; - -	hwif->tf_load	  = ide_tf_load; -	hwif->tf_read	  = ide_tf_read; - -	hwif->input_data  = ata_input_data; -	hwif->output_data = ata_output_data; -} +EXPORT_SYMBOL_GPL(ide_output_data);  u8 ide_read_error(ide_drive_t *drive)  { @@ -371,7 +364,7 @@ u8 ide_read_error(ide_drive_t *drive)  	memset(&task, 0, sizeof(task));  	task.tf_flags = IDE_TFLAG_IN_FEATURE; -	drive->hwif->tf_read(drive, &task); +	drive->hwif->tp_ops->tf_read(drive, &task);  	return task.tf.error;  } @@ -385,13 +378,28 @@ void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)  	task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |  			IDE_TFLAG_IN_NSECT; -	drive->hwif->tf_read(drive, &task); +	drive->hwif->tp_ops->tf_read(drive, &task);  	*bcount = (task.tf.lbah << 8) | task.tf.lbam;  	*ireason = task.tf.nsect & 3;  }  EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); +const struct ide_tp_ops default_tp_ops = { +	.exec_command		= ide_exec_command, +	.read_status		= ide_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= ide_read_sff_dma_status, + +	.set_irq		= ide_set_irq, + +	.tf_load		= ide_tf_load, +	.tf_read		= ide_tf_read, + +	.input_data		= ide_input_data, +	.output_data		= ide_output_data, +}; +  void ide_fix_driveid (struct hd_driveid *id)  {  #ifndef __LITTLE_ENDIAN @@ -545,10 +553,10 @@ int drive_is_ready (ide_drive_t *drive)  	 * about possible isa-pnp and pci-pnp issues yet.  	 */  	if (hwif->io_ports.ctl_addr) -		stat = hwif->read_altstatus(hwif); +		stat = hwif->tp_ops->read_altstatus(hwif);  	else  		/* Note: this may clear a pending IRQ!! */ -		stat = hwif->read_status(hwif); +		stat = hwif->tp_ops->read_status(hwif);  	if (stat & BUSY_STAT)  		/* drive busy:  definitely not interrupting */ @@ -574,24 +582,25 @@ EXPORT_SYMBOL(drive_is_ready);  static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)  {  	ide_hwif_t *hwif = drive->hwif; +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	unsigned long flags;  	int i;  	u8 stat;  	udelay(1);	/* spec allows drive 400ns to assert "BUSY" */ -	stat = hwif->read_status(hwif); +	stat = tp_ops->read_status(hwif);  	if (stat & BUSY_STAT) {  		local_irq_set(flags);  		timeout += jiffies; -		while ((stat = hwif->read_status(hwif)) & BUSY_STAT) { +		while ((stat = tp_ops->read_status(hwif)) & BUSY_STAT) {  			if (time_after(jiffies, timeout)) {  				/*  				 * One last read after the timeout in case  				 * heavy interrupt load made us not make any  				 * progress during the timeout..  				 */ -				stat = hwif->read_status(hwif); +				stat = tp_ops->read_status(hwif);  				if (!(stat & BUSY_STAT))  					break; @@ -611,7 +620,7 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti  	 */  	for (i = 0; i < 10; i++) {  		udelay(1); -		stat = hwif->read_status(hwif); +		stat = tp_ops->read_status(hwif);  		if (OK_STAT(stat, good, bad)) {  			*rstat = stat; @@ -737,6 +746,7 @@ no_80w:  int ide_driveid_update(ide_drive_t *drive)  {  	ide_hwif_t *hwif = drive->hwif; +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	struct hd_driveid *id;  	unsigned long timeout, flags;  	u8 stat; @@ -747,9 +757,9 @@ int ide_driveid_update(ide_drive_t *drive)  	 */  	SELECT_MASK(drive, 1); -	hwif->set_irq(hwif, 0); +	tp_ops->set_irq(hwif, 0);  	msleep(50); -	hwif->exec_command(hwif, WIN_IDENTIFY); +	tp_ops->exec_command(hwif, WIN_IDENTIFY);  	timeout = jiffies + WAIT_WORSTCASE;  	do {  		if (time_after(jiffies, timeout)) { @@ -758,11 +768,11 @@ int ide_driveid_update(ide_drive_t *drive)  		}  		msleep(50);	/* give drive a breather */ -		stat = hwif->read_altstatus(hwif); +		stat = tp_ops->read_altstatus(hwif);  	} while (stat & BUSY_STAT);  	msleep(50);	/* wait for IRQ and DRQ_STAT */ -	stat = hwif->read_status(hwif); +	stat = tp_ops->read_status(hwif);  	if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {  		SELECT_MASK(drive, 0); @@ -776,8 +786,8 @@ int ide_driveid_update(ide_drive_t *drive)  		local_irq_restore(flags);  		return 0;  	} -	hwif->input_data(drive, NULL, id, SECTOR_SIZE); -	(void)hwif->read_status(hwif);	/* clear drive IRQ */ +	tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); +	(void)tp_ops->read_status(hwif);	/* clear drive IRQ */  	local_irq_enable();  	local_irq_restore(flags);  	ide_fix_driveid(id); @@ -798,6 +808,7 @@ int ide_driveid_update(ide_drive_t *drive)  int ide_config_drive_speed(ide_drive_t *drive, u8 speed)  {  	ide_hwif_t *hwif = drive->hwif; +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	int error = 0;  	u8 stat;  	ide_task_t task; @@ -833,19 +844,19 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)  	SELECT_DRIVE(drive);  	SELECT_MASK(drive, 0);  	udelay(1); -	hwif->set_irq(hwif, 0); +	tp_ops->set_irq(hwif, 0);  	memset(&task, 0, sizeof(task));  	task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;  	task.tf.feature = SETFEATURES_XFER;  	task.tf.nsect   = speed; -	hwif->tf_load(drive, &task); +	tp_ops->tf_load(drive, &task); -	hwif->exec_command(hwif, WIN_SETFEATURES); +	tp_ops->exec_command(hwif, WIN_SETFEATURES);  	if (drive->quirk_list == 2) -		hwif->set_irq(hwif, 1); +		tp_ops->set_irq(hwif, 1);  	error = __ide_wait_stat(drive, drive->ready_stat,  				BUSY_STAT|DRQ_STAT|ERR_STAT, @@ -950,7 +961,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,  	spin_lock_irqsave(&ide_lock, flags);  	__ide_set_handler(drive, handler, timeout, expiry); -	hwif->exec_command(hwif, cmd); +	hwif->tp_ops->exec_command(hwif, cmd);  	/*  	 * Drive takes 400nS to respond, we must avoid the IRQ being  	 * serviced before that. @@ -968,7 +979,7 @@ void ide_execute_pkt_cmd(ide_drive_t *drive)  	unsigned long flags;  	spin_lock_irqsave(&ide_lock, flags); -	hwif->exec_command(hwif, WIN_PACKETCMD); +	hwif->tp_ops->exec_command(hwif, WIN_PACKETCMD);  	ndelay(400);  	spin_unlock_irqrestore(&ide_lock, flags);  } @@ -999,7 +1010,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)  	SELECT_DRIVE(drive);  	udelay (10); -	stat = hwif->read_status(hwif); +	stat = hwif->tp_ops->read_status(hwif);  	if (OK_STAT(stat, 0, BUSY_STAT))  		printk("%s: ATAPI reset complete\n", drive->name); @@ -1045,7 +1056,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)  		}  	} -	tmp = hwif->read_status(hwif); +	tmp = hwif->tp_ops->read_status(hwif);  	if (!OK_STAT(tmp, 0, BUSY_STAT)) {  		if (time_before(jiffies, hwgroup->poll_timeout)) { @@ -1159,6 +1170,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)  	ide_hwif_t *hwif;  	ide_hwgroup_t *hwgroup;  	struct ide_io_ports *io_ports; +	const struct ide_tp_ops *tp_ops;  	const struct ide_port_ops *port_ops;  	spin_lock_irqsave(&ide_lock, flags); @@ -1167,6 +1179,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)  	io_ports = &hwif->io_ports; +	tp_ops = hwif->tp_ops; +  	/* We must not reset with running handlers */  	BUG_ON(hwgroup->handler != NULL); @@ -1175,7 +1189,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)  		pre_reset(drive);  		SELECT_DRIVE(drive);  		udelay (20); -		hwif->exec_command(hwif, WIN_SRST); +		tp_ops->exec_command(hwif, WIN_SRST);  		ndelay(400);  		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;  		hwgroup->polling = 1; @@ -1208,11 +1222,11 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)  	 * TODO: add ->softreset method and stop abusing ->set_irq  	 */  	/* set SRST and nIEN */ -	hwif->set_irq(hwif, 4); +	tp_ops->set_irq(hwif, 4);  	/* more than enough time */  	udelay(10);  	/* clear SRST, leave nIEN (unless device is on the quirk list) */ -	hwif->set_irq(hwif, drive->quirk_list == 2); +	tp_ops->set_irq(hwif, drive->quirk_list == 2);  	/* more than enough time */  	udelay(10);  	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; @@ -1257,7 +1271,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)  		 * about locking issues (2.5 work ?).  		 */  		mdelay(1); -		stat = hwif->read_status(hwif); +		stat = hwif->tp_ops->read_status(hwif);  		if ((stat & BUSY_STAT) == 0)  			return 0;  		/* diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 7ac44d51547..97fefabea8b 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -325,7 +325,7 @@ static void ide_dump_sector(ide_drive_t *drive)  	else  		task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; -	drive->hwif->tf_read(drive, &task); +	drive->hwif->tp_ops->tf_read(drive, &task);  	if (lba48 || (tf->device & ATA_LBA))  		printk(", LBAsect=%llu", diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 3cc8ade2cc4..c588066295d 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -126,7 +126,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)  	id = drive->id;  	/* read 512 bytes of id info */ -	hwif->input_data(drive, NULL, id, SECTOR_SIZE); +	hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);  	drive->id_read = 1;  	local_irq_enable(); @@ -267,6 +267,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)  {  	ide_hwif_t *hwif = HWIF(drive);  	struct ide_io_ports *io_ports = &hwif->io_ports; +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	int use_altstatus = 0, rc;  	unsigned long timeout;  	u8 s = 0, a = 0; @@ -275,8 +276,8 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)  	msleep(50);  	if (io_ports->ctl_addr) { -		a = hwif->read_altstatus(hwif); -		s = hwif->read_status(hwif); +		a = tp_ops->read_altstatus(hwif); +		s = tp_ops->read_status(hwif);  		if ((a ^ s) & ~INDEX_STAT)  			/* ancient Seagate drives, broken interfaces */  			printk(KERN_INFO "%s: probing with STATUS(0x%02x) " @@ -297,11 +298,11 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)  		/* disable DMA & overlap */  		task.tf_flags = IDE_TFLAG_OUT_FEATURE; -		drive->hwif->tf_load(drive, &task); +		tp_ops->tf_load(drive, &task);  	}  	/* ask drive for ID */ -	hwif->exec_command(hwif, cmd); +	tp_ops->exec_command(hwif, cmd);  	timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;  	timeout += jiffies; @@ -312,13 +313,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)  		}  		/* give drive a breather */  		msleep(50); -		s = use_altstatus ? hwif->read_altstatus(hwif) -				  : hwif->read_status(hwif); +		s = use_altstatus ? tp_ops->read_altstatus(hwif) +				  : tp_ops->read_status(hwif);  	} while (s & BUSY_STAT);  	/* wait for IRQ and DRQ_STAT */  	msleep(50); -	s = hwif->read_status(hwif); +	s = tp_ops->read_status(hwif);  	if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) {  		unsigned long flags; @@ -330,7 +331,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)  		/* drive responded with ID */  		rc = 0;  		/* clear drive IRQ */ -		(void)hwif->read_status(hwif); +		(void)tp_ops->read_status(hwif);  		local_irq_restore(flags);  	} else {  		/* drive refused ID */ @@ -352,6 +353,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)  static int try_to_identify (ide_drive_t *drive, u8 cmd)  {  	ide_hwif_t *hwif = HWIF(drive); +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	int retval;  	int autoprobe = 0;  	unsigned long cookie = 0; @@ -367,7 +369,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)  			autoprobe = 1;  			cookie = probe_irq_on();  		} -		hwif->set_irq(hwif, autoprobe); +		tp_ops->set_irq(hwif, autoprobe);  	}  	retval = actual_try_to_identify(drive, cmd); @@ -375,9 +377,9 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)  	if (autoprobe) {  		int irq; -		hwif->set_irq(hwif, 0); +		tp_ops->set_irq(hwif, 0);  		/* clear drive IRQ */ -		(void)hwif->read_status(hwif); +		(void)tp_ops->read_status(hwif);  		udelay(5);  		irq = probe_irq_off(cookie);  		if (!hwif->irq) { @@ -402,7 +404,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif)  	do {  		msleep(50); -		stat = hwif->read_status(hwif); +		stat = hwif->tp_ops->read_status(hwif);  		if ((stat & BUSY_STAT) == 0)  			return 0;  	} while (time_before(jiffies, timeout)); @@ -417,7 +419,7 @@ static u8 ide_read_device(ide_drive_t *drive)  	memset(&task, 0, sizeof(task));  	task.tf_flags = IDE_TFLAG_IN_DEVICE; -	drive->hwif->tf_read(drive, &task); +	drive->hwif->tp_ops->tf_read(drive, &task);  	return task.tf.device;  } @@ -446,6 +448,7 @@ static u8 ide_read_device(ide_drive_t *drive)  static int do_probe (ide_drive_t *drive, u8 cmd)  {  	ide_hwif_t *hwif = HWIF(drive); +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	int rc;  	u8 stat; @@ -478,7 +481,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)  		return 3;  	} -	stat = hwif->read_status(hwif); +	stat = tp_ops->read_status(hwif);  	if (OK_STAT(stat, READY_STAT, BUSY_STAT) ||  	    drive->present || cmd == WIN_PIDENTIFY) { @@ -488,7 +491,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)  			rc = try_to_identify(drive,cmd);  		} -		stat = hwif->read_status(hwif); +		stat = tp_ops->read_status(hwif);  		if (stat == (BUSY_STAT | READY_STAT))  			return 4; @@ -499,13 +502,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)  			msleep(50);  			SELECT_DRIVE(drive);  			msleep(50); -			hwif->exec_command(hwif, WIN_SRST); +			tp_ops->exec_command(hwif, WIN_SRST);  			(void)ide_busy_sleep(hwif);  			rc = try_to_identify(drive, cmd);  		}  		/* ensure drive IRQ is clear */ -		stat = hwif->read_status(hwif); +		stat = tp_ops->read_status(hwif);  		if (rc == 1)  			printk(KERN_ERR "%s: no response (status = 0x%02x)\n", @@ -519,7 +522,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)  		SELECT_DRIVE(&hwif->drives[0]);  		msleep(50);  		/* ensure drive irq is clear */ -		(void)hwif->read_status(hwif); +		(void)tp_ops->read_status(hwif);  	}  	return rc;  } @@ -530,12 +533,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)  static void enable_nest (ide_drive_t *drive)  {  	ide_hwif_t *hwif = HWIF(drive); +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	u8 stat;  	printk("%s: enabling %s -- ", hwif->name, drive->id->model);  	SELECT_DRIVE(drive);  	msleep(50); -	hwif->exec_command(hwif, EXABYTE_ENABLE_NEST); +	tp_ops->exec_command(hwif, EXABYTE_ENABLE_NEST);  	if (ide_busy_sleep(hwif)) {  		printk(KERN_CONT "failed (timeout)\n"); @@ -544,7 +548,7 @@ static void enable_nest (ide_drive_t *drive)  	msleep(50); -	stat = hwif->read_status(hwif); +	stat = tp_ops->read_status(hwif);  	if (!OK_STAT(stat, 0, BAD_STAT))  		printk(KERN_CONT "failed (status = 0x%02x)\n", stat); @@ -726,7 +730,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)  		/* Ignore disks that we will not probe for later. */  		if (!drive->noprobe || drive->present) {  			SELECT_DRIVE(drive); -			hwif->set_irq(hwif, 1); +			hwif->tp_ops->set_irq(hwif, 1);  			mdelay(2);  			rc = ide_wait_not_busy(hwif, 35000);  			if (rc) @@ -1083,7 +1087,7 @@ static int init_irq (ide_hwif_t *hwif)  			sa = IRQF_SHARED;  		if (io_ports->ctl_addr) -			hwif->set_irq(hwif, 1); +			hwif->tp_ops->set_irq(hwif, 1);  		if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))  	       		goto out_unlink; @@ -1361,6 +1365,9 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,  	hwif->host_flags |= d->host_flags;  	hwif->pio_mask = d->pio_mask; +	if (d->tp_ops) +		hwif->tp_ops = d->tp_ops; +  	/* ->set_pio_mode for DTC2278 is currently limited to port 0 */  	if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)  		hwif->port_ops = d->port_ops; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index ef54728a74b..0af128826f1 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -398,7 +398,7 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,  		count = min(  			(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),  			bcount); -		drive->hwif->input_data(drive, NULL, bh->b_data + +		drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data +  					atomic_read(&bh->b_count), count);  		bcount -= count;  		atomic_add(count, &bh->b_count); @@ -424,7 +424,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,  			return;  		}  		count = min((unsigned int)pc->b_count, (unsigned int)bcount); -		drive->hwif->output_data(drive, NULL, pc->b_data, count); +		drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);  		bcount -= count;  		pc->b_data += count;  		pc->b_count -= count; @@ -932,7 +932,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)  	struct ide_atapi_pc *pc = tape->pc;  	u8 stat; -	stat = hwif->read_status(hwif); +	stat = hwif->tp_ops->read_status(hwif);  	if (stat & SEEK_STAT) {  		if (stat & ERR_STAT) { @@ -1019,7 +1019,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,  	 * If the tape is still busy, postpone our request and service  	 * the other device meanwhile.  	 */ -	stat = hwif->read_status(hwif); +	stat = hwif->tp_ops->read_status(hwif);  	if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2))  		set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags); diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index ea345369553..aeddbbd69e8 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -64,6 +64,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)  	ide_hwif_t *hwif	= HWIF(drive);  	struct ide_taskfile *tf = &task->tf;  	ide_handler_t *handler = NULL; +	const struct ide_tp_ops *tp_ops = hwif->tp_ops;  	const struct ide_dma_ops *dma_ops = hwif->dma_ops;  	if (task->data_phase == TASKFILE_MULTI_IN || @@ -80,15 +81,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)  	if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {  		ide_tf_dump(drive->name, tf); -		hwif->set_irq(hwif, 1); +		tp_ops->set_irq(hwif, 1);  		SELECT_MASK(drive, 0); -		hwif->tf_load(drive, task); +		tp_ops->tf_load(drive, task);  	}  	switch (task->data_phase) {  	case TASKFILE_MULTI_OUT:  	case TASKFILE_OUT: -		hwif->exec_command(hwif, tf->command); +		tp_ops->exec_command(hwif, tf->command);  		ndelay(400);	/* FIXME */  		return pre_task_out_intr(drive, task->rq);  	case TASKFILE_MULTI_IN: @@ -125,7 +126,7 @@ EXPORT_SYMBOL_GPL(do_rw_taskfile);  static ide_startstop_t set_multmode_intr(ide_drive_t *drive)  {  	ide_hwif_t *hwif = drive->hwif; -	u8 stat = hwif->read_status(hwif); +	u8 stat = hwif->tp_ops->read_status(hwif);  	if (OK_STAT(stat, READY_STAT, BAD_STAT))  		drive->mult_count = drive->mult_req; @@ -146,8 +147,12 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)  	int retries = 5;  	u8 stat; -	while (((stat = hwif->read_status(hwif)) & BUSY_STAT) && retries--) +	while (1) { +		stat = hwif->tp_ops->read_status(hwif); +		if ((stat & BUSY_STAT) == 0 || retries-- == 0) +			break;  		udelay(10); +	};  	if (OK_STAT(stat, READY_STAT, BAD_STAT))  		return ide_stopped; @@ -165,7 +170,7 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)  static ide_startstop_t recal_intr(ide_drive_t *drive)  {  	ide_hwif_t *hwif = drive->hwif; -	u8 stat = hwif->read_status(hwif); +	u8 stat = hwif->tp_ops->read_status(hwif);  	if (!OK_STAT(stat, READY_STAT, BAD_STAT))  		return ide_error(drive, "recal_intr", stat); @@ -182,7 +187,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)  	u8 stat;  	local_irq_enable_in_hardirq(); -	stat = hwif->read_status(hwif); +	stat = hwif->tp_ops->read_status(hwif);  	if (!OK_STAT(stat, READY_STAT, BAD_STAT))  		return ide_error(drive, "task_no_data_intr", stat); @@ -205,7 +210,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)  	 * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.  	 */  	for (retries = 0; retries < 1000; retries++) { -		stat = hwif->read_status(hwif); +		stat = hwif->tp_ops->read_status(hwif);  		if (stat & BUSY_STAT)  			udelay(10); @@ -260,9 +265,9 @@ static void ide_pio_sector(ide_drive_t *drive, struct request *rq,  	/* do the actual data transfer */  	if (write) -		hwif->output_data(drive, rq, buf, SECTOR_SIZE); +		hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);  	else -		hwif->input_data(drive, rq, buf, SECTOR_SIZE); +		hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);  	kunmap_atomic(buf, KM_BIO_SRC_IRQ);  #ifdef CONFIG_HIGHMEM @@ -389,7 +394,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)  {  	ide_hwif_t *hwif = drive->hwif;  	struct request *rq = hwif->hwgroup->rq; -	u8 stat = hwif->read_status(hwif); +	u8 stat = hwif->tp_ops->read_status(hwif);  	/* Error? */  	if (stat & ERR_STAT) @@ -423,7 +428,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive)  {  	ide_hwif_t *hwif = drive->hwif;  	struct request *rq = HWGROUP(drive)->rq; -	u8 stat = hwif->read_status(hwif); +	u8 stat = hwif->tp_ops->read_status(hwif);  	if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))  		return task_error(drive, rq, __func__, stat); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 961f31c648c..132b504168e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -101,7 +101,7 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)  	init_completion(&hwif->gendev_rel_comp); -	default_hwif_transport(hwif); +	hwif->tp_ops = &default_tp_ops;  	ide_port_init_devices_data(hwif);  } diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 1bb2aa72cc7..3e2c6125f03 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c @@ -66,6 +66,27 @@ static void falconide_output_data(ide_drive_t *drive, struct request *rq,  	outsw_swapw(data_addr, buf, (len + 1) / 2);  } +/* Atari has a byte-swapped IDE interface */ +static const struct ide_tp_ops falconide_tp_ops = { +	.exec_command		= ide_exec_command, +	.read_status		= ide_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= ide_read_sff_dma_status, + +	.set_irq		= ide_set_irq, + +	.tf_load		= ide_tf_load, +	.tf_read		= ide_tf_read, + +	.input_data		= falconide_input_data, +	.output_data		= falconide_output_data, +}; + +static const struct ide_port_info falconide_port_info = { +	.tp_ops			= &falconide_tp_ops, +	.host_flags		= IDE_HFLAG_NO_DMA, +}; +  static void __init falconide_setup_ports(hw_regs_t *hw)  {  	int i; @@ -111,12 +132,8 @@ static int __init falconide_init(void)  		u8 index = hwif->index;  		u8 idx[4] = { index, 0xff, 0xff, 0xff }; -		/* Atari has a byte-swapped IDE interface */ -		hwif->input_data  = falconide_input_data; -		hwif->output_data = falconide_output_data; -  		ide_get_lock(NULL, NULL); -		ide_device_add(idx, NULL, hws); +		ide_device_add(idx, &falconide_port_info, hws);  		ide_release_lock();  	} diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index fcb04b8b023..2dc306f852a 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c @@ -96,6 +96,27 @@ static void q40ide_output_data(ide_drive_t *drive, struct request *rq,  	outsw_swapw(data_addr, buf, (len + 1) / 2);  } +/* Q40 has a byte-swapped IDE interface */ +static const struct ide_tp_ops q40ide_tp_ops = { +	.exec_command		= ide_exec_command, +	.read_status		= ide_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= ide_read_sff_dma_status, + +	.set_irq		= ide_set_irq, + +	.tf_load		= ide_tf_load, +	.tf_read		= ide_tf_read, + +	.input_data		= q40ide_input_data, +	.output_data		= q40ide_output_data, +}; + +static const struct ide_port_info q40ide_port_info = { +	.tp_ops			= &q40ide_tp_ops, +	.host_flags		= IDE_HFLAG_NO_DMA, +}; +  /*    * the static array is needed to have the name reported in /proc/ioports,   * hwif->name unfortunately isn't available yet @@ -141,16 +162,12 @@ static int __init q40ide_init(void)  	if (hwif) {  		hwif->chipset = ide_generic; -		/* Q40 has a byte-swapped IDE interface */ -		hwif->input_data  = q40ide_input_data; -		hwif->output_data = q40ide_output_data; -  		hws[i] = &hw[i];  		idx[i] = hwif->index;  	}      } -    ide_device_add(idx, NULL, hws); +    ide_device_add(idx, &q40ide_port_info, hws);      return 0;  } diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 475da582fd8..ed1c9a13407 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -519,6 +519,23 @@ static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)  	*ata_regs = ahwif->regbase + (14 << IDE_REG_SHIFT);  } +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA +static const struct ide_tp_ops au1xxx_tp_ops = { +	.exec_command		= ide_exec_command, +	.read_status		= ide_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= ide_read_sff_dma_status, + +	.set_irq		= ide_set_irq, + +	.tf_load		= ide_tf_load, +	.tf_read		= ide_tf_read, + +	.input_data		= au1xxx_input_data, +	.output_data		= au1xxx_output_data, +}; +#endif +  static const struct ide_port_ops au1xxx_port_ops = {  	.set_pio_mode		= au1xxx_set_pio_mode,  	.set_dma_mode		= auide_set_dma_mode, @@ -526,6 +543,9 @@ static const struct ide_port_ops au1xxx_port_ops = {  static const struct ide_port_info au1xxx_port_info = {  	.init_dma		= auide_ddma_init, +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA +	.tp_ops			= &au1xxx_tp_ops, +#endif  	.port_ops		= &au1xxx_port_ops,  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA  	.dma_ops		= &au1xxx_dma_ops, @@ -596,15 +616,6 @@ static int au_ide_probe(struct device *dev)  	hw.dev = dev;  	hw.chipset = ide_au1xxx; -	/* If the user has selected DDMA assisted copies, -	   then set up a few local I/O function entry points  -	*/ - -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA	 -	hwif->input_data  = au1xxx_input_data; -	hwif->output_data = au1xxx_output_data; -#endif -  	auide_hwif.hwif                 = hwif;  	idx[0] = hwif->index; diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 02fd3a877af..5cd2b32ff0e 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -104,7 +104,22 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)  	}  } -static void __devinit superio_ide_init_iops (struct hwif_s *hwif) +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, + +	.set_irq		= ide_set_irq, + +	.tf_load		= ide_tf_load, +	.tf_read		= superio_tf_read, + +	.input_data		= ide_input_data, +	.output_data		= ide_output_data, +}; + +static void __devinit superio_init_iops(struct hwif_s *hwif)  {  	struct pci_dev *pdev = to_pci_dev(hwif->dev);  	u32 dma_stat; @@ -115,21 +130,6 @@ static void __devinit superio_ide_init_iops (struct hwif_s *hwif)  	/* Clear error/interrupt, enable dma */  	tmp = superio_ide_inb(dma_stat);  	outb(tmp | 0x66, dma_stat); - -	hwif->read_status	  = superio_read_status; -	hwif->read_sff_dma_status = superio_read_sff_dma_status; - -	hwif->tf_read = superio_tf_read; - -} - -static void __devinit init_iops_ns87415(ide_hwif_t *hwif) -{ -	struct pci_dev *dev = to_pci_dev(hwif->dev); - -	if (PCI_SLOT(dev->devfn) == 0xE) -		/* Built-in - assume it's under superio. */ -		superio_ide_init_iops(hwif);  }  #endif @@ -195,7 +195,7 @@ static int ns87415_dma_end(ide_drive_t *drive)  	u8 dma_stat = 0, dma_cmd = 0;  	drive->waiting_for_dma = 0; -	dma_stat = hwif->read_sff_dma_status(hwif); +	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 */ @@ -271,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->read_status(hwif); +			stat = hwif->tp_ops->read_status(hwif);                  	if (stat == 0xff)                          	break;          	} while ((stat & BUSY_STAT) && --timeout); @@ -306,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, @@ -318,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[] = { diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 38765d9b031..5b1a0e950df 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -808,19 +808,6 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)  	ide_set_hwifdata(hwif, ports); -	hwif->exec_command	  = scc_exec_command; -	hwif->read_status	  = scc_read_status; -	hwif->read_altstatus	  = scc_read_altstatus; -	hwif->read_sff_dma_status = scc_read_sff_dma_status; - -	hwif->set_irq = scc_set_irq; - -	hwif->tf_load = scc_tf_load; -	hwif->tf_read = scc_tf_read; - -	hwif->input_data  = scc_input_data; -	hwif->output_data = scc_output_data; -  	hwif->dma_base = dma_base;  	hwif->config_data = ports->ctl;  } @@ -872,6 +859,21 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)  		hwif->ultra_mask = ATA_UDMA5; /* 100MHz */  } +static const struct ide_tp_ops scc_tp_ops = { +	.exec_command		= scc_exec_command, +	.read_status		= scc_read_status, +	.read_altstatus		= scc_read_altstatus, +	.read_sff_dma_status	= scc_read_sff_dma_status, + +	.set_irq		= scc_set_irq, + +	.tf_load		= scc_tf_load, +	.tf_read		= scc_tf_read, + +	.input_data		= scc_input_data, +	.output_data		= scc_output_data, +}; +  static const struct ide_port_ops scc_port_ops = {  	.set_pio_mode		= scc_set_pio_mode,  	.set_dma_mode		= scc_set_dma_mode, @@ -895,6 +897,7 @@ static const struct ide_dma_ops scc_dma_ops = {        .name		= name_str,			\        .init_iops	= init_iops_scc,		\        .init_hwif	= init_hwif_scc,		\ +      .tp_ops		= &scc_tp_ops,		\        .port_ops		= &scc_port_ops,		\        .dma_ops		= &scc_dma_ops,			\        .host_flags	= IDE_HFLAG_SINGLE,		\ diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 86f7c490183..5598bd5936d 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -550,6 +550,21 @@ static int sgiioc4_dma_setup(ide_drive_t *drive)  	return 0;  } +static const struct ide_tp_ops sgiioc4_tp_ops = { +	.exec_command		= ide_exec_command, +	.read_status		= sgiioc4_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= ide_read_sff_dma_status, + +	.set_irq		= ide_set_irq, + +	.tf_load		= ide_tf_load, +	.tf_read		= ide_tf_read, + +	.input_data		= ide_input_data, +	.output_data		= ide_output_data, +}; +  static const struct ide_port_ops sgiioc4_port_ops = {  	.set_dma_mode		= sgiioc4_set_dma_mode,  	/* reset DMA engine, clear IRQs */ @@ -572,6 +587,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitdata = {  	.name			= DRV_NAME,  	.chipset		= ide_pci,  	.init_dma		= ide_dma_sgiioc4, +	.tp_ops			= &sgiioc4_tp_ops,  	.port_ops		= &sgiioc4_port_ops,  	.dma_ops		= &sgiioc4_dma_ops,  	.host_flags		= IDE_HFLAG_MMIO, @@ -626,8 +642,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)  	/* Initializing chipset IRQ Registers */  	writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); -	hwif->read_status = sgiioc4_read_status; -  	idx[0] = hwif->index;  	if (ide_device_add(idx, &d, hws)) diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ed073c6635a..ee557d10a76 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -974,6 +974,21 @@ static void pmac_ide_init_dev(ide_drive_t *drive)  	}  } +static const struct ide_tp_ops pmac_tp_ops = { +	.exec_command		= pmac_exec_command, +	.read_status		= ide_read_status, +	.read_altstatus		= ide_read_altstatus, +	.read_sff_dma_status	= ide_read_sff_dma_status, + +	.set_irq		= pmac_set_irq, + +	.tf_load		= ide_tf_load, +	.tf_read		= ide_tf_read, + +	.input_data		= ide_input_data, +	.output_data		= ide_output_data, +}; +  static const struct ide_port_ops pmac_ide_ata6_port_ops = {  	.init_dev		= pmac_ide_init_dev,  	.set_pio_mode		= pmac_ide_set_pio_mode, @@ -1003,10 +1018,11 @@ static const struct ide_port_info pmac_port_info = {  	.name			= DRV_NAME,  	.init_dma		= pmac_ide_init_dma,  	.chipset		= ide_pmac, +	.tp_ops			= &pmac_tp_ops, +	.port_ops		= &pmac_ide_port_ops,  #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC  	.dma_ops		= &pmac_dma_ops,  #endif -	.port_ops		= &pmac_ide_port_ops,  	.host_flags		= IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |  				  IDE_HFLAG_POST_SET_MODE |  				  IDE_HFLAG_MMIO | @@ -1106,9 +1122,6 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)  	if (hwif == NULL)  		return -ENOENT; -	hwif->exec_command = pmac_exec_command; -	hwif->set_irq	   = pmac_set_irq; -  	idx[0] = hwif->index;  	ide_device_add(idx, &d, hws); diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index c1b609d9cb2..804c3ef245f 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -125,7 +125,7 @@ int ide_pci_check_simplex(ide_hwif_t *hwif, const struct ide_port_info *d)  	 * we tune the drive then try to grab DMA ownership if we want to be  	 * the DMA end.  This has to be become dynamic to handle hot-plug.  	 */ -	dma_stat = hwif->read_sff_dma_status(hwif); +	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);  	if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {  		printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name);  		return -1; diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 2a86af91f64..659db3f7ae0 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -142,7 +142,8 @@ static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,  				unsigned int bcount, int write)  {  	ide_hwif_t *hwif = drive->hwif; -	xfer_func_t *xf = write ? hwif->output_data : hwif->input_data; +	const struct ide_tp_ops *tp_ops = hwif->tp_ops; +	xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;  	char *buf;  	int count; @@ -246,9 +247,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)  {  	ide_hwif_t *hwif = drive->hwif; -	if (hwif->read_status(hwif) & (BUSY_STAT | DRQ_STAT)) +	if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))  		/* force an abort */ -		hwif->exec_command(hwif, WIN_IDLEIMMEDIATE); +		hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE);  	rq->errors++; diff --git a/include/linux/ide.h b/include/linux/ide.h index e340218b2a5..1286a2275ef 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -408,8 +408,28 @@ typedef struct ide_drive_s {      ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))  #define IDE_CHIPSET_IS_PCI(c)	((IDE_CHIPSET_PCI_MASK >> (c)) & 1) +struct ide_task_s;  struct ide_port_info; +struct ide_tp_ops { +	void	(*exec_command)(struct hwif_s *, u8); +	u8	(*read_status)(struct hwif_s *); +	u8	(*read_altstatus)(struct hwif_s *); +	u8	(*read_sff_dma_status)(struct hwif_s *); + +	void	(*set_irq)(struct hwif_s *, int); + +	void	(*tf_load)(ide_drive_t *, struct ide_task_s *); +	void	(*tf_read)(ide_drive_t *, struct ide_task_s *); + +	void	(*input_data)(ide_drive_t *, struct request *, void *, +			      unsigned int); +	void	(*output_data)(ide_drive_t *, struct request *, void *, +			       unsigned int); +}; + +extern const struct ide_tp_ops default_tp_ops; +  struct ide_port_ops {  	/* host specific initialization of a device */  	void	(*init_dev)(ide_drive_t *); @@ -447,8 +467,6 @@ struct ide_dma_ops {  	void	(*dma_timeout)(struct ide_drive_s *);  }; -struct ide_task_s; -  typedef struct hwif_s {  	struct hwif_s *next;		/* for linked-list in ide_hwgroup_t */  	struct hwif_s *mate;		/* other hwif from same PCI chip */ @@ -486,22 +504,10 @@ typedef struct hwif_s {  	void (*rw_disk)(ide_drive_t *, struct request *); +	const struct ide_tp_ops		*tp_ops;  	const struct ide_port_ops	*port_ops;  	const struct ide_dma_ops	*dma_ops; -	void	(*exec_command)(struct hwif_s *, u8); -	u8	(*read_status)(struct hwif_s *); -	u8	(*read_altstatus)(struct hwif_s *); -	u8	(*read_sff_dma_status)(struct hwif_s *); - -	void	(*set_irq)(struct hwif_s *, int); - -	void (*tf_load)(ide_drive_t *, struct ide_task_s *); -	void (*tf_read)(ide_drive_t *, struct ide_task_s *); - -	void (*input_data)(ide_drive_t *, struct request *, void *, unsigned); -	void (*output_data)(ide_drive_t *, struct request *, void *, unsigned); -  	void (*ide_dma_clear_irq)(ide_drive_t *drive);  	/* dma physical region descriptor table (cpu view) */ @@ -949,6 +955,19 @@ typedef struct ide_task_s {  void ide_tf_dump(const char *, struct ide_taskfile *); +void ide_exec_command(ide_hwif_t *, u8); +u8 ide_read_status(ide_hwif_t *); +u8 ide_read_altstatus(ide_hwif_t *); +u8 ide_read_sff_dma_status(ide_hwif_t *); + +void ide_set_irq(ide_hwif_t *, int); + +void ide_tf_load(ide_drive_t *, ide_task_t *); +void ide_tf_read(ide_drive_t *, ide_task_t *); + +void ide_input_data(ide_drive_t *, struct request *, void *, unsigned int); +void ide_output_data(ide_drive_t *, struct request *, void *, unsigned int); +  extern void SELECT_DRIVE(ide_drive_t *);  void SELECT_MASK(ide_drive_t *, int); @@ -1022,8 +1041,6 @@ static inline int ide_hwif_setup_dma(ide_hwif_t *hwif,  }  #endif -extern void default_hwif_transport(ide_hwif_t *); -  typedef struct ide_pci_enablebit_s {  	u8	reg;	/* byte pci reg holding the enable-bit */  	u8	mask;	/* mask to isolate the enable-bit */ @@ -1112,6 +1129,7 @@ struct ide_port_info {  	int			(*init_dma)(ide_hwif_t *,  					    const struct ide_port_info *); +	const struct ide_tp_ops		*tp_ops;  	const struct ide_port_ops	*port_ops;  	const struct ide_dma_ops	*dma_ops;  |