diff options
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 416 |
1 files changed, 288 insertions, 128 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 19ddf924944f..efa4a18cfb9d 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -63,7 +63,6 @@ const struct ata_port_operations ata_sff_port_ops = { | |||
63 | .sff_tf_read = ata_sff_tf_read, | 63 | .sff_tf_read = ata_sff_tf_read, |
64 | .sff_exec_command = ata_sff_exec_command, | 64 | .sff_exec_command = ata_sff_exec_command, |
65 | .sff_data_xfer = ata_sff_data_xfer, | 65 | .sff_data_xfer = ata_sff_data_xfer, |
66 | .sff_irq_clear = ata_sff_irq_clear, | ||
67 | .sff_drain_fifo = ata_sff_drain_fifo, | 66 | .sff_drain_fifo = ata_sff_drain_fifo, |
68 | 67 | ||
69 | .lost_interrupt = ata_sff_lost_interrupt, | 68 | .lost_interrupt = ata_sff_lost_interrupt, |
@@ -395,33 +394,12 @@ void ata_sff_irq_on(struct ata_port *ap) | |||
395 | ata_sff_set_devctl(ap, ap->ctl); | 394 | ata_sff_set_devctl(ap, ap->ctl); |
396 | ata_wait_idle(ap); | 395 | ata_wait_idle(ap); |
397 | 396 | ||
398 | ap->ops->sff_irq_clear(ap); | 397 | if (ap->ops->sff_irq_clear) |
398 | ap->ops->sff_irq_clear(ap); | ||
399 | } | 399 | } |
400 | EXPORT_SYMBOL_GPL(ata_sff_irq_on); | 400 | EXPORT_SYMBOL_GPL(ata_sff_irq_on); |
401 | 401 | ||
402 | /** | 402 | /** |
403 | * ata_sff_irq_clear - Clear PCI IDE BMDMA interrupt. | ||
404 | * @ap: Port associated with this ATA transaction. | ||
405 | * | ||
406 | * Clear interrupt and error flags in DMA status register. | ||
407 | * | ||
408 | * May be used as the irq_clear() entry in ata_port_operations. | ||
409 | * | ||
410 | * LOCKING: | ||
411 | * spin_lock_irqsave(host lock) | ||
412 | */ | ||
413 | void ata_sff_irq_clear(struct ata_port *ap) | ||
414 | { | ||
415 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
416 | |||
417 | if (!mmio) | ||
418 | return; | ||
419 | |||
420 | iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS); | ||
421 | } | ||
422 | EXPORT_SYMBOL_GPL(ata_sff_irq_clear); | ||
423 | |||
424 | /** | ||
425 | * ata_sff_tf_load - send taskfile registers to host controller | 403 | * ata_sff_tf_load - send taskfile registers to host controller |
426 | * @ap: Port to which output is sent | 404 | * @ap: Port to which output is sent |
427 | * @tf: ATA taskfile register set | 405 | * @tf: ATA taskfile register set |
@@ -820,11 +798,15 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
820 | case ATAPI_PROT_NODATA: | 798 | case ATAPI_PROT_NODATA: |
821 | ap->hsm_task_state = HSM_ST_LAST; | 799 | ap->hsm_task_state = HSM_ST_LAST; |
822 | break; | 800 | break; |
801 | #ifdef CONFIG_ATA_BMDMA | ||
823 | case ATAPI_PROT_DMA: | 802 | case ATAPI_PROT_DMA: |
824 | ap->hsm_task_state = HSM_ST_LAST; | 803 | ap->hsm_task_state = HSM_ST_LAST; |
825 | /* initiate bmdma */ | 804 | /* initiate bmdma */ |
826 | ap->ops->bmdma_start(qc); | 805 | ap->ops->bmdma_start(qc); |
827 | break; | 806 | break; |
807 | #endif /* CONFIG_ATA_BMDMA */ | ||
808 | default: | ||
809 | BUG(); | ||
828 | } | 810 | } |
829 | } | 811 | } |
830 | 812 | ||
@@ -1491,27 +1473,27 @@ bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc) | |||
1491 | } | 1473 | } |
1492 | EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf); | 1474 | EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf); |
1493 | 1475 | ||
1494 | /** | 1476 | static unsigned int ata_sff_idle_irq(struct ata_port *ap) |
1495 | * ata_sff_host_intr - Handle host interrupt for given (port, task) | ||
1496 | * @ap: Port on which interrupt arrived (possibly...) | ||
1497 | * @qc: Taskfile currently active in engine | ||
1498 | * | ||
1499 | * Handle host interrupt for given queued command. Currently, | ||
1500 | * only DMA interrupts are handled. All other commands are | ||
1501 | * handled via polling with interrupts disabled (nIEN bit). | ||
1502 | * | ||
1503 | * LOCKING: | ||
1504 | * spin_lock_irqsave(host lock) | ||
1505 | * | ||
1506 | * RETURNS: | ||
1507 | * One if interrupt was handled, zero if not (shared irq). | ||
1508 | */ | ||
1509 | unsigned int ata_sff_host_intr(struct ata_port *ap, | ||
1510 | struct ata_queued_cmd *qc) | ||
1511 | { | 1477 | { |
1512 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1478 | ap->stats.idle_irq++; |
1513 | u8 status, host_stat = 0; | 1479 | |
1514 | bool bmdma_stopped = false; | 1480 | #ifdef ATA_IRQ_TRAP |
1481 | if ((ap->stats.idle_irq % 1000) == 0) { | ||
1482 | ap->ops->sff_check_status(ap); | ||
1483 | if (ap->ops->sff_irq_clear) | ||
1484 | ap->ops->sff_irq_clear(ap); | ||
1485 | ata_port_printk(ap, KERN_WARNING, "irq trap\n"); | ||
1486 | return 1; | ||
1487 | } | ||
1488 | #endif | ||
1489 | return 0; /* irq not handled */ | ||
1490 | } | ||
1491 | |||
1492 | static unsigned int __ata_sff_port_intr(struct ata_port *ap, | ||
1493 | struct ata_queued_cmd *qc, | ||
1494 | bool hsmv_on_idle) | ||
1495 | { | ||
1496 | u8 status; | ||
1515 | 1497 | ||
1516 | VPRINTK("ata%u: protocol %d task_state %d\n", | 1498 | VPRINTK("ata%u: protocol %d task_state %d\n", |
1517 | ap->print_id, qc->tf.protocol, ap->hsm_task_state); | 1499 | ap->print_id, qc->tf.protocol, ap->hsm_task_state); |
@@ -1528,90 +1510,56 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, | |||
1528 | * need to check ata_is_atapi(qc->tf.protocol) again. | 1510 | * need to check ata_is_atapi(qc->tf.protocol) again. |
1529 | */ | 1511 | */ |
1530 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) | 1512 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) |
1531 | goto idle_irq; | 1513 | return ata_sff_idle_irq(ap); |
1532 | break; | ||
1533 | case HSM_ST_LAST: | ||
1534 | if (qc->tf.protocol == ATA_PROT_DMA || | ||
1535 | qc->tf.protocol == ATAPI_PROT_DMA) { | ||
1536 | /* check status of DMA engine */ | ||
1537 | host_stat = ap->ops->bmdma_status(ap); | ||
1538 | VPRINTK("ata%u: host_stat 0x%X\n", | ||
1539 | ap->print_id, host_stat); | ||
1540 | |||
1541 | /* if it's not our irq... */ | ||
1542 | if (!(host_stat & ATA_DMA_INTR)) | ||
1543 | goto idle_irq; | ||
1544 | |||
1545 | /* before we do anything else, clear DMA-Start bit */ | ||
1546 | ap->ops->bmdma_stop(qc); | ||
1547 | bmdma_stopped = true; | ||
1548 | |||
1549 | if (unlikely(host_stat & ATA_DMA_ERR)) { | ||
1550 | /* error when transfering data to/from memory */ | ||
1551 | qc->err_mask |= AC_ERR_HOST_BUS; | ||
1552 | ap->hsm_task_state = HSM_ST_ERR; | ||
1553 | } | ||
1554 | } | ||
1555 | break; | 1514 | break; |
1556 | case HSM_ST: | 1515 | case HSM_ST: |
1516 | case HSM_ST_LAST: | ||
1557 | break; | 1517 | break; |
1558 | default: | 1518 | default: |
1559 | goto idle_irq; | 1519 | return ata_sff_idle_irq(ap); |
1560 | } | 1520 | } |
1561 | 1521 | ||
1562 | |||
1563 | /* check main status, clearing INTRQ if needed */ | 1522 | /* check main status, clearing INTRQ if needed */ |
1564 | status = ata_sff_irq_status(ap); | 1523 | status = ata_sff_irq_status(ap); |
1565 | if (status & ATA_BUSY) { | 1524 | if (status & ATA_BUSY) { |
1566 | if (bmdma_stopped) { | 1525 | if (hsmv_on_idle) { |
1567 | /* BMDMA engine is already stopped, we're screwed */ | 1526 | /* BMDMA engine is already stopped, we're screwed */ |
1568 | qc->err_mask |= AC_ERR_HSM; | 1527 | qc->err_mask |= AC_ERR_HSM; |
1569 | ap->hsm_task_state = HSM_ST_ERR; | 1528 | ap->hsm_task_state = HSM_ST_ERR; |
1570 | } else | 1529 | } else |
1571 | goto idle_irq; | 1530 | return ata_sff_idle_irq(ap); |
1572 | } | 1531 | } |
1573 | 1532 | ||
1574 | /* clear irq events */ | 1533 | /* clear irq events */ |
1575 | ap->ops->sff_irq_clear(ap); | 1534 | if (ap->ops->sff_irq_clear) |
1535 | ap->ops->sff_irq_clear(ap); | ||
1576 | 1536 | ||
1577 | ata_sff_hsm_move(ap, qc, status, 0); | 1537 | ata_sff_hsm_move(ap, qc, status, 0); |
1578 | 1538 | ||
1579 | if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA || | ||
1580 | qc->tf.protocol == ATAPI_PROT_DMA)) | ||
1581 | ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); | ||
1582 | |||
1583 | return 1; /* irq handled */ | 1539 | return 1; /* irq handled */ |
1584 | |||
1585 | idle_irq: | ||
1586 | ap->stats.idle_irq++; | ||
1587 | |||
1588 | #ifdef ATA_IRQ_TRAP | ||
1589 | if ((ap->stats.idle_irq % 1000) == 0) { | ||
1590 | ap->ops->sff_check_status(ap); | ||
1591 | ap->ops->sff_irq_clear(ap); | ||
1592 | ata_port_printk(ap, KERN_WARNING, "irq trap\n"); | ||
1593 | return 1; | ||
1594 | } | ||
1595 | #endif | ||
1596 | return 0; /* irq not handled */ | ||
1597 | } | 1540 | } |
1598 | EXPORT_SYMBOL_GPL(ata_sff_host_intr); | ||
1599 | 1541 | ||
1600 | /** | 1542 | /** |
1601 | * ata_sff_interrupt - Default ATA host interrupt handler | 1543 | * ata_sff_port_intr - Handle SFF port interrupt |
1602 | * @irq: irq line (unused) | 1544 | * @ap: Port on which interrupt arrived (possibly...) |
1603 | * @dev_instance: pointer to our ata_host information structure | 1545 | * @qc: Taskfile currently active in engine |
1604 | * | 1546 | * |
1605 | * Default interrupt handler for PCI IDE devices. Calls | 1547 | * Handle port interrupt for given queued command. |
1606 | * ata_sff_host_intr() for each port that is not disabled. | ||
1607 | * | 1548 | * |
1608 | * LOCKING: | 1549 | * LOCKING: |
1609 | * Obtains host lock during operation. | 1550 | * spin_lock_irqsave(host lock) |
1610 | * | 1551 | * |
1611 | * RETURNS: | 1552 | * RETURNS: |
1612 | * IRQ_NONE or IRQ_HANDLED. | 1553 | * One if interrupt was handled, zero if not (shared irq). |
1613 | */ | 1554 | */ |
1614 | irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) | 1555 | unsigned int ata_sff_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) |
1556 | { | ||
1557 | return __ata_sff_port_intr(ap, qc, false); | ||
1558 | } | ||
1559 | EXPORT_SYMBOL_GPL(ata_sff_port_intr); | ||
1560 | |||
1561 | static inline irqreturn_t __ata_sff_interrupt(int irq, void *dev_instance, | ||
1562 | unsigned int (*port_intr)(struct ata_port *, struct ata_queued_cmd *)) | ||
1615 | { | 1563 | { |
1616 | struct ata_host *host = dev_instance; | 1564 | struct ata_host *host = dev_instance; |
1617 | bool retried = false; | 1565 | bool retried = false; |
@@ -1631,7 +1579,7 @@ retry: | |||
1631 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 1579 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
1632 | if (qc) { | 1580 | if (qc) { |
1633 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) | 1581 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) |
1634 | handled |= ata_sff_host_intr(ap, qc); | 1582 | handled |= port_intr(ap, qc); |
1635 | else | 1583 | else |
1636 | polling |= 1 << i; | 1584 | polling |= 1 << i; |
1637 | } else | 1585 | } else |
@@ -1658,7 +1606,8 @@ retry: | |||
1658 | 1606 | ||
1659 | if (idle & (1 << i)) { | 1607 | if (idle & (1 << i)) { |
1660 | ap->ops->sff_check_status(ap); | 1608 | ap->ops->sff_check_status(ap); |
1661 | ap->ops->sff_irq_clear(ap); | 1609 | if (ap->ops->sff_irq_clear) |
1610 | ap->ops->sff_irq_clear(ap); | ||
1662 | } else { | 1611 | } else { |
1663 | /* clear INTRQ and check if BUSY cleared */ | 1612 | /* clear INTRQ and check if BUSY cleared */ |
1664 | if (!(ap->ops->sff_check_status(ap) & ATA_BUSY)) | 1613 | if (!(ap->ops->sff_check_status(ap) & ATA_BUSY)) |
@@ -1680,6 +1629,25 @@ retry: | |||
1680 | 1629 | ||
1681 | return IRQ_RETVAL(handled); | 1630 | return IRQ_RETVAL(handled); |
1682 | } | 1631 | } |
1632 | |||
1633 | /** | ||
1634 | * ata_sff_interrupt - Default SFF ATA host interrupt handler | ||
1635 | * @irq: irq line (unused) | ||
1636 | * @dev_instance: pointer to our ata_host information structure | ||
1637 | * | ||
1638 | * Default interrupt handler for PCI IDE devices. Calls | ||
1639 | * ata_sff_port_intr() for each port that is not disabled. | ||
1640 | * | ||
1641 | * LOCKING: | ||
1642 | * Obtains host lock during operation. | ||
1643 | * | ||
1644 | * RETURNS: | ||
1645 | * IRQ_NONE or IRQ_HANDLED. | ||
1646 | */ | ||
1647 | irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) | ||
1648 | { | ||
1649 | return __ata_sff_interrupt(irq, dev_instance, ata_sff_port_intr); | ||
1650 | } | ||
1683 | EXPORT_SYMBOL_GPL(ata_sff_interrupt); | 1651 | EXPORT_SYMBOL_GPL(ata_sff_interrupt); |
1684 | 1652 | ||
1685 | /** | 1653 | /** |
@@ -1717,7 +1685,7 @@ void ata_sff_lost_interrupt(struct ata_port *ap) | |||
1717 | status); | 1685 | status); |
1718 | /* Run the host interrupt logic as if the interrupt had not been | 1686 | /* Run the host interrupt logic as if the interrupt had not been |
1719 | lost */ | 1687 | lost */ |
1720 | ata_sff_host_intr(ap, qc); | 1688 | ata_sff_port_intr(ap, qc); |
1721 | } | 1689 | } |
1722 | EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt); | 1690 | EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt); |
1723 | 1691 | ||
@@ -1744,7 +1712,8 @@ void ata_sff_freeze(struct ata_port *ap) | |||
1744 | */ | 1712 | */ |
1745 | ap->ops->sff_check_status(ap); | 1713 | ap->ops->sff_check_status(ap); |
1746 | 1714 | ||
1747 | ap->ops->sff_irq_clear(ap); | 1715 | if (ap->ops->sff_irq_clear) |
1716 | ap->ops->sff_irq_clear(ap); | ||
1748 | } | 1717 | } |
1749 | EXPORT_SYMBOL_GPL(ata_sff_freeze); | 1718 | EXPORT_SYMBOL_GPL(ata_sff_freeze); |
1750 | 1719 | ||
@@ -1761,7 +1730,8 @@ void ata_sff_thaw(struct ata_port *ap) | |||
1761 | { | 1730 | { |
1762 | /* clear & re-enable interrupts */ | 1731 | /* clear & re-enable interrupts */ |
1763 | ap->ops->sff_check_status(ap); | 1732 | ap->ops->sff_check_status(ap); |
1764 | ap->ops->sff_irq_clear(ap); | 1733 | if (ap->ops->sff_irq_clear) |
1734 | ap->ops->sff_irq_clear(ap); | ||
1765 | ata_sff_irq_on(ap); | 1735 | ata_sff_irq_on(ap); |
1766 | } | 1736 | } |
1767 | EXPORT_SYMBOL_GPL(ata_sff_thaw); | 1737 | EXPORT_SYMBOL_GPL(ata_sff_thaw); |
@@ -2349,13 +2319,13 @@ int ata_pci_sff_init_host(struct ata_host *host) | |||
2349 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); | 2319 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); |
2350 | 2320 | ||
2351 | /** | 2321 | /** |
2352 | * ata_pci_sff_prepare_host - helper to prepare native PCI ATA host | 2322 | * ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host |
2353 | * @pdev: target PCI device | 2323 | * @pdev: target PCI device |
2354 | * @ppi: array of port_info, must be enough for two ports | 2324 | * @ppi: array of port_info, must be enough for two ports |
2355 | * @r_host: out argument for the initialized ATA host | 2325 | * @r_host: out argument for the initialized ATA host |
2356 | * | 2326 | * |
2357 | * Helper to allocate ATA host for @pdev, acquire all native PCI | 2327 | * Helper to allocate PIO-only SFF ATA host for @pdev, acquire |
2358 | * resources and initialize it accordingly in one go. | 2328 | * all PCI resources and initialize it accordingly in one go. |
2359 | * | 2329 | * |
2360 | * LOCKING: | 2330 | * LOCKING: |
2361 | * Inherited from calling layer (may sleep). | 2331 | * Inherited from calling layer (may sleep). |
@@ -2385,9 +2355,6 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev, | |||
2385 | if (rc) | 2355 | if (rc) |
2386 | goto err_out; | 2356 | goto err_out; |
2387 | 2357 | ||
2388 | /* init DMA related stuff */ | ||
2389 | ata_pci_bmdma_init(host); | ||
2390 | |||
2391 | devres_remove_group(&pdev->dev, NULL); | 2358 | devres_remove_group(&pdev->dev, NULL); |
2392 | *r_host = host; | 2359 | *r_host = host; |
2393 | return 0; | 2360 | return 0; |
@@ -2492,8 +2459,21 @@ out: | |||
2492 | } | 2459 | } |
2493 | EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); | 2460 | EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); |
2494 | 2461 | ||
2462 | static const struct ata_port_info *ata_sff_find_valid_pi( | ||
2463 | const struct ata_port_info * const *ppi) | ||
2464 | { | ||
2465 | int i; | ||
2466 | |||
2467 | /* look up the first valid port_info */ | ||
2468 | for (i = 0; i < 2 && ppi[i]; i++) | ||
2469 | if (ppi[i]->port_ops != &ata_dummy_port_ops) | ||
2470 | return ppi[i]; | ||
2471 | |||
2472 | return NULL; | ||
2473 | } | ||
2474 | |||
2495 | /** | 2475 | /** |
2496 | * ata_pci_sff_init_one - Initialize/register PCI IDE host controller | 2476 | * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller |
2497 | * @pdev: Controller to be initialized | 2477 | * @pdev: Controller to be initialized |
2498 | * @ppi: array of port_info, must be enough for two ports | 2478 | * @ppi: array of port_info, must be enough for two ports |
2499 | * @sht: scsi_host_template to use when registering the host | 2479 | * @sht: scsi_host_template to use when registering the host |
@@ -2502,11 +2482,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); | |||
2502 | * | 2482 | * |
2503 | * This is a helper function which can be called from a driver's | 2483 | * This is a helper function which can be called from a driver's |
2504 | * xxx_init_one() probe function if the hardware uses traditional | 2484 | * xxx_init_one() probe function if the hardware uses traditional |
2505 | * IDE taskfile registers. | 2485 | * IDE taskfile registers and is PIO only. |
2506 | * | ||
2507 | * This function calls pci_enable_device(), reserves its register | ||
2508 | * regions, sets the dma mask, enables bus master mode, and calls | ||
2509 | * ata_device_add() | ||
2510 | * | 2486 | * |
2511 | * ASSUMPTION: | 2487 | * ASSUMPTION: |
2512 | * Nobody makes a single channel controller that appears solely as | 2488 | * Nobody makes a single channel controller that appears solely as |
@@ -2523,20 +2499,13 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
2523 | struct scsi_host_template *sht, void *host_priv, int hflag) | 2499 | struct scsi_host_template *sht, void *host_priv, int hflag) |
2524 | { | 2500 | { |
2525 | struct device *dev = &pdev->dev; | 2501 | struct device *dev = &pdev->dev; |
2526 | const struct ata_port_info *pi = NULL; | 2502 | const struct ata_port_info *pi; |
2527 | struct ata_host *host = NULL; | 2503 | struct ata_host *host = NULL; |
2528 | int i, rc; | 2504 | int rc; |
2529 | 2505 | ||
2530 | DPRINTK("ENTER\n"); | 2506 | DPRINTK("ENTER\n"); |
2531 | 2507 | ||
2532 | /* look up the first valid port_info */ | 2508 | pi = ata_sff_find_valid_pi(ppi); |
2533 | for (i = 0; i < 2 && ppi[i]; i++) { | ||
2534 | if (ppi[i]->port_ops != &ata_dummy_port_ops) { | ||
2535 | pi = ppi[i]; | ||
2536 | break; | ||
2537 | } | ||
2538 | } | ||
2539 | |||
2540 | if (!pi) { | 2509 | if (!pi) { |
2541 | dev_printk(KERN_ERR, &pdev->dev, | 2510 | dev_printk(KERN_ERR, &pdev->dev, |
2542 | "no valid port_info specified\n"); | 2511 | "no valid port_info specified\n"); |
@@ -2557,7 +2526,6 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
2557 | host->private_data = host_priv; | 2526 | host->private_data = host_priv; |
2558 | host->flags |= hflag; | 2527 | host->flags |= hflag; |
2559 | 2528 | ||
2560 | pci_set_master(pdev); | ||
2561 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); | 2529 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); |
2562 | out: | 2530 | out: |
2563 | if (rc == 0) | 2531 | if (rc == 0) |
@@ -2571,6 +2539,12 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); | |||
2571 | 2539 | ||
2572 | #endif /* CONFIG_PCI */ | 2540 | #endif /* CONFIG_PCI */ |
2573 | 2541 | ||
2542 | /* | ||
2543 | * BMDMA support | ||
2544 | */ | ||
2545 | |||
2546 | #ifdef CONFIG_ATA_BMDMA | ||
2547 | |||
2574 | const struct ata_port_operations ata_bmdma_port_ops = { | 2548 | const struct ata_port_operations ata_bmdma_port_ops = { |
2575 | .inherits = &ata_sff_port_ops, | 2549 | .inherits = &ata_sff_port_ops, |
2576 | 2550 | ||
@@ -2580,6 +2554,7 @@ const struct ata_port_operations ata_bmdma_port_ops = { | |||
2580 | .qc_prep = ata_bmdma_qc_prep, | 2554 | .qc_prep = ata_bmdma_qc_prep, |
2581 | .qc_issue = ata_bmdma_qc_issue, | 2555 | .qc_issue = ata_bmdma_qc_issue, |
2582 | 2556 | ||
2557 | .sff_irq_clear = ata_bmdma_irq_clear, | ||
2583 | .bmdma_setup = ata_bmdma_setup, | 2558 | .bmdma_setup = ata_bmdma_setup, |
2584 | .bmdma_start = ata_bmdma_start, | 2559 | .bmdma_start = ata_bmdma_start, |
2585 | .bmdma_stop = ata_bmdma_stop, | 2560 | .bmdma_stop = ata_bmdma_stop, |
@@ -2804,6 +2779,75 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | |||
2804 | EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue); | 2779 | EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue); |
2805 | 2780 | ||
2806 | /** | 2781 | /** |
2782 | * ata_bmdma_port_intr - Handle BMDMA port interrupt | ||
2783 | * @ap: Port on which interrupt arrived (possibly...) | ||
2784 | * @qc: Taskfile currently active in engine | ||
2785 | * | ||
2786 | * Handle port interrupt for given queued command. | ||
2787 | * | ||
2788 | * LOCKING: | ||
2789 | * spin_lock_irqsave(host lock) | ||
2790 | * | ||
2791 | * RETURNS: | ||
2792 | * One if interrupt was handled, zero if not (shared irq). | ||
2793 | */ | ||
2794 | unsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | ||
2795 | { | ||
2796 | struct ata_eh_info *ehi = &ap->link.eh_info; | ||
2797 | u8 host_stat = 0; | ||
2798 | bool bmdma_stopped = false; | ||
2799 | unsigned int handled; | ||
2800 | |||
2801 | if (ap->hsm_task_state == HSM_ST_LAST && ata_is_dma(qc->tf.protocol)) { | ||
2802 | /* check status of DMA engine */ | ||
2803 | host_stat = ap->ops->bmdma_status(ap); | ||
2804 | VPRINTK("ata%u: host_stat 0x%X\n", ap->print_id, host_stat); | ||
2805 | |||
2806 | /* if it's not our irq... */ | ||
2807 | if (!(host_stat & ATA_DMA_INTR)) | ||
2808 | return ata_sff_idle_irq(ap); | ||
2809 | |||
2810 | /* before we do anything else, clear DMA-Start bit */ | ||
2811 | ap->ops->bmdma_stop(qc); | ||
2812 | bmdma_stopped = true; | ||
2813 | |||
2814 | if (unlikely(host_stat & ATA_DMA_ERR)) { | ||
2815 | /* error when transfering data to/from memory */ | ||
2816 | qc->err_mask |= AC_ERR_HOST_BUS; | ||
2817 | ap->hsm_task_state = HSM_ST_ERR; | ||
2818 | } | ||
2819 | } | ||
2820 | |||
2821 | handled = __ata_sff_port_intr(ap, qc, bmdma_stopped); | ||
2822 | |||
2823 | if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol)) | ||
2824 | ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); | ||
2825 | |||
2826 | return handled; | ||
2827 | } | ||
2828 | EXPORT_SYMBOL_GPL(ata_bmdma_port_intr); | ||
2829 | |||
2830 | /** | ||
2831 | * ata_bmdma_interrupt - Default BMDMA ATA host interrupt handler | ||
2832 | * @irq: irq line (unused) | ||
2833 | * @dev_instance: pointer to our ata_host information structure | ||
2834 | * | ||
2835 | * Default interrupt handler for PCI IDE devices. Calls | ||
2836 | * ata_bmdma_port_intr() for each port that is not disabled. | ||
2837 | * | ||
2838 | * LOCKING: | ||
2839 | * Obtains host lock during operation. | ||
2840 | * | ||
2841 | * RETURNS: | ||
2842 | * IRQ_NONE or IRQ_HANDLED. | ||
2843 | */ | ||
2844 | irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance) | ||
2845 | { | ||
2846 | return __ata_sff_interrupt(irq, dev_instance, ata_bmdma_port_intr); | ||
2847 | } | ||
2848 | EXPORT_SYMBOL_GPL(ata_bmdma_interrupt); | ||
2849 | |||
2850 | /** | ||
2807 | * ata_bmdma_error_handler - Stock error handler for BMDMA controller | 2851 | * ata_bmdma_error_handler - Stock error handler for BMDMA controller |
2808 | * @ap: port to handle error for | 2852 | * @ap: port to handle error for |
2809 | * | 2853 | * |
@@ -2848,7 +2892,8 @@ void ata_bmdma_error_handler(struct ata_port *ap) | |||
2848 | /* if we're gonna thaw, make sure IRQ is clear */ | 2892 | /* if we're gonna thaw, make sure IRQ is clear */ |
2849 | if (thaw) { | 2893 | if (thaw) { |
2850 | ap->ops->sff_check_status(ap); | 2894 | ap->ops->sff_check_status(ap); |
2851 | ap->ops->sff_irq_clear(ap); | 2895 | if (ap->ops->sff_irq_clear) |
2896 | ap->ops->sff_irq_clear(ap); | ||
2852 | } | 2897 | } |
2853 | } | 2898 | } |
2854 | 2899 | ||
@@ -2882,6 +2927,28 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) | |||
2882 | EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); | 2927 | EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); |
2883 | 2928 | ||
2884 | /** | 2929 | /** |
2930 | * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. | ||
2931 | * @ap: Port associated with this ATA transaction. | ||
2932 | * | ||
2933 | * Clear interrupt and error flags in DMA status register. | ||
2934 | * | ||
2935 | * May be used as the irq_clear() entry in ata_port_operations. | ||
2936 | * | ||
2937 | * LOCKING: | ||
2938 | * spin_lock_irqsave(host lock) | ||
2939 | */ | ||
2940 | void ata_bmdma_irq_clear(struct ata_port *ap) | ||
2941 | { | ||
2942 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
2943 | |||
2944 | if (!mmio) | ||
2945 | return; | ||
2946 | |||
2947 | iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS); | ||
2948 | } | ||
2949 | EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); | ||
2950 | |||
2951 | /** | ||
2885 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction | 2952 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction |
2886 | * @qc: Info associated with this ATA transaction. | 2953 | * @qc: Info associated with this ATA transaction. |
2887 | * | 2954 | * |
@@ -3137,7 +3204,100 @@ void ata_pci_bmdma_init(struct ata_host *host) | |||
3137 | } | 3204 | } |
3138 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); | 3205 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); |
3139 | 3206 | ||
3207 | /** | ||
3208 | * ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host | ||
3209 | * @pdev: target PCI device | ||
3210 | * @ppi: array of port_info, must be enough for two ports | ||
3211 | * @r_host: out argument for the initialized ATA host | ||
3212 | * | ||
3213 | * Helper to allocate BMDMA ATA host for @pdev, acquire all PCI | ||
3214 | * resources and initialize it accordingly in one go. | ||
3215 | * | ||
3216 | * LOCKING: | ||
3217 | * Inherited from calling layer (may sleep). | ||
3218 | * | ||
3219 | * RETURNS: | ||
3220 | * 0 on success, -errno otherwise. | ||
3221 | */ | ||
3222 | int ata_pci_bmdma_prepare_host(struct pci_dev *pdev, | ||
3223 | const struct ata_port_info * const * ppi, | ||
3224 | struct ata_host **r_host) | ||
3225 | { | ||
3226 | int rc; | ||
3227 | |||
3228 | rc = ata_pci_sff_prepare_host(pdev, ppi, r_host); | ||
3229 | if (rc) | ||
3230 | return rc; | ||
3231 | |||
3232 | ata_pci_bmdma_init(*r_host); | ||
3233 | return 0; | ||
3234 | } | ||
3235 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host); | ||
3236 | |||
3237 | /** | ||
3238 | * ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller | ||
3239 | * @pdev: Controller to be initialized | ||
3240 | * @ppi: array of port_info, must be enough for two ports | ||
3241 | * @sht: scsi_host_template to use when registering the host | ||
3242 | * @host_priv: host private_data | ||
3243 | * @hflags: host flags | ||
3244 | * | ||
3245 | * This function is similar to ata_pci_sff_init_one() but also | ||
3246 | * takes care of BMDMA initialization. | ||
3247 | * | ||
3248 | * LOCKING: | ||
3249 | * Inherited from PCI layer (may sleep). | ||
3250 | * | ||
3251 | * RETURNS: | ||
3252 | * Zero on success, negative on errno-based value on error. | ||
3253 | */ | ||
3254 | int ata_pci_bmdma_init_one(struct pci_dev *pdev, | ||
3255 | const struct ata_port_info * const * ppi, | ||
3256 | struct scsi_host_template *sht, void *host_priv, | ||
3257 | int hflags) | ||
3258 | { | ||
3259 | struct device *dev = &pdev->dev; | ||
3260 | const struct ata_port_info *pi; | ||
3261 | struct ata_host *host = NULL; | ||
3262 | int rc; | ||
3263 | |||
3264 | DPRINTK("ENTER\n"); | ||
3265 | |||
3266 | pi = ata_sff_find_valid_pi(ppi); | ||
3267 | if (!pi) { | ||
3268 | dev_printk(KERN_ERR, &pdev->dev, | ||
3269 | "no valid port_info specified\n"); | ||
3270 | return -EINVAL; | ||
3271 | } | ||
3272 | |||
3273 | if (!devres_open_group(dev, NULL, GFP_KERNEL)) | ||
3274 | return -ENOMEM; | ||
3275 | |||
3276 | rc = pcim_enable_device(pdev); | ||
3277 | if (rc) | ||
3278 | goto out; | ||
3279 | |||
3280 | /* prepare and activate BMDMA host */ | ||
3281 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); | ||
3282 | if (rc) | ||
3283 | goto out; | ||
3284 | host->private_data = host_priv; | ||
3285 | host->flags |= hflags; | ||
3286 | |||
3287 | pci_set_master(pdev); | ||
3288 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); | ||
3289 | out: | ||
3290 | if (rc == 0) | ||
3291 | devres_remove_group(&pdev->dev, NULL); | ||
3292 | else | ||
3293 | devres_release_group(&pdev->dev, NULL); | ||
3294 | |||
3295 | return rc; | ||
3296 | } | ||
3297 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); | ||
3298 | |||
3140 | #endif /* CONFIG_PCI */ | 3299 | #endif /* CONFIG_PCI */ |
3300 | #endif /* CONFIG_ATA_BMDMA */ | ||
3141 | 3301 | ||
3142 | /** | 3302 | /** |
3143 | * ata_sff_port_init - Initialize SFF/BMDMA ATA port | 3303 | * ata_sff_port_init - Initialize SFF/BMDMA ATA port |