[PATCH 1/4] libata.h: add low-level I/O calls

Akira Iguchi akira2.iguchi at toshiba.co.jp
Fri Jan 12 21:01:11 EST 2007


struct ata_io_operations has low-level I/O calls to access
the taskfile registers. The idea comes from drivers/ide
IN*/OUT* calls.

Current access functions in libata (ex: inb()) is replaced
by these calls, like
	inb()  ->   ap->io_ops->INB()

To initialize this operation in ata_port, there are
additional members in ata_probe_ent, ata_host and ata_port_info.

Signed-off-by: Kou Ishizaki <kou.ishizaki at toshiba.co.jp>
Signed-off-by: Akira Iguchi <akira2.iguchi at toshiba.co.jp>
---

--- linux-2.6.20-rc4/include/linux/libata.h.orig	2007-01-13 01:02:28.000000000 +0900
+++ linux-2.6.20-rc4/include/linux/libata.h	2007-01-13 01:03:24.000000000 +0900
@@ -372,6 +372,7 @@ struct ata_probe_ent {
 	struct list_head	node;
 	struct device 		*dev;
 	const struct ata_port_operations *port_ops;
+	struct ata_io_operations *io_ops;
 	struct scsi_host_template *sht;
 	struct ata_ioports	port[ATA_MAX_PORTS];
 	unsigned int		n_ports;
@@ -405,6 +406,7 @@ struct ata_host {
 	unsigned int		n_ports;
 	void			*private_data;
 	const struct ata_port_operations *ops;
+	struct ata_io_operations *io_ops;
 	unsigned long		flags;
 	int			simplex_claimed;	/* Keep seperate in case we
 							   ever need to do this locked */
@@ -534,6 +536,7 @@ struct ata_eh_context {
 struct ata_port {
 	struct Scsi_Host	*scsi_host; /* our co-allocated scsi host */
 	const struct ata_port_operations *ops;
+	struct ata_io_operations *io_ops;
 	spinlock_t		*lock;
 	unsigned long		flags;	/* ATA_FLAG_xxx */
 	unsigned int		pflags; /* ATA_PFLAG_xxx */
@@ -655,6 +658,18 @@ struct ata_port_operations {
 	u8   (*bmdma_status) (struct ata_port *ap);
 };
 
+struct ata_io_operations {
+	void (*OUTB)(u8 addr, unsigned long port);
+	void (*OUTW)(u16 addr, unsigned long port);
+	void (*OUTL)(u32 addr, unsigned long port);
+	void (*OUTSW)(unsigned long port, void *addr, u32 count);
+
+	u8  (*INB)(unsigned long port);
+	u16 (*INW)(unsigned long port);
+	u32 (*INL)(unsigned long port);
+	void (*INSW)(unsigned long port, void *addr, u32 count);
+};
+
 struct ata_port_info {
 	struct scsi_host_template	*sht;
 	unsigned long		flags;
@@ -662,6 +677,7 @@ struct ata_port_info {
 	unsigned long		mwdma_mask;
 	unsigned long		udma_mask;
 	const struct ata_port_operations *port_ops;
+	struct ata_io_operations *io_ops;
 	void 			*private_data;
 };
 
@@ -727,7 +743,8 @@ extern int ata_pci_clear_simplex(struct 
 extern int ata_device_add(const struct ata_probe_ent *ent);
 extern void ata_port_detach(struct ata_port *ap);
 extern void ata_host_init(struct ata_host *, struct device *,
-			  unsigned long, const struct ata_port_operations *);
+			  unsigned long, const struct ata_port_operations *,
+			  struct ata_io_operations *);
 extern void ata_host_remove(struct ata_host *host);
 extern int ata_scsi_detect(struct scsi_host_template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
@@ -761,6 +778,7 @@ extern void ata_port_queue_task(struct a
 extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
 			     unsigned long interval_msec,
 			     unsigned long timeout_msec);
+struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port);
 
 /*
  * Default driver ops implementations
@@ -1179,20 +1197,11 @@ static inline u8 ata_irq_ack(struct ata_
 			printk(KERN_ERR "abnormal status 0x%X\n", status);
 
 	/* get controller status; clear intr, err bits */
-	if (ap->flags & ATA_FLAG_MMIO) {
-		void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
-		host_stat = readb(mmio + ATA_DMA_STATUS);
-		writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
-		       mmio + ATA_DMA_STATUS);
-
-		post_stat = readb(mmio + ATA_DMA_STATUS);
-	} else {
-		host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-		outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
-		     ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-
-		post_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-	}
+	host_stat = ap->io_ops->INB(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+	ap->io_ops->OUTB(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+		      ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+	
+	post_stat = ap->io_ops->INB(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
 
 	if (ata_msg_intr(ap))
 		printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",



More information about the Linuxppc-dev mailing list