diff options
| -rw-r--r-- | drivers/ata/ahci.c | 48 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 3 | ||||
| -rw-r--r-- | drivers/ata/libata-eh.c | 17 | ||||
| -rw-r--r-- | drivers/ata/libata-pmp.c | 209 | ||||
| -rw-r--r-- | drivers/ata/sata_sil24.c | 30 | ||||
| -rw-r--r-- | include/linux/libata.h | 8 |
6 files changed, 118 insertions, 197 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index abfb72aae3de..10bc3f64c453 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -239,8 +239,6 @@ static void ahci_freeze(struct ata_port *ap); | |||
| 239 | static void ahci_thaw(struct ata_port *ap); | 239 | static void ahci_thaw(struct ata_port *ap); |
| 240 | static void ahci_pmp_attach(struct ata_port *ap); | 240 | static void ahci_pmp_attach(struct ata_port *ap); |
| 241 | static void ahci_pmp_detach(struct ata_port *ap); | 241 | static void ahci_pmp_detach(struct ata_port *ap); |
| 242 | static int ahci_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val); | ||
| 243 | static int ahci_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val); | ||
| 244 | static void ahci_error_handler(struct ata_port *ap); | 242 | static void ahci_error_handler(struct ata_port *ap); |
| 245 | static void ahci_vt8251_error_handler(struct ata_port *ap); | 243 | static void ahci_vt8251_error_handler(struct ata_port *ap); |
| 246 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 244 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); |
| @@ -297,8 +295,6 @@ static const struct ata_port_operations ahci_ops = { | |||
| 297 | 295 | ||
| 298 | .pmp_attach = ahci_pmp_attach, | 296 | .pmp_attach = ahci_pmp_attach, |
| 299 | .pmp_detach = ahci_pmp_detach, | 297 | .pmp_detach = ahci_pmp_detach, |
| 300 | .pmp_read = ahci_pmp_read, | ||
| 301 | .pmp_write = ahci_pmp_write, | ||
| 302 | 298 | ||
| 303 | #ifdef CONFIG_PM | 299 | #ifdef CONFIG_PM |
| 304 | .port_suspend = ahci_port_suspend, | 300 | .port_suspend = ahci_port_suspend, |
| @@ -333,8 +329,6 @@ static const struct ata_port_operations ahci_vt8251_ops = { | |||
| 333 | 329 | ||
| 334 | .pmp_attach = ahci_pmp_attach, | 330 | .pmp_attach = ahci_pmp_attach, |
| 335 | .pmp_detach = ahci_pmp_detach, | 331 | .pmp_detach = ahci_pmp_detach, |
| 336 | .pmp_read = ahci_pmp_read, | ||
| 337 | .pmp_write = ahci_pmp_write, | ||
| 338 | 332 | ||
| 339 | #ifdef CONFIG_PM | 333 | #ifdef CONFIG_PM |
| 340 | .port_suspend = ahci_port_suspend, | 334 | .port_suspend = ahci_port_suspend, |
| @@ -1421,12 +1415,17 @@ static void ahci_port_intr(struct ata_port *ap) | |||
| 1421 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1415 | struct ata_eh_info *ehi = &ap->link.eh_info; |
| 1422 | struct ahci_port_priv *pp = ap->private_data; | 1416 | struct ahci_port_priv *pp = ap->private_data; |
| 1423 | struct ahci_host_priv *hpriv = ap->host->private_data; | 1417 | struct ahci_host_priv *hpriv = ap->host->private_data; |
| 1418 | int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); | ||
| 1424 | u32 status, qc_active; | 1419 | u32 status, qc_active; |
| 1425 | int rc, known_irq = 0; | 1420 | int rc, known_irq = 0; |
| 1426 | 1421 | ||
| 1427 | status = readl(port_mmio + PORT_IRQ_STAT); | 1422 | status = readl(port_mmio + PORT_IRQ_STAT); |
| 1428 | writel(status, port_mmio + PORT_IRQ_STAT); | 1423 | writel(status, port_mmio + PORT_IRQ_STAT); |
| 1429 | 1424 | ||
| 1425 | /* ignore BAD_PMP while resetting */ | ||
| 1426 | if (unlikely(resetting)) | ||
| 1427 | status &= ~PORT_IRQ_BAD_PMP; | ||
| 1428 | |||
| 1430 | if (unlikely(status & PORT_IRQ_ERROR)) { | 1429 | if (unlikely(status & PORT_IRQ_ERROR)) { |
| 1431 | ahci_error_intr(ap, status); | 1430 | ahci_error_intr(ap, status); |
| 1432 | return; | 1431 | return; |
| @@ -1464,6 +1463,13 @@ static void ahci_port_intr(struct ata_port *ap) | |||
| 1464 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); | 1463 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); |
| 1465 | 1464 | ||
| 1466 | rc = ata_qc_complete_multiple(ap, qc_active, NULL); | 1465 | rc = ata_qc_complete_multiple(ap, qc_active, NULL); |
| 1466 | |||
| 1467 | /* If resetting, spurious or invalid completions are expected, | ||
| 1468 | * return unconditionally. | ||
| 1469 | */ | ||
| 1470 | if (resetting) | ||
| 1471 | return; | ||
| 1472 | |||
| 1467 | if (rc > 0) | 1473 | if (rc > 0) |
| 1468 | return; | 1474 | return; |
| 1469 | if (rc < 0) { | 1475 | if (rc < 0) { |
| @@ -1701,36 +1707,6 @@ static void ahci_pmp_detach(struct ata_port *ap) | |||
| 1701 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 1707 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); |
| 1702 | } | 1708 | } |
| 1703 | 1709 | ||
| 1704 | static int ahci_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val) | ||
| 1705 | { | ||
| 1706 | struct ata_port *ap = dev->link->ap; | ||
| 1707 | struct ata_taskfile tf; | ||
| 1708 | int rc; | ||
| 1709 | |||
| 1710 | ahci_kick_engine(ap, 0); | ||
| 1711 | |||
| 1712 | sata_pmp_read_init_tf(&tf, dev, pmp, reg); | ||
| 1713 | rc = ahci_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0, | ||
| 1714 | SATA_PMP_SCR_TIMEOUT); | ||
| 1715 | if (rc == 0) { | ||
| 1716 | ahci_tf_read(ap, &tf); | ||
| 1717 | *r_val = sata_pmp_read_val(&tf); | ||
| 1718 | } | ||
| 1719 | return rc; | ||
| 1720 | } | ||
| 1721 | |||
| 1722 | static int ahci_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val) | ||
| 1723 | { | ||
| 1724 | struct ata_port *ap = dev->link->ap; | ||
| 1725 | struct ata_taskfile tf; | ||
| 1726 | |||
| 1727 | ahci_kick_engine(ap, 0); | ||
| 1728 | |||
| 1729 | sata_pmp_write_init_tf(&tf, dev, pmp, reg, val); | ||
| 1730 | return ahci_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0, | ||
| 1731 | SATA_PMP_SCR_TIMEOUT); | ||
| 1732 | } | ||
| 1733 | |||
| 1734 | static int ahci_port_resume(struct ata_port *ap) | 1710 | static int ahci_port_resume(struct ata_port *ap) |
| 1735 | { | 1711 | { |
| 1736 | ahci_power_up(ap); | 1712 | ahci_power_up(ap); |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 59ebc5d5100a..ce8ccb434aff 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -7354,9 +7354,6 @@ EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); | |||
| 7354 | #endif /* CONFIG_PCI */ | 7354 | #endif /* CONFIG_PCI */ |
| 7355 | 7355 | ||
| 7356 | EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch); | 7356 | EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch); |
| 7357 | EXPORT_SYMBOL_GPL(sata_pmp_read_init_tf); | ||
| 7358 | EXPORT_SYMBOL_GPL(sata_pmp_read_val); | ||
| 7359 | EXPORT_SYMBOL_GPL(sata_pmp_write_init_tf); | ||
| 7360 | EXPORT_SYMBOL_GPL(sata_pmp_std_prereset); | 7357 | EXPORT_SYMBOL_GPL(sata_pmp_std_prereset); |
| 7361 | EXPORT_SYMBOL_GPL(sata_pmp_std_hardreset); | 7358 | EXPORT_SYMBOL_GPL(sata_pmp_std_hardreset); |
| 7362 | EXPORT_SYMBOL_GPL(sata_pmp_std_postreset); | 7359 | EXPORT_SYMBOL_GPL(sata_pmp_std_postreset); |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 1f84e40fa6ae..5a2b2af4d0c1 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -2557,7 +2557,11 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
| 2557 | 2557 | ||
| 2558 | /* reset */ | 2558 | /* reset */ |
| 2559 | if (reset) { | 2559 | if (reset) { |
| 2560 | ata_eh_freeze_port(ap); | 2560 | /* if PMP is attached, this function only deals with |
| 2561 | * downstream links, port should stay thawed. | ||
| 2562 | */ | ||
| 2563 | if (!ap->nr_pmp_links) | ||
| 2564 | ata_eh_freeze_port(ap); | ||
| 2561 | 2565 | ||
| 2562 | ata_port_for_each_link(link, ap) { | 2566 | ata_port_for_each_link(link, ap) { |
| 2563 | struct ata_eh_context *ehc = &link->eh_context; | 2567 | struct ata_eh_context *ehc = &link->eh_context; |
| @@ -2575,7 +2579,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
| 2575 | } | 2579 | } |
| 2576 | } | 2580 | } |
| 2577 | 2581 | ||
| 2578 | ata_eh_thaw_port(ap); | 2582 | if (!ap->nr_pmp_links) |
| 2583 | ata_eh_thaw_port(ap); | ||
| 2579 | } | 2584 | } |
| 2580 | 2585 | ||
| 2581 | /* the rest */ | 2586 | /* the rest */ |
| @@ -2610,8 +2615,14 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
| 2610 | if (ata_eh_handle_dev_fail(dev, rc)) | 2615 | if (ata_eh_handle_dev_fail(dev, rc)) |
| 2611 | nr_disabled_devs++; | 2616 | nr_disabled_devs++; |
| 2612 | 2617 | ||
| 2613 | if (ap->pflags & ATA_PFLAG_FROZEN) | 2618 | if (ap->pflags & ATA_PFLAG_FROZEN) { |
| 2619 | /* PMP reset requires working host port. | ||
| 2620 | * Can't retry if it's frozen. | ||
| 2621 | */ | ||
| 2622 | if (ap->nr_pmp_links) | ||
| 2623 | goto out; | ||
| 2614 | break; | 2624 | break; |
| 2625 | } | ||
| 2615 | } | 2626 | } |
| 2616 | 2627 | ||
| 2617 | if (nr_failed_devs) { | 2628 | if (nr_failed_devs) { |
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index f6c4b11336e9..c0c4dbcde091 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c | |||
| @@ -17,27 +17,35 @@ | |||
| 17 | * @reg: register to read | 17 | * @reg: register to read |
| 18 | * @r_val: resulting value | 18 | * @r_val: resulting value |
| 19 | * | 19 | * |
| 20 | * Wrapper around ap->ops->pmp_read to make it easier to call and | 20 | * Read PMP register. |
| 21 | * nomarlize error return value. | ||
| 22 | * | 21 | * |
| 23 | * LOCKING: | 22 | * LOCKING: |
| 24 | * Kernel thread context (may sleep). | 23 | * Kernel thread context (may sleep). |
| 25 | * | 24 | * |
| 26 | * RETURNS: | 25 | * RETURNS: |
| 27 | * 0 on success, -errno on failure. | 26 | * 0 on success, AC_ERR_* mask on failure. |
| 28 | */ | 27 | */ |
| 29 | static int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) | 28 | static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) |
| 30 | { | 29 | { |
| 31 | struct ata_port *ap = link->ap; | 30 | struct ata_port *ap = link->ap; |
| 32 | struct ata_device *pmp_dev = ap->link.device; | 31 | struct ata_device *pmp_dev = ap->link.device; |
| 33 | int rc; | 32 | struct ata_taskfile tf; |
| 34 | 33 | unsigned int err_mask; | |
| 35 | might_sleep(); | 34 | |
| 36 | 35 | ata_tf_init(pmp_dev, &tf); | |
| 37 | rc = ap->ops->pmp_read(pmp_dev, link->pmp, reg, r_val); | 36 | tf.command = ATA_CMD_PMP_READ; |
| 38 | if (rc) | 37 | tf.protocol = ATA_PROT_NODATA; |
| 39 | rc = -EIO; | 38 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
| 40 | return rc; | 39 | tf.feature = reg; |
| 40 | tf.device = link->pmp; | ||
| 41 | |||
| 42 | err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, | ||
| 43 | SATA_PMP_SCR_TIMEOUT); | ||
| 44 | if (err_mask) | ||
| 45 | return err_mask; | ||
| 46 | |||
| 47 | *r_val = tf.nsect | tf.lbal << 8 | tf.lbam << 16 | tf.lbah << 24; | ||
| 48 | return 0; | ||
| 41 | } | 49 | } |
| 42 | 50 | ||
| 43 | /** | 51 | /** |
| @@ -46,27 +54,33 @@ static int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) | |||
| 46 | * @reg: register to write | 54 | * @reg: register to write |
| 47 | * @r_val: value to write | 55 | * @r_val: value to write |
| 48 | * | 56 | * |
| 49 | * Wrapper around ap->ops->pmp_write to make it easier to call | 57 | * Write PMP register. |
| 50 | * and nomarlize error return value. | ||
| 51 | * | 58 | * |
| 52 | * LOCKING: | 59 | * LOCKING: |
| 53 | * Kernel thread context (may sleep). | 60 | * Kernel thread context (may sleep). |
| 54 | * | 61 | * |
| 55 | * RETURNS: | 62 | * RETURNS: |
| 56 | * 0 on success, -errno on failure. | 63 | * 0 on success, AC_ERR_* mask on failure. |
| 57 | */ | 64 | */ |
| 58 | static int sata_pmp_write(struct ata_link *link, int reg, u32 val) | 65 | static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val) |
| 59 | { | 66 | { |
| 60 | struct ata_port *ap = link->ap; | 67 | struct ata_port *ap = link->ap; |
| 61 | struct ata_device *pmp_dev = ap->link.device; | 68 | struct ata_device *pmp_dev = ap->link.device; |
| 62 | int rc; | 69 | struct ata_taskfile tf; |
| 63 | 70 | ||
| 64 | might_sleep(); | 71 | ata_tf_init(pmp_dev, &tf); |
| 65 | 72 | tf.command = ATA_CMD_PMP_WRITE; | |
| 66 | rc = ap->ops->pmp_write(pmp_dev, link->pmp, reg, val); | 73 | tf.protocol = ATA_PROT_NODATA; |
| 67 | if (rc) | 74 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
| 68 | rc = -EIO; | 75 | tf.feature = reg; |
| 69 | return rc; | 76 | tf.device = link->pmp; |
| 77 | tf.nsect = val & 0xff; | ||
| 78 | tf.lbal = (val >> 8) & 0xff; | ||
| 79 | tf.lbam = (val >> 16) & 0xff; | ||
| 80 | tf.lbah = (val >> 24) & 0xff; | ||
| 81 | |||
| 82 | return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, | ||
| 83 | SATA_PMP_SCR_TIMEOUT); | ||
| 70 | } | 84 | } |
| 71 | 85 | ||
| 72 | /** | 86 | /** |
| @@ -100,71 +114,6 @@ int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc) | |||
| 100 | } | 114 | } |
| 101 | 115 | ||
| 102 | /** | 116 | /** |
| 103 | * sata_pmp_read_init_tf - initialize TF for PMP read | ||
| 104 | * @tf: taskfile to initialize | ||
| 105 | * @dev: PMP dev | ||
| 106 | * @pmp: port multiplier port number | ||
| 107 | * @reg: register to read | ||
| 108 | * | ||
| 109 | * Initialize @tf for PMP read command. | ||
| 110 | * | ||
| 111 | * LOCKING: | ||
| 112 | * None. | ||
| 113 | */ | ||
| 114 | void sata_pmp_read_init_tf(struct ata_taskfile *tf, | ||
| 115 | struct ata_device *dev, int pmp, int reg) | ||
| 116 | { | ||
| 117 | ata_tf_init(dev, tf); | ||
| 118 | tf->command = ATA_CMD_PMP_READ; | ||
| 119 | tf->protocol = ATA_PROT_NODATA; | ||
| 120 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
| 121 | tf->feature = reg; | ||
| 122 | tf->device = pmp; | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 126 | * sata_pmp_read_val - extract PMP read result from TF | ||
| 127 | * @tf: target TF | ||
| 128 | * | ||
| 129 | * Determine PMP read result from @tf. | ||
| 130 | * | ||
| 131 | * LOCKING: | ||
| 132 | * None. | ||
| 133 | */ | ||
| 134 | u32 sata_pmp_read_val(const struct ata_taskfile *tf) | ||
| 135 | { | ||
| 136 | return tf->nsect | tf->lbal << 8 | tf->lbam << 16 | tf->lbah << 24; | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * sata_pmp_read_init_tf - initialize TF for PMP write | ||
| 141 | * @tf: taskfile to initialize | ||
| 142 | * @dev: PMP dev | ||
| 143 | * @pmp: port multiplier port number | ||
| 144 | * @reg: register to read | ||
| 145 | * @val: value to write | ||
| 146 | * | ||
| 147 | * Initialize @tf for PMP write command. | ||
| 148 | * | ||
| 149 | * LOCKING: | ||
| 150 | * None. | ||
| 151 | */ | ||
| 152 | void sata_pmp_write_init_tf(struct ata_taskfile *tf, | ||
| 153 | struct ata_device *dev, int pmp, int reg, u32 val) | ||
| 154 | { | ||
| 155 | ata_tf_init(dev, tf); | ||
| 156 | tf->command = ATA_CMD_PMP_WRITE; | ||
| 157 | tf->protocol = ATA_PROT_NODATA; | ||
| 158 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
| 159 | tf->feature = reg; | ||
| 160 | tf->device = pmp; | ||
| 161 | tf->nsect = val & 0xff; | ||
| 162 | tf->lbal = (val >> 8) & 0xff; | ||
| 163 | tf->lbam = (val >> 16) & 0xff; | ||
| 164 | tf->lbah = (val >> 24) & 0xff; | ||
| 165 | } | ||
| 166 | |||
| 167 | /** | ||
| 168 | * sata_pmp_scr_read - read PSCR | 117 | * sata_pmp_scr_read - read PSCR |
| 169 | * @link: ATA link to read PSCR for | 118 | * @link: ATA link to read PSCR for |
| 170 | * @reg: PSCR to read | 119 | * @reg: PSCR to read |
| @@ -181,10 +130,18 @@ void sata_pmp_write_init_tf(struct ata_taskfile *tf, | |||
| 181 | */ | 130 | */ |
| 182 | int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *r_val) | 131 | int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *r_val) |
| 183 | { | 132 | { |
| 133 | unsigned int err_mask; | ||
| 134 | |||
| 184 | if (reg > SATA_PMP_PSCR_CONTROL) | 135 | if (reg > SATA_PMP_PSCR_CONTROL) |
| 185 | return -EINVAL; | 136 | return -EINVAL; |
| 186 | 137 | ||
| 187 | return sata_pmp_read(link, reg, r_val); | 138 | err_mask = sata_pmp_read(link, reg, r_val); |
| 139 | if (err_mask) { | ||
| 140 | ata_link_printk(link, KERN_WARNING, "failed to read SCR %d " | ||
| 141 | "(Emask=0x%x)\n", reg, err_mask); | ||
| 142 | return -EIO; | ||
| 143 | } | ||
| 144 | return 0; | ||
| 188 | } | 145 | } |
| 189 | 146 | ||
| 190 | /** | 147 | /** |
| @@ -204,10 +161,18 @@ int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *r_val) | |||
| 204 | */ | 161 | */ |
| 205 | int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val) | 162 | int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val) |
| 206 | { | 163 | { |
| 164 | unsigned int err_mask; | ||
| 165 | |||
| 207 | if (reg > SATA_PMP_PSCR_CONTROL) | 166 | if (reg > SATA_PMP_PSCR_CONTROL) |
| 208 | return -EINVAL; | 167 | return -EINVAL; |
| 209 | 168 | ||
| 210 | return sata_pmp_write(link, reg, val); | 169 | err_mask = sata_pmp_write(link, reg, val); |
| 170 | if (err_mask) { | ||
| 171 | ata_link_printk(link, KERN_WARNING, "failed to write SCR %d " | ||
| 172 | "(Emask=0x%x)\n", reg, err_mask); | ||
| 173 | return -EIO; | ||
| 174 | } | ||
| 175 | return 0; | ||
| 211 | } | 176 | } |
| 212 | 177 | ||
| 213 | /** | 178 | /** |
| @@ -361,16 +326,17 @@ void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class) | |||
| 361 | static int sata_pmp_read_gscr(struct ata_device *dev, u32 *gscr) | 326 | static int sata_pmp_read_gscr(struct ata_device *dev, u32 *gscr) |
| 362 | { | 327 | { |
| 363 | static const int gscr_to_read[] = { 0, 1, 2, 32, 33, 64, 96 }; | 328 | static const int gscr_to_read[] = { 0, 1, 2, 32, 33, 64, 96 }; |
| 364 | int i, rc; | 329 | int i; |
| 365 | 330 | ||
| 366 | for (i = 0; i < ARRAY_SIZE(gscr_to_read); i++) { | 331 | for (i = 0; i < ARRAY_SIZE(gscr_to_read); i++) { |
| 367 | int reg = gscr_to_read[i]; | 332 | int reg = gscr_to_read[i]; |
| 333 | unsigned int err_mask; | ||
| 368 | 334 | ||
| 369 | rc = sata_pmp_read(dev->link, reg, &gscr[reg]); | 335 | err_mask = sata_pmp_read(dev->link, reg, &gscr[reg]); |
| 370 | if (rc) { | 336 | if (err_mask) { |
| 371 | ata_dev_printk(dev, KERN_ERR, "failed to read " | 337 | ata_dev_printk(dev, KERN_ERR, "failed to read PMP " |
| 372 | "PMP GSCR[%d] (errno=%d)\n", reg, rc); | 338 | "GSCR[%d] (Emask=0x%x)\n", reg, err_mask); |
| 373 | return rc; | 339 | return -EIO; |
| 374 | } | 340 | } |
| 375 | } | 341 | } |
| 376 | 342 | ||
| @@ -392,6 +358,7 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
| 392 | { | 358 | { |
| 393 | struct ata_port *ap = dev->link->ap; | 359 | struct ata_port *ap = dev->link->ap; |
| 394 | u32 *gscr = dev->gscr; | 360 | u32 *gscr = dev->gscr; |
| 361 | unsigned int err_mask = 0; | ||
| 395 | const char *reason; | 362 | const char *reason; |
| 396 | int nr_ports, rc; | 363 | int nr_ports, rc; |
| 397 | 364 | ||
| @@ -408,8 +375,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
| 408 | dev->flags |= ATA_DFLAG_AN; | 375 | dev->flags |= ATA_DFLAG_AN; |
| 409 | 376 | ||
| 410 | /* monitor SERR_PHYRDY_CHG on fan-out ports */ | 377 | /* monitor SERR_PHYRDY_CHG on fan-out ports */ |
| 411 | rc = sata_pmp_write(dev->link, SATA_PMP_GSCR_ERROR_EN, SERR_PHYRDY_CHG); | 378 | err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_ERROR_EN, |
| 412 | if (rc) { | 379 | SERR_PHYRDY_CHG); |
| 380 | if (err_mask) { | ||
| 381 | rc = -EIO; | ||
| 413 | reason = "failed to write GSCR_ERROR_EN"; | 382 | reason = "failed to write GSCR_ERROR_EN"; |
| 414 | goto fail; | 383 | goto fail; |
| 415 | } | 384 | } |
| @@ -418,9 +387,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
| 418 | if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { | 387 | if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { |
| 419 | gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; | 388 | gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; |
| 420 | 389 | ||
| 421 | rc = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN, | 390 | err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN, |
| 422 | gscr[SATA_PMP_GSCR_FEAT_EN]); | 391 | gscr[SATA_PMP_GSCR_FEAT_EN]); |
| 423 | if (rc) { | 392 | if (err_mask) { |
| 393 | rc = -EIO; | ||
| 424 | reason = "failed to write GSCR_FEAT_EN"; | 394 | reason = "failed to write GSCR_FEAT_EN"; |
| 425 | goto fail; | 395 | goto fail; |
| 426 | } | 396 | } |
| @@ -447,7 +417,8 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
| 447 | 417 | ||
| 448 | fail: | 418 | fail: |
| 449 | ata_dev_printk(dev, KERN_ERR, | 419 | ata_dev_printk(dev, KERN_ERR, |
| 450 | "failed to configure Port Multiplier (%s)\n", reason); | 420 | "failed to configure Port Multiplier (%s, Emask=0x%x)\n", |
| 421 | reason, err_mask); | ||
| 451 | return rc; | 422 | return rc; |
| 452 | } | 423 | } |
| 453 | 424 | ||
| @@ -812,13 +783,14 @@ static int sata_pmp_revalidate(struct ata_device *dev, unsigned int new_class) | |||
| 812 | */ | 783 | */ |
| 813 | static int sata_pmp_revalidate_quick(struct ata_device *dev) | 784 | static int sata_pmp_revalidate_quick(struct ata_device *dev) |
| 814 | { | 785 | { |
| 786 | unsigned int err_mask; | ||
| 815 | u32 prod_id; | 787 | u32 prod_id; |
| 816 | int rc; | ||
| 817 | 788 | ||
| 818 | rc = sata_pmp_read(dev->link, SATA_PMP_GSCR_PROD_ID, &prod_id); | 789 | err_mask = sata_pmp_read(dev->link, SATA_PMP_GSCR_PROD_ID, &prod_id); |
| 819 | if (rc) { | 790 | if (err_mask) { |
| 820 | ata_dev_printk(dev, KERN_ERR, "failed to read PMP product ID\n"); | 791 | ata_dev_printk(dev, KERN_ERR, "failed to read PMP product ID " |
| 821 | return rc; | 792 | "(Emask=0x%x)\n", err_mask); |
| 793 | return -EIO; | ||
| 822 | } | 794 | } |
| 823 | 795 | ||
| 824 | if (prod_id != dev->gscr[SATA_PMP_GSCR_PROD_ID]) { | 796 | if (prod_id != dev->gscr[SATA_PMP_GSCR_PROD_ID]) { |
| @@ -1049,6 +1021,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap, | |||
| 1049 | struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; | 1021 | struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; |
| 1050 | struct ata_link *link; | 1022 | struct ata_link *link; |
| 1051 | struct ata_device *dev; | 1023 | struct ata_device *dev; |
| 1024 | unsigned int err_mask; | ||
| 1052 | u32 gscr_error, sntf; | 1025 | u32 gscr_error, sntf; |
| 1053 | int cnt, rc; | 1026 | int cnt, rc; |
| 1054 | 1027 | ||
| @@ -1107,20 +1080,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap, | |||
| 1107 | if (pmp_dev->flags & ATA_DFLAG_AN) { | 1080 | if (pmp_dev->flags & ATA_DFLAG_AN) { |
| 1108 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; | 1081 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; |
| 1109 | 1082 | ||
| 1110 | rc = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, | 1083 | err_mask = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, |
| 1111 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); | 1084 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); |
| 1112 | if (rc) { | 1085 | if (err_mask) { |
| 1113 | ata_dev_printk(pmp_dev, KERN_ERR, | 1086 | ata_dev_printk(pmp_dev, KERN_ERR, "failed to write " |
| 1114 | "failed to write PMP_FEAT_EN\n"); | 1087 | "PMP_FEAT_EN (Emask=0x%x)\n", err_mask); |
| 1088 | rc = -EIO; | ||
| 1115 | goto pmp_fail; | 1089 | goto pmp_fail; |
| 1116 | } | 1090 | } |
| 1117 | } | 1091 | } |
| 1118 | 1092 | ||
| 1119 | /* check GSCR_ERROR */ | 1093 | /* check GSCR_ERROR */ |
| 1120 | rc = sata_pmp_read(pmp_link, SATA_PMP_GSCR_ERROR, &gscr_error); | 1094 | err_mask = sata_pmp_read(pmp_link, SATA_PMP_GSCR_ERROR, &gscr_error); |
| 1121 | if (rc) { | 1095 | if (err_mask) { |
| 1122 | ata_dev_printk(pmp_dev, KERN_ERR, | 1096 | ata_dev_printk(pmp_dev, KERN_ERR, "failed to read " |
| 1123 | "failed to read PMP_GSCR_ERROR\n"); | 1097 | "PMP_GSCR_ERROR (Emask=0x%x)\n", err_mask); |
| 1098 | rc = -EIO; | ||
| 1124 | goto pmp_fail; | 1099 | goto pmp_fail; |
| 1125 | } | 1100 | } |
| 1126 | 1101 | ||
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 15b9a80a1782..b0619278454a 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
| @@ -337,8 +337,6 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); | |||
| 337 | static void sil24_irq_clear(struct ata_port *ap); | 337 | static void sil24_irq_clear(struct ata_port *ap); |
| 338 | static void sil24_pmp_attach(struct ata_port *ap); | 338 | static void sil24_pmp_attach(struct ata_port *ap); |
| 339 | static void sil24_pmp_detach(struct ata_port *ap); | 339 | static void sil24_pmp_detach(struct ata_port *ap); |
| 340 | static int sil24_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val); | ||
| 341 | static int sil24_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val); | ||
| 342 | static void sil24_freeze(struct ata_port *ap); | 340 | static void sil24_freeze(struct ata_port *ap); |
| 343 | static void sil24_thaw(struct ata_port *ap); | 341 | static void sil24_thaw(struct ata_port *ap); |
| 344 | static void sil24_error_handler(struct ata_port *ap); | 342 | static void sil24_error_handler(struct ata_port *ap); |
| @@ -411,8 +409,6 @@ static const struct ata_port_operations sil24_ops = { | |||
| 411 | 409 | ||
| 412 | .pmp_attach = sil24_pmp_attach, | 410 | .pmp_attach = sil24_pmp_attach, |
| 413 | .pmp_detach = sil24_pmp_detach, | 411 | .pmp_detach = sil24_pmp_detach, |
| 414 | .pmp_read = sil24_pmp_read, | ||
| 415 | .pmp_write = sil24_pmp_write, | ||
| 416 | 412 | ||
| 417 | .freeze = sil24_freeze, | 413 | .freeze = sil24_freeze, |
| 418 | .thaw = sil24_thaw, | 414 | .thaw = sil24_thaw, |
| @@ -928,32 +924,6 @@ static void sil24_pmp_detach(struct ata_port *ap) | |||
| 928 | sil24_config_pmp(ap, 0); | 924 | sil24_config_pmp(ap, 0); |
| 929 | } | 925 | } |
| 930 | 926 | ||
| 931 | static int sil24_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val) | ||
| 932 | { | ||
| 933 | struct ata_port *ap = dev->link->ap; | ||
| 934 | struct ata_taskfile tf; | ||
| 935 | int rc; | ||
| 936 | |||
| 937 | sata_pmp_read_init_tf(&tf, dev, pmp, reg); | ||
| 938 | rc = sil24_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0, | ||
| 939 | SATA_PMP_SCR_TIMEOUT); | ||
| 940 | if (rc == 0) { | ||
| 941 | sil24_read_tf(ap, 0, &tf); | ||
| 942 | *r_val = sata_pmp_read_val(&tf); | ||
| 943 | } | ||
| 944 | return rc; | ||
| 945 | } | ||
| 946 | |||
| 947 | static int sil24_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val) | ||
| 948 | { | ||
| 949 | struct ata_port *ap = dev->link->ap; | ||
| 950 | struct ata_taskfile tf; | ||
| 951 | |||
| 952 | sata_pmp_write_init_tf(&tf, dev, pmp, reg, val); | ||
| 953 | return sil24_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0, | ||
| 954 | SATA_PMP_SCR_TIMEOUT); | ||
| 955 | } | ||
| 956 | |||
| 957 | static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class, | 927 | static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class, |
| 958 | unsigned long deadline) | 928 | unsigned long deadline) |
| 959 | { | 929 | { |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 529af9fbed53..2439f1fa47a1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -669,8 +669,6 @@ struct ata_port_operations { | |||
| 669 | /* port multiplier */ | 669 | /* port multiplier */ |
| 670 | void (*pmp_attach) (struct ata_port *ap); | 670 | void (*pmp_attach) (struct ata_port *ap); |
| 671 | void (*pmp_detach) (struct ata_port *ap); | 671 | void (*pmp_detach) (struct ata_port *ap); |
| 672 | int (*pmp_read) (struct ata_device *dev, int pmp, int reg, u32 *r_val); | ||
| 673 | int (*pmp_write) (struct ata_device *dev, int pmp, int reg, u32 val); | ||
| 674 | 672 | ||
| 675 | /* Error handlers. ->error_handler overrides ->eng_timeout and | 673 | /* Error handlers. ->error_handler overrides ->eng_timeout and |
| 676 | * indicates that new-style EH is in place. | 674 | * indicates that new-style EH is in place. |
| @@ -957,12 +955,6 @@ extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long); | |||
| 957 | * PMP | 955 | * PMP |
| 958 | */ | 956 | */ |
| 959 | extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc); | 957 | extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc); |
| 960 | extern void sata_pmp_read_init_tf(struct ata_taskfile *tf, | ||
| 961 | struct ata_device *dev, int pmp, int reg); | ||
| 962 | extern u32 sata_pmp_read_val(const struct ata_taskfile *tf); | ||
| 963 | extern void sata_pmp_write_init_tf(struct ata_taskfile *tf, | ||
| 964 | struct ata_device *dev, | ||
| 965 | int pmp, int reg, u32 val); | ||
| 966 | extern int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline); | 958 | extern int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline); |
| 967 | extern int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, | 959 | extern int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, |
| 968 | unsigned long deadline); | 960 | unsigned long deadline); |
