s390/ism: move oddities of device IO to wrapper function

ISM devices are special in how they access PCI memory space. Provide
wrappers for handling commands to the device. No functional change.

Signed-off-by: Sebastian Ott <sebott@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Sebastian Ott 2019-04-23 11:57:46 +02:00 committed by Martin Schwidefsky
parent 81deca12c2
commit c475f1770a
2 changed files with 31 additions and 16 deletions

View File

@ -6,6 +6,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <net/smc.h>
#include <asm/pci_insn.h>
#define UTIL_STR_LEN 16
@ -194,8 +195,6 @@ struct ism_dev {
struct pci_dev *pdev;
struct smcd_dev *smcd;
void __iomem *ctl;
struct ism_sba *sba;
dma_addr_t sba_dma_addr;
DECLARE_BITMAP(sba_bitmap, ISM_NR_DMBS);
@ -209,6 +208,30 @@ struct ism_dev {
#define ISM_CREATE_REQ(dmb, idx, sf, offset) \
((dmb) | (idx) << 24 | (sf) << 23 | (offset))
static inline void __ism_read_cmd(struct ism_dev *ism, void *data,
unsigned long offset, unsigned long len)
{
struct zpci_dev *zdev = to_zpci(ism->pdev);
u64 req = ZPCI_CREATE_REQ(zdev->fh, 2, 8);
while (len > 0) {
__zpci_load(data, req, offset);
offset += 8;
data += 8;
len -= 8;
}
}
static inline void __ism_write_cmd(struct ism_dev *ism, void *data,
unsigned long offset, unsigned long len)
{
struct zpci_dev *zdev = to_zpci(ism->pdev);
u64 req = ZPCI_CREATE_REQ(zdev->fh, 2, len);
if (len)
__zpci_store_block(data, req, offset);
}
static inline int __ism_move(struct ism_dev *ism, u64 dmb_req, void *data,
unsigned int size)
{

View File

@ -38,19 +38,18 @@ static int ism_cmd(struct ism_dev *ism, void *cmd)
struct ism_req_hdr *req = cmd;
struct ism_resp_hdr *resp = cmd;
memcpy_toio(ism->ctl + sizeof(*req), req + 1, req->len - sizeof(*req));
memcpy_toio(ism->ctl, req, sizeof(*req));
__ism_write_cmd(ism, req + 1, sizeof(*req), req->len - sizeof(*req));
__ism_write_cmd(ism, req, 0, sizeof(*req));
WRITE_ONCE(resp->ret, ISM_ERROR);
memcpy_fromio(resp, ism->ctl, sizeof(*resp));
__ism_read_cmd(ism, resp, 0, sizeof(*resp));
if (resp->ret) {
debug_text_event(ism_debug_info, 0, "cmd failure");
debug_event(ism_debug_info, 0, resp, sizeof(*resp));
goto out;
}
memcpy_fromio(resp + 1, ism->ctl + sizeof(*resp),
resp->len - sizeof(*resp));
__ism_read_cmd(ism, resp + 1, sizeof(*resp), resp->len - sizeof(*resp));
out:
return resp->ret;
}
@ -512,13 +511,9 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret)
goto err_disable;
ism->ctl = pci_iomap(pdev, 2, 0);
if (!ism->ctl)
goto err_resource;
ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (ret)
goto err_unmap;
goto err_resource;
dma_set_seg_boundary(&pdev->dev, SZ_1M - 1);
dma_set_max_seg_size(&pdev->dev, SZ_1M);
@ -527,7 +522,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ism->smcd = smcd_alloc_dev(&pdev->dev, dev_name(&pdev->dev), &ism_ops,
ISM_NR_DMBS);
if (!ism->smcd)
goto err_unmap;
goto err_resource;
ism->smcd->priv = ism;
ret = ism_dev_init(ism);
@ -538,8 +533,6 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_free:
smcd_free_dev(ism->smcd);
err_unmap:
pci_iounmap(pdev, ism->ctl);
err_resource:
pci_release_mem_regions(pdev);
err_disable:
@ -568,7 +561,6 @@ static void ism_remove(struct pci_dev *pdev)
ism_dev_exit(ism);
smcd_free_dev(ism->smcd);
pci_iounmap(pdev, ism->ctl);
pci_release_mem_regions(pdev);
pci_disable_device(pdev);
dev_set_drvdata(&pdev->dev, NULL);