Loading drivers/ata/pdc_adma.c +67 −15 Original line number Original line Diff line number Diff line Loading @@ -92,6 +92,8 @@ enum { /* CPB bits */ /* CPB bits */ cDONE = (1 << 0), cDONE = (1 << 0), cATERR = (1 << 3), cVLD = (1 << 0), cVLD = (1 << 0), cDAT = (1 << 2), cDAT = (1 << 2), cIEN = (1 << 3), cIEN = (1 << 3), Loading Loading @@ -131,14 +133,15 @@ static int adma_ata_init_one (struct pci_dev *pdev, static int adma_port_start(struct ata_port *ap); static int adma_port_start(struct ata_port *ap); static void adma_host_stop(struct ata_host *host); static void adma_host_stop(struct ata_host *host); static void adma_port_stop(struct ata_port *ap); static void adma_port_stop(struct ata_port *ap); static void adma_phy_reset(struct ata_port *ap); static void adma_qc_prep(struct ata_queued_cmd *qc); static void adma_qc_prep(struct ata_queued_cmd *qc); static unsigned int adma_qc_issue(struct ata_queued_cmd *qc); static unsigned int adma_qc_issue(struct ata_queued_cmd *qc); static int adma_check_atapi_dma(struct ata_queued_cmd *qc); static int adma_check_atapi_dma(struct ata_queued_cmd *qc); static void adma_bmdma_stop(struct ata_queued_cmd *qc); static void adma_bmdma_stop(struct ata_queued_cmd *qc); static u8 adma_bmdma_status(struct ata_port *ap); static u8 adma_bmdma_status(struct ata_port *ap); static void adma_irq_clear(struct ata_port *ap); static void adma_irq_clear(struct ata_port *ap); static void adma_eng_timeout(struct ata_port *ap); static void adma_freeze(struct ata_port *ap); static void adma_thaw(struct ata_port *ap); static void adma_error_handler(struct ata_port *ap); static struct scsi_host_template adma_ata_sht = { static struct scsi_host_template adma_ata_sht = { .module = THIS_MODULE, .module = THIS_MODULE, Loading @@ -165,12 +168,13 @@ static const struct ata_port_operations adma_ata_ops = { .exec_command = ata_exec_command, .exec_command = ata_exec_command, .check_status = ata_check_status, .check_status = ata_check_status, .dev_select = ata_std_dev_select, .dev_select = ata_std_dev_select, .phy_reset = adma_phy_reset, .check_atapi_dma = adma_check_atapi_dma, .check_atapi_dma = adma_check_atapi_dma, .data_xfer = ata_data_xfer, .data_xfer = ata_data_xfer, .qc_prep = adma_qc_prep, .qc_prep = adma_qc_prep, .qc_issue = adma_qc_issue, .qc_issue = adma_qc_issue, .eng_timeout = adma_eng_timeout, .freeze = adma_freeze, .thaw = adma_thaw, .error_handler = adma_error_handler, .irq_clear = adma_irq_clear, .irq_clear = adma_irq_clear, .irq_on = ata_irq_on, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, .irq_ack = ata_irq_ack, Loading @@ -184,7 +188,7 @@ static const struct ata_port_operations adma_ata_ops = { static struct ata_port_info adma_port_info[] = { static struct ata_port_info adma_port_info[] = { /* board_1841_idx */ /* board_1841_idx */ { { .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, ATA_FLAG_PIO_POLLING, .pio_mask = 0x10, /* pio4 */ .pio_mask = 0x10, /* pio4 */ Loading Loading @@ -273,24 +277,41 @@ static inline void adma_enter_reg_mode(struct ata_port *ap) readb(chan + ADMA_STATUS); /* flush */ readb(chan + ADMA_STATUS); /* flush */ } } static void adma_phy_reset(struct ata_port *ap) static void adma_freeze(struct ata_port *ap) { { struct adma_port_priv *pp = ap->private_data; void __iomem *chan = ADMA_PORT_REGS(ap); pp->state = adma_state_idle; /* mask/clear ATA interrupts */ writeb(ATA_NIEN, ap->ioaddr.ctl_addr); ata_check_status(ap); /* reset ADMA to idle state */ writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL); udelay(2); writew(aPIOMD4 | aNIEN, chan + ADMA_CONTROL); udelay(2); } static void adma_thaw(struct ata_port *ap) { adma_reinit_engine(ap); adma_reinit_engine(ap); ata_port_probe(ap); ata_bus_reset(ap); } } static void adma_eng_timeout(struct ata_port *ap) static int adma_prereset(struct ata_port *ap, unsigned long deadline) { { struct adma_port_priv *pp = ap->private_data; struct adma_port_priv *pp = ap->private_data; if (pp->state != adma_state_idle) /* healthy paranoia */ if (pp->state != adma_state_idle) /* healthy paranoia */ pp->state = adma_state_mmio; pp->state = adma_state_mmio; adma_reinit_engine(ap); adma_reinit_engine(ap); ata_eng_timeout(ap); return ata_std_prereset(ap, deadline); } static void adma_error_handler(struct ata_port *ap) { ata_do_eh(ap, adma_prereset, ata_std_softreset, NULL, ata_std_postreset); } } static int adma_fill_sg(struct ata_queued_cmd *qc) static int adma_fill_sg(struct ata_queued_cmd *qc) Loading Loading @@ -466,12 +487,31 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host) continue; continue; qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { if ((status & (aPERR | aPSD | aUIRQ))) if (status & aPERR) qc->err_mask |= AC_ERR_HOST_BUS; else if ((status & (aPSD | aUIRQ))) qc->err_mask |= AC_ERR_OTHER; qc->err_mask |= AC_ERR_OTHER; if (pp->pkt[0] & cATERR) qc->err_mask |= AC_ERR_DEV; else if (pp->pkt[0] != cDONE) else if (pp->pkt[0] != cDONE) qc->err_mask |= AC_ERR_OTHER; qc->err_mask |= AC_ERR_OTHER; if (!qc->err_mask) ata_qc_complete(qc); ata_qc_complete(qc); else { struct ata_eh_info *ehi = &ap->eh_info; ata_ehi_clear_desc(ehi); ata_ehi_push_desc(ehi, "ADMA-status 0x%02X", status); ata_ehi_push_desc(ehi, "pkt[0] 0x%02X", pp->pkt[0]); if (qc->err_mask == AC_ERR_DEV) ata_port_abort(ap); else ata_port_freeze(ap); } } } } } return handled; return handled; Loading Loading @@ -502,7 +542,19 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host) /* complete taskfile transaction */ /* complete taskfile transaction */ pp->state = adma_state_idle; pp->state = adma_state_idle; qc->err_mask |= ac_err_mask(status); qc->err_mask |= ac_err_mask(status); if (!qc->err_mask) ata_qc_complete(qc); ata_qc_complete(qc); else { struct ata_eh_info *ehi = &ap->eh_info; ata_ehi_clear_desc(ehi); ata_ehi_push_desc(ehi, "status 0x%02X", status); if (qc->err_mask == AC_ERR_DEV) ata_port_abort(ap); else ata_port_freeze(ap); } handled = 1; handled = 1; } } } } Loading Loading
drivers/ata/pdc_adma.c +67 −15 Original line number Original line Diff line number Diff line Loading @@ -92,6 +92,8 @@ enum { /* CPB bits */ /* CPB bits */ cDONE = (1 << 0), cDONE = (1 << 0), cATERR = (1 << 3), cVLD = (1 << 0), cVLD = (1 << 0), cDAT = (1 << 2), cDAT = (1 << 2), cIEN = (1 << 3), cIEN = (1 << 3), Loading Loading @@ -131,14 +133,15 @@ static int adma_ata_init_one (struct pci_dev *pdev, static int adma_port_start(struct ata_port *ap); static int adma_port_start(struct ata_port *ap); static void adma_host_stop(struct ata_host *host); static void adma_host_stop(struct ata_host *host); static void adma_port_stop(struct ata_port *ap); static void adma_port_stop(struct ata_port *ap); static void adma_phy_reset(struct ata_port *ap); static void adma_qc_prep(struct ata_queued_cmd *qc); static void adma_qc_prep(struct ata_queued_cmd *qc); static unsigned int adma_qc_issue(struct ata_queued_cmd *qc); static unsigned int adma_qc_issue(struct ata_queued_cmd *qc); static int adma_check_atapi_dma(struct ata_queued_cmd *qc); static int adma_check_atapi_dma(struct ata_queued_cmd *qc); static void adma_bmdma_stop(struct ata_queued_cmd *qc); static void adma_bmdma_stop(struct ata_queued_cmd *qc); static u8 adma_bmdma_status(struct ata_port *ap); static u8 adma_bmdma_status(struct ata_port *ap); static void adma_irq_clear(struct ata_port *ap); static void adma_irq_clear(struct ata_port *ap); static void adma_eng_timeout(struct ata_port *ap); static void adma_freeze(struct ata_port *ap); static void adma_thaw(struct ata_port *ap); static void adma_error_handler(struct ata_port *ap); static struct scsi_host_template adma_ata_sht = { static struct scsi_host_template adma_ata_sht = { .module = THIS_MODULE, .module = THIS_MODULE, Loading @@ -165,12 +168,13 @@ static const struct ata_port_operations adma_ata_ops = { .exec_command = ata_exec_command, .exec_command = ata_exec_command, .check_status = ata_check_status, .check_status = ata_check_status, .dev_select = ata_std_dev_select, .dev_select = ata_std_dev_select, .phy_reset = adma_phy_reset, .check_atapi_dma = adma_check_atapi_dma, .check_atapi_dma = adma_check_atapi_dma, .data_xfer = ata_data_xfer, .data_xfer = ata_data_xfer, .qc_prep = adma_qc_prep, .qc_prep = adma_qc_prep, .qc_issue = adma_qc_issue, .qc_issue = adma_qc_issue, .eng_timeout = adma_eng_timeout, .freeze = adma_freeze, .thaw = adma_thaw, .error_handler = adma_error_handler, .irq_clear = adma_irq_clear, .irq_clear = adma_irq_clear, .irq_on = ata_irq_on, .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, .irq_ack = ata_irq_ack, Loading @@ -184,7 +188,7 @@ static const struct ata_port_operations adma_ata_ops = { static struct ata_port_info adma_port_info[] = { static struct ata_port_info adma_port_info[] = { /* board_1841_idx */ /* board_1841_idx */ { { .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, ATA_FLAG_PIO_POLLING, .pio_mask = 0x10, /* pio4 */ .pio_mask = 0x10, /* pio4 */ Loading Loading @@ -273,24 +277,41 @@ static inline void adma_enter_reg_mode(struct ata_port *ap) readb(chan + ADMA_STATUS); /* flush */ readb(chan + ADMA_STATUS); /* flush */ } } static void adma_phy_reset(struct ata_port *ap) static void adma_freeze(struct ata_port *ap) { { struct adma_port_priv *pp = ap->private_data; void __iomem *chan = ADMA_PORT_REGS(ap); pp->state = adma_state_idle; /* mask/clear ATA interrupts */ writeb(ATA_NIEN, ap->ioaddr.ctl_addr); ata_check_status(ap); /* reset ADMA to idle state */ writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL); udelay(2); writew(aPIOMD4 | aNIEN, chan + ADMA_CONTROL); udelay(2); } static void adma_thaw(struct ata_port *ap) { adma_reinit_engine(ap); adma_reinit_engine(ap); ata_port_probe(ap); ata_bus_reset(ap); } } static void adma_eng_timeout(struct ata_port *ap) static int adma_prereset(struct ata_port *ap, unsigned long deadline) { { struct adma_port_priv *pp = ap->private_data; struct adma_port_priv *pp = ap->private_data; if (pp->state != adma_state_idle) /* healthy paranoia */ if (pp->state != adma_state_idle) /* healthy paranoia */ pp->state = adma_state_mmio; pp->state = adma_state_mmio; adma_reinit_engine(ap); adma_reinit_engine(ap); ata_eng_timeout(ap); return ata_std_prereset(ap, deadline); } static void adma_error_handler(struct ata_port *ap) { ata_do_eh(ap, adma_prereset, ata_std_softreset, NULL, ata_std_postreset); } } static int adma_fill_sg(struct ata_queued_cmd *qc) static int adma_fill_sg(struct ata_queued_cmd *qc) Loading Loading @@ -466,12 +487,31 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host) continue; continue; qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { if ((status & (aPERR | aPSD | aUIRQ))) if (status & aPERR) qc->err_mask |= AC_ERR_HOST_BUS; else if ((status & (aPSD | aUIRQ))) qc->err_mask |= AC_ERR_OTHER; qc->err_mask |= AC_ERR_OTHER; if (pp->pkt[0] & cATERR) qc->err_mask |= AC_ERR_DEV; else if (pp->pkt[0] != cDONE) else if (pp->pkt[0] != cDONE) qc->err_mask |= AC_ERR_OTHER; qc->err_mask |= AC_ERR_OTHER; if (!qc->err_mask) ata_qc_complete(qc); ata_qc_complete(qc); else { struct ata_eh_info *ehi = &ap->eh_info; ata_ehi_clear_desc(ehi); ata_ehi_push_desc(ehi, "ADMA-status 0x%02X", status); ata_ehi_push_desc(ehi, "pkt[0] 0x%02X", pp->pkt[0]); if (qc->err_mask == AC_ERR_DEV) ata_port_abort(ap); else ata_port_freeze(ap); } } } } } return handled; return handled; Loading Loading @@ -502,7 +542,19 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host) /* complete taskfile transaction */ /* complete taskfile transaction */ pp->state = adma_state_idle; pp->state = adma_state_idle; qc->err_mask |= ac_err_mask(status); qc->err_mask |= ac_err_mask(status); if (!qc->err_mask) ata_qc_complete(qc); ata_qc_complete(qc); else { struct ata_eh_info *ehi = &ap->eh_info; ata_ehi_clear_desc(ehi); ata_ehi_push_desc(ehi, "status 0x%02X", status); if (qc->err_mask == AC_ERR_DEV) ata_port_abort(ap); else ata_port_freeze(ap); } handled = 1; handled = 1; } } } } Loading