Lines Matching +full:tf +full:- +full:a

1 // SPDX-License-Identifier: GPL-2.0-only
3 * libata-pmp.c - libata port multiplier support
14 #include "libata-transport.h"
25 * sata_pmp_read - read PMP register
40 struct ata_port *ap = link->ap; in sata_pmp_read()
41 struct ata_device *pmp_dev = ap->link.device; in sata_pmp_read()
42 struct ata_taskfile tf; in sata_pmp_read() local
45 ata_tf_init(pmp_dev, &tf); in sata_pmp_read()
46 tf.command = ATA_CMD_PMP_READ; in sata_pmp_read()
47 tf.protocol = ATA_PROT_NODATA; in sata_pmp_read()
48 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; in sata_pmp_read()
49 tf.feature = reg; in sata_pmp_read()
50 tf.device = link->pmp; in sata_pmp_read()
52 err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, in sata_pmp_read()
57 *r_val = tf.nsect | tf.lbal << 8 | tf.lbam << 16 | tf.lbah << 24; in sata_pmp_read()
62 * sata_pmp_write - write PMP register
77 struct ata_port *ap = link->ap; in sata_pmp_write()
78 struct ata_device *pmp_dev = ap->link.device; in sata_pmp_write()
79 struct ata_taskfile tf; in sata_pmp_write() local
81 ata_tf_init(pmp_dev, &tf); in sata_pmp_write()
82 tf.command = ATA_CMD_PMP_WRITE; in sata_pmp_write()
83 tf.protocol = ATA_PROT_NODATA; in sata_pmp_write()
84 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; in sata_pmp_write()
85 tf.feature = reg; in sata_pmp_write()
86 tf.device = link->pmp; in sata_pmp_write()
87 tf.nsect = val & 0xff; in sata_pmp_write()
88 tf.lbal = (val >> 8) & 0xff; in sata_pmp_write()
89 tf.lbam = (val >> 16) & 0xff; in sata_pmp_write()
90 tf.lbah = (val >> 24) & 0xff; in sata_pmp_write()
92 return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, in sata_pmp_write()
97 * sata_pmp_qc_defer_cmd_switch - qc_defer for command switching PMP
100 * A host which has command switching PMP support cannot issue
111 struct ata_link *link = qc->dev->link; in sata_pmp_qc_defer_cmd_switch()
112 struct ata_port *ap = link->ap; in sata_pmp_qc_defer_cmd_switch()
114 if (ap->excl_link == NULL || ap->excl_link == link) { in sata_pmp_qc_defer_cmd_switch()
115 if (ap->nr_active_links == 0 || ata_link_active(link)) { in sata_pmp_qc_defer_cmd_switch()
116 qc->flags |= ATA_QCFLAG_CLEAR_EXCL; in sata_pmp_qc_defer_cmd_switch()
120 ap->excl_link = link; in sata_pmp_qc_defer_cmd_switch()
127 * sata_pmp_scr_read - read PSCR
139 * 0 on success, -errno on failure.
146 return -EINVAL; in sata_pmp_scr_read()
152 return -EIO; in sata_pmp_scr_read()
158 * sata_pmp_scr_write - write PSCR
170 * 0 on success, -errno on failure.
177 return -EINVAL; in sata_pmp_scr_write()
183 return -EIO; in sata_pmp_scr_write()
189 * sata_pmp_set_lpm - configure LPM for a PMP link
201 * 0 on success, -errno on failure.
210 * sata_pmp_read_gscr - read GSCR block of SATA PMP
221 * 0 on success, -errno on failure.
232 err_mask = sata_pmp_read(dev->link, reg, &gscr[reg]); in sata_pmp_read_gscr()
236 return -EIO; in sata_pmp_read_gscr()
260 struct ata_port *ap = dev->link->ap; in sata_pmp_configure()
261 u32 *gscr = dev->gscr; in sata_pmp_configure()
271 rc = -EINVAL; in sata_pmp_configure()
276 if ((ap->flags & ATA_FLAG_AN) && in sata_pmp_configure()
278 dev->flags |= ATA_DFLAG_AN; in sata_pmp_configure()
280 /* monitor SERR_PHYRDY_CHG on fan-out ports */ in sata_pmp_configure()
281 err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_ERROR_EN, in sata_pmp_configure()
284 rc = -EIO; in sata_pmp_configure()
290 * With "cached read" HDD testing and multiple ports busy on a SATA in sata_pmp_configure()
291 * host controller, 3x26 PMP will very rarely drop a deferred in sata_pmp_configure()
298 err_mask = sata_pmp_read(&ap->link, PMP_GSCR_SII_POL, &reg); in sata_pmp_configure()
300 rc = -EIO; in sata_pmp_configure()
305 err_mask = sata_pmp_write(&ap->link, PMP_GSCR_SII_POL, reg); in sata_pmp_configure()
307 rc = -EIO; in sata_pmp_configure()
321 if (!(dev->flags & ATA_DFLAG_AN)) in sata_pmp_configure()
324 "hotplug won't work on fan-out ports. Use warm-plug instead.\n"); in sata_pmp_configure()
338 struct ata_link *pmp_link = ap->pmp_link; in sata_pmp_init_links()
345 return -ENOMEM; in sata_pmp_init_links()
350 ap->pmp_link = pmp_link; in sata_pmp_init_links()
362 struct ata_eh_context *ehc = &link->eh_context; in sata_pmp_init_links()
364 link->flags = 0; in sata_pmp_init_links()
365 ehc->i.probe_mask |= ATA_ALL_DEVICES; in sata_pmp_init_links()
366 ehc->i.action |= ATA_EH_RESET; in sata_pmp_init_links()
371 while (--i >= 0) in sata_pmp_init_links()
374 ap->pmp_link = NULL; in sata_pmp_init_links()
380 u32 *gscr = ap->link.device->gscr; in sata_pmp_quirks()
389 link->flags |= ATA_LFLAG_NO_LPM; in sata_pmp_quirks()
395 if (link->pmp < 5) in sata_pmp_quirks()
396 link->flags |= ATA_LFLAG_NO_SRST | in sata_pmp_quirks()
400 if (link->pmp == 5) in sata_pmp_quirks()
401 link->flags |= ATA_LFLAG_NO_SRST | in sata_pmp_quirks()
413 link->flags |= ATA_LFLAG_NO_LPM | in sata_pmp_quirks()
420 link->flags |= ATA_LFLAG_NO_LPM; in sata_pmp_quirks()
427 if (link->pmp <= 5) in sata_pmp_quirks()
428 link->flags |= ATA_LFLAG_NO_SRST | in sata_pmp_quirks()
434 if (link->pmp == 6) in sata_pmp_quirks()
435 link->flags |= ATA_LFLAG_NO_SRST | in sata_pmp_quirks()
445 * occupied by a pseudo configuration device in sata_pmp_quirks()
448 ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY; in sata_pmp_quirks()
458 link->flags |= ATA_LFLAG_NO_LPM | in sata_pmp_quirks()
466 if (link->pmp == 4) in sata_pmp_quirks()
467 link->flags |= ATA_LFLAG_DISABLED; in sata_pmp_quirks()
473 * sata_pmp_attach - attach a SATA PMP device
483 * 0 on success, -errno on failure.
487 struct ata_link *link = dev->link; in sata_pmp_attach()
488 struct ata_port *ap = link->ap; in sata_pmp_attach()
496 return -EINVAL; in sata_pmp_attach()
501 return -EINVAL; in sata_pmp_attach()
504 if (dev->devno) { in sata_pmp_attach()
506 return -EINVAL; in sata_pmp_attach()
509 WARN_ON(link->pmp != 0); in sata_pmp_attach()
510 link->pmp = SATA_PMP_CTRL_PORT; in sata_pmp_attach()
513 rc = sata_pmp_read_gscr(dev, dev->gscr); in sata_pmp_attach()
522 rc = sata_pmp_init_links(ap, sata_pmp_gscr_ports(dev->gscr)); in sata_pmp_attach()
529 spin_lock_irqsave(ap->lock, flags); in sata_pmp_attach()
530 WARN_ON(ap->nr_pmp_links); in sata_pmp_attach()
531 ap->nr_pmp_links = sata_pmp_gscr_ports(dev->gscr); in sata_pmp_attach()
532 spin_unlock_irqrestore(ap->lock, flags); in sata_pmp_attach()
536 if (ap->ops->pmp_attach) in sata_pmp_attach()
537 ap->ops->pmp_attach(ap); in sata_pmp_attach()
545 link->pmp = 0; in sata_pmp_attach()
550 * sata_pmp_detach - detach a SATA PMP device
561 struct ata_link *link = dev->link; in sata_pmp_detach()
562 struct ata_port *ap = link->ap; in sata_pmp_detach()
568 WARN_ON(!ata_is_host_link(link) || dev->devno || in sata_pmp_detach()
569 link->pmp != SATA_PMP_CTRL_PORT); in sata_pmp_detach()
571 if (ap->ops->pmp_detach) in sata_pmp_detach()
572 ap->ops->pmp_detach(ap); in sata_pmp_detach()
575 ata_eh_detach_dev(tlink->device); in sata_pmp_detach()
577 spin_lock_irqsave(ap->lock, flags); in sata_pmp_detach()
578 ap->nr_pmp_links = 0; in sata_pmp_detach()
579 link->pmp = 0; in sata_pmp_detach()
580 spin_unlock_irqrestore(ap->lock, flags); in sata_pmp_detach()
584 * sata_pmp_same_pmp - does new GSCR matches the configured PMP?
599 const u32 *old_gscr = dev->gscr; in sata_pmp_same_pmp()
635 * sata_pmp_revalidate - revalidate SATA PMP
639 * Re-read GSCR block and make sure @dev is still attached to the
646 * 0 on success, -errno otherwise.
650 struct ata_link *link = dev->link; in sata_pmp_revalidate()
651 u32 *gscr = (void *)dev->sector_buf; in sata_pmp_revalidate()
657 rc = -ENODEV; in sata_pmp_revalidate()
663 rc = -ENODEV; in sata_pmp_revalidate()
674 rc = -ENODEV; in sata_pmp_revalidate()
678 memcpy(dev->gscr, gscr, sizeof(gscr[0]) * SATA_PMP_GSCR_DWORDS); in sata_pmp_revalidate()
694 * sata_pmp_revalidate_quick - revalidate SATA PMP quickly
703 * 0 on success, -errno otherwise.
710 err_mask = sata_pmp_read(dev->link, SATA_PMP_GSCR_PROD_ID, &prod_id); in sata_pmp_revalidate_quick()
715 return -EIO; in sata_pmp_revalidate_quick()
718 if (prod_id != dev->gscr[SATA_PMP_GSCR_PROD_ID]) { in sata_pmp_revalidate_quick()
721 return -EIO; in sata_pmp_revalidate_quick()
728 * sata_pmp_eh_recover_pmp - recover PMP
734 * always be performed in hard->soft sequence and recovery
741 * 0 on success, -errno on failure.
746 struct ata_link *link = &ap->link; in sata_pmp_eh_recover_pmp()
747 struct ata_eh_context *ehc = &link->eh_context; in sata_pmp_eh_recover_pmp()
748 struct ata_device *dev = link->device; in sata_pmp_eh_recover_pmp()
753 if (dev->flags & ATA_DFLAG_DETACH) { in sata_pmp_eh_recover_pmp()
755 rc = -ENODEV; in sata_pmp_eh_recover_pmp()
760 ehc->classes[0] = ATA_DEV_UNKNOWN; in sata_pmp_eh_recover_pmp()
762 if (ehc->i.action & ATA_EH_RESET) { in sata_pmp_eh_recover_pmp()
774 struct ata_eh_context *ehc = &tlink->eh_context; in sata_pmp_eh_recover_pmp()
776 ehc->i.probe_mask |= ATA_ALL_DEVICES; in sata_pmp_eh_recover_pmp()
777 ehc->i.action |= ATA_EH_RESET; in sata_pmp_eh_recover_pmp()
784 if (ehc->i.action & ATA_EH_REVALIDATE) in sata_pmp_eh_recover_pmp()
785 rc = sata_pmp_revalidate(dev, ehc->classes[0]); in sata_pmp_eh_recover_pmp()
790 tries--; in sata_pmp_eh_recover_pmp()
792 if (rc == -ENODEV) { in sata_pmp_eh_recover_pmp()
793 ehc->i.probe_mask |= ATA_ALL_DEVICES; in sata_pmp_eh_recover_pmp()
806 ehc->i.action |= ATA_EH_RESET; in sata_pmp_eh_recover_pmp()
817 ehc->i.flags = 0; in sata_pmp_eh_recover_pmp()
837 spin_lock_irqsave(ap->lock, flags); in sata_pmp_eh_handle_disabled_links()
840 if (!(link->flags & ATA_LFLAG_DISABLED)) in sata_pmp_eh_handle_disabled_links()
843 spin_unlock_irqrestore(ap->lock, flags); in sata_pmp_eh_handle_disabled_links()
861 spin_lock_irqsave(ap->lock, flags); in sata_pmp_eh_handle_disabled_links()
864 spin_unlock_irqrestore(ap->lock, flags); in sata_pmp_eh_handle_disabled_links()
871 struct ata_port *ap = link->ap; in sata_pmp_handle_link_fail()
874 if (link_tries[link->pmp] && --link_tries[link->pmp]) in sata_pmp_handle_link_fail()
878 if (!(link->flags & ATA_LFLAG_DISABLED)) { in sata_pmp_handle_link_fail()
883 spin_lock_irqsave(ap->lock, flags); in sata_pmp_handle_link_fail()
884 link->flags |= ATA_LFLAG_DISABLED; in sata_pmp_handle_link_fail()
885 spin_unlock_irqrestore(ap->lock, flags); in sata_pmp_handle_link_fail()
888 ata_dev_disable(link->device); in sata_pmp_handle_link_fail()
889 link->eh_context.i.action = 0; in sata_pmp_handle_link_fail()
895 * sata_pmp_eh_recover - recover PMP-enabled port
907 * 0 on success, -errno on failure.
911 struct ata_port_operations *ops = ap->ops; in sata_pmp_eh_recover()
913 struct ata_link *pmp_link = &ap->link; in sata_pmp_eh_recover()
914 struct ata_device *pmp_dev = pmp_link->device; in sata_pmp_eh_recover()
915 struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; in sata_pmp_eh_recover()
916 u32 *gscr = pmp_dev->gscr; in sata_pmp_eh_recover()
925 link_tries[link->pmp] = ATA_EH_PMP_LINK_TRIES; in sata_pmp_eh_recover()
930 rc = ata_eh_recover(ap, &ops->reset, NULL); in sata_pmp_eh_recover()
932 ata_for_each_dev(dev, &ap->link, ALL) in sata_pmp_eh_recover()
937 if (pmp_dev->class != ATA_DEV_PMP) in sata_pmp_eh_recover()
942 link_tries[link->pmp] = ATA_EH_PMP_LINK_TRIES; in sata_pmp_eh_recover()
948 rc = sata_pmp_eh_recover_pmp(ap, &ops->reset); in sata_pmp_eh_recover()
974 rc = ata_eh_recover(ap, &ops->pmp_reset, &link); in sata_pmp_eh_recover()
979 rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf); in sata_pmp_eh_recover()
981 sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf); in sata_pmp_eh_recover()
984 * If LPM is active on any fan-out port, hotplug wouldn't in sata_pmp_eh_recover()
988 if (link->lpm_policy > ATA_LPM_MAX_POWER) in sata_pmp_eh_recover()
998 if (pmp_dev->flags & ATA_DFLAG_AN) { in sata_pmp_eh_recover()
1007 rc = -EIO; in sata_pmp_eh_recover()
1018 rc = -EIO; in sata_pmp_eh_recover()
1024 if (!(gscr_error & (1 << link->pmp))) in sata_pmp_eh_recover()
1028 ata_ehi_hotplugged(&link->eh_context.i); in sata_pmp_eh_recover()
1048 pmp_ehc->i.action |= ATA_EH_RESET; in sata_pmp_eh_recover()
1057 if (ap->pflags & ATA_PFLAG_UNLOADING) in sata_pmp_eh_recover()
1063 if (--pmp_tries) { in sata_pmp_eh_recover()
1064 pmp_ehc->i.action |= ATA_EH_RESET; in sata_pmp_eh_recover()
1077 * sata_pmp_error_handler - do standard error handling for PMP-enabled host
1080 * Perform standard error handling sequence for PMP-enabled host