diff options
Diffstat (limited to 'drivers/s390/net/netiucv.c')
-rw-r--r-- | drivers/s390/net/netiucv.c | 162 |
1 files changed, 133 insertions, 29 deletions
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index aec9e5d3cf4..52574ce797b 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -1,11 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * IUCV network driver | 2 | * IUCV network driver |
3 | * | 3 | * |
4 | * Copyright 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation | 4 | * Copyright IBM Corp. 2001, 2009 |
5 | * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) | ||
6 | * | 5 | * |
7 | * Sysfs integration and all bugs therein by Cornelia Huck | 6 | * Author(s): |
8 | * (cornelia.huck@de.ibm.com) | 7 | * Original netiucv driver: |
8 | * Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) | ||
9 | * Sysfs integration and all bugs therein: | ||
10 | * Cornelia Huck (cornelia.huck@de.ibm.com) | ||
11 | * PM functions: | ||
12 | * Ursula Braun (ursula.braun@de.ibm.com) | ||
9 | * | 13 | * |
10 | * Documentation used: | 14 | * Documentation used: |
11 | * the source of the original IUCV driver by: | 15 | * the source of the original IUCV driver by: |
@@ -149,10 +153,27 @@ PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ | |||
149 | 153 | ||
150 | #define PRINTK_HEADER " iucv: " /* for debugging */ | 154 | #define PRINTK_HEADER " iucv: " /* for debugging */ |
151 | 155 | ||
156 | /* dummy device to make sure netiucv_pm functions are called */ | ||
157 | static struct device *netiucv_dev; | ||
158 | |||
159 | static int netiucv_pm_prepare(struct device *); | ||
160 | static void netiucv_pm_complete(struct device *); | ||
161 | static int netiucv_pm_freeze(struct device *); | ||
162 | static int netiucv_pm_restore_thaw(struct device *); | ||
163 | |||
164 | static struct dev_pm_ops netiucv_pm_ops = { | ||
165 | .prepare = netiucv_pm_prepare, | ||
166 | .complete = netiucv_pm_complete, | ||
167 | .freeze = netiucv_pm_freeze, | ||
168 | .thaw = netiucv_pm_restore_thaw, | ||
169 | .restore = netiucv_pm_restore_thaw, | ||
170 | }; | ||
171 | |||
152 | static struct device_driver netiucv_driver = { | 172 | static struct device_driver netiucv_driver = { |
153 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
154 | .name = "netiucv", | 174 | .name = "netiucv", |
155 | .bus = &iucv_bus, | 175 | .bus = &iucv_bus, |
176 | .pm = &netiucv_pm_ops, | ||
156 | }; | 177 | }; |
157 | 178 | ||
158 | static int netiucv_callback_connreq(struct iucv_path *, | 179 | static int netiucv_callback_connreq(struct iucv_path *, |
@@ -233,6 +254,7 @@ struct netiucv_priv { | |||
233 | fsm_instance *fsm; | 254 | fsm_instance *fsm; |
234 | struct iucv_connection *conn; | 255 | struct iucv_connection *conn; |
235 | struct device *dev; | 256 | struct device *dev; |
257 | int pm_state; | ||
236 | }; | 258 | }; |
237 | 259 | ||
238 | /** | 260 | /** |
@@ -1265,6 +1287,72 @@ static int netiucv_close(struct net_device *dev) | |||
1265 | return 0; | 1287 | return 0; |
1266 | } | 1288 | } |
1267 | 1289 | ||
1290 | static int netiucv_pm_prepare(struct device *dev) | ||
1291 | { | ||
1292 | IUCV_DBF_TEXT(trace, 3, __func__); | ||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | static void netiucv_pm_complete(struct device *dev) | ||
1297 | { | ||
1298 | IUCV_DBF_TEXT(trace, 3, __func__); | ||
1299 | return; | ||
1300 | } | ||
1301 | |||
1302 | /** | ||
1303 | * netiucv_pm_freeze() - Freeze PM callback | ||
1304 | * @dev: netiucv device | ||
1305 | * | ||
1306 | * close open netiucv interfaces | ||
1307 | */ | ||
1308 | static int netiucv_pm_freeze(struct device *dev) | ||
1309 | { | ||
1310 | struct netiucv_priv *priv = dev->driver_data; | ||
1311 | struct net_device *ndev = NULL; | ||
1312 | int rc = 0; | ||
1313 | |||
1314 | IUCV_DBF_TEXT(trace, 3, __func__); | ||
1315 | if (priv && priv->conn) | ||
1316 | ndev = priv->conn->netdev; | ||
1317 | if (!ndev) | ||
1318 | goto out; | ||
1319 | netif_device_detach(ndev); | ||
1320 | priv->pm_state = fsm_getstate(priv->fsm); | ||
1321 | rc = netiucv_close(ndev); | ||
1322 | out: | ||
1323 | return rc; | ||
1324 | } | ||
1325 | |||
1326 | /** | ||
1327 | * netiucv_pm_restore_thaw() - Thaw and restore PM callback | ||
1328 | * @dev: netiucv device | ||
1329 | * | ||
1330 | * re-open netiucv interfaces closed during freeze | ||
1331 | */ | ||
1332 | static int netiucv_pm_restore_thaw(struct device *dev) | ||
1333 | { | ||
1334 | struct netiucv_priv *priv = dev->driver_data; | ||
1335 | struct net_device *ndev = NULL; | ||
1336 | int rc = 0; | ||
1337 | |||
1338 | IUCV_DBF_TEXT(trace, 3, __func__); | ||
1339 | if (priv && priv->conn) | ||
1340 | ndev = priv->conn->netdev; | ||
1341 | if (!ndev) | ||
1342 | goto out; | ||
1343 | switch (priv->pm_state) { | ||
1344 | case DEV_STATE_RUNNING: | ||
1345 | case DEV_STATE_STARTWAIT: | ||
1346 | rc = netiucv_open(ndev); | ||
1347 | break; | ||
1348 | default: | ||
1349 | break; | ||
1350 | } | ||
1351 | netif_device_attach(ndev); | ||
1352 | out: | ||
1353 | return rc; | ||
1354 | } | ||
1355 | |||
1268 | /** | 1356 | /** |
1269 | * Start transmission of a packet. | 1357 | * Start transmission of a packet. |
1270 | * Called from generic network device layer. | 1358 | * Called from generic network device layer. |
@@ -1364,7 +1452,7 @@ static int netiucv_change_mtu(struct net_device * dev, int new_mtu) | |||
1364 | static ssize_t user_show(struct device *dev, struct device_attribute *attr, | 1452 | static ssize_t user_show(struct device *dev, struct device_attribute *attr, |
1365 | char *buf) | 1453 | char *buf) |
1366 | { | 1454 | { |
1367 | struct netiucv_priv *priv = dev->driver_data; | 1455 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1368 | 1456 | ||
1369 | IUCV_DBF_TEXT(trace, 5, __func__); | 1457 | IUCV_DBF_TEXT(trace, 5, __func__); |
1370 | return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); | 1458 | return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); |
@@ -1373,7 +1461,7 @@ static ssize_t user_show(struct device *dev, struct device_attribute *attr, | |||
1373 | static ssize_t user_write(struct device *dev, struct device_attribute *attr, | 1461 | static ssize_t user_write(struct device *dev, struct device_attribute *attr, |
1374 | const char *buf, size_t count) | 1462 | const char *buf, size_t count) |
1375 | { | 1463 | { |
1376 | struct netiucv_priv *priv = dev->driver_data; | 1464 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1377 | struct net_device *ndev = priv->conn->netdev; | 1465 | struct net_device *ndev = priv->conn->netdev; |
1378 | char *p; | 1466 | char *p; |
1379 | char *tmp; | 1467 | char *tmp; |
@@ -1430,7 +1518,8 @@ static DEVICE_ATTR(user, 0644, user_show, user_write); | |||
1430 | 1518 | ||
1431 | static ssize_t buffer_show (struct device *dev, struct device_attribute *attr, | 1519 | static ssize_t buffer_show (struct device *dev, struct device_attribute *attr, |
1432 | char *buf) | 1520 | char *buf) |
1433 | { struct netiucv_priv *priv = dev->driver_data; | 1521 | { |
1522 | struct netiucv_priv *priv = dev_get_drvdata(dev); | ||
1434 | 1523 | ||
1435 | IUCV_DBF_TEXT(trace, 5, __func__); | 1524 | IUCV_DBF_TEXT(trace, 5, __func__); |
1436 | return sprintf(buf, "%d\n", priv->conn->max_buffsize); | 1525 | return sprintf(buf, "%d\n", priv->conn->max_buffsize); |
@@ -1439,7 +1528,7 @@ static ssize_t buffer_show (struct device *dev, struct device_attribute *attr, | |||
1439 | static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, | 1528 | static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, |
1440 | const char *buf, size_t count) | 1529 | const char *buf, size_t count) |
1441 | { | 1530 | { |
1442 | struct netiucv_priv *priv = dev->driver_data; | 1531 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1443 | struct net_device *ndev = priv->conn->netdev; | 1532 | struct net_device *ndev = priv->conn->netdev; |
1444 | char *e; | 1533 | char *e; |
1445 | int bs1; | 1534 | int bs1; |
@@ -1487,7 +1576,7 @@ static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); | |||
1487 | static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, | 1576 | static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, |
1488 | char *buf) | 1577 | char *buf) |
1489 | { | 1578 | { |
1490 | struct netiucv_priv *priv = dev->driver_data; | 1579 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1491 | 1580 | ||
1492 | IUCV_DBF_TEXT(trace, 5, __func__); | 1581 | IUCV_DBF_TEXT(trace, 5, __func__); |
1493 | return sprintf(buf, "%s\n", fsm_getstate_str(priv->fsm)); | 1582 | return sprintf(buf, "%s\n", fsm_getstate_str(priv->fsm)); |
@@ -1498,7 +1587,7 @@ static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL); | |||
1498 | static ssize_t conn_fsm_show (struct device *dev, | 1587 | static ssize_t conn_fsm_show (struct device *dev, |
1499 | struct device_attribute *attr, char *buf) | 1588 | struct device_attribute *attr, char *buf) |
1500 | { | 1589 | { |
1501 | struct netiucv_priv *priv = dev->driver_data; | 1590 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1502 | 1591 | ||
1503 | IUCV_DBF_TEXT(trace, 5, __func__); | 1592 | IUCV_DBF_TEXT(trace, 5, __func__); |
1504 | return sprintf(buf, "%s\n", fsm_getstate_str(priv->conn->fsm)); | 1593 | return sprintf(buf, "%s\n", fsm_getstate_str(priv->conn->fsm)); |
@@ -1509,7 +1598,7 @@ static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL); | |||
1509 | static ssize_t maxmulti_show (struct device *dev, | 1598 | static ssize_t maxmulti_show (struct device *dev, |
1510 | struct device_attribute *attr, char *buf) | 1599 | struct device_attribute *attr, char *buf) |
1511 | { | 1600 | { |
1512 | struct netiucv_priv *priv = dev->driver_data; | 1601 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1513 | 1602 | ||
1514 | IUCV_DBF_TEXT(trace, 5, __func__); | 1603 | IUCV_DBF_TEXT(trace, 5, __func__); |
1515 | return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti); | 1604 | return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti); |
@@ -1519,7 +1608,7 @@ static ssize_t maxmulti_write (struct device *dev, | |||
1519 | struct device_attribute *attr, | 1608 | struct device_attribute *attr, |
1520 | const char *buf, size_t count) | 1609 | const char *buf, size_t count) |
1521 | { | 1610 | { |
1522 | struct netiucv_priv *priv = dev->driver_data; | 1611 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1523 | 1612 | ||
1524 | IUCV_DBF_TEXT(trace, 4, __func__); | 1613 | IUCV_DBF_TEXT(trace, 4, __func__); |
1525 | priv->conn->prof.maxmulti = 0; | 1614 | priv->conn->prof.maxmulti = 0; |
@@ -1531,7 +1620,7 @@ static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write); | |||
1531 | static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, | 1620 | static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, |
1532 | char *buf) | 1621 | char *buf) |
1533 | { | 1622 | { |
1534 | struct netiucv_priv *priv = dev->driver_data; | 1623 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1535 | 1624 | ||
1536 | IUCV_DBF_TEXT(trace, 5, __func__); | 1625 | IUCV_DBF_TEXT(trace, 5, __func__); |
1537 | return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue); | 1626 | return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue); |
@@ -1540,7 +1629,7 @@ static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, | |||
1540 | static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, | 1629 | static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, |
1541 | const char *buf, size_t count) | 1630 | const char *buf, size_t count) |
1542 | { | 1631 | { |
1543 | struct netiucv_priv *priv = dev->driver_data; | 1632 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1544 | 1633 | ||
1545 | IUCV_DBF_TEXT(trace, 4, __func__); | 1634 | IUCV_DBF_TEXT(trace, 4, __func__); |
1546 | priv->conn->prof.maxcqueue = 0; | 1635 | priv->conn->prof.maxcqueue = 0; |
@@ -1552,7 +1641,7 @@ static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write); | |||
1552 | static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, | 1641 | static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, |
1553 | char *buf) | 1642 | char *buf) |
1554 | { | 1643 | { |
1555 | struct netiucv_priv *priv = dev->driver_data; | 1644 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1556 | 1645 | ||
1557 | IUCV_DBF_TEXT(trace, 5, __func__); | 1646 | IUCV_DBF_TEXT(trace, 5, __func__); |
1558 | return sprintf(buf, "%ld\n", priv->conn->prof.doios_single); | 1647 | return sprintf(buf, "%ld\n", priv->conn->prof.doios_single); |
@@ -1561,7 +1650,7 @@ static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, | |||
1561 | static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, | 1650 | static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, |
1562 | const char *buf, size_t count) | 1651 | const char *buf, size_t count) |
1563 | { | 1652 | { |
1564 | struct netiucv_priv *priv = dev->driver_data; | 1653 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1565 | 1654 | ||
1566 | IUCV_DBF_TEXT(trace, 4, __func__); | 1655 | IUCV_DBF_TEXT(trace, 4, __func__); |
1567 | priv->conn->prof.doios_single = 0; | 1656 | priv->conn->prof.doios_single = 0; |
@@ -1573,7 +1662,7 @@ static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write); | |||
1573 | static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, | 1662 | static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, |
1574 | char *buf) | 1663 | char *buf) |
1575 | { | 1664 | { |
1576 | struct netiucv_priv *priv = dev->driver_data; | 1665 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1577 | 1666 | ||
1578 | IUCV_DBF_TEXT(trace, 5, __func__); | 1667 | IUCV_DBF_TEXT(trace, 5, __func__); |
1579 | return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi); | 1668 | return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi); |
@@ -1582,7 +1671,7 @@ static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, | |||
1582 | static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, | 1671 | static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, |
1583 | const char *buf, size_t count) | 1672 | const char *buf, size_t count) |
1584 | { | 1673 | { |
1585 | struct netiucv_priv *priv = dev->driver_data; | 1674 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1586 | 1675 | ||
1587 | IUCV_DBF_TEXT(trace, 5, __func__); | 1676 | IUCV_DBF_TEXT(trace, 5, __func__); |
1588 | priv->conn->prof.doios_multi = 0; | 1677 | priv->conn->prof.doios_multi = 0; |
@@ -1594,7 +1683,7 @@ static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write); | |||
1594 | static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, | 1683 | static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, |
1595 | char *buf) | 1684 | char *buf) |
1596 | { | 1685 | { |
1597 | struct netiucv_priv *priv = dev->driver_data; | 1686 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1598 | 1687 | ||
1599 | IUCV_DBF_TEXT(trace, 5, __func__); | 1688 | IUCV_DBF_TEXT(trace, 5, __func__); |
1600 | return sprintf(buf, "%ld\n", priv->conn->prof.txlen); | 1689 | return sprintf(buf, "%ld\n", priv->conn->prof.txlen); |
@@ -1603,7 +1692,7 @@ static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, | |||
1603 | static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, | 1692 | static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, |
1604 | const char *buf, size_t count) | 1693 | const char *buf, size_t count) |
1605 | { | 1694 | { |
1606 | struct netiucv_priv *priv = dev->driver_data; | 1695 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1607 | 1696 | ||
1608 | IUCV_DBF_TEXT(trace, 4, __func__); | 1697 | IUCV_DBF_TEXT(trace, 4, __func__); |
1609 | priv->conn->prof.txlen = 0; | 1698 | priv->conn->prof.txlen = 0; |
@@ -1615,7 +1704,7 @@ static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write); | |||
1615 | static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, | 1704 | static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, |
1616 | char *buf) | 1705 | char *buf) |
1617 | { | 1706 | { |
1618 | struct netiucv_priv *priv = dev->driver_data; | 1707 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1619 | 1708 | ||
1620 | IUCV_DBF_TEXT(trace, 5, __func__); | 1709 | IUCV_DBF_TEXT(trace, 5, __func__); |
1621 | return sprintf(buf, "%ld\n", priv->conn->prof.tx_time); | 1710 | return sprintf(buf, "%ld\n", priv->conn->prof.tx_time); |
@@ -1624,7 +1713,7 @@ static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, | |||
1624 | static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, | 1713 | static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, |
1625 | const char *buf, size_t count) | 1714 | const char *buf, size_t count) |
1626 | { | 1715 | { |
1627 | struct netiucv_priv *priv = dev->driver_data; | 1716 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1628 | 1717 | ||
1629 | IUCV_DBF_TEXT(trace, 4, __func__); | 1718 | IUCV_DBF_TEXT(trace, 4, __func__); |
1630 | priv->conn->prof.tx_time = 0; | 1719 | priv->conn->prof.tx_time = 0; |
@@ -1636,7 +1725,7 @@ static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write); | |||
1636 | static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, | 1725 | static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, |
1637 | char *buf) | 1726 | char *buf) |
1638 | { | 1727 | { |
1639 | struct netiucv_priv *priv = dev->driver_data; | 1728 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1640 | 1729 | ||
1641 | IUCV_DBF_TEXT(trace, 5, __func__); | 1730 | IUCV_DBF_TEXT(trace, 5, __func__); |
1642 | return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending); | 1731 | return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending); |
@@ -1645,7 +1734,7 @@ static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, | |||
1645 | static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, | 1734 | static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, |
1646 | const char *buf, size_t count) | 1735 | const char *buf, size_t count) |
1647 | { | 1736 | { |
1648 | struct netiucv_priv *priv = dev->driver_data; | 1737 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1649 | 1738 | ||
1650 | IUCV_DBF_TEXT(trace, 4, __func__); | 1739 | IUCV_DBF_TEXT(trace, 4, __func__); |
1651 | priv->conn->prof.tx_pending = 0; | 1740 | priv->conn->prof.tx_pending = 0; |
@@ -1657,7 +1746,7 @@ static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write); | |||
1657 | static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, | 1746 | static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, |
1658 | char *buf) | 1747 | char *buf) |
1659 | { | 1748 | { |
1660 | struct netiucv_priv *priv = dev->driver_data; | 1749 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1661 | 1750 | ||
1662 | IUCV_DBF_TEXT(trace, 5, __func__); | 1751 | IUCV_DBF_TEXT(trace, 5, __func__); |
1663 | return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending); | 1752 | return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending); |
@@ -1666,7 +1755,7 @@ static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, | |||
1666 | static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr, | 1755 | static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr, |
1667 | const char *buf, size_t count) | 1756 | const char *buf, size_t count) |
1668 | { | 1757 | { |
1669 | struct netiucv_priv *priv = dev->driver_data; | 1758 | struct netiucv_priv *priv = dev_get_drvdata(dev); |
1670 | 1759 | ||
1671 | IUCV_DBF_TEXT(trace, 4, __func__); | 1760 | IUCV_DBF_TEXT(trace, 4, __func__); |
1672 | priv->conn->prof.tx_max_pending = 0; | 1761 | priv->conn->prof.tx_max_pending = 0; |
@@ -1731,7 +1820,6 @@ static int netiucv_register_device(struct net_device *ndev) | |||
1731 | struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); | 1820 | struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); |
1732 | int ret; | 1821 | int ret; |
1733 | 1822 | ||
1734 | |||
1735 | IUCV_DBF_TEXT(trace, 3, __func__); | 1823 | IUCV_DBF_TEXT(trace, 3, __func__); |
1736 | 1824 | ||
1737 | if (dev) { | 1825 | if (dev) { |
@@ -1758,7 +1846,7 @@ static int netiucv_register_device(struct net_device *ndev) | |||
1758 | if (ret) | 1846 | if (ret) |
1759 | goto out_unreg; | 1847 | goto out_unreg; |
1760 | priv->dev = dev; | 1848 | priv->dev = dev; |
1761 | dev->driver_data = priv; | 1849 | dev_set_drvdata(dev, priv); |
1762 | return 0; | 1850 | return 0; |
1763 | 1851 | ||
1764 | out_unreg: | 1852 | out_unreg: |
@@ -2100,6 +2188,7 @@ static void __exit netiucv_exit(void) | |||
2100 | netiucv_unregister_device(dev); | 2188 | netiucv_unregister_device(dev); |
2101 | } | 2189 | } |
2102 | 2190 | ||
2191 | device_unregister(netiucv_dev); | ||
2103 | driver_unregister(&netiucv_driver); | 2192 | driver_unregister(&netiucv_driver); |
2104 | iucv_unregister(&netiucv_handler, 1); | 2193 | iucv_unregister(&netiucv_handler, 1); |
2105 | iucv_unregister_dbf_views(); | 2194 | iucv_unregister_dbf_views(); |
@@ -2125,10 +2214,25 @@ static int __init netiucv_init(void) | |||
2125 | IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc); | 2214 | IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc); |
2126 | goto out_iucv; | 2215 | goto out_iucv; |
2127 | } | 2216 | } |
2128 | 2217 | /* establish dummy device */ | |
2218 | netiucv_dev = kzalloc(sizeof(struct device), GFP_KERNEL); | ||
2219 | if (!netiucv_dev) { | ||
2220 | rc = -ENOMEM; | ||
2221 | goto out_driver; | ||
2222 | } | ||
2223 | dev_set_name(netiucv_dev, "netiucv"); | ||
2224 | netiucv_dev->bus = &iucv_bus; | ||
2225 | netiucv_dev->parent = iucv_root; | ||
2226 | netiucv_dev->release = (void (*)(struct device *))kfree; | ||
2227 | netiucv_dev->driver = &netiucv_driver; | ||
2228 | rc = device_register(netiucv_dev); | ||
2229 | if (rc) | ||
2230 | goto out_driver; | ||
2129 | netiucv_banner(); | 2231 | netiucv_banner(); |
2130 | return rc; | 2232 | return rc; |
2131 | 2233 | ||
2234 | out_driver: | ||
2235 | driver_unregister(&netiucv_driver); | ||
2132 | out_iucv: | 2236 | out_iucv: |
2133 | iucv_unregister(&netiucv_handler, 1); | 2237 | iucv_unregister(&netiucv_handler, 1); |
2134 | out_dbf: | 2238 | out_dbf: |