diff options
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/ctcm_fsms.c | 4 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_main.c | 4 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_mpc.c | 20 | ||||
-rw-r--r-- | drivers/s390/net/fsm.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/ism_drv.c | 53 | ||||
-rw-r--r-- | drivers/s390/net/lcs.c | 15 | ||||
-rw-r--r-- | drivers/s390/net/netiucv.c | 44 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core.h | 9 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 131 | ||||
-rw-r--r-- | drivers/s390/net/qeth_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/smsgiucv_app.c | 21 |
11 files changed, 169 insertions, 136 deletions
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c index 90ec477386a8..9678c6a2cda7 100644 --- a/drivers/s390/net/ctcm_fsms.c +++ b/drivers/s390/net/ctcm_fsms.c @@ -1325,7 +1325,7 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg) clear_normalized_cda(&ch->ccw[1]); CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n", - (void *)(unsigned long)ch->ccw[1].cda, + (void *)(u64)dma32_to_u32(ch->ccw[1].cda), ch->trans_skb->data); ch->ccw[1].count = ch->max_bufsize; @@ -1340,7 +1340,7 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg) } CTCM_PR_DBGDATA("ccwcda=0x%p data=0x%p\n", - (void *)(unsigned long)ch->ccw[1].cda, + (void *)(u64)dma32_to_u32(ch->ccw[1].cda), ch->trans_skb->data); ch->ccw[1].count = ch->trans_skb->len; diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index ac15d7c2b200..b93c2eb45916 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -996,7 +996,7 @@ static int ctcm_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; dev->hard_header_len = LL_HEADER_LENGTH + 2; } - dev->mtu = new_mtu; + WRITE_ONCE(dev->mtu, new_mtu); return 0; } @@ -1389,7 +1389,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, ch->ccw[15].cmd_code = CCW_CMD_WRITE; ch->ccw[15].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[15].count = TH_HEADER_LENGTH; - ch->ccw[15].cda = virt_to_phys(ch->discontact_th); + ch->ccw[15].cda = virt_to_dma32(ch->discontact_th); ch->ccw[16].cmd_code = CCW_CMD_NOOP; ch->ccw[16].flags = CCW_FLAG_SLI; diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 7a2f34a5e0e0..9e580ef69bda 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -1708,57 +1708,57 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side) ch->ccw[9].cmd_code = CCW_CMD_WRITE; ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[9].count = TH_HEADER_LENGTH; - ch->ccw[9].cda = virt_to_phys(ch->xid_th); + ch->ccw[9].cda = virt_to_dma32(ch->xid_th); if (ch->xid == NULL) goto done; ch->ccw[10].cmd_code = CCW_CMD_WRITE; ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[10].count = XID2_LENGTH; - ch->ccw[10].cda = virt_to_phys(ch->xid); + ch->ccw[10].cda = virt_to_dma32(ch->xid); ch->ccw[11].cmd_code = CCW_CMD_READ; ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[11].count = TH_HEADER_LENGTH; - ch->ccw[11].cda = virt_to_phys(ch->rcvd_xid_th); + ch->ccw[11].cda = virt_to_dma32(ch->rcvd_xid_th); ch->ccw[12].cmd_code = CCW_CMD_READ; ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[12].count = XID2_LENGTH; - ch->ccw[12].cda = virt_to_phys(ch->rcvd_xid); + ch->ccw[12].cda = virt_to_dma32(ch->rcvd_xid); ch->ccw[13].cmd_code = CCW_CMD_READ; - ch->ccw[13].cda = virt_to_phys(ch->rcvd_xid_id); + ch->ccw[13].cda = virt_to_dma32(ch->rcvd_xid_id); } else { /* side == YSIDE : mpc_action_yside_xid */ ch->ccw[9].cmd_code = CCW_CMD_READ; ch->ccw[9].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[9].count = TH_HEADER_LENGTH; - ch->ccw[9].cda = virt_to_phys(ch->rcvd_xid_th); + ch->ccw[9].cda = virt_to_dma32(ch->rcvd_xid_th); ch->ccw[10].cmd_code = CCW_CMD_READ; ch->ccw[10].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[10].count = XID2_LENGTH; - ch->ccw[10].cda = virt_to_phys(ch->rcvd_xid); + ch->ccw[10].cda = virt_to_dma32(ch->rcvd_xid); if (ch->xid_th == NULL) goto done; ch->ccw[11].cmd_code = CCW_CMD_WRITE; ch->ccw[11].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[11].count = TH_HEADER_LENGTH; - ch->ccw[11].cda = virt_to_phys(ch->xid_th); + ch->ccw[11].cda = virt_to_dma32(ch->xid_th); if (ch->xid == NULL) goto done; ch->ccw[12].cmd_code = CCW_CMD_WRITE; ch->ccw[12].flags = CCW_FLAG_SLI | CCW_FLAG_CC; ch->ccw[12].count = XID2_LENGTH; - ch->ccw[12].cda = virt_to_phys(ch->xid); + ch->ccw[12].cda = virt_to_dma32(ch->xid); if (ch->xid_id == NULL) goto done; ch->ccw[13].cmd_code = CCW_CMD_WRITE; - ch->ccw[13].cda = virt_to_phys(ch->xid_id); + ch->ccw[13].cda = virt_to_dma32(ch->xid_id); } ch->ccw[13].flags = CCW_FLAG_SLI | CCW_FLAG_CC; diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c index 0ff61d00feb1..8672d225ba77 100644 --- a/drivers/s390/net/fsm.c +++ b/drivers/s390/net/fsm.c @@ -9,7 +9,7 @@ #include <linux/slab.h> #include <linux/timer.h> -MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); +MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert <felfert@millenux.com>"); MODULE_DESCRIPTION("Finite state machine helper functions"); MODULE_LICENSE("GPL"); diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index 2c8e964425dc..2f34761e6413 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -292,13 +292,16 @@ out: static void ism_free_dmb(struct ism_dev *ism, struct ism_dmb *dmb) { clear_bit(dmb->sba_idx, ism->sba_bitmap); - dma_free_coherent(&ism->pdev->dev, dmb->dmb_len, - dmb->cpu_addr, dmb->dma_addr); + dma_unmap_page(&ism->pdev->dev, dmb->dma_addr, dmb->dmb_len, + DMA_FROM_DEVICE); + folio_put(virt_to_folio(dmb->cpu_addr)); } static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb) { + struct folio *folio; unsigned long bit; + int rc; if (PAGE_ALIGN(dmb->dmb_len) > dma_get_max_seg_size(&ism->pdev->dev)) return -EINVAL; @@ -315,14 +318,30 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb) test_and_set_bit(dmb->sba_idx, ism->sba_bitmap)) return -EINVAL; - dmb->cpu_addr = dma_alloc_coherent(&ism->pdev->dev, dmb->dmb_len, - &dmb->dma_addr, - GFP_KERNEL | __GFP_NOWARN | - __GFP_NOMEMALLOC | __GFP_NORETRY); - if (!dmb->cpu_addr) - clear_bit(dmb->sba_idx, ism->sba_bitmap); + folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC | + __GFP_NORETRY, get_order(dmb->dmb_len)); - return dmb->cpu_addr ? 0 : -ENOMEM; + if (!folio) { + rc = -ENOMEM; + goto out_bit; + } + + dmb->cpu_addr = folio_address(folio); + dmb->dma_addr = dma_map_page(&ism->pdev->dev, + virt_to_page(dmb->cpu_addr), 0, + dmb->dmb_len, DMA_FROM_DEVICE); + if (dma_mapping_error(&ism->pdev->dev, dmb->dma_addr)) { + rc = -ENOMEM; + goto out_free; + } + + return 0; + +out_free: + kfree(dmb->cpu_addr); +out_bit: + clear_bit(dmb->sba_idx, ism->sba_bitmap); + return rc; } int ism_register_dmb(struct ism_dev *ism, struct ism_dmb *dmb, @@ -569,6 +588,15 @@ out: return ret; } +static void ism_dev_release(struct device *dev) +{ + struct ism_dev *ism; + + ism = container_of(dev, struct ism_dev, dev); + + kfree(ism); +} + static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct ism_dev *ism; @@ -582,6 +610,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev_set_drvdata(&pdev->dev, ism); ism->pdev = pdev; ism->dev.parent = &pdev->dev; + ism->dev.release = ism_dev_release; device_initialize(&ism->dev); dev_set_name(&ism->dev, dev_name(&pdev->dev)); ret = device_add(&ism->dev); @@ -618,7 +647,7 @@ err: device_del(&ism->dev); err_dev: dev_set_drvdata(&pdev->dev, NULL); - kfree(ism); + put_device(&ism->dev); return ret; } @@ -663,7 +692,7 @@ static void ism_remove(struct pci_dev *pdev) pci_disable_device(pdev); device_del(&ism->dev); dev_set_drvdata(&pdev->dev, NULL); - kfree(ism); + put_device(&ism->dev); } static struct pci_driver ism_driver = { @@ -726,7 +755,7 @@ static int smcd_query_rgid(struct smcd_dev *smcd, struct smcd_gid *rgid, } static int smcd_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb, - struct ism_client *client) + void *client) { return ism_register_dmb(smcd->priv, (struct ism_dmb *)dmb, client); } diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index a1f2acd6fb8f..88db8378325a 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Linux for S/390 Lan Channel Station Network Driver + * Linux for S/390 LAN channel station device driver * * Copyright IBM Corp. 1999, 2009 * Author(s): Original Code written by @@ -218,7 +218,7 @@ lcs_setup_read_ccws(struct lcs_card *card) * we do not need to do set_normalized_cda. */ card->read.ccws[cnt].cda = - (__u32)virt_to_phys(card->read.iob[cnt].data); + virt_to_dma32(card->read.iob[cnt].data); ((struct lcs_header *) card->read.iob[cnt].data)->offset = LCS_ILLEGAL_OFFSET; card->read.iob[cnt].callback = lcs_get_frames_cb; @@ -230,8 +230,7 @@ lcs_setup_read_ccws(struct lcs_card *card) card->read.ccws[LCS_NUM_BUFFS - 1].flags |= CCW_FLAG_SUSPEND; /* Last ccw is a tic (transfer in channel). */ card->read.ccws[LCS_NUM_BUFFS].cmd_code = LCS_CCW_TRANSFER; - card->read.ccws[LCS_NUM_BUFFS].cda = - (__u32)virt_to_phys(card->read.ccws); + card->read.ccws[LCS_NUM_BUFFS].cda = virt_to_dma32(card->read.ccws); /* Setg initial state of the read channel. */ card->read.state = LCS_CH_STATE_INIT; @@ -273,12 +272,11 @@ lcs_setup_write_ccws(struct lcs_card *card) * we do not need to do set_normalized_cda. */ card->write.ccws[cnt].cda = - (__u32)virt_to_phys(card->write.iob[cnt].data); + virt_to_dma32(card->write.iob[cnt].data); } /* Last ccw is a tic (transfer in channel). */ card->write.ccws[LCS_NUM_BUFFS].cmd_code = LCS_CCW_TRANSFER; - card->write.ccws[LCS_NUM_BUFFS].cda = - (__u32)virt_to_phys(card->write.ccws); + card->write.ccws[LCS_NUM_BUFFS].cda = virt_to_dma32(card->write.ccws); /* Set initial state of the write channel. */ card->read.state = LCS_CH_STATE_INIT; @@ -1399,7 +1397,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) if ((channel->state != LCS_CH_STATE_INIT) && (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) && (irb->scsw.cmd.cpa != 0)) { - index = (struct ccw1 *) __va((addr_t) irb->scsw.cmd.cpa) + index = (struct ccw1 *)dma32_to_virt(irb->scsw.cmd.cpa) - channel->ccws; if ((irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED) || (irb->scsw.cmd.cstat & SCHN_STAT_PCI)) @@ -2382,5 +2380,6 @@ module_init(lcs_init_module); module_exit(lcs_cleanup_module); MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>"); +MODULE_DESCRIPTION("S/390 LAN channel station device driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 8852b03f943b..31c9f95d809d 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1319,7 +1319,7 @@ static ssize_t user_show(struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%s\n", netiucv_printuser(priv->conn)); + return sysfs_emit(buf, "%s\n", netiucv_printuser(priv->conn)); } static int netiucv_check_user(const char *buf, size_t count, char *username, @@ -1415,7 +1415,7 @@ static ssize_t buffer_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%d\n", priv->conn->max_buffsize); + return sysfs_emit(buf, "%d\n", priv->conn->max_buffsize); } static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, @@ -1473,7 +1473,7 @@ static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%s\n", fsm_getstate_str(priv->fsm)); + return sysfs_emit(buf, "%s\n", fsm_getstate_str(priv->fsm)); } static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL); @@ -1484,7 +1484,7 @@ static ssize_t conn_fsm_show (struct device *dev, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%s\n", fsm_getstate_str(priv->conn->fsm)); + return sysfs_emit(buf, "%s\n", fsm_getstate_str(priv->conn->fsm)); } static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL); @@ -1495,7 +1495,7 @@ static ssize_t maxmulti_show (struct device *dev, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.maxmulti); } static ssize_t maxmulti_write (struct device *dev, @@ -1517,7 +1517,7 @@ static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.maxcqueue); } static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, @@ -1538,7 +1538,7 @@ static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.doios_single); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.doios_single); } static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, @@ -1559,7 +1559,7 @@ static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.doios_multi); } static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, @@ -1580,7 +1580,7 @@ static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.txlen); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.txlen); } static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, @@ -1601,7 +1601,7 @@ static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.tx_time); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.tx_time); } static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, @@ -1622,7 +1622,7 @@ static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.tx_pending); } static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, @@ -1643,7 +1643,7 @@ static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, struct netiucv_priv *priv = dev_get_drvdata(dev); IUCV_DBF_TEXT(trace, 5, __func__); - return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending); + return sysfs_emit(buf, "%ld\n", priv->conn->prof.tx_max_pending); } static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr, @@ -1696,26 +1696,14 @@ static const struct attribute_group *netiucv_attr_groups[] = { static int netiucv_register_device(struct net_device *ndev) { struct netiucv_priv *priv = netdev_priv(ndev); - struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); + struct device *dev; int ret; IUCV_DBF_TEXT(trace, 3, __func__); - if (dev) { - dev_set_name(dev, "net%s", ndev->name); - dev->bus = &iucv_bus; - dev->parent = iucv_root; - dev->groups = netiucv_attr_groups; - /* - * The release function could be called after the - * module has been unloaded. It's _only_ task is to - * free the struct. Therefore, we specify kfree() - * directly here. (Probably a little bit obfuscating - * but legitime ...). - */ - dev->release = (void (*)(struct device *))kfree; - dev->driver = &netiucv_driver; - } else + dev = iucv_alloc_device(netiucv_attr_groups, &netiucv_driver, NULL, + "net%s", ndev->name); + if (!dev) return -ENOMEM; ret = device_register(dev); diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 613eab729704..41fe8a043d61 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -956,7 +956,7 @@ static inline struct dst_entry *qeth_dst_check_rcu(struct sk_buff *skb, struct dst_entry *dst = skb_dst(skb); struct rt6_info *rt; - rt = (struct rt6_info *) dst; + rt = dst_rt6_info(dst); if (dst) { if (proto == htons(ETH_P_IPV6)) dst = dst_check(dst, rt6_get_cookie(rt)); @@ -970,15 +970,14 @@ static inline struct dst_entry *qeth_dst_check_rcu(struct sk_buff *skb, static inline __be32 qeth_next_hop_v4_rcu(struct sk_buff *skb, struct dst_entry *dst) { - struct rtable *rt = (struct rtable *) dst; - - return (rt) ? rt_nexthop(rt, ip_hdr(skb)->daddr) : ip_hdr(skb)->daddr; + return (dst) ? rt_nexthop(dst_rtable(dst), ip_hdr(skb)->daddr) : + ip_hdr(skb)->daddr; } static inline struct in6_addr *qeth_next_hop_v6_rcu(struct sk_buff *skb, struct dst_entry *dst) { - struct rt6_info *rt = (struct rt6_info *) dst; + struct rt6_info *rt = dst_rt6_info(dst); if (rt && !ipv6_addr_any(&rt->rt6i_gateway)) return &rt->rt6i_gateway; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index cf8506d0f185..20328d695ef9 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -364,30 +364,33 @@ out: return rc; } +static void qeth_free_cq(struct qeth_card *card) +{ + if (card->qdio.c_q) { + qeth_free_qdio_queue(card->qdio.c_q); + card->qdio.c_q = NULL; + } +} + static int qeth_alloc_cq(struct qeth_card *card) { if (card->options.cq == QETH_CQ_ENABLED) { QETH_CARD_TEXT(card, 2, "cqon"); - card->qdio.c_q = qeth_alloc_qdio_queue(); if (!card->qdio.c_q) { - dev_err(&card->gdev->dev, "Failed to create completion queue\n"); - return -ENOMEM; + card->qdio.c_q = qeth_alloc_qdio_queue(); + if (!card->qdio.c_q) { + dev_err(&card->gdev->dev, + "Failed to create completion queue\n"); + return -ENOMEM; + } } } else { QETH_CARD_TEXT(card, 2, "nocq"); - card->qdio.c_q = NULL; + qeth_free_cq(card); } return 0; } -static void qeth_free_cq(struct qeth_card *card) -{ - if (card->qdio.c_q) { - qeth_free_qdio_queue(card->qdio.c_q); - card->qdio.c_q = NULL; - } -} - static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15, int delayed) { @@ -426,7 +429,7 @@ static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u8 flags, u32 len, ccw->cmd_code = cmd_code; ccw->flags = flags | CCW_FLAG_SLI; ccw->count = len; - ccw->cda = (__u32)virt_to_phys(data); + ccw->cda = virt_to_dma32(data); } static int __qeth_issue_next_read(struct qeth_card *card) @@ -1179,6 +1182,20 @@ static int qeth_check_irb_error(struct qeth_card *card, struct ccw_device *cdev, } } +/** + * qeth_irq() - qeth interrupt handler + * @cdev: ccw device + * @intparm: expect pointer to iob + * @irb: Interruption Response Block + * + * In the good path: + * corresponding qeth channel is locked with last used iob as active_cmd. + * But this function is also called for error interrupts. + * + * Caller ensures that: + * Interrupts are disabled; ccw device lock is held; + * + */ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) { @@ -1220,11 +1237,10 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, iob = (struct qeth_cmd_buffer *) (addr_t)intparm; } - qeth_unlock_channel(card, channel); - rc = qeth_check_irb_error(card, cdev, irb); if (rc) { /* IO was terminated, free its resources. */ + qeth_unlock_channel(card, channel); if (iob) qeth_cancel_cmd(iob, rc); return; @@ -1268,6 +1284,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, rc = qeth_get_problem(card, cdev, irb); if (rc) { card->read_or_write_problem = 1; + qeth_unlock_channel(card, channel); if (iob) qeth_cancel_cmd(iob, rc); qeth_clear_ipacmd_list(card); @@ -1276,6 +1293,26 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, } } + if (scsw_cmd_is_valid_cc(&irb->scsw) && irb->scsw.cmd.cc == 1 && iob) { + /* channel command hasn't started: retry. + * active_cmd is still set to last iob + */ + QETH_CARD_TEXT(card, 2, "irqcc1"); + rc = ccw_device_start_timeout(cdev, __ccw_from_cmd(iob), + (addr_t)iob, 0, 0, iob->timeout); + if (rc) { + QETH_DBF_MESSAGE(2, + "ccw retry on %x failed, rc = %i\n", + CARD_DEVID(card), rc); + QETH_CARD_TEXT_(card, 2, " err%d", rc); + qeth_unlock_channel(card, channel); + qeth_cancel_cmd(iob, rc); + } + return; + } + + qeth_unlock_channel(card, channel); + if (iob) { /* sanity check: */ if (irb->scsw.cmd.count > iob->length) { @@ -1359,7 +1396,7 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, qeth_tx_complete_buf(queue, buf, error, budget); for (i = 0; i < queue->max_elements; ++i) { - void *data = phys_to_virt(buf->buffer->element[i].addr); + void *data = dma64_to_virt(buf->buffer->element[i].addr); if (__test_and_clear_bit(i, buf->from_kmem_cache) && data) kmem_cache_free(qeth_core_header_cache, data); @@ -1404,7 +1441,7 @@ static void qeth_tx_complete_pending_bufs(struct qeth_card *card, for (i = 0; i < aob->sb_count && i < queue->max_elements; i++) { - void *data = phys_to_virt(aob->sba[i]); + void *data = dma64_to_virt(aob->sba[i]); if (test_bit(i, buf->from_kmem_cache) && data) kmem_cache_free(qeth_core_header_cache, @@ -2594,6 +2631,10 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "allcqdbf"); + /* completion */ + if (qeth_alloc_cq(card)) + goto out_err; + if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED, QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED) return 0; @@ -2629,10 +2670,6 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) queue->priority = QETH_QIB_PQUE_PRIO_DEFAULT; } - /* completion */ - if (qeth_alloc_cq(card)) - goto out_freeoutq; - return 0; out_freeoutq: @@ -2643,6 +2680,8 @@ out_freeoutq: qeth_free_buffer_pool(card); out_buffer_pool: atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); + qeth_free_cq(card); +out_err: return -ENOMEM; } @@ -2650,11 +2689,12 @@ static void qeth_free_qdio_queues(struct qeth_card *card) { int i, j; + qeth_free_cq(card); + if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) == QETH_QDIO_UNINITIALIZED) return; - qeth_free_cq(card); for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { if (card->qdio.in_q->bufs[j].rx_skb) { consume_skb(card->qdio.in_q->bufs[j].rx_skb); @@ -2918,8 +2958,8 @@ static int qeth_init_input_buffer(struct qeth_card *card, */ for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) { buf->buffer->element[i].length = PAGE_SIZE; - buf->buffer->element[i].addr = - page_to_phys(pool_entry->elements[i]); + buf->buffer->element[i].addr = u64_to_dma64( + page_to_phys(pool_entry->elements[i])); if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1) buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY; else @@ -3708,24 +3748,11 @@ static void qeth_qdio_poll(struct ccw_device *cdev, unsigned long card_ptr) int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq) { - int rc; - - if (card->options.cq == QETH_CQ_NOTAVAILABLE) { - rc = -1; - goto out; - } else { - if (card->options.cq == cq) { - rc = 0; - goto out; - } - - qeth_free_qdio_queues(card); - card->options.cq = cq; - rc = 0; - } -out: - return rc; + if (card->options.cq == QETH_CQ_NOTAVAILABLE) + return -1; + card->options.cq = cq; + return 0; } EXPORT_SYMBOL_GPL(qeth_configure_cq); @@ -3765,9 +3792,9 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err, while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) && buffer->element[e].addr) { - unsigned long phys_aob_addr = buffer->element[e].addr; + dma64_t phys_aob_addr = buffer->element[e].addr; - qeth_qdio_handle_aob(card, phys_to_virt(phys_aob_addr)); + qeth_qdio_handle_aob(card, dma64_to_virt(phys_aob_addr)); ++e; } qeth_scrub_qdio_buffer(buffer, QDIO_MAX_ELEMENTS_PER_BUFFER); @@ -4042,7 +4069,7 @@ static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf, if (hd_len) { is_first_elem = false; - buffer->element[element].addr = virt_to_phys(hdr); + buffer->element[element].addr = virt_to_dma64(hdr); buffer->element[element].length = hd_len; buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG; @@ -4063,7 +4090,7 @@ static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf, elem_length = min_t(unsigned int, length, PAGE_SIZE - offset_in_page(data)); - buffer->element[element].addr = virt_to_phys(data); + buffer->element[element].addr = virt_to_dma64(data); buffer->element[element].length = elem_length; length -= elem_length; if (is_first_elem) { @@ -4093,7 +4120,7 @@ static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf, elem_length = min_t(unsigned int, length, PAGE_SIZE - offset_in_page(data)); - buffer->element[element].addr = virt_to_phys(data); + buffer->element[element].addr = virt_to_dma64(data); buffer->element[element].length = elem_length; buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG; @@ -5569,7 +5596,7 @@ next_packet: offset = 0; } - hdr = phys_to_virt(element->addr) + offset; + hdr = dma64_to_virt(element->addr) + offset; offset += sizeof(*hdr); skb = NULL; @@ -5661,7 +5688,7 @@ use_skb: walk_packet: while (skb_len) { int data_len = min(skb_len, (int)(element->length - offset)); - char *data = phys_to_virt(element->addr) + offset; + char *data = dma64_to_virt(element->addr) + offset; skb_len -= data_len; offset += data_len; @@ -7023,14 +7050,16 @@ int qeth_open(struct net_device *dev) card->data.state = CH_STATE_UP; netif_tx_start_all_queues(dev); - local_bh_disable(); qeth_for_each_output_queue(card, queue, i) { netif_napi_add_tx(dev, &queue->napi, qeth_tx_poll); napi_enable(&queue->napi); - napi_schedule(&queue->napi); } - napi_enable(&card->napi); + + local_bh_disable(); + qeth_for_each_output_queue(card, queue, i) { + napi_schedule(&queue->napi); + } napi_schedule(&card->napi); /* kick-start the NAPI softirq: */ local_bh_enable(); diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c index c1caf7734c3e..f184c58ecf24 100644 --- a/drivers/s390/net/qeth_ethtool.c +++ b/drivers/s390/net/qeth_ethtool.c @@ -247,7 +247,7 @@ static int qeth_set_channels(struct net_device *dev, } static int qeth_get_ts_info(struct net_device *dev, - struct ethtool_ts_info *info) + struct kernel_ethtool_ts_info *info) { struct qeth_card *card = dev->ml_priv; diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c index 0a263999f7ae..cc44cbb0028b 100644 --- a/drivers/s390/net/smsgiucv_app.c +++ b/drivers/s390/net/smsgiucv_app.c @@ -156,25 +156,14 @@ static int __init smsgiucv_app_init(void) if (!MACHINE_IS_VM) return -ENODEV; - smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL); - if (!smsg_app_dev) - return -ENOMEM; - smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus); - if (!smsgiucv_drv) { - kfree(smsg_app_dev); + if (!smsgiucv_drv) return -ENODEV; - } - rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT); - if (rc) { - kfree(smsg_app_dev); - goto fail; - } - smsg_app_dev->bus = &iucv_bus; - smsg_app_dev->parent = iucv_root; - smsg_app_dev->release = (void (*)(struct device *)) kfree; - smsg_app_dev->driver = smsgiucv_drv; + smsg_app_dev = iucv_alloc_device(NULL, smsgiucv_drv, NULL, KMSG_COMPONENT); + if (!smsg_app_dev) + return -ENOMEM; + rc = device_register(smsg_app_dev); if (rc) { put_device(smsg_app_dev); |