From c93b76b34b4d8dbe8e3443eb27e49ac60034342b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 7 May 2015 15:54:02 +0300 Subject: mei: bus: report also uuid in module alias In order to automate modules matching add device uuid which is reported in client enumeration, keep also the name that is needed in for nfc distinguishing radio vendor Report mei:name:uuid Cc: linux-api@vger.kernel.org Cc: Samuel Ortiz Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/nfc/mei_phy.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/nfc/mei_phy.h') diff --git a/drivers/nfc/mei_phy.h b/drivers/nfc/mei_phy.h index d669900f8278..06608c28ff14 100644 --- a/drivers/nfc/mei_phy.h +++ b/drivers/nfc/mei_phy.h @@ -3,7 +3,10 @@ #include #include +#include +#define MEI_NFC_UUID __UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, \ + 0x94, 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c) #define MEI_NFC_HEADER_SIZE 10 #define MEI_NFC_MAX_HCI_PAYLOAD 300 -- cgit v1.2.3-59-g8ed1b From be9b720a0ccba096d669bc86634f900b82b9bf71 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 7 May 2015 15:54:04 +0300 Subject: NFC: mei_phy: move all nfc logic from mei driver to nfc move nfc logic to mei_phy module, we prefer as much as possible not to deal with a particualr client protocol in the mei generic infrasutcutre Cc: Samuel Ortiz Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 36 +----- drivers/misc/mei/mei_dev.h | 7 +- drivers/misc/mei/nfc.c | 175 +-------------------------- drivers/nfc/mei_phy.c | 293 ++++++++++++++++++++++++++++++++++++++++----- drivers/nfc/mei_phy.h | 35 ++++-- 5 files changed, 304 insertions(+), 242 deletions(-) (limited to 'drivers/nfc/mei_phy.h') diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index e76d94aa6e12..de8fd089a8a4 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -220,8 +220,7 @@ struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *dev, struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, struct mei_me_client *me_cl, struct mei_cl *cl, - char *name, - struct mei_cl_ops *ops) + char *name) { struct mei_cl_device *device; int status; @@ -235,9 +234,8 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, kfree(device); return NULL; } - device->cl = cl; - device->ops = ops; + device->cl = cl; device->dev.parent = dev->dev; device->dev.bus = &mei_cl_bus_type; device->dev.type = &mei_cl_device_type; @@ -294,7 +292,7 @@ void mei_cl_driver_unregister(struct mei_cl_driver *driver) } EXPORT_SYMBOL_GPL(mei_cl_driver_unregister); -static ssize_t ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, +ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bool blocking) { struct mei_device *dev; @@ -408,16 +406,6 @@ out: return rets; } -inline ssize_t __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length) -{ - return ___mei_cl_send(cl, buf, length, 0); -} - -inline ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length) -{ - return ___mei_cl_send(cl, buf, length, 1); -} - ssize_t mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) { struct mei_cl *cl = device->cl; @@ -425,23 +413,17 @@ ssize_t mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) if (cl == NULL) return -ENODEV; - if (device->ops && device->ops->send) - return device->ops->send(device, buf, length); - - return __mei_cl_send(cl, buf, length); + return __mei_cl_send(cl, buf, length, 1); } EXPORT_SYMBOL_GPL(mei_cl_send); ssize_t mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length) { - struct mei_cl *cl = device->cl; + struct mei_cl *cl = device->cl; if (cl == NULL) return -ENODEV; - if (device->ops && device->ops->recv) - return device->ops->recv(device, buf, length); - return __mei_cl_recv(cl, buf, length); } EXPORT_SYMBOL_GPL(mei_cl_recv); @@ -522,10 +504,7 @@ int mei_cl_enable_device(struct mei_cl_device *device) if (device->event_cb) mei_cl_read_start(device->cl, 0, NULL); - if (!device->ops || !device->ops->enable) - return 0; - - return device->ops->enable(device); + return 0; } EXPORT_SYMBOL_GPL(mei_cl_enable_device); @@ -540,9 +519,6 @@ int mei_cl_disable_device(struct mei_cl_device *device) dev = cl->dev; - if (device->ops && device->ops->disable) - device->ops->disable(device); - device->event_cb = NULL; mutex_lock(&dev->device_lock); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index ab719e674edf..2175bff2730f 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -352,12 +352,11 @@ struct mei_cl_ops { struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, struct mei_me_client *me_cl, struct mei_cl *cl, - char *name, - struct mei_cl_ops *ops); + char *name); void mei_cl_remove_device(struct mei_cl_device *device); -ssize_t __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length); -ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length); +ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, + bool blocking); ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); void mei_cl_bus_rx_event(struct mei_cl *cl); void mei_cl_bus_remove_devices(struct mei_device *dev); diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index e2a6ba0236c8..b983c4ecad38 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -95,28 +95,21 @@ struct mei_nfc_hci_hdr { * @cl: NFC host client * @cl_info: NFC info host client * @init_work: perform connection to the info client - * @send_wq: send completion wait queue * @fw_ivn: NFC Interface Version Number * @vendor_id: NFC manufacturer ID * @radio_type: NFC radio type * @bus_name: bus name * - * @req_id: message counter - * @recv_req_id: reception message counter */ struct mei_nfc_dev { struct mei_me_client *me_cl; struct mei_cl *cl; struct mei_cl *cl_info; struct work_struct init_work; - wait_queue_head_t send_wq; u8 fw_ivn; u8 vendor_id; u8 radio_type; char *bus_name; - - u16 req_id; - u16 recv_req_id; }; /* UUIDs for NFC F/W clients */ @@ -202,73 +195,6 @@ static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev) return 0; } -static int mei_nfc_connect(struct mei_nfc_dev *ndev) -{ - struct mei_device *dev; - struct mei_cl *cl; - struct mei_nfc_cmd *cmd, *reply; - struct mei_nfc_connect *connect; - struct mei_nfc_connect_resp *connect_resp; - size_t connect_length, connect_resp_length; - int bytes_recv, ret; - - cl = ndev->cl; - dev = cl->dev; - - connect_length = sizeof(struct mei_nfc_cmd) + - sizeof(struct mei_nfc_connect); - - connect_resp_length = sizeof(struct mei_nfc_cmd) + - sizeof(struct mei_nfc_connect_resp); - - cmd = kzalloc(connect_length, GFP_KERNEL); - if (!cmd) - return -ENOMEM; - connect = (struct mei_nfc_connect *)cmd->data; - - reply = kzalloc(connect_resp_length, GFP_KERNEL); - if (!reply) { - kfree(cmd); - return -ENOMEM; - } - - connect_resp = (struct mei_nfc_connect_resp *)reply->data; - - cmd->command = MEI_NFC_CMD_MAINTENANCE; - cmd->data_size = 3; - cmd->sub_command = MEI_NFC_SUBCMD_CONNECT; - connect->fw_ivn = ndev->fw_ivn; - connect->vendor_id = ndev->vendor_id; - - ret = __mei_cl_send(cl, (u8 *)cmd, connect_length); - if (ret < 0) { - dev_err(dev->dev, "Could not send connect cmd\n"); - goto err; - } - - bytes_recv = __mei_cl_recv(cl, (u8 *)reply, connect_resp_length); - if (bytes_recv < 0) { - dev_err(dev->dev, "Could not read connect response\n"); - ret = bytes_recv; - goto err; - } - - dev_info(dev->dev, "IVN 0x%x Vendor ID 0x%x\n", - connect_resp->fw_ivn, connect_resp->vendor_id); - - dev_info(dev->dev, "ME FW %d.%d.%d.%d\n", - connect_resp->me_major, connect_resp->me_minor, - connect_resp->me_hotfix, connect_resp->me_build); - - ret = 0; - -err: - kfree(reply); - kfree(cmd); - - return ret; -} - static int mei_nfc_if_version(struct mei_nfc_dev *ndev) { struct mei_device *dev; @@ -288,7 +214,7 @@ static int mei_nfc_if_version(struct mei_nfc_dev *ndev) cmd.data_size = 1; cmd.sub_command = MEI_NFC_SUBCMD_IF_VERSION; - ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd)); + ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd), 1); if (ret < 0) { dev_err(dev->dev, "Could not send IF version cmd\n"); return ret; @@ -320,100 +246,6 @@ err: return ret; } -static int mei_nfc_enable(struct mei_cl_device *cldev) -{ - struct mei_device *dev; - struct mei_nfc_dev *ndev; - int ret; - - ndev = (struct mei_nfc_dev *)cldev->priv_data; - dev = ndev->cl->dev; - - ret = mei_nfc_connect(ndev); - if (ret < 0) { - dev_err(dev->dev, "Could not connect to NFC"); - return ret; - } - - return 0; -} - -static int mei_nfc_disable(struct mei_cl_device *cldev) -{ - return 0; -} - -static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) -{ - struct mei_device *dev; - struct mei_nfc_dev *ndev; - struct mei_nfc_hci_hdr *hdr; - u8 *mei_buf; - int err; - - ndev = (struct mei_nfc_dev *) cldev->priv_data; - dev = ndev->cl->dev; - - err = -ENOMEM; - mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); - if (!mei_buf) - goto out; - - hdr = (struct mei_nfc_hci_hdr *) mei_buf; - hdr->cmd = MEI_NFC_CMD_HCI_SEND; - hdr->status = 0; - hdr->req_id = ndev->req_id; - hdr->reserved = 0; - hdr->data_size = length; - - memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); - err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE); - if (err < 0) - goto out; - - if (!wait_event_interruptible_timeout(ndev->send_wq, - ndev->recv_req_id == ndev->req_id, HZ)) { - dev_err(dev->dev, "NFC MEI command timeout\n"); - err = -ETIME; - } else { - ndev->req_id++; - } -out: - kfree(mei_buf); - return err; -} - -static int mei_nfc_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) -{ - struct mei_nfc_dev *ndev; - struct mei_nfc_hci_hdr *hci_hdr; - int received_length; - - ndev = (struct mei_nfc_dev *)cldev->priv_data; - - received_length = __mei_cl_recv(ndev->cl, buf, length); - if (received_length < 0) - return received_length; - - hci_hdr = (struct mei_nfc_hci_hdr *) buf; - - if (hci_hdr->cmd == MEI_NFC_CMD_HCI_SEND) { - ndev->recv_req_id = hci_hdr->req_id; - wake_up(&ndev->send_wq); - - return 0; - } - - return received_length; -} - -static struct mei_cl_ops nfc_ops = { - .enable = mei_nfc_enable, - .disable = mei_nfc_disable, - .send = mei_nfc_send, - .recv = mei_nfc_recv, -}; - static void mei_nfc_init(struct work_struct *work) { struct mei_device *dev; @@ -473,7 +305,7 @@ static void mei_nfc_init(struct work_struct *work) } cldev = mei_cl_add_device(dev, ndev->me_cl, ndev->cl, - ndev->bus_name, &nfc_ops); + ndev->bus_name); if (!cldev) { dev_err(dev->dev, "Could not add the NFC device to the MEI bus\n"); @@ -539,10 +371,7 @@ int mei_nfc_host_init(struct mei_device *dev, struct mei_me_client *me_cl) ndev->cl = cl; - 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; diff --git a/drivers/nfc/mei_phy.c b/drivers/nfc/mei_phy.c index 11c7cbdade66..7f1495d649bb 100644 --- a/drivers/nfc/mei_phy.c +++ b/drivers/nfc/mei_phy.c @@ -24,7 +24,52 @@ #include "mei_phy.h" -struct mei_nfc_hdr { +struct mei_nfc_cmd { + u8 command; + u8 status; + u16 req_id; + u32 reserved; + u16 data_size; + u8 sub_command; + u8 data[]; +} __packed; + +struct mei_nfc_reply { + u8 command; + u8 status; + u16 req_id; + u32 reserved; + u16 data_size; + u8 sub_command; + u8 reply_status; + u8 data[]; +} __packed; + +struct mei_nfc_if_version { + u8 radio_version_sw[3]; + u8 reserved[3]; + u8 radio_version_hw[3]; + u8 i2c_addr; + u8 fw_ivn; + u8 vendor_id; + u8 radio_type; +} __packed; + +struct mei_nfc_connect { + u8 fw_ivn; + u8 vendor_id; +} __packed; + +struct mei_nfc_connect_resp { + u8 fw_ivn; + u8 vendor_id; + u16 me_major; + u16 me_minor; + u16 me_hotfix; + u16 me_build; +} __packed; + +struct mei_nfc_hci_hdr { u8 cmd; u8 status; u16 req_id; @@ -32,6 +77,16 @@ struct mei_nfc_hdr { u16 data_size; } __packed; +#define MEI_NFC_CMD_MAINTENANCE 0x00 +#define MEI_NFC_CMD_HCI_SEND 0x01 +#define MEI_NFC_CMD_HCI_RECV 0x02 + +#define MEI_NFC_SUBCMD_CONNECT 0x00 +#define MEI_NFC_SUBCMD_IF_VERSION 0x01 + +#define MEI_NFC_HEADER_SIZE 10 + + #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) #define MEI_DUMP_SKB_IN(info, skb) \ @@ -45,51 +100,156 @@ do { \ do { \ pr_debug("%s:\n", info); \ print_hex_dump_debug("mei out: ", DUMP_PREFIX_OFFSET, \ - 16, 1, (skb)->data, (skb)->len, false); \ + 16, 1, (skb)->data, (skb)->len, false); \ } while (0) -int nfc_mei_phy_enable(void *phy_id) + +static int mei_nfc_if_version(struct nfc_mei_phy *phy) { - int r; - struct nfc_mei_phy *phy = phy_id; + + struct mei_nfc_cmd cmd; + struct mei_nfc_reply *reply = NULL; + struct mei_nfc_if_version *version; + size_t if_version_length; + int bytes_recv, r; pr_info("%s\n", __func__); - if (phy->powered == 1) - return 0; + memset(&cmd, 0, sizeof(struct mei_nfc_cmd)); + cmd.command = MEI_NFC_CMD_MAINTENANCE; + cmd.data_size = 1; + cmd.sub_command = MEI_NFC_SUBCMD_IF_VERSION; - r = mei_cl_enable_device(phy->device); + r = mei_cl_send(phy->device, (u8 *)&cmd, sizeof(struct mei_nfc_cmd)); if (r < 0) { - pr_err("Could not enable device\n"); + pr_err("Could not send IF version cmd\n"); return r; } - r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy); - if (r) { - pr_err("Event cb registration failed\n"); - mei_cl_disable_device(phy->device); - phy->powered = 0; + /* to be sure on the stack we alloc memory */ + if_version_length = sizeof(struct mei_nfc_reply) + + sizeof(struct mei_nfc_if_version); - return r; + reply = kzalloc(if_version_length, GFP_KERNEL); + if (!reply) + return -ENOMEM; + + bytes_recv = mei_cl_recv(phy->device, (u8 *)reply, if_version_length); + if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) { + pr_err("Could not read IF version\n"); + r = -EIO; + goto err; } - phy->powered = 1; + version = (struct mei_nfc_if_version *)reply->data; - return 0; + phy->fw_ivn = version->fw_ivn; + phy->vendor_id = version->vendor_id; + phy->radio_type = version->radio_type; + +err: + kfree(reply); + return r; } -EXPORT_SYMBOL_GPL(nfc_mei_phy_enable); -void nfc_mei_phy_disable(void *phy_id) +static int mei_nfc_connect(struct nfc_mei_phy *phy) { - struct nfc_mei_phy *phy = phy_id; + struct mei_nfc_cmd *cmd, *reply; + struct mei_nfc_connect *connect; + struct mei_nfc_connect_resp *connect_resp; + size_t connect_length, connect_resp_length; + int bytes_recv, r; pr_info("%s\n", __func__); - mei_cl_disable_device(phy->device); + connect_length = sizeof(struct mei_nfc_cmd) + + sizeof(struct mei_nfc_connect); - phy->powered = 0; + connect_resp_length = sizeof(struct mei_nfc_cmd) + + sizeof(struct mei_nfc_connect_resp); + + cmd = kzalloc(connect_length, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + connect = (struct mei_nfc_connect *)cmd->data; + + reply = kzalloc(connect_resp_length, GFP_KERNEL); + if (!reply) { + kfree(cmd); + return -ENOMEM; + } + + connect_resp = (struct mei_nfc_connect_resp *)reply->data; + + cmd->command = MEI_NFC_CMD_MAINTENANCE; + cmd->data_size = 3; + cmd->sub_command = MEI_NFC_SUBCMD_CONNECT; + connect->fw_ivn = phy->fw_ivn; + connect->vendor_id = phy->vendor_id; + + r = mei_cl_send(phy->device, (u8 *)cmd, connect_length); + if (r < 0) { + pr_err("Could not send connect cmd %d\n", r); + goto err; + } + + bytes_recv = mei_cl_recv(phy->device, (u8 *)reply, connect_resp_length); + if (bytes_recv < 0) { + r = bytes_recv; + pr_err("Could not read connect response %d\n", r); + goto err; + } + + pr_info("IVN 0x%x Vendor ID 0x%x\n", + connect_resp->fw_ivn, connect_resp->vendor_id); + + pr_info("ME FW %d.%d.%d.%d\n", + connect_resp->me_major, connect_resp->me_minor, + connect_resp->me_hotfix, connect_resp->me_build); + + r = 0; + +err: + kfree(reply); + kfree(cmd); + + return r; +} + +static int mei_nfc_send(struct nfc_mei_phy *phy, u8 *buf, size_t length) +{ + struct mei_nfc_hci_hdr *hdr; + u8 *mei_buf; + int err; + + err = -ENOMEM; + mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); + if (!mei_buf) + goto out; + + hdr = (struct mei_nfc_hci_hdr *) mei_buf; + hdr->cmd = MEI_NFC_CMD_HCI_SEND; + hdr->status = 0; + hdr->req_id = phy->req_id; + hdr->reserved = 0; + hdr->data_size = length; + + memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); + err = mei_cl_send(phy->device, mei_buf, length + MEI_NFC_HEADER_SIZE); + if (err < 0) + goto out; + + if (!wait_event_interruptible_timeout(phy->send_wq, + phy->recv_req_id == phy->req_id, HZ)) { + pr_err("NFC MEI command timeout\n"); + err = -ETIME; + } else { + phy->req_id++; + } +out: + kfree(mei_buf); + return err; } -EXPORT_SYMBOL_GPL(nfc_mei_phy_disable); /* * Writing a frame must not return the number of written bytes. @@ -103,14 +263,37 @@ static int nfc_mei_phy_write(void *phy_id, struct sk_buff *skb) MEI_DUMP_SKB_OUT("mei frame sent", skb); - r = mei_cl_send(phy->device, skb->data, skb->len); + r = mei_nfc_send(phy, skb->data, skb->len); if (r > 0) r = 0; return r; } -void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context) +static int mei_nfc_recv(struct nfc_mei_phy *phy, u8 *buf, size_t length) +{ + struct mei_nfc_hci_hdr *hci_hdr; + int received_length; + + received_length = mei_cl_recv(phy->device, buf, length); + if (received_length < 0) + return received_length; + + hci_hdr = (struct mei_nfc_hci_hdr *) buf; + + if (hci_hdr->cmd == MEI_NFC_CMD_HCI_SEND) { + phy->recv_req_id = hci_hdr->req_id; + wake_up(&phy->send_wq); + + return 0; + } + + return received_length; +} + + +static void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, + void *context) { struct nfc_mei_phy *phy = context; @@ -125,7 +308,7 @@ void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context) if (!skb) return; - reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); + reply_size = mei_nfc_recv(phy, skb->data, MEI_NFC_MAX_READ); if (reply_size < MEI_NFC_HEADER_SIZE) { kfree_skb(skb); return; @@ -139,7 +322,61 @@ void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context) nfc_hci_recv_frame(phy->hdev, skb); } } -EXPORT_SYMBOL_GPL(nfc_mei_event_cb); + +static int nfc_mei_phy_enable(void *phy_id) +{ + int r; + struct nfc_mei_phy *phy = phy_id; + + pr_info("%s\n", __func__); + + if (phy->powered == 1) + return 0; + + r = mei_cl_enable_device(phy->device); + if (r < 0) { + pr_err("Could not enable device %d\n", r); + return r; + } + + r = mei_nfc_if_version(phy); + if (r < 0) { + pr_err("Could not enable device %d\n", r); + goto err; + } + + r = mei_nfc_connect(phy); + if (r < 0) { + pr_err("Could not connect to device %d\n", r); + goto err; + } + + r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy); + if (r) { + pr_err("Event cb registration failed %d\n", r); + goto err; + } + + phy->powered = 1; + + return 0; + +err: + phy->powered = 0; + mei_cl_disable_device(phy->device); + return r; +} + +static void nfc_mei_phy_disable(void *phy_id) +{ + struct nfc_mei_phy *phy = phy_id; + + pr_info("%s\n", __func__); + + mei_cl_disable_device(phy->device); + + phy->powered = 0; +} struct nfc_phy_ops mei_phy_ops = { .write = nfc_mei_phy_write, @@ -157,6 +394,7 @@ struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device) return NULL; phy->device = device; + init_waitqueue_head(&phy->send_wq); mei_cl_set_drvdata(device, phy); return phy; @@ -165,6 +403,7 @@ EXPORT_SYMBOL_GPL(nfc_mei_phy_alloc); void nfc_mei_phy_free(struct nfc_mei_phy *phy) { + mei_cl_disable_device(phy->device); kfree(phy); } EXPORT_SYMBOL_GPL(nfc_mei_phy_free); diff --git a/drivers/nfc/mei_phy.h b/drivers/nfc/mei_phy.h index 06608c28ff14..a51f8f2685cc 100644 --- a/drivers/nfc/mei_phy.h +++ b/drivers/nfc/mei_phy.h @@ -10,23 +10,42 @@ #define MEI_NFC_HEADER_SIZE 10 #define MEI_NFC_MAX_HCI_PAYLOAD 300 +/** + * struct nfc_mei_phy + * + * @device: mei device + * @hdev: nfc hci device + + * @send_wq: send completion wait queue + * @fw_ivn: NFC Interface Version Number + * @vendor_id: NFC manufacturer ID + * @radio_type: NFC radio type + * @reserved: reserved for alignment + * @req_id: message counter + * @recv_req_id: reception message counter + * @powered: the device is in powered state + * @hard_fault: < 0 if hardware error occurred + * and prevents normal operation. + */ struct nfc_mei_phy { struct mei_cl_device *device; struct nfc_hci_dev *hdev; - int powered; + wait_queue_head_t send_wq; + u8 fw_ivn; + u8 vendor_id; + u8 radio_type; + u8 reserved; + + u16 req_id; + u16 recv_req_id; - int hard_fault; /* - * < 0 if hardware error occured - * and prevents normal operation. - */ + int powered; + int hard_fault; }; extern struct nfc_phy_ops mei_phy_ops; -int nfc_mei_phy_enable(void *phy_id); -void nfc_mei_phy_disable(void *phy_id); -void nfc_mei_event_cb(struct mei_cl_device *device, u32 events, void *context); struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *device); void nfc_mei_phy_free(struct nfc_mei_phy *phy); -- cgit v1.2.3-59-g8ed1b From b144ce2d37619e05afdb0a15676500d76a64b1be Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 27 May 2015 17:17:27 -0700 Subject: mei: fix up uuid matching A previous commit, c93b76b34b4d ("mei: bus: report also uuid in module alias") caused a build error as I missed applying a needed patch to add some macros to uapi/linux/uuid.h. Instead of those additional macros, change the mei code to use the existing uuid structure directly. Fixes: c93b76b34b4d Cc: Tomas Winkler Cc: Samuel Ortiz Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 9 ++------- drivers/nfc/mei_phy.h | 2 +- include/linux/mod_devicetable.h | 2 +- scripts/mod/file2alias.c | 7 +++++-- 4 files changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/nfc/mei_phy.h') diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index de8fd089a8a4..357b6ae4d207 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -30,11 +30,6 @@ #define to_mei_cl_driver(d) container_of(d, struct mei_cl_driver, driver) #define to_mei_cl_device(d) container_of(d, struct mei_cl_device, dev) -static inline uuid_le uuid_le_cast(const __u8 uuid[16]) -{ - return *(uuid_le *)uuid; -} - static int mei_cl_device_match(struct device *dev, struct device_driver *drv) { struct mei_cl_device *device = to_mei_cl_device(dev); @@ -54,9 +49,9 @@ static int mei_cl_device_match(struct device *dev, struct device_driver *drv) id = driver->id_table; - while (uuid_le_cmp(NULL_UUID_LE, uuid_le_cast(id->uuid))) { + while (uuid_le_cmp(NULL_UUID_LE, id->uuid)) { - if (!uuid_le_cmp(*uuid, uuid_le_cast(id->uuid))) { + if (!uuid_le_cmp(*uuid, id->uuid)) { if (id->name[0]) { if (!strncmp(name, id->name, sizeof(id->name))) return 1; diff --git a/drivers/nfc/mei_phy.h b/drivers/nfc/mei_phy.h index a51f8f2685cc..fbfa3e61738f 100644 --- a/drivers/nfc/mei_phy.h +++ b/drivers/nfc/mei_phy.h @@ -5,7 +5,7 @@ #include #include -#define MEI_NFC_UUID __UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, \ +#define MEI_NFC_UUID UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, \ 0x94, 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c) #define MEI_NFC_HEADER_SIZE 10 #define MEI_NFC_MAX_HCI_PAYLOAD 300 diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 2d2b2b571d61..048c270822f9 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -614,7 +614,7 @@ struct ipack_device_id { */ struct mei_cl_device_id { char name[MEI_CL_NAME_SIZE]; - __u8 uuid[16]; + uuid_le uuid; kernel_ulong_t driver_info; }; diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 62c517f4b592..718b2a29bd43 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -34,6 +34,9 @@ typedef Elf64_Addr kernel_ulong_t; typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; +typedef struct { + __u8 b[16]; +} uuid_le; /* Big exception to the "don't include kernel headers into userspace, which * even potentially has different endianness and word sizes, since @@ -131,13 +134,13 @@ static inline void add_wildcard(char *str) strcat(str + len, "*"); } -static inline void add_uuid(char *str, __u8 uuid[16]) +static inline void add_uuid(char *str, uuid_le uuid) { int len = strlen(str); int i; for (i = 0; i < 16; i++) - sprintf(str + len + (i << 1), "%02x", uuid[i]); + sprintf(str + len + (i << 1), "%02x", uuid.b[i]); } /** -- cgit v1.2.3-59-g8ed1b