Move the fields that are specific to the s390 ism_vpci driver out of the generic ism_dev into a local ismvp_dev structure. Signed-off-by: Alexandra Winter <wintera@xxxxxxxxxxxxx> --- drivers/s390/net/ism.h | 11 +++++ drivers/s390/net/ism_drv.c | 87 +++++++++++++++++++++++--------------- include/linux/ism.h | 20 +++------ 3 files changed, 71 insertions(+), 47 deletions(-) diff --git a/drivers/s390/net/ism.h b/drivers/s390/net/ism.h index 0deca6d0e328..720a783ebf90 100644 --- a/drivers/s390/net/ism.h +++ b/drivers/s390/net/ism.h @@ -196,6 +196,17 @@ struct ism_sba { u16 dmbe_mask[ISM_NR_DMBS]; }; +struct ismvp_dev { + struct ism_dev ism; + struct ism_sba *sba; + dma_addr_t sba_dma_addr; + DECLARE_BITMAP(sba_bitmap, ISM_NR_DMBS); + + struct ism_eq *ieq; + dma_addr_t ieq_dma_addr; + int ieq_idx; +}; + #define ISM_CREATE_REQ(dmb, idx, sf, offset) \ ((dmb) | (idx) << 24 | (sf) << 23 | (offset)) diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index c0954d6dd9f5..c1fb65db504c 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -84,6 +84,7 @@ static int query_info(struct ism_dev *ism) static int register_sba(struct ism_dev *ism) { + struct ismvp_dev *ismvp; union ism_reg_sba cmd; dma_addr_t dma_handle; struct ism_sba *sba; @@ -103,14 +104,16 @@ static int register_sba(struct ism_dev *ism) return -EIO; } - ism->sba = sba; - ism->sba_dma_addr = dma_handle; + ismvp = container_of(ism, struct ismvp_dev, ism); + ismvp->sba = sba; + ismvp->sba_dma_addr = dma_handle; return 0; } static int register_ieq(struct ism_dev *ism) { + struct ismvp_dev *ismvp = container_of(ism, struct ismvp_dev, ism); union ism_reg_ieq cmd; dma_addr_t dma_handle; struct ism_eq *ieq; @@ -131,18 +134,19 @@ static int register_ieq(struct ism_dev *ism) return -EIO; } - ism->ieq = ieq; - ism->ieq_idx = -1; - ism->ieq_dma_addr = dma_handle; + ismvp->ieq = ieq; + ismvp->ieq_idx = -1; + ismvp->ieq_dma_addr = dma_handle; return 0; } static int unregister_sba(struct ism_dev *ism) { + struct ismvp_dev *ismvp = container_of(ism, struct ismvp_dev, ism); int ret; - if (!ism->sba) + if (!ismvp->sba) return 0; ret = ism_cmd_simple(ism, ISM_UNREG_SBA); @@ -150,19 +154,20 @@ static int unregister_sba(struct ism_dev *ism) return -EIO; dma_free_coherent(ism->dev.parent, PAGE_SIZE, - ism->sba, ism->sba_dma_addr); + ismvp->sba, ismvp->sba_dma_addr); - ism->sba = NULL; - ism->sba_dma_addr = 0; + ismvp->sba = NULL; + ismvp->sba_dma_addr = 0; return 0; } static int unregister_ieq(struct ism_dev *ism) { + struct ismvp_dev *ismvp = container_of(ism, struct ismvp_dev, ism); int ret; - if (!ism->ieq) + if (!ismvp->ieq) return 0; ret = ism_cmd_simple(ism, ISM_UNREG_IEQ); @@ -170,10 +175,10 @@ static int unregister_ieq(struct ism_dev *ism) return -EIO; dma_free_coherent(ism->dev.parent, PAGE_SIZE, - ism->ieq, ism->ieq_dma_addr); + ismvp->ieq, ismvp->ieq_dma_addr); - ism->ieq = NULL; - ism->ieq_dma_addr = 0; + ismvp->ieq = NULL; + ismvp->ieq_dma_addr = 0; return 0; } @@ -215,7 +220,9 @@ static int ism_query_rgid(struct ism_dev *ism, uuid_t *rgid, u32 vid_valid, static void ism_free_dmb(struct ism_dev *ism, struct ism_dmb *dmb) { - clear_bit(dmb->sba_idx, ism->sba_bitmap); + struct ismvp_dev *ismvp = container_of(ism, struct ismvp_dev, ism); + + clear_bit(dmb->sba_idx, ismvp->sba_bitmap); dma_unmap_page(ism->dev.parent, dmb->dma_addr, dmb->dmb_len, DMA_FROM_DEVICE); folio_put(virt_to_folio(dmb->cpu_addr)); @@ -223,6 +230,7 @@ static void ism_free_dmb(struct ism_dev *ism, struct ism_dmb *dmb) static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb) { + struct ismvp_dev *ismvp = container_of(ism, struct ismvp_dev, ism); struct folio *folio; unsigned long bit; int rc; @@ -231,7 +239,7 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb) return -EINVAL; if (!dmb->sba_idx) { - bit = find_next_zero_bit(ism->sba_bitmap, ISM_NR_DMBS, + bit = find_next_zero_bit(ismvp->sba_bitmap, ISM_NR_DMBS, ISM_DMB_BIT_OFFSET); if (bit == ISM_NR_DMBS) return -ENOSPC; @@ -239,7 +247,7 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb) dmb->sba_idx = bit; } if (dmb->sba_idx < ISM_DMB_BIT_OFFSET || - test_and_set_bit(dmb->sba_idx, ism->sba_bitmap)) + test_and_set_bit(dmb->sba_idx, ismvp->sba_bitmap)) return -EINVAL; folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC | @@ -264,7 +272,7 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb) out_free: kfree(dmb->cpu_addr); out_bit: - clear_bit(dmb->sba_idx, ism->sba_bitmap); + clear_bit(dmb->sba_idx, ismvp->sba_bitmap); return rc; } @@ -424,15 +432,16 @@ static u16 ism_get_chid(struct ism_dev *ism) static void ism_handle_event(struct ism_dev *ism) { + struct ismvp_dev *ismvp = container_of(ism, struct ismvp_dev, ism); struct ism_event *entry; struct ism_client *clt; int i; - while ((ism->ieq_idx + 1) != READ_ONCE(ism->ieq->header.idx)) { - if (++(ism->ieq_idx) == ARRAY_SIZE(ism->ieq->entry)) - ism->ieq_idx = 0; + while ((ismvp->ieq_idx + 1) != READ_ONCE(ismvp->ieq->header.idx)) { + if (++ismvp->ieq_idx == ARRAY_SIZE(ismvp->ieq->entry)) + ismvp->ieq_idx = 0; - entry = &ism->ieq->entry[ism->ieq_idx]; + entry = &ismvp->ieq->entry[ismvp->ieq_idx]; debug_event(ism_debug_info, 2, entry, sizeof(*entry)); for (i = 0; i < MAX_CLIENTS; ++i) { clt = ism->subs[i]; @@ -445,16 +454,19 @@ static void ism_handle_event(struct ism_dev *ism) static irqreturn_t ism_handle_irq(int irq, void *data) { struct ism_dev *ism = data; + struct ismvp_dev *ismvp; unsigned long bit, end; unsigned long *bv; u16 dmbemask; u8 client_id; - bv = (void *) &ism->sba->dmb_bits[ISM_DMB_WORD_OFFSET]; - end = sizeof(ism->sba->dmb_bits) * BITS_PER_BYTE - ISM_DMB_BIT_OFFSET; + ismvp = container_of(ism, struct ismvp_dev, ism); + + bv = (void *)&ismvp->sba->dmb_bits[ISM_DMB_WORD_OFFSET]; + end = sizeof(ismvp->sba->dmb_bits) * BITS_PER_BYTE - ISM_DMB_BIT_OFFSET; spin_lock(&ism->lock); - ism->sba->s = 0; + ismvp->sba->s = 0; barrier(); for (bit = 0;;) { bit = find_next_bit_inv(bv, end, bit); @@ -462,8 +474,8 @@ static irqreturn_t ism_handle_irq(int irq, void *data) break; clear_bit_inv(bit, bv); - dmbemask = ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET]; - ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0; + dmbemask = ismvp->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET]; + ismvp->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0; barrier(); client_id = ism->sba_client_arr[bit]; if (unlikely(client_id == NO_CLIENT || !ism->subs[client_id])) @@ -471,8 +483,8 @@ static irqreturn_t ism_handle_irq(int irq, void *data) ism->subs[client_id]->handle_irq(ism, bit + ISM_DMB_BIT_OFFSET, dmbemask); } - if (ism->sba->e) { - ism->sba->e = 0; + if (ismvp->sba->e) { + ismvp->sba->e = 0; barrier(); ism_handle_event(ism); } @@ -480,7 +492,7 @@ static irqreturn_t ism_handle_irq(int irq, void *data) return IRQ_HANDLED; } -static const struct ism_ops ism_vp_ops = { +static const struct ism_ops ismvp_ops = { .query_remote_gid = ism_query_rgid, .register_dmb = ism_register_dmb, .unregister_dmb = ism_unregister_dmb, @@ -531,7 +543,7 @@ static int ism_dev_init(struct ism_dev *ism) else ism_v2_capable = false; - ism->ops = &ism_vp_ops; + ism->ops = &ismvp_ops; ism_dev_register(ism); query_info(ism); @@ -553,12 +565,14 @@ static int ism_dev_init(struct ism_dev *ism) static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct ismvp_dev *ismvp; struct ism_dev *ism; int ret; - ism = kzalloc(sizeof(*ism), GFP_KERNEL); - if (!ism) + ismvp = kzalloc(sizeof(*ismvp), GFP_KERNEL); + if (!ismvp) return -ENOMEM; + ism = &ismvp->ism; spin_lock_init(&ism->lock); dev_set_drvdata(&pdev->dev, ism); @@ -599,6 +613,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) device_del(&ism->dev); err_dev: dev_set_drvdata(&pdev->dev, NULL); + kfree(ismvp); return ret; } @@ -627,7 +642,11 @@ static void ism_dev_exit(struct ism_dev *ism) static void ism_remove(struct pci_dev *pdev) { - struct ism_dev *ism = dev_get_drvdata(&pdev->dev); + struct ismvp_dev *ismvp; + struct ism_dev *ism; + + ism = dev_get_drvdata(&pdev->dev); + ismvp = container_of(ism, struct ismvp_dev, ism); ism_dev_exit(ism); @@ -635,7 +654,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); + kfree(ismvp); } static struct pci_driver ism_driver = { diff --git a/include/linux/ism.h b/include/linux/ism.h index 929a1f275419..f28238fb5d74 100644 --- a/include/linux/ism.h +++ b/include/linux/ism.h @@ -281,24 +281,18 @@ struct ism_ops { struct ism_dev { const struct ism_ops *ops; - spinlock_t lock; /* protects the ism device */ struct list_head list; - struct pci_dev *pdev; - - struct ism_sba *sba; - dma_addr_t sba_dma_addr; - DECLARE_BITMAP(sba_bitmap, ISM_NR_DMBS); - u8 *sba_client_arr; /* entries are indices into 'clients' array */ - void *priv[MAX_CLIENTS]; - - struct ism_eq *ieq; - dma_addr_t ieq_dma_addr; - struct device dev; uuid_t gid; - int ieq_idx; + /* get this lock before accessing any of the fields below */ + spinlock_t lock; + /* indexed by dmb idx; entries are indices into priv and subs arrays: */ + u8 *sba_client_arr; + /* Sparse array of all ISM clients */ struct ism_client *subs[MAX_CLIENTS]; + /* priv pointer per client; for client usage only */ + void *priv[MAX_CLIENTS]; }; int ism_dev_register(struct ism_dev *ism); -- 2.45.2