| .. | .. |
|---|
| 24 | 24 | #include <linux/timer.h> |
|---|
| 25 | 25 | #include <linux/kernel_stat.h> |
|---|
| 26 | 26 | #include <linux/sched/signal.h> |
|---|
| 27 | +#include <linux/dma-mapping.h> |
|---|
| 27 | 28 | |
|---|
| 28 | 29 | #include <asm/ccwdev.h> |
|---|
| 29 | 30 | #include <asm/cio.h> |
|---|
| .. | .. |
|---|
| 642 | 643 | return device_add(dev); |
|---|
| 643 | 644 | } |
|---|
| 644 | 645 | |
|---|
| 645 | | -static int match_dev_id(struct device *dev, void *data) |
|---|
| 646 | +static int match_dev_id(struct device *dev, const void *data) |
|---|
| 646 | 647 | { |
|---|
| 647 | 648 | struct ccw_device *cdev = to_ccwdev(dev); |
|---|
| 648 | | - struct ccw_dev_id *dev_id = data; |
|---|
| 649 | + struct ccw_dev_id *dev_id = (void *)data; |
|---|
| 649 | 650 | |
|---|
| 650 | 651 | return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); |
|---|
| 651 | 652 | } |
|---|
| .. | .. |
|---|
| 687 | 688 | struct ccw_device *cdev; |
|---|
| 688 | 689 | |
|---|
| 689 | 690 | cdev = to_ccwdev(dev); |
|---|
| 691 | + cio_gp_dma_free(cdev->private->dma_pool, cdev->private->dma_area, |
|---|
| 692 | + sizeof(*cdev->private->dma_area)); |
|---|
| 693 | + cio_gp_dma_destroy(cdev->private->dma_pool, &cdev->dev); |
|---|
| 690 | 694 | /* Release reference of parent subchannel. */ |
|---|
| 691 | 695 | put_device(cdev->dev.parent); |
|---|
| 692 | 696 | kfree(cdev->private); |
|---|
| .. | .. |
|---|
| 696 | 700 | static struct ccw_device * io_subchannel_allocate_dev(struct subchannel *sch) |
|---|
| 697 | 701 | { |
|---|
| 698 | 702 | struct ccw_device *cdev; |
|---|
| 703 | + struct gen_pool *dma_pool; |
|---|
| 699 | 704 | |
|---|
| 700 | 705 | cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); |
|---|
| 701 | | - if (cdev) { |
|---|
| 702 | | - cdev->private = kzalloc(sizeof(struct ccw_device_private), |
|---|
| 703 | | - GFP_KERNEL | GFP_DMA); |
|---|
| 704 | | - if (cdev->private) |
|---|
| 705 | | - return cdev; |
|---|
| 706 | | - } |
|---|
| 706 | + if (!cdev) |
|---|
| 707 | + goto err_cdev; |
|---|
| 708 | + cdev->private = kzalloc(sizeof(struct ccw_device_private), |
|---|
| 709 | + GFP_KERNEL | GFP_DMA); |
|---|
| 710 | + if (!cdev->private) |
|---|
| 711 | + goto err_priv; |
|---|
| 712 | + cdev->dev.coherent_dma_mask = sch->dev.coherent_dma_mask; |
|---|
| 713 | + cdev->dev.dma_mask = sch->dev.dma_mask; |
|---|
| 714 | + dma_pool = cio_gp_dma_create(&cdev->dev, 1); |
|---|
| 715 | + if (!dma_pool) |
|---|
| 716 | + goto err_dma_pool; |
|---|
| 717 | + cdev->private->dma_pool = dma_pool; |
|---|
| 718 | + cdev->private->dma_area = cio_gp_dma_zalloc(dma_pool, &cdev->dev, |
|---|
| 719 | + sizeof(*cdev->private->dma_area)); |
|---|
| 720 | + if (!cdev->private->dma_area) |
|---|
| 721 | + goto err_dma_area; |
|---|
| 722 | + return cdev; |
|---|
| 723 | +err_dma_area: |
|---|
| 724 | + cio_gp_dma_destroy(dma_pool, &cdev->dev); |
|---|
| 725 | +err_dma_pool: |
|---|
| 726 | + kfree(cdev->private); |
|---|
| 727 | +err_priv: |
|---|
| 707 | 728 | kfree(cdev); |
|---|
| 729 | +err_cdev: |
|---|
| 708 | 730 | return ERR_PTR(-ENOMEM); |
|---|
| 709 | 731 | } |
|---|
| 710 | 732 | |
|---|
| .. | .. |
|---|
| 886 | 908 | wake_up(&ccw_device_init_wq); |
|---|
| 887 | 909 | break; |
|---|
| 888 | 910 | case DEV_STATE_OFFLINE: |
|---|
| 889 | | - /* |
|---|
| 911 | + /* |
|---|
| 890 | 912 | * We can't register the device in interrupt context so |
|---|
| 891 | 913 | * we schedule a work item. |
|---|
| 892 | 914 | */ |
|---|
| .. | .. |
|---|
| 1067 | 1089 | if (!io_priv) |
|---|
| 1068 | 1090 | goto out_schedule; |
|---|
| 1069 | 1091 | |
|---|
| 1092 | + io_priv->dma_area = dma_alloc_coherent(&sch->dev, |
|---|
| 1093 | + sizeof(*io_priv->dma_area), |
|---|
| 1094 | + &io_priv->dma_area_dma, GFP_KERNEL); |
|---|
| 1095 | + if (!io_priv->dma_area) { |
|---|
| 1096 | + kfree(io_priv); |
|---|
| 1097 | + goto out_schedule; |
|---|
| 1098 | + } |
|---|
| 1099 | + |
|---|
| 1070 | 1100 | set_io_private(sch, io_priv); |
|---|
| 1071 | 1101 | css_schedule_eval(sch->schid); |
|---|
| 1072 | 1102 | return 0; |
|---|
| .. | .. |
|---|
| 1093 | 1123 | set_io_private(sch, NULL); |
|---|
| 1094 | 1124 | spin_unlock_irq(sch->lock); |
|---|
| 1095 | 1125 | out_free: |
|---|
| 1126 | + dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area), |
|---|
| 1127 | + io_priv->dma_area, io_priv->dma_area_dma); |
|---|
| 1096 | 1128 | kfree(io_priv); |
|---|
| 1097 | 1129 | sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); |
|---|
| 1098 | 1130 | return 0; |
|---|
| .. | .. |
|---|
| 1235 | 1267 | sch = to_subchannel(cdev->dev.parent); |
|---|
| 1236 | 1268 | if ((sch->schib.pmcw.pam & sch->opm) == sch->vpm) |
|---|
| 1237 | 1269 | break; |
|---|
| 1238 | | - /* fall through */ |
|---|
| 1270 | + fallthrough; |
|---|
| 1239 | 1271 | case DEV_STATE_DISCONNECTED: |
|---|
| 1240 | 1272 | CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n", |
|---|
| 1241 | 1273 | cdev->private->dev_id.ssid, |
|---|
| .. | .. |
|---|
| 1598 | 1630 | return ERR_CAST(sch); |
|---|
| 1599 | 1631 | |
|---|
| 1600 | 1632 | io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); |
|---|
| 1601 | | - if (!io_priv) { |
|---|
| 1602 | | - put_device(&sch->dev); |
|---|
| 1603 | | - return ERR_PTR(-ENOMEM); |
|---|
| 1604 | | - } |
|---|
| 1633 | + if (!io_priv) |
|---|
| 1634 | + goto err_priv; |
|---|
| 1635 | + io_priv->dma_area = dma_alloc_coherent(&sch->dev, |
|---|
| 1636 | + sizeof(*io_priv->dma_area), |
|---|
| 1637 | + &io_priv->dma_area_dma, GFP_KERNEL); |
|---|
| 1638 | + if (!io_priv->dma_area) |
|---|
| 1639 | + goto err_dma_area; |
|---|
| 1605 | 1640 | set_io_private(sch, io_priv); |
|---|
| 1606 | 1641 | cdev = io_subchannel_create_ccwdev(sch); |
|---|
| 1607 | 1642 | if (IS_ERR(cdev)) { |
|---|
| 1643 | + dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area), |
|---|
| 1644 | + io_priv->dma_area, io_priv->dma_area_dma); |
|---|
| 1645 | + set_io_private(sch, NULL); |
|---|
| 1608 | 1646 | put_device(&sch->dev); |
|---|
| 1609 | 1647 | kfree(io_priv); |
|---|
| 1610 | 1648 | return cdev; |
|---|
| .. | .. |
|---|
| 1612 | 1650 | cdev->drv = drv; |
|---|
| 1613 | 1651 | ccw_device_set_int_class(cdev); |
|---|
| 1614 | 1652 | return cdev; |
|---|
| 1653 | + |
|---|
| 1654 | +err_dma_area: |
|---|
| 1655 | + kfree(io_priv); |
|---|
| 1656 | +err_priv: |
|---|
| 1657 | + put_device(&sch->dev); |
|---|
| 1658 | + return ERR_PTR(-ENOMEM); |
|---|
| 1615 | 1659 | } |
|---|
| 1616 | 1660 | |
|---|
| 1617 | 1661 | void __init ccw_device_destroy_console(struct ccw_device *cdev) |
|---|
| .. | .. |
|---|
| 1620 | 1664 | struct io_subchannel_private *io_priv = to_io_private(sch); |
|---|
| 1621 | 1665 | |
|---|
| 1622 | 1666 | set_io_private(sch, NULL); |
|---|
| 1667 | + dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area), |
|---|
| 1668 | + io_priv->dma_area, io_priv->dma_area_dma); |
|---|
| 1623 | 1669 | put_device(&sch->dev); |
|---|
| 1624 | 1670 | put_device(&cdev->dev); |
|---|
| 1625 | 1671 | kfree(io_priv); |
|---|
| .. | .. |
|---|
| 1654 | 1700 | EXPORT_SYMBOL_GPL(ccw_device_force_console); |
|---|
| 1655 | 1701 | #endif |
|---|
| 1656 | 1702 | |
|---|
| 1657 | | -/* |
|---|
| 1658 | | - * get ccw_device matching the busid, but only if owned by cdrv |
|---|
| 1659 | | - */ |
|---|
| 1660 | | -static int |
|---|
| 1661 | | -__ccwdev_check_busid(struct device *dev, void *id) |
|---|
| 1662 | | -{ |
|---|
| 1663 | | - char *bus_id; |
|---|
| 1664 | | - |
|---|
| 1665 | | - bus_id = id; |
|---|
| 1666 | | - |
|---|
| 1667 | | - return (strcmp(bus_id, dev_name(dev)) == 0); |
|---|
| 1668 | | -} |
|---|
| 1669 | | - |
|---|
| 1670 | | - |
|---|
| 1671 | 1703 | /** |
|---|
| 1672 | 1704 | * get_ccwdev_by_busid() - obtain device from a bus id |
|---|
| 1673 | 1705 | * @cdrv: driver the device is owned by |
|---|
| .. | .. |
|---|
| 1684 | 1716 | { |
|---|
| 1685 | 1717 | struct device *dev; |
|---|
| 1686 | 1718 | |
|---|
| 1687 | | - dev = driver_find_device(&cdrv->driver, NULL, (void *)bus_id, |
|---|
| 1688 | | - __ccwdev_check_busid); |
|---|
| 1719 | + dev = driver_find_device_by_name(&cdrv->driver, bus_id); |
|---|
| 1689 | 1720 | |
|---|
| 1690 | 1721 | return dev ? to_ccwdev(dev) : NULL; |
|---|
| 1691 | 1722 | } |
|---|
| .. | .. |
|---|
| 2065 | 2096 | case CDEV_TODO_UNREG_EVAL: |
|---|
| 2066 | 2097 | if (!sch_is_pseudo_sch(sch)) |
|---|
| 2067 | 2098 | css_schedule_eval(sch->schid); |
|---|
| 2068 | | - /* fall-through */ |
|---|
| 2099 | + fallthrough; |
|---|
| 2069 | 2100 | case CDEV_TODO_UNREG: |
|---|
| 2070 | 2101 | if (sch_is_pseudo_sch(sch)) |
|---|
| 2071 | 2102 | ccw_device_unregister(cdev); |
|---|