Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright IBM Corp. 2012
0004  *
0005  * Author(s):
0006  *   Jan Glauber <jang@linux.vnet.ibm.com>
0007  */
0008 
0009 #define KMSG_COMPONENT "zpci"
0010 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0011 
0012 #include <linux/compat.h>
0013 #include <linux/kernel.h>
0014 #include <linux/miscdevice.h>
0015 #include <linux/slab.h>
0016 #include <linux/err.h>
0017 #include <linux/delay.h>
0018 #include <linux/pci.h>
0019 #include <linux/uaccess.h>
0020 #include <asm/asm-extable.h>
0021 #include <asm/pci_debug.h>
0022 #include <asm/pci_clp.h>
0023 #include <asm/clp.h>
0024 #include <uapi/asm/clp.h>
0025 
0026 #include "pci_bus.h"
0027 
0028 bool zpci_unique_uid;
0029 
0030 void update_uid_checking(bool new)
0031 {
0032     if (zpci_unique_uid != new)
0033         zpci_dbg(3, "uid checking:%d\n", new);
0034 
0035     zpci_unique_uid = new;
0036 }
0037 
0038 static inline void zpci_err_clp(unsigned int rsp, int rc)
0039 {
0040     struct {
0041         unsigned int rsp;
0042         int rc;
0043     } __packed data = {rsp, rc};
0044 
0045     zpci_err_hex(&data, sizeof(data));
0046 }
0047 
0048 /*
0049  * Call Logical Processor with c=1, lps=0 and command 1
0050  * to get the bit mask of installed logical processors
0051  */
0052 static inline int clp_get_ilp(unsigned long *ilp)
0053 {
0054     unsigned long mask;
0055     int cc = 3;
0056 
0057     asm volatile (
0058         "   .insn   rrf,0xb9a00000,%[mask],%[cmd],8,0\n"
0059         "0: ipm %[cc]\n"
0060         "   srl %[cc],28\n"
0061         "1:\n"
0062         EX_TABLE(0b, 1b)
0063         : [cc] "+d" (cc), [mask] "=d" (mask) : [cmd] "a" (1)
0064         : "cc");
0065     *ilp = mask;
0066     return cc;
0067 }
0068 
0069 /*
0070  * Call Logical Processor with c=0, the give constant lps and an lpcb request.
0071  */
0072 static __always_inline int clp_req(void *data, unsigned int lps)
0073 {
0074     struct { u8 _[CLP_BLK_SIZE]; } *req = data;
0075     u64 ignored;
0076     int cc = 3;
0077 
0078     asm volatile (
0079         "   .insn   rrf,0xb9a00000,%[ign],%[req],0,%[lps]\n"
0080         "0: ipm %[cc]\n"
0081         "   srl %[cc],28\n"
0082         "1:\n"
0083         EX_TABLE(0b, 1b)
0084         : [cc] "+d" (cc), [ign] "=d" (ignored), "+m" (*req)
0085         : [req] "a" (req), [lps] "i" (lps)
0086         : "cc");
0087     return cc;
0088 }
0089 
0090 static void *clp_alloc_block(gfp_t gfp_mask)
0091 {
0092     return (void *) __get_free_pages(gfp_mask, get_order(CLP_BLK_SIZE));
0093 }
0094 
0095 static void clp_free_block(void *ptr)
0096 {
0097     free_pages((unsigned long) ptr, get_order(CLP_BLK_SIZE));
0098 }
0099 
0100 static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
0101                       struct clp_rsp_query_pci_grp *response)
0102 {
0103     zdev->tlb_refresh = response->refresh;
0104     zdev->dma_mask = response->dasm;
0105     zdev->msi_addr = response->msia;
0106     zdev->max_msi = response->noi;
0107     zdev->fmb_update = response->mui;
0108     zdev->version = response->version;
0109     zdev->maxstbl = response->maxstbl;
0110     zdev->dtsm = response->dtsm;
0111 
0112     switch (response->version) {
0113     case 1:
0114         zdev->max_bus_speed = PCIE_SPEED_5_0GT;
0115         break;
0116     default:
0117         zdev->max_bus_speed = PCI_SPEED_UNKNOWN;
0118         break;
0119     }
0120 }
0121 
0122 static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid)
0123 {
0124     struct clp_req_rsp_query_pci_grp *rrb;
0125     int rc;
0126 
0127     rrb = clp_alloc_block(GFP_KERNEL);
0128     if (!rrb)
0129         return -ENOMEM;
0130 
0131     memset(rrb, 0, sizeof(*rrb));
0132     rrb->request.hdr.len = sizeof(rrb->request);
0133     rrb->request.hdr.cmd = CLP_QUERY_PCI_FNGRP;
0134     rrb->response.hdr.len = sizeof(rrb->response);
0135     rrb->request.pfgid = pfgid;
0136 
0137     rc = clp_req(rrb, CLP_LPS_PCI);
0138     if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
0139         clp_store_query_pci_fngrp(zdev, &rrb->response);
0140     else {
0141         zpci_err("Q PCI FGRP:\n");
0142         zpci_err_clp(rrb->response.hdr.rsp, rc);
0143         rc = -EIO;
0144     }
0145     clp_free_block(rrb);
0146     return rc;
0147 }
0148 
0149 static int clp_store_query_pci_fn(struct zpci_dev *zdev,
0150                   struct clp_rsp_query_pci *response)
0151 {
0152     int i;
0153 
0154     for (i = 0; i < PCI_STD_NUM_BARS; i++) {
0155         zdev->bars[i].val = le32_to_cpu(response->bar[i]);
0156         zdev->bars[i].size = response->bar_size[i];
0157     }
0158     zdev->start_dma = response->sdma;
0159     zdev->end_dma = response->edma;
0160     zdev->pchid = response->pchid;
0161     zdev->pfgid = response->pfgid;
0162     zdev->pft = response->pft;
0163     zdev->vfn = response->vfn;
0164     zdev->port = response->port;
0165     zdev->uid = response->uid;
0166     zdev->fmb_length = sizeof(u32) * response->fmb_len;
0167     zdev->rid_available = response->rid_avail;
0168     zdev->is_physfn = response->is_physfn;
0169     if (!s390_pci_no_rid && zdev->rid_available)
0170         zdev->devfn = response->rid & ZPCI_RID_MASK_DEVFN;
0171 
0172     memcpy(zdev->pfip, response->pfip, sizeof(zdev->pfip));
0173     if (response->util_str_avail) {
0174         memcpy(zdev->util_str, response->util_str,
0175                sizeof(zdev->util_str));
0176         zdev->util_str_avail = 1;
0177     }
0178     zdev->mio_capable = response->mio_addr_avail;
0179     for (i = 0; i < PCI_STD_NUM_BARS; i++) {
0180         if (!(response->mio.valid & (1 << (PCI_STD_NUM_BARS - i - 1))))
0181             continue;
0182 
0183         zdev->bars[i].mio_wb = (void __iomem *) response->mio.addr[i].wb;
0184         zdev->bars[i].mio_wt = (void __iomem *) response->mio.addr[i].wt;
0185     }
0186     return 0;
0187 }
0188 
0189 int clp_query_pci_fn(struct zpci_dev *zdev)
0190 {
0191     struct clp_req_rsp_query_pci *rrb;
0192     int rc;
0193 
0194     rrb = clp_alloc_block(GFP_KERNEL);
0195     if (!rrb)
0196         return -ENOMEM;
0197 
0198     memset(rrb, 0, sizeof(*rrb));
0199     rrb->request.hdr.len = sizeof(rrb->request);
0200     rrb->request.hdr.cmd = CLP_QUERY_PCI_FN;
0201     rrb->response.hdr.len = sizeof(rrb->response);
0202     rrb->request.fh = zdev->fh;
0203 
0204     rc = clp_req(rrb, CLP_LPS_PCI);
0205     if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
0206         rc = clp_store_query_pci_fn(zdev, &rrb->response);
0207         if (rc)
0208             goto out;
0209         rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid);
0210     } else {
0211         zpci_err("Q PCI FN:\n");
0212         zpci_err_clp(rrb->response.hdr.rsp, rc);
0213         rc = -EIO;
0214     }
0215 out:
0216     clp_free_block(rrb);
0217     return rc;
0218 }
0219 
0220 /**
0221  * clp_set_pci_fn() - Execute a command on a PCI function
0222  * @zdev: Function that will be affected
0223  * @fh: Out parameter for updated function handle
0224  * @nr_dma_as: DMA address space number
0225  * @command: The command code to execute
0226  *
0227  * Returns: 0 on success, < 0 for Linux errors (e.g. -ENOMEM), and
0228  * > 0 for non-success platform responses
0229  */
0230 static int clp_set_pci_fn(struct zpci_dev *zdev, u32 *fh, u8 nr_dma_as, u8 command)
0231 {
0232     struct clp_req_rsp_set_pci *rrb;
0233     int rc, retries = 100;
0234     u32 gisa = 0;
0235 
0236     *fh = 0;
0237     rrb = clp_alloc_block(GFP_KERNEL);
0238     if (!rrb)
0239         return -ENOMEM;
0240 
0241     if (command != CLP_SET_DISABLE_PCI_FN)
0242         gisa = zdev->gisa;
0243 
0244     do {
0245         memset(rrb, 0, sizeof(*rrb));
0246         rrb->request.hdr.len = sizeof(rrb->request);
0247         rrb->request.hdr.cmd = CLP_SET_PCI_FN;
0248         rrb->response.hdr.len = sizeof(rrb->response);
0249         rrb->request.fh = zdev->fh;
0250         rrb->request.oc = command;
0251         rrb->request.ndas = nr_dma_as;
0252         rrb->request.gisa = gisa;
0253 
0254         rc = clp_req(rrb, CLP_LPS_PCI);
0255         if (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY) {
0256             retries--;
0257             if (retries < 0)
0258                 break;
0259             msleep(20);
0260         }
0261     } while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY);
0262 
0263     if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
0264         *fh = rrb->response.fh;
0265     } else {
0266         zpci_err("Set PCI FN:\n");
0267         zpci_err_clp(rrb->response.hdr.rsp, rc);
0268         if (!rc)
0269             rc = rrb->response.hdr.rsp;
0270     }
0271     clp_free_block(rrb);
0272     return rc;
0273 }
0274 
0275 int clp_setup_writeback_mio(void)
0276 {
0277     struct clp_req_rsp_slpc_pci *rrb;
0278     u8  wb_bit_pos;
0279     int rc;
0280 
0281     rrb = clp_alloc_block(GFP_KERNEL);
0282     if (!rrb)
0283         return -ENOMEM;
0284 
0285     memset(rrb, 0, sizeof(*rrb));
0286     rrb->request.hdr.len = sizeof(rrb->request);
0287     rrb->request.hdr.cmd = CLP_SLPC;
0288     rrb->response.hdr.len = sizeof(rrb->response);
0289 
0290     rc = clp_req(rrb, CLP_LPS_PCI);
0291     if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
0292         if (rrb->response.vwb) {
0293             wb_bit_pos = rrb->response.mio_wb;
0294             set_bit_inv(wb_bit_pos, &mio_wb_bit_mask);
0295             zpci_dbg(3, "wb bit: %d\n", wb_bit_pos);
0296         } else {
0297             zpci_dbg(3, "wb bit: n.a.\n");
0298         }
0299 
0300     } else {
0301         zpci_err("SLPC PCI:\n");
0302         zpci_err_clp(rrb->response.hdr.rsp, rc);
0303         rc = -EIO;
0304     }
0305     clp_free_block(rrb);
0306     return rc;
0307 }
0308 
0309 int clp_enable_fh(struct zpci_dev *zdev, u32 *fh, u8 nr_dma_as)
0310 {
0311     int rc;
0312 
0313     rc = clp_set_pci_fn(zdev, fh, nr_dma_as, CLP_SET_ENABLE_PCI_FN);
0314     zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, *fh, rc);
0315     if (!rc && zpci_use_mio(zdev)) {
0316         rc = clp_set_pci_fn(zdev, fh, nr_dma_as, CLP_SET_ENABLE_MIO);
0317         zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n",
0318                 zdev->fid, *fh, rc);
0319         if (rc)
0320             clp_disable_fh(zdev, fh);
0321     }
0322     return rc;
0323 }
0324 
0325 int clp_disable_fh(struct zpci_dev *zdev, u32 *fh)
0326 {
0327     int rc;
0328 
0329     if (!zdev_enabled(zdev))
0330         return 0;
0331 
0332     rc = clp_set_pci_fn(zdev, fh, 0, CLP_SET_DISABLE_PCI_FN);
0333     zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, *fh, rc);
0334     return rc;
0335 }
0336 
0337 static int clp_list_pci_req(struct clp_req_rsp_list_pci *rrb,
0338                 u64 *resume_token, int *nentries)
0339 {
0340     int rc;
0341 
0342     memset(rrb, 0, sizeof(*rrb));
0343     rrb->request.hdr.len = sizeof(rrb->request);
0344     rrb->request.hdr.cmd = CLP_LIST_PCI;
0345     /* store as many entries as possible */
0346     rrb->response.hdr.len = CLP_BLK_SIZE - LIST_PCI_HDR_LEN;
0347     rrb->request.resume_token = *resume_token;
0348 
0349     /* Get PCI function handle list */
0350     rc = clp_req(rrb, CLP_LPS_PCI);
0351     if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
0352         zpci_err("List PCI FN:\n");
0353         zpci_err_clp(rrb->response.hdr.rsp, rc);
0354         return -EIO;
0355     }
0356 
0357     update_uid_checking(rrb->response.uid_checking);
0358     WARN_ON_ONCE(rrb->response.entry_size !=
0359         sizeof(struct clp_fh_list_entry));
0360 
0361     *nentries = (rrb->response.hdr.len - LIST_PCI_HDR_LEN) /
0362         rrb->response.entry_size;
0363     *resume_token = rrb->response.resume_token;
0364 
0365     return rc;
0366 }
0367 
0368 static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, void *data,
0369             void (*cb)(struct clp_fh_list_entry *, void *))
0370 {
0371     u64 resume_token = 0;
0372     int nentries, i, rc;
0373 
0374     do {
0375         rc = clp_list_pci_req(rrb, &resume_token, &nentries);
0376         if (rc)
0377             return rc;
0378         for (i = 0; i < nentries; i++)
0379             cb(&rrb->response.fh_list[i], data);
0380     } while (resume_token);
0381 
0382     return rc;
0383 }
0384 
0385 static int clp_find_pci(struct clp_req_rsp_list_pci *rrb, u32 fid,
0386             struct clp_fh_list_entry *entry)
0387 {
0388     struct clp_fh_list_entry *fh_list;
0389     u64 resume_token = 0;
0390     int nentries, i, rc;
0391 
0392     do {
0393         rc = clp_list_pci_req(rrb, &resume_token, &nentries);
0394         if (rc)
0395             return rc;
0396         fh_list = rrb->response.fh_list;
0397         for (i = 0; i < nentries; i++) {
0398             if (fh_list[i].fid == fid) {
0399                 *entry = fh_list[i];
0400                 return 0;
0401             }
0402         }
0403     } while (resume_token);
0404 
0405     return -ENODEV;
0406 }
0407 
0408 static void __clp_add(struct clp_fh_list_entry *entry, void *data)
0409 {
0410     struct zpci_dev *zdev;
0411 
0412     if (!entry->vendor_id)
0413         return;
0414 
0415     zdev = get_zdev_by_fid(entry->fid);
0416     if (zdev) {
0417         zpci_zdev_put(zdev);
0418         return;
0419     }
0420     zpci_create_device(entry->fid, entry->fh, entry->config_state);
0421 }
0422 
0423 int clp_scan_pci_devices(void)
0424 {
0425     struct clp_req_rsp_list_pci *rrb;
0426     int rc;
0427 
0428     rrb = clp_alloc_block(GFP_KERNEL);
0429     if (!rrb)
0430         return -ENOMEM;
0431 
0432     rc = clp_list_pci(rrb, NULL, __clp_add);
0433 
0434     clp_free_block(rrb);
0435     return rc;
0436 }
0437 
0438 /*
0439  * Get the current function handle of the function matching @fid
0440  */
0441 int clp_refresh_fh(u32 fid, u32 *fh)
0442 {
0443     struct clp_req_rsp_list_pci *rrb;
0444     struct clp_fh_list_entry entry;
0445     int rc;
0446 
0447     rrb = clp_alloc_block(GFP_NOWAIT);
0448     if (!rrb)
0449         return -ENOMEM;
0450 
0451     rc = clp_find_pci(rrb, fid, &entry);
0452     if (!rc)
0453         *fh = entry.fh;
0454 
0455     clp_free_block(rrb);
0456     return rc;
0457 }
0458 
0459 int clp_get_state(u32 fid, enum zpci_state *state)
0460 {
0461     struct clp_req_rsp_list_pci *rrb;
0462     struct clp_fh_list_entry entry;
0463     int rc;
0464 
0465     rrb = clp_alloc_block(GFP_ATOMIC);
0466     if (!rrb)
0467         return -ENOMEM;
0468 
0469     rc = clp_find_pci(rrb, fid, &entry);
0470     if (!rc) {
0471         *state = entry.config_state;
0472     } else if (rc == -ENODEV) {
0473         *state = ZPCI_FN_STATE_RESERVED;
0474         rc = 0;
0475     }
0476 
0477     clp_free_block(rrb);
0478     return rc;
0479 }
0480 
0481 static int clp_base_slpc(struct clp_req *req, struct clp_req_rsp_slpc *lpcb)
0482 {
0483     unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
0484 
0485     if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
0486         lpcb->response.hdr.len > limit)
0487         return -EINVAL;
0488     return clp_req(lpcb, CLP_LPS_BASE) ? -EOPNOTSUPP : 0;
0489 }
0490 
0491 static int clp_base_command(struct clp_req *req, struct clp_req_hdr *lpcb)
0492 {
0493     switch (lpcb->cmd) {
0494     case 0x0001: /* store logical-processor characteristics */
0495         return clp_base_slpc(req, (void *) lpcb);
0496     default:
0497         return -EINVAL;
0498     }
0499 }
0500 
0501 static int clp_pci_slpc(struct clp_req *req, struct clp_req_rsp_slpc_pci *lpcb)
0502 {
0503     unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
0504 
0505     if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
0506         lpcb->response.hdr.len > limit)
0507         return -EINVAL;
0508     return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
0509 }
0510 
0511 static int clp_pci_list(struct clp_req *req, struct clp_req_rsp_list_pci *lpcb)
0512 {
0513     unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
0514 
0515     if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
0516         lpcb->response.hdr.len > limit)
0517         return -EINVAL;
0518     if (lpcb->request.reserved2 != 0)
0519         return -EINVAL;
0520     return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
0521 }
0522 
0523 static int clp_pci_query(struct clp_req *req,
0524              struct clp_req_rsp_query_pci *lpcb)
0525 {
0526     unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
0527 
0528     if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
0529         lpcb->response.hdr.len > limit)
0530         return -EINVAL;
0531     if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0)
0532         return -EINVAL;
0533     return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
0534 }
0535 
0536 static int clp_pci_query_grp(struct clp_req *req,
0537                  struct clp_req_rsp_query_pci_grp *lpcb)
0538 {
0539     unsigned long limit = PAGE_SIZE - sizeof(lpcb->request);
0540 
0541     if (lpcb->request.hdr.len != sizeof(lpcb->request) ||
0542         lpcb->response.hdr.len > limit)
0543         return -EINVAL;
0544     if (lpcb->request.reserved2 != 0 || lpcb->request.reserved3 != 0 ||
0545         lpcb->request.reserved4 != 0)
0546         return -EINVAL;
0547     return clp_req(lpcb, CLP_LPS_PCI) ? -EOPNOTSUPP : 0;
0548 }
0549 
0550 static int clp_pci_command(struct clp_req *req, struct clp_req_hdr *lpcb)
0551 {
0552     switch (lpcb->cmd) {
0553     case 0x0001: /* store logical-processor characteristics */
0554         return clp_pci_slpc(req, (void *) lpcb);
0555     case 0x0002: /* list PCI functions */
0556         return clp_pci_list(req, (void *) lpcb);
0557     case 0x0003: /* query PCI function */
0558         return clp_pci_query(req, (void *) lpcb);
0559     case 0x0004: /* query PCI function group */
0560         return clp_pci_query_grp(req, (void *) lpcb);
0561     default:
0562         return -EINVAL;
0563     }
0564 }
0565 
0566 static int clp_normal_command(struct clp_req *req)
0567 {
0568     struct clp_req_hdr *lpcb;
0569     void __user *uptr;
0570     int rc;
0571 
0572     rc = -EINVAL;
0573     if (req->lps != 0 && req->lps != 2)
0574         goto out;
0575 
0576     rc = -ENOMEM;
0577     lpcb = clp_alloc_block(GFP_KERNEL);
0578     if (!lpcb)
0579         goto out;
0580 
0581     rc = -EFAULT;
0582     uptr = (void __force __user *)(unsigned long) req->data_p;
0583     if (copy_from_user(lpcb, uptr, PAGE_SIZE) != 0)
0584         goto out_free;
0585 
0586     rc = -EINVAL;
0587     if (lpcb->fmt != 0 || lpcb->reserved1 != 0 || lpcb->reserved2 != 0)
0588         goto out_free;
0589 
0590     switch (req->lps) {
0591     case 0:
0592         rc = clp_base_command(req, lpcb);
0593         break;
0594     case 2:
0595         rc = clp_pci_command(req, lpcb);
0596         break;
0597     }
0598     if (rc)
0599         goto out_free;
0600 
0601     rc = -EFAULT;
0602     if (copy_to_user(uptr, lpcb, PAGE_SIZE) != 0)
0603         goto out_free;
0604 
0605     rc = 0;
0606 
0607 out_free:
0608     clp_free_block(lpcb);
0609 out:
0610     return rc;
0611 }
0612 
0613 static int clp_immediate_command(struct clp_req *req)
0614 {
0615     void __user *uptr;
0616     unsigned long ilp;
0617     int exists;
0618 
0619     if (req->cmd > 1 || clp_get_ilp(&ilp) != 0)
0620         return -EINVAL;
0621 
0622     uptr = (void __force __user *)(unsigned long) req->data_p;
0623     if (req->cmd == 0) {
0624         /* Command code 0: test for a specific processor */
0625         exists = test_bit_inv(req->lps, &ilp);
0626         return put_user(exists, (int __user *) uptr);
0627     }
0628     /* Command code 1: return bit mask of installed processors */
0629     return put_user(ilp, (unsigned long __user *) uptr);
0630 }
0631 
0632 static long clp_misc_ioctl(struct file *filp, unsigned int cmd,
0633                unsigned long arg)
0634 {
0635     struct clp_req req;
0636     void __user *argp;
0637 
0638     if (cmd != CLP_SYNC)
0639         return -EINVAL;
0640 
0641     argp = is_compat_task() ? compat_ptr(arg) : (void __user *) arg;
0642     if (copy_from_user(&req, argp, sizeof(req)))
0643         return -EFAULT;
0644     if (req.r != 0)
0645         return -EINVAL;
0646     return req.c ? clp_immediate_command(&req) : clp_normal_command(&req);
0647 }
0648 
0649 static int clp_misc_release(struct inode *inode, struct file *filp)
0650 {
0651     return 0;
0652 }
0653 
0654 static const struct file_operations clp_misc_fops = {
0655     .owner = THIS_MODULE,
0656     .open = nonseekable_open,
0657     .release = clp_misc_release,
0658     .unlocked_ioctl = clp_misc_ioctl,
0659     .compat_ioctl = clp_misc_ioctl,
0660     .llseek = no_llseek,
0661 };
0662 
0663 static struct miscdevice clp_misc_device = {
0664     .minor = MISC_DYNAMIC_MINOR,
0665     .name = "clp",
0666     .fops = &clp_misc_fops,
0667 };
0668 
0669 static int __init clp_misc_init(void)
0670 {
0671     return misc_register(&clp_misc_device);
0672 }
0673 
0674 device_initcall(clp_misc_init);