aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_qstor.c
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2007-11-07 10:54:15 -0500
committerJeff Garzik <jeff@garzik.org>2007-11-08 13:08:41 -0500
commit6004bda1cce51273ac9e71a39e680831b9ff4503 (patch)
treec1a27e4485f7ec2c06aeaaec8b0878a0dd115398 /drivers/ata/sata_qstor.c
parent904c7bad994e6e7f9997174e0b33fcc521862136 (diff)
libata sata_qstor conversion to new error handling (EH).
sata_qstor conversion to new error handling (EH). Convert sata_qstor to use the newer libata EH mechanisms. Based on earlier work by Jeff Garzik. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_qstor.c')
-rw-r--r--drivers/ata/sata_qstor.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 7446a335fc92..2f1de6ec044c 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -116,14 +116,15 @@ static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
116static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 116static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
117static int qs_port_start(struct ata_port *ap); 117static int qs_port_start(struct ata_port *ap);
118static void qs_host_stop(struct ata_host *host); 118static void qs_host_stop(struct ata_host *host);
119static void qs_phy_reset(struct ata_port *ap);
120static void qs_qc_prep(struct ata_queued_cmd *qc); 119static void qs_qc_prep(struct ata_queued_cmd *qc);
121static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); 120static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
122static int qs_check_atapi_dma(struct ata_queued_cmd *qc); 121static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
123static void qs_bmdma_stop(struct ata_queued_cmd *qc); 122static void qs_bmdma_stop(struct ata_queued_cmd *qc);
124static u8 qs_bmdma_status(struct ata_port *ap); 123static u8 qs_bmdma_status(struct ata_port *ap);
125static void qs_irq_clear(struct ata_port *ap); 124static void qs_irq_clear(struct ata_port *ap);
126static void qs_eng_timeout(struct ata_port *ap); 125static void qs_freeze(struct ata_port *ap);
126static void qs_thaw(struct ata_port *ap);
127static void qs_error_handler(struct ata_port *ap);
127 128
128static struct scsi_host_template qs_ata_sht = { 129static struct scsi_host_template qs_ata_sht = {
129 .module = THIS_MODULE, 130 .module = THIS_MODULE,
@@ -150,11 +151,12 @@ static const struct ata_port_operations qs_ata_ops = {
150 .check_atapi_dma = qs_check_atapi_dma, 151 .check_atapi_dma = qs_check_atapi_dma,
151 .exec_command = ata_exec_command, 152 .exec_command = ata_exec_command,
152 .dev_select = ata_std_dev_select, 153 .dev_select = ata_std_dev_select,
153 .phy_reset = qs_phy_reset,
154 .qc_prep = qs_qc_prep, 154 .qc_prep = qs_qc_prep,
155 .qc_issue = qs_qc_issue, 155 .qc_issue = qs_qc_issue,
156 .data_xfer = ata_data_xfer, 156 .data_xfer = ata_data_xfer,
157 .eng_timeout = qs_eng_timeout, 157 .freeze = qs_freeze,
158 .thaw = qs_thaw,
159 .error_handler = qs_error_handler,
158 .irq_clear = qs_irq_clear, 160 .irq_clear = qs_irq_clear,
159 .irq_on = ata_irq_on, 161 .irq_on = ata_irq_on,
160 .scr_read = qs_scr_read, 162 .scr_read = qs_scr_read,
@@ -169,8 +171,6 @@ static const struct ata_port_info qs_port_info[] = {
169 /* board_2068_idx */ 171 /* board_2068_idx */
170 { 172 {
171 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 173 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
172 ATA_FLAG_SATA_RESET |
173 //FIXME ATA_FLAG_SRST |
174 ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, 174 ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
175 .pio_mask = 0x10, /* pio4 */ 175 .pio_mask = 0x10, /* pio4 */
176 .udma_mask = ATA_UDMA6, 176 .udma_mask = ATA_UDMA6,
@@ -235,16 +235,28 @@ static inline void qs_reset_channel_logic(struct ata_port *ap)
235 qs_enter_reg_mode(ap); 235 qs_enter_reg_mode(ap);
236} 236}
237 237
238static void qs_phy_reset(struct ata_port *ap) 238static void qs_freeze(struct ata_port *ap)
239{ 239{
240 qs_reset_channel_logic(ap); 240 u8 __iomem *mmio_base = qs_mmio_base(ap->host);
241 sata_phy_reset(ap); 241
242 writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
243 qs_enter_reg_mode(ap);
244}
245
246static void qs_thaw(struct ata_port *ap)
247{
248 u8 __iomem *mmio_base = qs_mmio_base(ap->host);
249
250 qs_enter_reg_mode(ap);
251 writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */
242} 252}
243 253
244static void qs_eng_timeout(struct ata_port *ap) 254static int qs_prereset(struct ata_link *link, unsigned long deadline)
245{ 255{
256 struct ata_port *ap = link->ap;
257
246 qs_reset_channel_logic(ap); 258 qs_reset_channel_logic(ap);
247 ata_eng_timeout(ap); 259 return ata_std_prereset(link, deadline);
248} 260}
249 261
250static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) 262static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -255,6 +267,13 @@ static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
255 return 0; 267 return 0;
256} 268}
257 269
270static void qs_error_handler(struct ata_port *ap)
271{
272 qs_enter_reg_mode(ap);
273 ata_do_eh(ap, qs_prereset, ata_std_softreset, NULL,
274 ata_std_postreset);
275}
276
258static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) 277static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
259{ 278{
260 if (sc_reg > SCR_CONTROL) 279 if (sc_reg > SCR_CONTROL)
@@ -353,7 +372,6 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
353 372
354 switch (qc->tf.protocol) { 373 switch (qc->tf.protocol) {
355 case ATA_PROT_DMA: 374 case ATA_PROT_DMA:
356
357 pp->state = qs_state_pkt; 375 pp->state = qs_state_pkt;
358 qs_packet_start(qc); 376 qs_packet_start(qc);
359 return 0; 377 return 0;
@@ -370,6 +388,26 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
370 return ata_qc_issue_prot(qc); 388 return ata_qc_issue_prot(qc);
371} 389}
372 390
391static void qs_do_or_die(struct ata_queued_cmd *qc, u8 status)
392{
393 qc->err_mask |= ac_err_mask(status);
394
395 if (!qc->err_mask) {
396 ata_qc_complete(qc);
397 } else {
398 struct ata_port *ap = qc->ap;
399 struct ata_eh_info *ehi = &ap->link.eh_info;
400
401 ata_ehi_clear_desc(ehi);
402 ata_ehi_push_desc(ehi, "status 0x%02X", status);
403
404 if (qc->err_mask == AC_ERR_DEV)
405 ata_port_abort(ap);
406 else
407 ata_port_freeze(ap);
408 }
409}
410
373static inline unsigned int qs_intr_pkt(struct ata_host *host) 411static inline unsigned int qs_intr_pkt(struct ata_host *host)
374{ 412{
375 unsigned int handled = 0; 413 unsigned int handled = 0;
@@ -402,8 +440,7 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)
402 case 0: /* successful CPB */ 440 case 0: /* successful CPB */
403 case 3: /* device error */ 441 case 3: /* device error */
404 qs_enter_reg_mode(qc->ap); 442 qs_enter_reg_mode(qc->ap);
405 qc->err_mask |= ac_err_mask(sDST); 443 qs_do_or_die(qc, sDST);
406 ata_qc_complete(qc);
407 break; 444 break;
408 default: 445 default:
409 break; 446 break;