aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-09-23 00:19:54 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-12 14:55:44 -0400
commit7d50b60b5e38f910ad69f0187af00f5d6a8970d4 (patch)
tree627c57902e588ad6e7f51a2df9f2b8f091e014c0 /drivers/ata
parent238180343eff95697ed71eea137cf61ba3cea6ad (diff)
ahci: implement PMP support
Implement AHCI PMP support. ahci only supports command based switching. Also, for some reason, NCQ over PMP doesn't work now. Other than that, everything works. Tested on ICH9R, JMB360/363 + SIMG3726, 4726 and 5744. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Forrest Zhao <forrest.zhao@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci.c220
1 files changed, 174 insertions, 46 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index b615390b6b8..b697da483b7 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -46,7 +46,7 @@
46#include <linux/libata.h> 46#include <linux/libata.h>
47 47
48#define DRV_NAME "ahci" 48#define DRV_NAME "ahci"
49#define DRV_VERSION "2.3" 49#define DRV_VERSION "3.0"
50 50
51 51
52enum { 52enum {
@@ -96,6 +96,7 @@ enum {
96 96
97 /* HOST_CAP bits */ 97 /* HOST_CAP bits */
98 HOST_CAP_SSC = (1 << 14), /* Slumber capable */ 98 HOST_CAP_SSC = (1 << 14), /* Slumber capable */
99 HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */
99 HOST_CAP_CLO = (1 << 24), /* Command List Override support */ 100 HOST_CAP_CLO = (1 << 24), /* Command List Override support */
100 HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ 101 HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
101 HOST_CAP_SNTF = (1 << 29), /* SNotification register */ 102 HOST_CAP_SNTF = (1 << 29), /* SNotification register */
@@ -143,7 +144,8 @@ enum {
143 PORT_IRQ_IF_ERR | 144 PORT_IRQ_IF_ERR |
144 PORT_IRQ_CONNECT | 145 PORT_IRQ_CONNECT |
145 PORT_IRQ_PHYRDY | 146 PORT_IRQ_PHYRDY |
146 PORT_IRQ_UNK_FIS, 147 PORT_IRQ_UNK_FIS |
148 PORT_IRQ_BAD_PMP,
147 PORT_IRQ_ERROR = PORT_IRQ_FREEZE | 149 PORT_IRQ_ERROR = PORT_IRQ_FREEZE |
148 PORT_IRQ_TF_ERR | 150 PORT_IRQ_TF_ERR |
149 PORT_IRQ_HBUS_DATA_ERR, 151 PORT_IRQ_HBUS_DATA_ERR,
@@ -153,6 +155,7 @@ enum {
153 155
154 /* PORT_CMD bits */ 156 /* PORT_CMD bits */
155 PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ 157 PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */
158 PORT_CMD_PMP = (1 << 17), /* PMP attached */
156 PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ 159 PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */
157 PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ 160 PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */
158 PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ 161 PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */
@@ -204,6 +207,7 @@ struct ahci_host_priv {
204}; 207};
205 208
206struct ahci_port_priv { 209struct ahci_port_priv {
210 struct ata_link *active_link;
207 struct ahci_cmd_hdr *cmd_slot; 211 struct ahci_cmd_hdr *cmd_slot;
208 dma_addr_t cmd_slot_dma; 212 dma_addr_t cmd_slot_dma;
209 void *cmd_tbl; 213 void *cmd_tbl;
@@ -229,6 +233,10 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc);
229static u8 ahci_check_status(struct ata_port *ap); 233static u8 ahci_check_status(struct ata_port *ap);
230static void ahci_freeze(struct ata_port *ap); 234static void ahci_freeze(struct ata_port *ap);
231static void ahci_thaw(struct ata_port *ap); 235static void ahci_thaw(struct ata_port *ap);
236static void ahci_pmp_attach(struct ata_port *ap);
237static void ahci_pmp_detach(struct ata_port *ap);
238static int ahci_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val);
239static int ahci_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val);
232static void ahci_error_handler(struct ata_port *ap); 240static void ahci_error_handler(struct ata_port *ap);
233static void ahci_vt8251_error_handler(struct ata_port *ap); 241static void ahci_vt8251_error_handler(struct ata_port *ap);
234static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); 242static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
@@ -268,7 +276,7 @@ static const struct ata_port_operations ahci_ops = {
268 276
269 .tf_read = ahci_tf_read, 277 .tf_read = ahci_tf_read,
270 278
271 .qc_defer = ata_std_qc_defer, 279 .qc_defer = sata_pmp_qc_defer_cmd_switch,
272 .qc_prep = ahci_qc_prep, 280 .qc_prep = ahci_qc_prep,
273 .qc_issue = ahci_qc_issue, 281 .qc_issue = ahci_qc_issue,
274 282
@@ -283,6 +291,11 @@ static const struct ata_port_operations ahci_ops = {
283 .error_handler = ahci_error_handler, 291 .error_handler = ahci_error_handler,
284 .post_internal_cmd = ahci_post_internal_cmd, 292 .post_internal_cmd = ahci_post_internal_cmd,
285 293
294 .pmp_attach = ahci_pmp_attach,
295 .pmp_detach = ahci_pmp_detach,
296 .pmp_read = ahci_pmp_read,
297 .pmp_write = ahci_pmp_write,
298
286#ifdef CONFIG_PM 299#ifdef CONFIG_PM
287 .port_suspend = ahci_port_suspend, 300 .port_suspend = ahci_port_suspend,
288 .port_resume = ahci_port_resume, 301 .port_resume = ahci_port_resume,
@@ -299,7 +312,7 @@ static const struct ata_port_operations ahci_vt8251_ops = {
299 312
300 .tf_read = ahci_tf_read, 313 .tf_read = ahci_tf_read,
301 314
302 .qc_defer = ata_std_qc_defer, 315 .qc_defer = sata_pmp_qc_defer_cmd_switch,
303 .qc_prep = ahci_qc_prep, 316 .qc_prep = ahci_qc_prep,
304 .qc_issue = ahci_qc_issue, 317 .qc_issue = ahci_qc_issue,
305 318
@@ -314,6 +327,11 @@ static const struct ata_port_operations ahci_vt8251_ops = {
314 .error_handler = ahci_vt8251_error_handler, 327 .error_handler = ahci_vt8251_error_handler,
315 .post_internal_cmd = ahci_post_internal_cmd, 328 .post_internal_cmd = ahci_post_internal_cmd,
316 329
330 .pmp_attach = ahci_pmp_attach,
331 .pmp_detach = ahci_pmp_detach,
332 .pmp_read = ahci_pmp_read,
333 .pmp_write = ahci_pmp_write,
334
317#ifdef CONFIG_PM 335#ifdef CONFIG_PM
318 .port_suspend = ahci_port_suspend, 336 .port_suspend = ahci_port_suspend,
319 .port_resume = ahci_port_resume, 337 .port_resume = ahci_port_resume,
@@ -1114,7 +1132,12 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
1114static int ahci_softreset(struct ata_link *link, unsigned int *class, 1132static int ahci_softreset(struct ata_link *link, unsigned int *class,
1115 unsigned long deadline) 1133 unsigned long deadline)
1116{ 1134{
1117 return ahci_do_softreset(link, class, 0, deadline); 1135 int pmp = 0;
1136
1137 if (link->ap->flags & ATA_FLAG_PMP)
1138 pmp = SATA_PMP_CTRL_PORT;
1139
1140 return ahci_do_softreset(link, class, pmp, deadline);
1118} 1141}
1119 1142
1120static int ahci_hardreset(struct ata_link *link, unsigned int *class, 1143static int ahci_hardreset(struct ata_link *link, unsigned int *class,
@@ -1141,7 +1164,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
1141 1164
1142 if (rc == 0 && ata_link_online(link)) 1165 if (rc == 0 && ata_link_online(link))
1143 *class = ahci_dev_classify(ap); 1166 *class = ahci_dev_classify(ap);
1144 if (*class == ATA_DEV_UNKNOWN) 1167 if (rc != -EAGAIN && *class == ATA_DEV_UNKNOWN)
1145 *class = ATA_DEV_NONE; 1168 *class = ATA_DEV_NONE;
1146 1169
1147 DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); 1170 DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
@@ -1196,6 +1219,12 @@ static void ahci_postreset(struct ata_link *link, unsigned int *class)
1196 } 1219 }
1197} 1220}
1198 1221
1222static int ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
1223 unsigned long deadline)
1224{
1225 return ahci_do_softreset(link, class, link->pmp, deadline);
1226}
1227
1199static u8 ahci_check_status(struct ata_port *ap) 1228static u8 ahci_check_status(struct ata_port *ap)
1200{ 1229{
1201 void __iomem *mmio = ap->ioaddr.cmd_addr; 1230 void __iomem *mmio = ap->ioaddr.cmd_addr;
@@ -1254,7 +1283,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
1254 */ 1283 */
1255 cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; 1284 cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ;
1256 1285
1257 ata_tf_to_fis(&qc->tf, 0, 1, cmd_tbl); 1286 ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, cmd_tbl);
1258 if (is_atapi) { 1287 if (is_atapi) {
1259 memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); 1288 memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
1260 memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); 1289 memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len);
@@ -1267,7 +1296,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
1267 /* 1296 /*
1268 * Fill in command slot information. 1297 * Fill in command slot information.
1269 */ 1298 */
1270 opts = cmd_fis_len | n_elem << 16; 1299 opts = cmd_fis_len | n_elem << 16 | (qc->dev->link->pmp << 12);
1271 if (qc->tf.flags & ATA_TFLAG_WRITE) 1300 if (qc->tf.flags & ATA_TFLAG_WRITE)
1272 opts |= AHCI_CMD_WRITE; 1301 opts |= AHCI_CMD_WRITE;
1273 if (is_atapi) 1302 if (is_atapi)
@@ -1279,65 +1308,85 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
1279static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) 1308static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
1280{ 1309{
1281 struct ahci_port_priv *pp = ap->private_data; 1310 struct ahci_port_priv *pp = ap->private_data;
1282 struct ata_eh_info *ehi = &ap->link.eh_info; 1311 struct ata_eh_info *host_ehi = &ap->link.eh_info;
1283 unsigned int err_mask = 0, action = 0; 1312 struct ata_link *link = NULL;
1284 struct ata_queued_cmd *qc; 1313 struct ata_queued_cmd *active_qc;
1314 struct ata_eh_info *active_ehi;
1285 u32 serror; 1315 u32 serror;
1286 1316
1287 ata_ehi_clear_desc(ehi); 1317 /* determine active link */
1318 ata_port_for_each_link(link, ap)
1319 if (ata_link_active(link))
1320 break;
1321 if (!link)
1322 link = &ap->link;
1323
1324 active_qc = ata_qc_from_tag(ap, link->active_tag);
1325 active_ehi = &link->eh_info;
1326
1327 /* record irq stat */
1328 ata_ehi_clear_desc(host_ehi);
1329 ata_ehi_push_desc(host_ehi, "irq_stat 0x%08x", irq_stat);
1288 1330
1289 /* AHCI needs SError cleared; otherwise, it might lock up */ 1331 /* AHCI needs SError cleared; otherwise, it might lock up */
1290 ahci_scr_read(ap, SCR_ERROR, &serror); 1332 ahci_scr_read(ap, SCR_ERROR, &serror);
1291 ahci_scr_write(ap, SCR_ERROR, serror); 1333 ahci_scr_write(ap, SCR_ERROR, serror);
1292 1334 host_ehi->serror |= serror;
1293 /* analyze @irq_stat */
1294 ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat);
1295 1335
1296 /* some controllers set IRQ_IF_ERR on device errors, ignore it */ 1336 /* some controllers set IRQ_IF_ERR on device errors, ignore it */
1297 if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR) 1337 if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
1298 irq_stat &= ~PORT_IRQ_IF_ERR; 1338 irq_stat &= ~PORT_IRQ_IF_ERR;
1299 1339
1300 if (irq_stat & PORT_IRQ_TF_ERR) { 1340 if (irq_stat & PORT_IRQ_TF_ERR) {
1301 err_mask |= AC_ERR_DEV; 1341 /* If qc is active, charge it; otherwise, the active
1342 * link. There's no active qc on NCQ errors. It will
1343 * be determined by EH by reading log page 10h.
1344 */
1345 if (active_qc)
1346 active_qc->err_mask |= AC_ERR_DEV;
1347 else
1348 active_ehi->err_mask |= AC_ERR_DEV;
1349
1302 if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL) 1350 if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
1303 serror &= ~SERR_INTERNAL; 1351 host_ehi->serror &= ~SERR_INTERNAL;
1352 }
1353
1354 if (irq_stat & PORT_IRQ_UNK_FIS) {
1355 u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK);
1356
1357 active_ehi->err_mask |= AC_ERR_HSM;
1358 active_ehi->action |= ATA_EH_SOFTRESET;
1359 ata_ehi_push_desc(active_ehi,
1360 "unknown FIS %08x %08x %08x %08x" ,
1361 unk[0], unk[1], unk[2], unk[3]);
1362 }
1363
1364 if (ap->nr_pmp_links && (irq_stat & PORT_IRQ_BAD_PMP)) {
1365 active_ehi->err_mask |= AC_ERR_HSM;
1366 active_ehi->action |= ATA_EH_SOFTRESET;
1367 ata_ehi_push_desc(active_ehi, "incorrect PMP");
1304 } 1368 }
1305 1369
1306 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { 1370 if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
1307 err_mask |= AC_ERR_HOST_BUS; 1371 host_ehi->err_mask |= AC_ERR_HOST_BUS;
1308 action |= ATA_EH_SOFTRESET; 1372 host_ehi->action |= ATA_EH_SOFTRESET;
1373 ata_ehi_push_desc(host_ehi, "host bus error");
1309 } 1374 }
1310 1375
1311 if (irq_stat & PORT_IRQ_IF_ERR) { 1376 if (irq_stat & PORT_IRQ_IF_ERR) {
1312 err_mask |= AC_ERR_ATA_BUS; 1377 host_ehi->err_mask |= AC_ERR_ATA_BUS;
1313 action |= ATA_EH_SOFTRESET; 1378 host_ehi->action |= ATA_EH_SOFTRESET;
1314 ata_ehi_push_desc(ehi, "interface fatal error"); 1379 ata_ehi_push_desc(host_ehi, "interface fatal error");
1315 } 1380 }
1316 1381
1317 if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { 1382 if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) {
1318 ata_ehi_hotplugged(ehi); 1383 ata_ehi_hotplugged(host_ehi);
1319 ata_ehi_push_desc(ehi, "%s", irq_stat & PORT_IRQ_CONNECT ? 1384 ata_ehi_push_desc(host_ehi, "%s",
1385 irq_stat & PORT_IRQ_CONNECT ?
1320 "connection status changed" : "PHY RDY changed"); 1386 "connection status changed" : "PHY RDY changed");
1321 } 1387 }
1322 1388
1323 if (irq_stat & PORT_IRQ_UNK_FIS) {
1324 u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK);
1325
1326 err_mask |= AC_ERR_HSM;
1327 action |= ATA_EH_SOFTRESET;
1328 ata_ehi_push_desc(ehi, "unknown FIS %08x %08x %08x %08x",
1329 unk[0], unk[1], unk[2], unk[3]);
1330 }
1331
1332 /* okay, let's hand over to EH */ 1389 /* okay, let's hand over to EH */
1333 ehi->serror |= serror;
1334 ehi->action |= action;
1335
1336 qc = ata_qc_from_tag(ap, ap->link.active_tag);
1337 if (qc)
1338 qc->err_mask |= err_mask;
1339 else
1340 ehi->err_mask |= err_mask;
1341 1390
1342 if (irq_stat & PORT_IRQ_FREEZE) 1391 if (irq_stat & PORT_IRQ_FREEZE)
1343 ata_port_freeze(ap); 1392 ata_port_freeze(ap);
@@ -1375,7 +1424,8 @@ static void ahci_port_intr(struct ata_port *ap)
1375 sata_async_notification(ap); 1424 sata_async_notification(ap);
1376 } 1425 }
1377 1426
1378 if (ap->link.sactive) 1427 /* pp->active_link is valid iff any command is in flight */
1428 if (ap->qc_active && pp->active_link->sactive)
1379 qc_active = readl(port_mmio + PORT_SCR_ACT); 1429 qc_active = readl(port_mmio + PORT_SCR_ACT);
1380 else 1430 else
1381 qc_active = readl(port_mmio + PORT_CMD_ISSUE); 1431 qc_active = readl(port_mmio + PORT_CMD_ISSUE);
@@ -1513,6 +1563,13 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
1513{ 1563{
1514 struct ata_port *ap = qc->ap; 1564 struct ata_port *ap = qc->ap;
1515 void __iomem *port_mmio = ahci_port_base(ap); 1565 void __iomem *port_mmio = ahci_port_base(ap);
1566 struct ahci_port_priv *pp = ap->private_data;
1567
1568 /* Keep track of the currently active link. It will be used
1569 * in completion path to determine whether NCQ phase is in
1570 * progress.
1571 */
1572 pp->active_link = qc->dev->link;
1516 1573
1517 if (qc->tf.protocol == ATA_PROT_NCQ) 1574 if (qc->tf.protocol == ATA_PROT_NCQ)
1518 writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); 1575 writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
@@ -1542,8 +1599,11 @@ static void ahci_thaw(struct ata_port *ap)
1542 writel(tmp, port_mmio + PORT_IRQ_STAT); 1599 writel(tmp, port_mmio + PORT_IRQ_STAT);
1543 writel(1 << ap->port_no, mmio + HOST_IRQ_STAT); 1600 writel(1 << ap->port_no, mmio + HOST_IRQ_STAT);
1544 1601
1545 /* turn IRQ back on */ 1602 /* turn IRQ back on, ignore BAD_PMP if PMP isn't attached */
1546 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); 1603 tmp = pp->intr_mask;
1604 if (!ap->nr_pmp_links)
1605 tmp &= ~PORT_IRQ_BAD_PMP;
1606 writel(tmp, port_mmio + PORT_IRQ_MASK);
1547} 1607}
1548 1608
1549static void ahci_error_handler(struct ata_port *ap) 1609static void ahci_error_handler(struct ata_port *ap)
@@ -1555,8 +1615,10 @@ static void ahci_error_handler(struct ata_port *ap)
1555 } 1615 }
1556 1616
1557 /* perform recovery */ 1617 /* perform recovery */
1558 ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_hardreset, 1618 sata_pmp_do_eh(ap, ata_std_prereset, ahci_softreset,
1559 ahci_postreset); 1619 ahci_hardreset, ahci_postreset,
1620 sata_pmp_std_prereset, ahci_pmp_softreset,
1621 sata_pmp_std_hardreset, sata_pmp_std_postreset);
1560} 1622}
1561 1623
1562static void ahci_vt8251_error_handler(struct ata_port *ap) 1624static void ahci_vt8251_error_handler(struct ata_port *ap)
@@ -1581,11 +1643,74 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
1581 ahci_kick_engine(ap, 1); 1643 ahci_kick_engine(ap, 1);
1582} 1644}
1583 1645
1646static void ahci_pmp_attach(struct ata_port *ap)
1647{
1648 void __iomem *port_mmio = ahci_port_base(ap);
1649 u32 cmd;
1650
1651 cmd = readl(port_mmio + PORT_CMD);
1652 cmd |= PORT_CMD_PMP;
1653 writel(cmd, port_mmio + PORT_CMD);
1654}
1655
1656static void ahci_pmp_detach(struct ata_port *ap)
1657{
1658 void __iomem *port_mmio = ahci_port_base(ap);
1659 struct ahci_host_priv *hpriv = ap->host->private_data;
1660 unsigned long flags;
1661 u32 cmd;
1662
1663 cmd = readl(port_mmio + PORT_CMD);
1664 cmd &= ~PORT_CMD_PMP;
1665 writel(cmd, port_mmio + PORT_CMD);
1666
1667 if (hpriv->cap & HOST_CAP_NCQ) {
1668 spin_lock_irqsave(ap->lock, flags);
1669 ap->flags |= ATA_FLAG_NCQ;
1670 spin_unlock_irqrestore(ap->lock, flags);
1671 }
1672}
1673
1674static int ahci_pmp_read(struct ata_device *dev, int pmp, int reg, u32 *r_val)
1675{
1676 struct ata_port *ap = dev->link->ap;
1677 struct ata_taskfile tf;
1678 int rc;
1679
1680 ahci_kick_engine(ap, 0);
1681
1682 sata_pmp_read_init_tf(&tf, dev, pmp, reg);
1683 rc = ahci_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0,
1684 SATA_PMP_SCR_TIMEOUT);
1685 if (rc == 0) {
1686 ahci_tf_read(ap, &tf);
1687 *r_val = sata_pmp_read_val(&tf);
1688 }
1689 return rc;
1690}
1691
1692static int ahci_pmp_write(struct ata_device *dev, int pmp, int reg, u32 val)
1693{
1694 struct ata_port *ap = dev->link->ap;
1695 struct ata_taskfile tf;
1696
1697 ahci_kick_engine(ap, 0);
1698
1699 sata_pmp_write_init_tf(&tf, dev, pmp, reg, val);
1700 return ahci_exec_polled_cmd(ap, SATA_PMP_CTRL_PORT, &tf, 1, 0,
1701 SATA_PMP_SCR_TIMEOUT);
1702}
1703
1584static int ahci_port_resume(struct ata_port *ap) 1704static int ahci_port_resume(struct ata_port *ap)
1585{ 1705{
1586 ahci_power_up(ap); 1706 ahci_power_up(ap);
1587 ahci_start_port(ap); 1707 ahci_start_port(ap);
1588 1708
1709 if (ap->nr_pmp_links)
1710 ahci_pmp_attach(ap);
1711 else
1712 ahci_pmp_detach(ap);
1713
1589 return 0; 1714 return 0;
1590} 1715}
1591 1716
@@ -1866,6 +1991,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1866 if (hpriv->cap & HOST_CAP_NCQ) 1991 if (hpriv->cap & HOST_CAP_NCQ)
1867 pi.flags |= ATA_FLAG_NCQ; 1992 pi.flags |= ATA_FLAG_NCQ;
1868 1993
1994 if (hpriv->cap & HOST_CAP_PMP)
1995 pi.flags |= ATA_FLAG_PMP;
1996
1869 host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map)); 1997 host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map));
1870 if (!host) 1998 if (!host)
1871 return -ENOMEM; 1999 return -ENOMEM;