aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-06-29 02:09:24 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-07-12 20:13:10 -0400
commit309b8c89c8ddf9dd8e5f253c185d6af1d0358a79 (patch)
treec4065fa67a3460c4e33d5e12f000b9b5000a35c7
parent8f1a60868f4594bc5576cca8952635f475e8bec6 (diff)
drm/nouveau: downgrade severity of most init table parser errors
As long as we know the length of the opcode, we're probably better off trying to parse the remainder of an init table rather than aborting in the middle of it. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c112
1 files changed, 70 insertions, 42 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index ed0f5303850d..2e8cdd71a6ec 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -935,7 +935,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
935 NV_ERROR(bios->dev, 935 NV_ERROR(bios->dev,
936 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", 936 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
937 offset, config, count); 937 offset, config, count);
938 return -EINVAL; 938 return len;
939 } 939 }
940 940
941 configval = ROM32(bios->data[offset + 11 + config * 4]); 941 configval = ROM32(bios->data[offset + 11 + config * 4]);
@@ -1037,7 +1037,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
1037 NV_ERROR(bios->dev, 1037 NV_ERROR(bios->dev,
1038 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", 1038 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
1039 offset, config, count); 1039 offset, config, count);
1040 return -EINVAL; 1040 return len;
1041 } 1041 }
1042 1042
1043 freq = ROM16(bios->data[offset + 12 + config * 2]); 1043 freq = ROM16(bios->data[offset + 12 + config * 2]);
@@ -1209,7 +1209,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1209 dpe = nouveau_bios_dp_table(dev, dcb, &dummy); 1209 dpe = nouveau_bios_dp_table(dev, dcb, &dummy);
1210 if (!dpe) { 1210 if (!dpe) {
1211 NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset); 1211 NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
1212 return -EINVAL; 1212 return 3;
1213 } 1213 }
1214 1214
1215 switch (cond) { 1215 switch (cond) {
@@ -1233,12 +1233,16 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1233 int ret; 1233 int ret;
1234 1234
1235 auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index); 1235 auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index);
1236 if (!auxch) 1236 if (!auxch) {
1237 return -ENODEV; 1237 NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset);
1238 return 3;
1239 }
1238 1240
1239 ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1); 1241 ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1);
1240 if (ret) 1242 if (ret) {
1241 return ret; 1243 NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret);
1244 return 3;
1245 }
1242 1246
1243 if (cond & 1) 1247 if (cond & 1)
1244 iexec->execute = false; 1248 iexec->execute = false;
@@ -1407,7 +1411,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
1407 NV_ERROR(bios->dev, 1411 NV_ERROR(bios->dev,
1408 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", 1412 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
1409 offset, config, count); 1413 offset, config, count);
1410 return -EINVAL; 1414 return len;
1411 } 1415 }
1412 1416
1413 freq = ROM32(bios->data[offset + 11 + config * 4]); 1417 freq = ROM32(bios->data[offset + 11 + config * 4]);
@@ -1467,6 +1471,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1467 * "mask n" and OR it with "data n" before writing it back to the device 1471 * "mask n" and OR it with "data n" before writing it back to the device
1468 */ 1472 */
1469 1473
1474 struct drm_device *dev = bios->dev;
1470 uint8_t i2c_index = bios->data[offset + 1]; 1475 uint8_t i2c_index = bios->data[offset + 1];
1471 uint8_t i2c_address = bios->data[offset + 2] >> 1; 1476 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1472 uint8_t count = bios->data[offset + 3]; 1477 uint8_t count = bios->data[offset + 3];
@@ -1481,9 +1486,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1481 "Count: 0x%02X\n", 1486 "Count: 0x%02X\n",
1482 offset, i2c_index, i2c_address, count); 1487 offset, i2c_index, i2c_address, count);
1483 1488
1484 chan = init_i2c_device_find(bios->dev, i2c_index); 1489 chan = init_i2c_device_find(dev, i2c_index);
1485 if (!chan) 1490 if (!chan) {
1486 return -ENODEV; 1491 NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
1492 return len;
1493 }
1487 1494
1488 for (i = 0; i < count; i++) { 1495 for (i = 0; i < count; i++) {
1489 uint8_t reg = bios->data[offset + 4 + i * 3]; 1496 uint8_t reg = bios->data[offset + 4 + i * 3];
@@ -1494,8 +1501,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1494 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, 1501 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1495 I2C_SMBUS_READ, reg, 1502 I2C_SMBUS_READ, reg,
1496 I2C_SMBUS_BYTE_DATA, &val); 1503 I2C_SMBUS_BYTE_DATA, &val);
1497 if (ret < 0) 1504 if (ret < 0) {
1498 return ret; 1505 NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret);
1506 return len;
1507 }
1499 1508
1500 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " 1509 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
1501 "Mask: 0x%02X, Data: 0x%02X\n", 1510 "Mask: 0x%02X, Data: 0x%02X\n",
@@ -1509,8 +1518,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1509 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, 1518 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1510 I2C_SMBUS_WRITE, reg, 1519 I2C_SMBUS_WRITE, reg,
1511 I2C_SMBUS_BYTE_DATA, &val); 1520 I2C_SMBUS_BYTE_DATA, &val);
1512 if (ret < 0) 1521 if (ret < 0) {
1513 return ret; 1522 NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
1523 return len;
1524 }
1514 } 1525 }
1515 1526
1516 return len; 1527 return len;
@@ -1535,6 +1546,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1535 * "DCB I2C table entry index", set the register to "data n" 1546 * "DCB I2C table entry index", set the register to "data n"
1536 */ 1547 */
1537 1548
1549 struct drm_device *dev = bios->dev;
1538 uint8_t i2c_index = bios->data[offset + 1]; 1550 uint8_t i2c_index = bios->data[offset + 1];
1539 uint8_t i2c_address = bios->data[offset + 2] >> 1; 1551 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1540 uint8_t count = bios->data[offset + 3]; 1552 uint8_t count = bios->data[offset + 3];
@@ -1549,9 +1561,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1549 "Count: 0x%02X\n", 1561 "Count: 0x%02X\n",
1550 offset, i2c_index, i2c_address, count); 1562 offset, i2c_index, i2c_address, count);
1551 1563
1552 chan = init_i2c_device_find(bios->dev, i2c_index); 1564 chan = init_i2c_device_find(dev, i2c_index);
1553 if (!chan) 1565 if (!chan) {
1554 return -ENODEV; 1566 NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
1567 return len;
1568 }
1555 1569
1556 for (i = 0; i < count; i++) { 1570 for (i = 0; i < count; i++) {
1557 uint8_t reg = bios->data[offset + 4 + i * 2]; 1571 uint8_t reg = bios->data[offset + 4 + i * 2];
@@ -1568,8 +1582,10 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1568 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, 1582 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1569 I2C_SMBUS_WRITE, reg, 1583 I2C_SMBUS_WRITE, reg,
1570 I2C_SMBUS_BYTE_DATA, &val); 1584 I2C_SMBUS_BYTE_DATA, &val);
1571 if (ret < 0) 1585 if (ret < 0) {
1572 return ret; 1586 NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
1587 return len;
1588 }
1573 } 1589 }
1574 1590
1575 return len; 1591 return len;
@@ -1592,6 +1608,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1592 * address" on the I2C bus given by "DCB I2C table entry index" 1608 * address" on the I2C bus given by "DCB I2C table entry index"
1593 */ 1609 */
1594 1610
1611 struct drm_device *dev = bios->dev;
1595 uint8_t i2c_index = bios->data[offset + 1]; 1612 uint8_t i2c_index = bios->data[offset + 1];
1596 uint8_t i2c_address = bios->data[offset + 2] >> 1; 1613 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1597 uint8_t count = bios->data[offset + 3]; 1614 uint8_t count = bios->data[offset + 3];
@@ -1599,7 +1616,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1599 struct nouveau_i2c_chan *chan; 1616 struct nouveau_i2c_chan *chan;
1600 struct i2c_msg msg; 1617 struct i2c_msg msg;
1601 uint8_t data[256]; 1618 uint8_t data[256];
1602 int i; 1619 int ret, i;
1603 1620
1604 if (!iexec->execute) 1621 if (!iexec->execute)
1605 return len; 1622 return len;
@@ -1608,9 +1625,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1608 "Count: 0x%02X\n", 1625 "Count: 0x%02X\n",
1609 offset, i2c_index, i2c_address, count); 1626 offset, i2c_index, i2c_address, count);
1610 1627
1611 chan = init_i2c_device_find(bios->dev, i2c_index); 1628 chan = init_i2c_device_find(dev, i2c_index);
1612 if (!chan) 1629 if (!chan) {
1613 return -ENODEV; 1630 NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
1631 return len;
1632 }
1614 1633
1615 for (i = 0; i < count; i++) { 1634 for (i = 0; i < count; i++) {
1616 data[i] = bios->data[offset + 4 + i]; 1635 data[i] = bios->data[offset + 4 + i];
@@ -1623,8 +1642,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1623 msg.flags = 0; 1642 msg.flags = 0;
1624 msg.len = count; 1643 msg.len = count;
1625 msg.buf = data; 1644 msg.buf = data;
1626 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1645 ret = i2c_transfer(&chan->adapter, &msg, 1);
1627 return -EIO; 1646 if (ret != 1) {
1647 NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
1648 return len;
1649 }
1628 } 1650 }
1629 1651
1630 return len; 1652 return len;
@@ -1648,6 +1670,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1648 * used -- see get_tmds_index_reg() 1670 * used -- see get_tmds_index_reg()
1649 */ 1671 */
1650 1672
1673 struct drm_device *dev = bios->dev;
1651 uint8_t mlv = bios->data[offset + 1]; 1674 uint8_t mlv = bios->data[offset + 1];
1652 uint32_t tmdsaddr = bios->data[offset + 2]; 1675 uint32_t tmdsaddr = bios->data[offset + 2];
1653 uint8_t mask = bios->data[offset + 3]; 1676 uint8_t mask = bios->data[offset + 3];
@@ -1662,8 +1685,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1662 offset, mlv, tmdsaddr, mask, data); 1685 offset, mlv, tmdsaddr, mask, data);
1663 1686
1664 reg = get_tmds_index_reg(bios->dev, mlv); 1687 reg = get_tmds_index_reg(bios->dev, mlv);
1665 if (!reg) 1688 if (!reg) {
1666 return -EINVAL; 1689 NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
1690 return 5;
1691 }
1667 1692
1668 bios_wr32(bios, reg, 1693 bios_wr32(bios, reg,
1669 tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); 1694 tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
@@ -1693,6 +1718,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
1693 * register is used -- see get_tmds_index_reg() 1718 * register is used -- see get_tmds_index_reg()
1694 */ 1719 */
1695 1720
1721 struct drm_device *dev = bios->dev;
1696 uint8_t mlv = bios->data[offset + 1]; 1722 uint8_t mlv = bios->data[offset + 1];
1697 uint8_t count = bios->data[offset + 2]; 1723 uint8_t count = bios->data[offset + 2];
1698 int len = 3 + count * 2; 1724 int len = 3 + count * 2;
@@ -1706,8 +1732,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
1706 offset, mlv, count); 1732 offset, mlv, count);
1707 1733
1708 reg = get_tmds_index_reg(bios->dev, mlv); 1734 reg = get_tmds_index_reg(bios->dev, mlv);
1709 if (!reg) 1735 if (!reg) {
1710 return -EINVAL; 1736 NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
1737 return len;
1738 }
1711 1739
1712 for (i = 0; i < count; i++) { 1740 for (i = 0; i < count; i++) {
1713 uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; 1741 uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
@@ -2816,7 +2844,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2816 2844
2817 if (dev_priv->card_type != NV_50) { 2845 if (dev_priv->card_type != NV_50) {
2818 NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); 2846 NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
2819 return -ENODEV; 2847 return 1;
2820 } 2848 }
2821 2849
2822 if (!iexec->execute) 2850 if (!iexec->execute)
@@ -2888,10 +2916,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
2888 uint8_t index; 2916 uint8_t index;
2889 int i; 2917 int i;
2890 2918
2891 2919 /* critical! to know the length of the opcode */;
2892 if (!iexec->execute)
2893 return len;
2894
2895 if (!blocklen) { 2920 if (!blocklen) {
2896 NV_ERROR(bios->dev, 2921 NV_ERROR(bios->dev,
2897 "0x%04X: Zero block length - has the M table " 2922 "0x%04X: Zero block length - has the M table "
@@ -2899,6 +2924,9 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
2899 return -EINVAL; 2924 return -EINVAL;
2900 } 2925 }
2901 2926
2927 if (!iexec->execute)
2928 return len;
2929
2902 strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; 2930 strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
2903 index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; 2931 index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
2904 2932
@@ -3080,14 +3108,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3080 3108
3081 if (!bios->display.output) { 3109 if (!bios->display.output) {
3082 NV_ERROR(dev, "INIT_AUXCH: no active output\n"); 3110 NV_ERROR(dev, "INIT_AUXCH: no active output\n");
3083 return -EINVAL; 3111 return len;
3084 } 3112 }
3085 3113
3086 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); 3114 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
3087 if (!auxch) { 3115 if (!auxch) {
3088 NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", 3116 NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
3089 bios->display.output->i2c_index); 3117 bios->display.output->i2c_index);
3090 return -ENODEV; 3118 return len;
3091 } 3119 }
3092 3120
3093 if (!iexec->execute) 3121 if (!iexec->execute)
@@ -3100,7 +3128,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3100 ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); 3128 ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
3101 if (ret) { 3129 if (ret) {
3102 NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); 3130 NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
3103 return ret; 3131 return len;
3104 } 3132 }
3105 3133
3106 data &= bios->data[offset + 0]; 3134 data &= bios->data[offset + 0];
@@ -3109,7 +3137,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3109 ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); 3137 ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
3110 if (ret) { 3138 if (ret) {
3111 NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); 3139 NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
3112 return ret; 3140 return len;
3113 } 3141 }
3114 } 3142 }
3115 3143
@@ -3139,14 +3167,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3139 3167
3140 if (!bios->display.output) { 3168 if (!bios->display.output) {
3141 NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); 3169 NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
3142 return -EINVAL; 3170 return len;
3143 } 3171 }
3144 3172
3145 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); 3173 auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
3146 if (!auxch) { 3174 if (!auxch) {
3147 NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", 3175 NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
3148 bios->display.output->i2c_index); 3176 bios->display.output->i2c_index);
3149 return -ENODEV; 3177 return len;
3150 } 3178 }
3151 3179
3152 if (!iexec->execute) 3180 if (!iexec->execute)
@@ -3157,7 +3185,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3157 ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); 3185 ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
3158 if (ret) { 3186 if (ret) {
3159 NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); 3187 NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
3160 return ret; 3188 return len;
3161 } 3189 }
3162 } 3190 }
3163 3191