| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * libata-eh.c - libata error handling |
|---|
| 3 | 4 | * |
|---|
| 4 | | - * Maintained by: Tejun Heo <tj@kernel.org> |
|---|
| 5 | | - * Please ALWAYS copy linux-ide@vger.kernel.org |
|---|
| 6 | | - * on emails. |
|---|
| 7 | | - * |
|---|
| 8 | 5 | * Copyright 2006 Tejun Heo <htejun@gmail.com> |
|---|
| 9 | | - * |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or |
|---|
| 12 | | - * modify it under the terms of the GNU General Public License as |
|---|
| 13 | | - * published by the Free Software Foundation; either version 2, or |
|---|
| 14 | | - * (at your option) any later version. |
|---|
| 15 | | - * |
|---|
| 16 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 17 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 18 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 19 | | - * General Public License for more details. |
|---|
| 20 | | - * |
|---|
| 21 | | - * You should have received a copy of the GNU General Public License |
|---|
| 22 | | - * along with this program; see the file COPYING. If not, write to |
|---|
| 23 | | - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, |
|---|
| 24 | | - * USA. |
|---|
| 25 | | - * |
|---|
| 26 | 6 | * |
|---|
| 27 | 7 | * libata documentation is available via 'make {ps|pdf}docs', |
|---|
| 28 | 8 | * as Documentation/driver-api/libata.rst |
|---|
| 29 | 9 | * |
|---|
| 30 | 10 | * Hardware documentation available from http://www.t13.org/ and |
|---|
| 31 | 11 | * http://www.sata-io.org/ |
|---|
| 32 | | - * |
|---|
| 33 | 12 | */ |
|---|
| 34 | 13 | |
|---|
| 35 | 14 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 209 | 188 | __ata_ehi_pushv_desc(ehi, fmt, args); |
|---|
| 210 | 189 | va_end(args); |
|---|
| 211 | 190 | } |
|---|
| 191 | +EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); |
|---|
| 212 | 192 | |
|---|
| 213 | 193 | /** |
|---|
| 214 | 194 | * ata_ehi_push_desc - push error description with separator |
|---|
| .. | .. |
|---|
| 232 | 212 | __ata_ehi_pushv_desc(ehi, fmt, args); |
|---|
| 233 | 213 | va_end(args); |
|---|
| 234 | 214 | } |
|---|
| 215 | +EXPORT_SYMBOL_GPL(ata_ehi_push_desc); |
|---|
| 235 | 216 | |
|---|
| 236 | 217 | /** |
|---|
| 237 | 218 | * ata_ehi_clear_desc - clean error description |
|---|
| .. | .. |
|---|
| 247 | 228 | ehi->desc[0] = '\0'; |
|---|
| 248 | 229 | ehi->desc_len = 0; |
|---|
| 249 | 230 | } |
|---|
| 231 | +EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); |
|---|
| 250 | 232 | |
|---|
| 251 | 233 | /** |
|---|
| 252 | 234 | * ata_port_desc - append port description |
|---|
| .. | .. |
|---|
| 274 | 256 | __ata_ehi_pushv_desc(&ap->link.eh_info, fmt, args); |
|---|
| 275 | 257 | va_end(args); |
|---|
| 276 | 258 | } |
|---|
| 259 | +EXPORT_SYMBOL_GPL(ata_port_desc); |
|---|
| 277 | 260 | |
|---|
| 278 | 261 | #ifdef CONFIG_PCI |
|---|
| 279 | | - |
|---|
| 280 | 262 | /** |
|---|
| 281 | 263 | * ata_port_pbar_desc - append PCI BAR description |
|---|
| 282 | 264 | * @ap: target ATA port |
|---|
| .. | .. |
|---|
| 313 | 295 | ata_port_desc(ap, "%s 0x%llx", name, |
|---|
| 314 | 296 | start + (unsigned long long)offset); |
|---|
| 315 | 297 | } |
|---|
| 316 | | - |
|---|
| 298 | +EXPORT_SYMBOL_GPL(ata_port_pbar_desc); |
|---|
| 317 | 299 | #endif /* CONFIG_PCI */ |
|---|
| 318 | 300 | |
|---|
| 319 | 301 | static int ata_lookup_timeout_table(u8 cmd) |
|---|
| .. | .. |
|---|
| 927 | 909 | void ata_qc_schedule_eh(struct ata_queued_cmd *qc) |
|---|
| 928 | 910 | { |
|---|
| 929 | 911 | struct ata_port *ap = qc->ap; |
|---|
| 930 | | - struct request_queue *q = qc->scsicmd->device->request_queue; |
|---|
| 931 | | - unsigned long flags; |
|---|
| 932 | 912 | |
|---|
| 933 | 913 | WARN_ON(!ap->ops->error_handler); |
|---|
| 934 | 914 | |
|---|
| .. | .. |
|---|
| 940 | 920 | * Note that ATA_QCFLAG_FAILED is unconditionally set after |
|---|
| 941 | 921 | * this function completes. |
|---|
| 942 | 922 | */ |
|---|
| 943 | | - spin_lock_irqsave(q->queue_lock, flags); |
|---|
| 944 | 923 | blk_abort_request(qc->scsicmd->request); |
|---|
| 945 | | - spin_unlock_irqrestore(q->queue_lock, flags); |
|---|
| 946 | 924 | } |
|---|
| 947 | 925 | |
|---|
| 948 | 926 | /** |
|---|
| .. | .. |
|---|
| 1002 | 980 | /* see: ata_std_sched_eh, unless you know better */ |
|---|
| 1003 | 981 | ap->ops->sched_eh(ap); |
|---|
| 1004 | 982 | } |
|---|
| 983 | +EXPORT_SYMBOL_GPL(ata_port_schedule_eh); |
|---|
| 1005 | 984 | |
|---|
| 1006 | 985 | static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link) |
|---|
| 1007 | 986 | { |
|---|
| .. | .. |
|---|
| 1044 | 1023 | { |
|---|
| 1045 | 1024 | return ata_do_link_abort(link->ap, link); |
|---|
| 1046 | 1025 | } |
|---|
| 1026 | +EXPORT_SYMBOL_GPL(ata_link_abort); |
|---|
| 1047 | 1027 | |
|---|
| 1048 | 1028 | /** |
|---|
| 1049 | 1029 | * ata_port_abort - abort all qc's on the port |
|---|
| .. | .. |
|---|
| 1061 | 1041 | { |
|---|
| 1062 | 1042 | return ata_do_link_abort(ap, NULL); |
|---|
| 1063 | 1043 | } |
|---|
| 1044 | +EXPORT_SYMBOL_GPL(ata_port_abort); |
|---|
| 1064 | 1045 | |
|---|
| 1065 | 1046 | /** |
|---|
| 1066 | 1047 | * __ata_port_freeze - freeze port |
|---|
| .. | .. |
|---|
| 1117 | 1098 | |
|---|
| 1118 | 1099 | return nr_aborted; |
|---|
| 1119 | 1100 | } |
|---|
| 1120 | | - |
|---|
| 1121 | | -/** |
|---|
| 1122 | | - * sata_async_notification - SATA async notification handler |
|---|
| 1123 | | - * @ap: ATA port where async notification is received |
|---|
| 1124 | | - * |
|---|
| 1125 | | - * Handler to be called when async notification via SDB FIS is |
|---|
| 1126 | | - * received. This function schedules EH if necessary. |
|---|
| 1127 | | - * |
|---|
| 1128 | | - * LOCKING: |
|---|
| 1129 | | - * spin_lock_irqsave(host lock) |
|---|
| 1130 | | - * |
|---|
| 1131 | | - * RETURNS: |
|---|
| 1132 | | - * 1 if EH is scheduled, 0 otherwise. |
|---|
| 1133 | | - */ |
|---|
| 1134 | | -int sata_async_notification(struct ata_port *ap) |
|---|
| 1135 | | -{ |
|---|
| 1136 | | - u32 sntf; |
|---|
| 1137 | | - int rc; |
|---|
| 1138 | | - |
|---|
| 1139 | | - if (!(ap->flags & ATA_FLAG_AN)) |
|---|
| 1140 | | - return 0; |
|---|
| 1141 | | - |
|---|
| 1142 | | - rc = sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf); |
|---|
| 1143 | | - if (rc == 0) |
|---|
| 1144 | | - sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf); |
|---|
| 1145 | | - |
|---|
| 1146 | | - if (!sata_pmp_attached(ap) || rc) { |
|---|
| 1147 | | - /* PMP is not attached or SNTF is not available */ |
|---|
| 1148 | | - if (!sata_pmp_attached(ap)) { |
|---|
| 1149 | | - /* PMP is not attached. Check whether ATAPI |
|---|
| 1150 | | - * AN is configured. If so, notify media |
|---|
| 1151 | | - * change. |
|---|
| 1152 | | - */ |
|---|
| 1153 | | - struct ata_device *dev = ap->link.device; |
|---|
| 1154 | | - |
|---|
| 1155 | | - if ((dev->class == ATA_DEV_ATAPI) && |
|---|
| 1156 | | - (dev->flags & ATA_DFLAG_AN)) |
|---|
| 1157 | | - ata_scsi_media_change_notify(dev); |
|---|
| 1158 | | - return 0; |
|---|
| 1159 | | - } else { |
|---|
| 1160 | | - /* PMP is attached but SNTF is not available. |
|---|
| 1161 | | - * ATAPI async media change notification is |
|---|
| 1162 | | - * not used. The PMP must be reporting PHY |
|---|
| 1163 | | - * status change, schedule EH. |
|---|
| 1164 | | - */ |
|---|
| 1165 | | - ata_port_schedule_eh(ap); |
|---|
| 1166 | | - return 1; |
|---|
| 1167 | | - } |
|---|
| 1168 | | - } else { |
|---|
| 1169 | | - /* PMP is attached and SNTF is available */ |
|---|
| 1170 | | - struct ata_link *link; |
|---|
| 1171 | | - |
|---|
| 1172 | | - /* check and notify ATAPI AN */ |
|---|
| 1173 | | - ata_for_each_link(link, ap, EDGE) { |
|---|
| 1174 | | - if (!(sntf & (1 << link->pmp))) |
|---|
| 1175 | | - continue; |
|---|
| 1176 | | - |
|---|
| 1177 | | - if ((link->device->class == ATA_DEV_ATAPI) && |
|---|
| 1178 | | - (link->device->flags & ATA_DFLAG_AN)) |
|---|
| 1179 | | - ata_scsi_media_change_notify(link->device); |
|---|
| 1180 | | - } |
|---|
| 1181 | | - |
|---|
| 1182 | | - /* If PMP is reporting that PHY status of some |
|---|
| 1183 | | - * downstream ports has changed, schedule EH. |
|---|
| 1184 | | - */ |
|---|
| 1185 | | - if (sntf & (1 << SATA_PMP_CTRL_PORT)) { |
|---|
| 1186 | | - ata_port_schedule_eh(ap); |
|---|
| 1187 | | - return 1; |
|---|
| 1188 | | - } |
|---|
| 1189 | | - |
|---|
| 1190 | | - return 0; |
|---|
| 1191 | | - } |
|---|
| 1192 | | -} |
|---|
| 1101 | +EXPORT_SYMBOL_GPL(ata_port_freeze); |
|---|
| 1193 | 1102 | |
|---|
| 1194 | 1103 | /** |
|---|
| 1195 | 1104 | * ata_eh_freeze_port - EH helper to freeze port |
|---|
| .. | .. |
|---|
| 1211 | 1120 | __ata_port_freeze(ap); |
|---|
| 1212 | 1121 | spin_unlock_irqrestore(ap->lock, flags); |
|---|
| 1213 | 1122 | } |
|---|
| 1123 | +EXPORT_SYMBOL_GPL(ata_eh_freeze_port); |
|---|
| 1214 | 1124 | |
|---|
| 1215 | 1125 | /** |
|---|
| 1216 | | - * ata_port_thaw_port - EH helper to thaw port |
|---|
| 1126 | + * ata_eh_thaw_port - EH helper to thaw port |
|---|
| 1217 | 1127 | * @ap: ATA port to thaw |
|---|
| 1218 | 1128 | * |
|---|
| 1219 | 1129 | * Thaw frozen port @ap. |
|---|
| .. | .. |
|---|
| 1318 | 1228 | */ |
|---|
| 1319 | 1229 | ata_ering_clear(&dev->ering); |
|---|
| 1320 | 1230 | } |
|---|
| 1231 | +EXPORT_SYMBOL_GPL(ata_dev_disable); |
|---|
| 1321 | 1232 | |
|---|
| 1322 | 1233 | /** |
|---|
| 1323 | 1234 | * ata_eh_detach_dev - detach ATA device |
|---|
| .. | .. |
|---|
| 1446 | 1357 | if (err_mask & AC_ERR_NODEV_HINT) |
|---|
| 1447 | 1358 | return "Polling detection error"; |
|---|
| 1448 | 1359 | return "unknown error"; |
|---|
| 1449 | | -} |
|---|
| 1450 | | - |
|---|
| 1451 | | -/** |
|---|
| 1452 | | - * ata_eh_read_log_10h - Read log page 10h for NCQ error details |
|---|
| 1453 | | - * @dev: Device to read log page 10h from |
|---|
| 1454 | | - * @tag: Resulting tag of the failed command |
|---|
| 1455 | | - * @tf: Resulting taskfile registers of the failed command |
|---|
| 1456 | | - * |
|---|
| 1457 | | - * Read log page 10h to obtain NCQ error details and clear error |
|---|
| 1458 | | - * condition. |
|---|
| 1459 | | - * |
|---|
| 1460 | | - * LOCKING: |
|---|
| 1461 | | - * Kernel thread context (may sleep). |
|---|
| 1462 | | - * |
|---|
| 1463 | | - * RETURNS: |
|---|
| 1464 | | - * 0 on success, -errno otherwise. |
|---|
| 1465 | | - */ |
|---|
| 1466 | | -static int ata_eh_read_log_10h(struct ata_device *dev, |
|---|
| 1467 | | - int *tag, struct ata_taskfile *tf) |
|---|
| 1468 | | -{ |
|---|
| 1469 | | - u8 *buf = dev->link->ap->sector_buf; |
|---|
| 1470 | | - unsigned int err_mask; |
|---|
| 1471 | | - u8 csum; |
|---|
| 1472 | | - int i; |
|---|
| 1473 | | - |
|---|
| 1474 | | - err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1); |
|---|
| 1475 | | - if (err_mask) |
|---|
| 1476 | | - return -EIO; |
|---|
| 1477 | | - |
|---|
| 1478 | | - csum = 0; |
|---|
| 1479 | | - for (i = 0; i < ATA_SECT_SIZE; i++) |
|---|
| 1480 | | - csum += buf[i]; |
|---|
| 1481 | | - if (csum) |
|---|
| 1482 | | - ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n", |
|---|
| 1483 | | - csum); |
|---|
| 1484 | | - |
|---|
| 1485 | | - if (buf[0] & 0x80) |
|---|
| 1486 | | - return -ENOENT; |
|---|
| 1487 | | - |
|---|
| 1488 | | - *tag = buf[0] & 0x1f; |
|---|
| 1489 | | - |
|---|
| 1490 | | - tf->command = buf[2]; |
|---|
| 1491 | | - tf->feature = buf[3]; |
|---|
| 1492 | | - tf->lbal = buf[4]; |
|---|
| 1493 | | - tf->lbam = buf[5]; |
|---|
| 1494 | | - tf->lbah = buf[6]; |
|---|
| 1495 | | - tf->device = buf[7]; |
|---|
| 1496 | | - tf->hob_lbal = buf[8]; |
|---|
| 1497 | | - tf->hob_lbam = buf[9]; |
|---|
| 1498 | | - tf->hob_lbah = buf[10]; |
|---|
| 1499 | | - tf->nsect = buf[12]; |
|---|
| 1500 | | - tf->hob_nsect = buf[13]; |
|---|
| 1501 | | - if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id)) |
|---|
| 1502 | | - tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16]; |
|---|
| 1503 | | - |
|---|
| 1504 | | - return 0; |
|---|
| 1505 | 1360 | } |
|---|
| 1506 | 1361 | |
|---|
| 1507 | 1362 | /** |
|---|
| .. | .. |
|---|
| 1688 | 1543 | } |
|---|
| 1689 | 1544 | |
|---|
| 1690 | 1545 | /** |
|---|
| 1691 | | - * ata_eh_analyze_ncq_error - analyze NCQ error |
|---|
| 1692 | | - * @link: ATA link to analyze NCQ error for |
|---|
| 1693 | | - * |
|---|
| 1694 | | - * Read log page 10h, determine the offending qc and acquire |
|---|
| 1695 | | - * error status TF. For NCQ device errors, all LLDDs have to do |
|---|
| 1696 | | - * is setting AC_ERR_DEV in ehi->err_mask. This function takes |
|---|
| 1697 | | - * care of the rest. |
|---|
| 1698 | | - * |
|---|
| 1699 | | - * LOCKING: |
|---|
| 1700 | | - * Kernel thread context (may sleep). |
|---|
| 1701 | | - */ |
|---|
| 1702 | | -void ata_eh_analyze_ncq_error(struct ata_link *link) |
|---|
| 1703 | | -{ |
|---|
| 1704 | | - struct ata_port *ap = link->ap; |
|---|
| 1705 | | - struct ata_eh_context *ehc = &link->eh_context; |
|---|
| 1706 | | - struct ata_device *dev = link->device; |
|---|
| 1707 | | - struct ata_queued_cmd *qc; |
|---|
| 1708 | | - struct ata_taskfile tf; |
|---|
| 1709 | | - int tag, rc; |
|---|
| 1710 | | - |
|---|
| 1711 | | - /* if frozen, we can't do much */ |
|---|
| 1712 | | - if (ap->pflags & ATA_PFLAG_FROZEN) |
|---|
| 1713 | | - return; |
|---|
| 1714 | | - |
|---|
| 1715 | | - /* is it NCQ device error? */ |
|---|
| 1716 | | - if (!link->sactive || !(ehc->i.err_mask & AC_ERR_DEV)) |
|---|
| 1717 | | - return; |
|---|
| 1718 | | - |
|---|
| 1719 | | - /* has LLDD analyzed already? */ |
|---|
| 1720 | | - ata_qc_for_each_raw(ap, qc, tag) { |
|---|
| 1721 | | - if (!(qc->flags & ATA_QCFLAG_FAILED)) |
|---|
| 1722 | | - continue; |
|---|
| 1723 | | - |
|---|
| 1724 | | - if (qc->err_mask) |
|---|
| 1725 | | - return; |
|---|
| 1726 | | - } |
|---|
| 1727 | | - |
|---|
| 1728 | | - /* okay, this error is ours */ |
|---|
| 1729 | | - memset(&tf, 0, sizeof(tf)); |
|---|
| 1730 | | - rc = ata_eh_read_log_10h(dev, &tag, &tf); |
|---|
| 1731 | | - if (rc) { |
|---|
| 1732 | | - ata_link_err(link, "failed to read log page 10h (errno=%d)\n", |
|---|
| 1733 | | - rc); |
|---|
| 1734 | | - return; |
|---|
| 1735 | | - } |
|---|
| 1736 | | - |
|---|
| 1737 | | - if (!(link->sactive & (1 << tag))) { |
|---|
| 1738 | | - ata_link_err(link, "log page 10h reported inactive tag %d\n", |
|---|
| 1739 | | - tag); |
|---|
| 1740 | | - return; |
|---|
| 1741 | | - } |
|---|
| 1742 | | - |
|---|
| 1743 | | - /* we've got the perpetrator, condemn it */ |
|---|
| 1744 | | - qc = __ata_qc_from_tag(ap, tag); |
|---|
| 1745 | | - memcpy(&qc->result_tf, &tf, sizeof(tf)); |
|---|
| 1746 | | - qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; |
|---|
| 1747 | | - qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; |
|---|
| 1748 | | - if (dev->class == ATA_DEV_ZAC && |
|---|
| 1749 | | - ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) { |
|---|
| 1750 | | - char sense_key, asc, ascq; |
|---|
| 1751 | | - |
|---|
| 1752 | | - sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; |
|---|
| 1753 | | - asc = (qc->result_tf.auxiliary >> 8) & 0xff; |
|---|
| 1754 | | - ascq = qc->result_tf.auxiliary & 0xff; |
|---|
| 1755 | | - ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq); |
|---|
| 1756 | | - ata_scsi_set_sense_information(dev, qc->scsicmd, |
|---|
| 1757 | | - &qc->result_tf); |
|---|
| 1758 | | - qc->flags |= ATA_QCFLAG_SENSE_VALID; |
|---|
| 1759 | | - } |
|---|
| 1760 | | - |
|---|
| 1761 | | - ehc->i.err_mask &= ~AC_ERR_DEV; |
|---|
| 1762 | | -} |
|---|
| 1763 | | - |
|---|
| 1764 | | -/** |
|---|
| 1765 | 1546 | * ata_eh_analyze_tf - analyze taskfile of a failed qc |
|---|
| 1766 | 1547 | * @qc: qc to analyze |
|---|
| 1767 | 1548 | * @tf: Taskfile registers to analyze |
|---|
| .. | .. |
|---|
| 1803 | 1584 | case ATA_DEV_ZAC: |
|---|
| 1804 | 1585 | if (stat & ATA_SENSE) |
|---|
| 1805 | 1586 | ata_eh_request_sense(qc, qc->scsicmd); |
|---|
| 1806 | | - /* fall through */ |
|---|
| 1587 | + fallthrough; |
|---|
| 1807 | 1588 | case ATA_DEV_ATA: |
|---|
| 1808 | 1589 | if (err & ATA_ICRC) |
|---|
| 1809 | 1590 | qc->err_mask |= AC_ERR_ATA_BUS; |
|---|
| .. | .. |
|---|
| 2350 | 2131 | { ATA_CMD_WRITE_QUEUED_FUA_EXT, "WRITE DMA QUEUED FUA EXT" }, |
|---|
| 2351 | 2132 | { ATA_CMD_FPDMA_READ, "READ FPDMA QUEUED" }, |
|---|
| 2352 | 2133 | { ATA_CMD_FPDMA_WRITE, "WRITE FPDMA QUEUED" }, |
|---|
| 2134 | + { ATA_CMD_NCQ_NON_DATA, "NCQ NON-DATA" }, |
|---|
| 2353 | 2135 | { ATA_CMD_FPDMA_SEND, "SEND FPDMA QUEUED" }, |
|---|
| 2354 | 2136 | { ATA_CMD_FPDMA_RECV, "RECEIVE FPDMA QUEUED" }, |
|---|
| 2355 | 2137 | { ATA_CMD_PIO_READ, "READ SECTOR(S)" }, |
|---|
| .. | .. |
|---|
| 3465 | 3247 | int rc; |
|---|
| 3466 | 3248 | |
|---|
| 3467 | 3249 | /* if the link or host doesn't do LPM, noop */ |
|---|
| 3468 | | - if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) |
|---|
| 3250 | + if (!IS_ENABLED(CONFIG_SATA_HOST) || |
|---|
| 3251 | + (link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) |
|---|
| 3469 | 3252 | return 0; |
|---|
| 3470 | 3253 | |
|---|
| 3471 | 3254 | /* |
|---|
| .. | .. |
|---|
| 3699 | 3482 | case -ENODEV: |
|---|
| 3700 | 3483 | /* device missing or wrong IDENTIFY data, schedule probing */ |
|---|
| 3701 | 3484 | ehc->i.probe_mask |= (1 << dev->devno); |
|---|
| 3702 | | - /* fall through */ |
|---|
| 3485 | + fallthrough; |
|---|
| 3703 | 3486 | case -EINVAL: |
|---|
| 3704 | 3487 | /* give it just one more chance */ |
|---|
| 3705 | 3488 | ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); |
|---|
| 3706 | | - /* fall through */ |
|---|
| 3489 | + fallthrough; |
|---|
| 3707 | 3490 | case -EIO: |
|---|
| 3708 | 3491 | if (ehc->tries[dev->devno] == 1) { |
|---|
| 3709 | 3492 | /* This is the last chance, better to slow |
|---|
| .. | .. |
|---|
| 4081 | 3864 | |
|---|
| 4082 | 3865 | ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); |
|---|
| 4083 | 3866 | } |
|---|
| 3867 | +EXPORT_SYMBOL_GPL(ata_std_error_handler); |
|---|
| 4084 | 3868 | |
|---|
| 4085 | 3869 | #ifdef CONFIG_PM |
|---|
| 4086 | 3870 | /** |
|---|