aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkira Iguchi <akira2.iguchi@toshiba.co.jp>2007-01-26 02:27:32 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-09 17:39:38 -0500
commit836250069fc0eeebe8b6aed772281535cc6e34f9 (patch)
tree73c886ae7fd75dd2c9b5b17e11ea3b6b76b42fed
parent7f25377043925554cb9f3f9d8ada3390f71a5d10 (diff)
libata: add another IRQ calls (core and headers)
This patch is against the libata core and headers. Two IRQ calls are added in ata_port_operations. - irq_on() is used to enable interrupts. - irq_ack() is used to acknowledge a device interrupt. In most drivers, ata_irq_on() and ata_irq_ack() are used for irq_on and irq_ack respectively. In some drivers (ex: ahci, sata_sil24) which cannot use them as is, ata_dummy_irq_on() and ata_dummy_irq_ack() are used. Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp> Signed-off-by: Akira Iguchi <akira2.iguchi@toshiba.co.jp> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/libata-core.c20
-rw-r--r--drivers/ata/libata-sff.c43
-rw-r--r--include/linux/libata.h42
3 files changed, 57 insertions, 48 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index f210dbd4cbe6..2e8ca652c0d9 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2664,8 +2664,7 @@ void ata_bus_reset(struct ata_port *ap)
2664 ap->device[1].class = ata_dev_try_classify(ap, 1, &err); 2664 ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
2665 2665
2666 /* re-enable interrupts */ 2666 /* re-enable interrupts */
2667 if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ 2667 ap->ops->irq_on(ap);
2668 ata_irq_on(ap);
2669 2668
2670 /* is double-select really necessary? */ 2669 /* is double-select really necessary? */
2671 if (ap->device[1].class != ATA_DEV_NONE) 2670 if (ap->device[1].class != ATA_DEV_NONE)
@@ -3054,11 +3053,8 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
3054 sata_scr_write(ap, SCR_ERROR, serror); 3053 sata_scr_write(ap, SCR_ERROR, serror);
3055 3054
3056 /* re-enable interrupts */ 3055 /* re-enable interrupts */
3057 if (!ap->ops->error_handler) { 3056 if (!ap->ops->error_handler)
3058 /* FIXME: hack. create a hook instead */ 3057 ap->ops->irq_on(ap);
3059 if (ap->ioaddr.ctl_addr)
3060 ata_irq_on(ap);
3061 }
3062 3058
3063 /* is double-select really necessary? */ 3059 /* is double-select really necessary? */
3064 if (classes[0] != ATA_DEV_NONE) 3060 if (classes[0] != ATA_DEV_NONE)
@@ -4169,7 +4165,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
4169 qc = ata_qc_from_tag(ap, qc->tag); 4165 qc = ata_qc_from_tag(ap, qc->tag);
4170 if (qc) { 4166 if (qc) {
4171 if (likely(!(qc->err_mask & AC_ERR_HSM))) { 4167 if (likely(!(qc->err_mask & AC_ERR_HSM))) {
4172 ata_irq_on(ap); 4168 ap->ops->irq_on(ap);
4173 ata_qc_complete(qc); 4169 ata_qc_complete(qc);
4174 } else 4170 } else
4175 ata_port_freeze(ap); 4171 ata_port_freeze(ap);
@@ -4185,7 +4181,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
4185 } else { 4181 } else {
4186 if (in_wq) { 4182 if (in_wq) {
4187 spin_lock_irqsave(ap->lock, flags); 4183 spin_lock_irqsave(ap->lock, flags);
4188 ata_irq_on(ap); 4184 ap->ops->irq_on(ap);
4189 ata_qc_complete(qc); 4185 ata_qc_complete(qc);
4190 spin_unlock_irqrestore(ap->lock, flags); 4186 spin_unlock_irqrestore(ap->lock, flags);
4191 } else 4187 } else
@@ -5010,7 +5006,7 @@ idle_irq:
5010 5006
5011#ifdef ATA_IRQ_TRAP 5007#ifdef ATA_IRQ_TRAP
5012 if ((ap->stats.idle_irq % 1000) == 0) { 5008 if ((ap->stats.idle_irq % 1000) == 0) {
5013 ata_irq_ack(ap, 0); /* debug trap */ 5009 ap->ops->irq_ack(ap, 0); /* debug trap */
5014 ata_port_printk(ap, KERN_WARNING, "irq trap\n"); 5010 ata_port_printk(ap, KERN_WARNING, "irq trap\n");
5015 return 1; 5011 return 1;
5016 } 5012 }
@@ -6271,3 +6267,7 @@ EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
6271EXPORT_SYMBOL_GPL(ata_eh_qc_complete); 6267EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
6272EXPORT_SYMBOL_GPL(ata_eh_qc_retry); 6268EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
6273EXPORT_SYMBOL_GPL(ata_do_eh); 6269EXPORT_SYMBOL_GPL(ata_do_eh);
6270EXPORT_SYMBOL_GPL(ata_irq_on);
6271EXPORT_SYMBOL_GPL(ata_dummy_irq_on);
6272EXPORT_SYMBOL_GPL(ata_irq_ack);
6273EXPORT_SYMBOL_GPL(ata_dummy_irq_ack);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index c561b3be4a97..16bc3e35bdd4 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -64,6 +64,46 @@ u8 ata_irq_on(struct ata_port *ap)
64 return tmp; 64 return tmp;
65} 65}
66 66
67u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
68
69/**
70 * ata_irq_ack - Acknowledge a device interrupt.
71 * @ap: Port on which interrupts are enabled.
72 *
73 * Wait up to 10 ms for legacy IDE device to become idle (BUSY
74 * or BUSY+DRQ clear). Obtain dma status and port status from
75 * device. Clear the interrupt. Return port status.
76 *
77 * LOCKING:
78 */
79
80u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
81{
82 unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
83 u8 host_stat, post_stat, status;
84
85 status = ata_busy_wait(ap, bits, 1000);
86 if (status & bits)
87 if (ata_msg_err(ap))
88 printk(KERN_ERR "abnormal status 0x%X\n", status);
89
90 /* get controller status; clear intr, err bits */
91 host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
92 iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
93 ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
94
95 post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
96
97 if (ata_msg_intr(ap))
98 printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
99 __FUNCTION__,
100 host_stat, post_stat, status);
101
102 return status;
103}
104
105u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq) { return 0; }
106
67/** 107/**
68 * ata_tf_load - send taskfile registers to host controller 108 * ata_tf_load - send taskfile registers to host controller
69 * @ap: Port to which output is sent 109 * @ap: Port to which output is sent
@@ -370,8 +410,7 @@ void ata_bmdma_thaw(struct ata_port *ap)
370 /* clear & re-enable interrupts */ 410 /* clear & re-enable interrupts */
371 ata_chk_status(ap); 411 ata_chk_status(ap);
372 ap->ops->irq_clear(ap); 412 ap->ops->irq_clear(ap);
373 if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ 413 ap->ops->irq_on(ap);
374 ata_irq_on(ap);
375} 414}
376 415
377/** 416/**
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 308bb8cbe50f..bdfe6ea8edf7 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -632,6 +632,8 @@ struct ata_port_operations {
632 632
633 irq_handler_t irq_handler; 633 irq_handler_t irq_handler;
634 void (*irq_clear) (struct ata_port *); 634 void (*irq_clear) (struct ata_port *);
635 u8 (*irq_on) (struct ata_port *);
636 u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq);
635 637
636 u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); 638 u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
637 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, 639 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
@@ -813,6 +815,10 @@ extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
813extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, 815extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
814 int queue_depth); 816 int queue_depth);
815extern struct ata_device *ata_dev_pair(struct ata_device *adev); 817extern struct ata_device *ata_dev_pair(struct ata_device *adev);
818extern u8 ata_irq_on(struct ata_port *ap);
819extern u8 ata_dummy_irq_on(struct ata_port *ap);
820extern u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq);
821extern u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq);
816 822
817/* 823/*
818 * Timing helpers 824 * Timing helpers
@@ -1147,42 +1153,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
1147 qc->result_tf.feature = 0; 1153 qc->result_tf.feature = 0;
1148} 1154}
1149 1155
1150/**
1151 * ata_irq_ack - Acknowledge a device interrupt.
1152 * @ap: Port on which interrupts are enabled.
1153 *
1154 * Wait up to 10 ms for legacy IDE device to become idle (BUSY
1155 * or BUSY+DRQ clear). Obtain dma status and port status from
1156 * device. Clear the interrupt. Return port status.
1157 *
1158 * LOCKING:
1159 */
1160
1161static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
1162{
1163 unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
1164 u8 host_stat, post_stat, status;
1165
1166 status = ata_busy_wait(ap, bits, 1000);
1167 if (status & bits)
1168 if (ata_msg_err(ap))
1169 printk(KERN_ERR "abnormal status 0x%X\n", status);
1170
1171 /* get controller status; clear intr, err bits */
1172 host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
1173 iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
1174 ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
1175
1176 post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
1177
1178 if (ata_msg_intr(ap))
1179 printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
1180 __FUNCTION__,
1181 host_stat, post_stat, status);
1182
1183 return status;
1184}
1185
1186static inline int ata_try_flush_cache(const struct ata_device *dev) 1156static inline int ata_try_flush_cache(const struct ata_device *dev)
1187{ 1157{
1188 return ata_id_wcache_enabled(dev->id) || 1158 return ata_id_wcache_enabled(dev->id) ||