/** * mei_wd_host_init - connect to the watchdog client * * @dev: the device structure * @me_cl: me client * * Return: -ENOTTY if wd client cannot be found * -EIO if write has failed * 0 on success */ int mei_wd_host_init(struct mei_device *dev, struct mei_me_client *me_cl) { struct mei_cl *cl = &dev->wd_cl; int ret; mei_cl_init(cl, dev); dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; dev->wd_state = MEI_WD_IDLE; ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); if (ret < 0) { dev_info(dev->dev, "wd: failed link client\n"); return ret; } ret = mei_cl_connect(cl, me_cl, NULL); if (ret) { dev_err(dev->dev, "wd: failed to connect = %d\n", ret); mei_cl_unlink(cl); return ret; } ret = mei_watchdog_register(dev); if (ret) { mei_cl_disconnect(cl); mei_cl_unlink(cl); } return ret; }
/** * mei_amthif_host_init - mei initialization amthif client. * * @dev: the device structure * @me_cl: me client * * Return: 0 on success, <0 on failure. */ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl) { struct mei_cl *cl = &dev->iamthif_cl; int ret; mutex_lock(&dev->device_lock); if (mei_cl_is_connected(cl)) { ret = 0; goto out; } dev->iamthif_state = MEI_IAMTHIF_IDLE; mei_cl_init(cl, dev); ret = mei_cl_link(cl); if (ret < 0) { dev_err(dev->dev, "amthif: failed cl_link %d\n", ret); goto out; } ret = mei_cl_connect(cl, me_cl, NULL); out: mutex_unlock(&dev->device_lock); return ret; }
/** * mei_open - the open function * * @inode: pointer to inode structure * @file: pointer to file structure e * returns 0 on success, <0 on error */ static int mei_open(struct inode *inode, struct file *file) { struct miscdevice *misc = file->private_data; struct pci_dev *pdev; struct mei_cl *cl; struct mei_device *dev; int err; err = -ENODEV; if (!misc->parent) goto out; pdev = container_of(misc->parent, struct pci_dev, dev); dev = pci_get_drvdata(pdev); if (!dev) goto out; mutex_lock(&dev->device_lock); err = -ENOMEM; cl = mei_cl_allocate(dev); if (!cl) goto out_unlock; err = -ENODEV; if (dev->dev_state != MEI_DEV_ENABLED) { dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", mei_dev_state_str(dev->dev_state)); goto out_unlock; } err = -EMFILE; if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) { dev_err(&dev->pdev->dev, "open_handle_count exceded %d", MEI_MAX_OPEN_HANDLE_COUNT); goto out_unlock; } err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (err) goto out_unlock; file->private_data = cl; mutex_unlock(&dev->device_lock); return nonseekable_open(inode, file); out_unlock: mutex_unlock(&dev->device_lock); kfree(cl); out: return err; }
/** * mei_open - the open function * * @inode: pointer to inode structure * @file: pointer to file structure * * returns 0 on success, <0 on error */ static int mei_open(struct inode *inode, struct file *file) { struct miscdevice *misc = file->private_data; struct pci_dev *pdev; struct mei_cl *cl; struct mei_device *dev; int err; if (!misc->parent) return -ENODEV; pdev = container_of(misc->parent, struct pci_dev, dev); dev = pci_get_drvdata(pdev); if (!dev) return -ENODEV; mutex_lock(&dev->device_lock); cl = NULL; err = -ENODEV; if (dev->dev_state != MEI_DEV_ENABLED) { dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", mei_dev_state_str(dev->dev_state)); goto err_unlock; } err = -ENOMEM; cl = mei_cl_allocate(dev); if (!cl) goto err_unlock; /* open_handle_count check is handled in the mei_cl_link */ err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (err) goto err_unlock; file->private_data = cl; mutex_unlock(&dev->device_lock); return nonseekable_open(inode, file); err_unlock: mutex_unlock(&dev->device_lock); kfree(cl); return err; }
/** * mei_wd_host_init - connect to the watchdog client * * @dev: the device structure * * returns -ENENT if wd client cannot be found * -EIO if write has failed * 0 on success */ int mei_wd_host_init(struct mei_device *dev) { struct mei_cl *cl = &dev->wd_cl; int i; int ret; mei_cl_init(cl, dev); dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; dev->wd_state = MEI_WD_IDLE; /* check for valid client id */ i = mei_me_cl_by_uuid(dev, &mei_wd_guid); if (i < 0) { dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); return -ENOENT; } cl->me_client_id = dev->me_clients[i].client_id; ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); if (ret < 0) { dev_info(&dev->pdev->dev, "wd: failed link client\n"); return -ENOENT; } cl->state = MEI_FILE_CONNECTING; ret = mei_cl_connect(cl, NULL); if (ret) { dev_err(&dev->pdev->dev, "wd: failed to connect = %d\n", ret); mei_cl_unlink(cl); return ret; } ret = mei_watchdog_register(dev); if (ret) { mei_cl_disconnect(cl); mei_cl_unlink(cl); } return ret; }
int mei_nfc_host_init(struct mei_device *dev) { struct mei_nfc_dev *ndev; struct mei_cl *cl_info, *cl = NULL; struct mei_me_client *me_cl; int ret; /* in case of internal reset bail out * as the device is already setup */ cl = mei_cl_bus_find_cl_by_uuid(dev, mei_nfc_guid); if (cl) return 0; ndev = kzalloc(sizeof(struct mei_nfc_dev), GFP_KERNEL); if (!ndev) { ret = -ENOMEM; goto err; } ndev->cl_info = mei_cl_allocate(dev); ndev->cl = mei_cl_allocate(dev); cl = ndev->cl; cl_info = ndev->cl_info; if (!cl || !cl_info) { ret = -ENOMEM; goto err; } /* check for valid client id */ me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); if (!me_cl) { dev_info(dev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } cl_info->me_client_id = me_cl->client_id; cl_info->cl_uuid = me_cl->props.protocol_name; mei_me_cl_put(me_cl); ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; list_add_tail(&cl_info->device_link, &dev->device_list); /* check for valid client id */ me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); if (!me_cl) { dev_info(dev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } cl->me_client_id = me_cl->client_id; cl->cl_uuid = me_cl->props.protocol_name; mei_me_cl_put(me_cl); ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; list_add_tail(&cl->device_link, &dev->device_list); ndev->req_id = 1; INIT_WORK(&ndev->init_work, mei_nfc_init); init_waitqueue_head(&ndev->send_wq); schedule_work(&ndev->init_work); return 0; err: mei_nfc_free(ndev); return ret; }
int mei_nfc_host_init(struct mei_device *dev) { struct mei_nfc_dev *ndev = &nfc_dev; struct mei_cl *cl_info, *cl = NULL; int i, ret; /* already initialzed */ if (ndev->cl_info) return 0; ndev->cl_info = mei_cl_allocate(dev); ndev->cl = mei_cl_allocate(dev); cl = ndev->cl; cl_info = ndev->cl_info; if (!cl || !cl_info) { ret = -ENOMEM; goto err; } /* check for valid client id */ i = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); if (i < 0) { dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); ret = -ENOENT; goto err; } cl_info->me_client_id = dev->me_clients[i].client_id; ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; cl_info->device_uuid = mei_nfc_info_guid; list_add_tail(&cl_info->device_link, &dev->device_list); /* check for valid client id */ i = mei_me_cl_by_uuid(dev, &mei_nfc_guid); if (i < 0) { dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); ret = -ENOENT; goto err; } cl->me_client_id = dev->me_clients[i].client_id; ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; cl->device_uuid = mei_nfc_guid; list_add_tail(&cl->device_link, &dev->device_list); ndev->req_id = 1; INIT_WORK(&ndev->init_work, mei_nfc_init); init_waitqueue_head(&ndev->send_wq); schedule_work(&ndev->init_work); return 0; err: mei_nfc_free(ndev); return ret; }