.. | .. |
---|
| 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)" }, |
---|
.. | .. |
---|
2921 | 2703 | postreset(slave, classes); |
---|
2922 | 2704 | } |
---|
2923 | 2705 | |
---|
2924 | | - /* |
---|
2925 | | - * Some controllers can't be frozen very well and may set spurious |
---|
2926 | | - * error conditions during reset. Clear accumulated error |
---|
2927 | | - * information and re-thaw the port if frozen. As reset is the |
---|
2928 | | - * final recovery action and we cross check link onlineness against |
---|
2929 | | - * device classification later, no hotplug event is lost by this. |
---|
2930 | | - */ |
---|
| 2706 | + /* clear cached SError */ |
---|
2931 | 2707 | spin_lock_irqsave(link->ap->lock, flags); |
---|
2932 | | - memset(&link->eh_info, 0, sizeof(link->eh_info)); |
---|
| 2708 | + link->eh_info.serror = 0; |
---|
2933 | 2709 | if (slave) |
---|
2934 | | - memset(&slave->eh_info, 0, sizeof(link->eh_info)); |
---|
2935 | | - ap->pflags &= ~ATA_PFLAG_EH_PENDING; |
---|
| 2710 | + slave->eh_info.serror = 0; |
---|
2936 | 2711 | spin_unlock_irqrestore(link->ap->lock, flags); |
---|
2937 | 2712 | |
---|
2938 | 2713 | if (ap->pflags & ATA_PFLAG_FROZEN) |
---|
.. | .. |
---|
3465 | 3240 | int rc; |
---|
3466 | 3241 | |
---|
3467 | 3242 | /* if the link or host doesn't do LPM, noop */ |
---|
3468 | | - if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) |
---|
| 3243 | + if (!IS_ENABLED(CONFIG_SATA_HOST) || |
---|
| 3244 | + (link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) |
---|
3469 | 3245 | return 0; |
---|
3470 | 3246 | |
---|
3471 | 3247 | /* |
---|
.. | .. |
---|
3699 | 3475 | case -ENODEV: |
---|
3700 | 3476 | /* device missing or wrong IDENTIFY data, schedule probing */ |
---|
3701 | 3477 | ehc->i.probe_mask |= (1 << dev->devno); |
---|
3702 | | - /* fall through */ |
---|
| 3478 | + fallthrough; |
---|
3703 | 3479 | case -EINVAL: |
---|
3704 | 3480 | /* give it just one more chance */ |
---|
3705 | 3481 | ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); |
---|
3706 | | - /* fall through */ |
---|
| 3482 | + fallthrough; |
---|
3707 | 3483 | case -EIO: |
---|
3708 | 3484 | if (ehc->tries[dev->devno] == 1) { |
---|
3709 | 3485 | /* This is the last chance, better to slow |
---|
.. | .. |
---|
4081 | 3857 | |
---|
4082 | 3858 | ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset); |
---|
4083 | 3859 | } |
---|
| 3860 | +EXPORT_SYMBOL_GPL(ata_std_error_handler); |
---|
4084 | 3861 | |
---|
4085 | 3862 | #ifdef CONFIG_PM |
---|
4086 | 3863 | /** |
---|