From: Oren Weil <oren.jer.weil@intel.com>
To: gregkh@suse.de
Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
alan@linux.intel.com, david@woodhou.se,
Oren Weil <oren.jer.weil@intel.com>
Subject: [PATCH 3/8] staging/mei: MEI "Link" layer code - MEI Hardware communications.
Date: Wed, 27 Apr 2011 13:27:32 +0300 [thread overview]
Message-ID: <1303900057-21694-4-git-send-email-oren.jer.weil@intel.com> (raw)
In-Reply-To: <1303900057-21694-1-git-send-email-oren.jer.weil@intel.com>
functions that handle the communication between clients.
e.g. connect/disconnect to/from a client, send MEI message,
read MEI message, flow control handling.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Itzhak Tzeel-Krupp <itzhak.tzeel-krupp@intel.com>
Signed-off-by: Oren Weil <oren.jer.weil@intel.com>
---
drivers/staging/mei/interface.c | 440 +++++++++++++++++++++++++++++++++++++++
drivers/staging/mei/interface.h | 124 +++++++++++
2 files changed, 564 insertions(+), 0 deletions(-)
create mode 100644 drivers/staging/mei/interface.c
create mode 100644 drivers/staging/mei/interface.h
diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c
new file mode 100644
index 0000000..620770b
--- /dev/null
+++ b/drivers/staging/mei/interface.c
@@ -0,0 +1,440 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/pci.h>
+#include "mei.h"
+#include "interface.h"
+
+
+
+/**
+ * mei_set_csr_register - writes H_CSR register to the mei device,
+ * and ignores the H_IS bit for it is write-one-to-zero.
+ *
+ * @dev: the device structure
+ */
+void mei_hcsr_set(struct mei_device *dev)
+{
+ if ((dev->host_hw_state & H_IS) == H_IS)
+ dev->host_hw_state &= ~H_IS;
+ mei_reg_write(dev, H_CSR, dev->host_hw_state);
+ dev->host_hw_state = mei_hcsr_read(dev);
+}
+
+/**
+ * mei_csr_enable_interrupts - enables mei device interrupts
+ *
+ * @dev: the device structure
+ */
+void mei_enable_interrupts(struct mei_device *dev)
+{
+ dev->host_hw_state |= H_IE;
+ mei_hcsr_set(dev);
+}
+
+/**
+ * mei_csr_disable_interrupts - disables mei device interrupts
+ *
+ * @dev: the device structure
+ */
+void mei_disable_interrupts(struct mei_device *dev)
+{
+ dev->host_hw_state &= ~H_IE;
+ mei_hcsr_set(dev);
+}
+
+/**
+ * _host_get_filled_slots - gets number of device filled buffer slots
+ *
+ * @device: the device structure
+ *
+ * returns number of filled slots
+ */
+static unsigned char _host_get_filled_slots(const struct mei_device *dev)
+{
+ char read_ptr, write_ptr;
+
+ read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
+ write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
+
+ return (unsigned char) (write_ptr - read_ptr);
+}
+
+/**
+ * mei_host_buffer_is_empty - checks if host buffer is empty.
+ *
+ * @dev: the device structure
+ *
+ * returns 1 if empty, 0 - otherwise.
+ */
+int mei_host_buffer_is_empty(struct mei_device *dev)
+{
+ unsigned char filled_slots;
+
+ dev->host_hw_state = mei_hcsr_read(dev);
+ filled_slots = _host_get_filled_slots(dev);
+
+ if (filled_slots == 0)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * mei_count_empty_write_slots - counts write empty slots.
+ *
+ * @dev: the device structure
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
+ */
+int mei_count_empty_write_slots(struct mei_device *dev)
+{
+ unsigned char buffer_depth, filled_slots, empty_slots;
+
+ dev->host_hw_state = mei_hcsr_read(dev);
+ buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+ filled_slots = _host_get_filled_slots(dev);
+ empty_slots = buffer_depth - filled_slots;
+
+ /* check for overflow */
+ if (filled_slots > buffer_depth)
+ return -EOVERFLOW;
+
+ return empty_slots;
+}
+
+/**
+ * mei_write_message - writes a message to mei device.
+ *
+ * @dev: the device structure
+ * @header: header of message
+ * @write_buffer: message buffer will be written
+ * @write_length: message size will be written
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_write_message(struct mei_device *dev,
+ struct mei_msg_hdr *header,
+ unsigned char *write_buffer,
+ unsigned long write_length)
+{
+ u32 temp_msg = 0;
+ unsigned long bytes_written = 0;
+ unsigned char buffer_depth, filled_slots, empty_slots;
+ unsigned long dw_to_write;
+
+ dev->host_hw_state = mei_hcsr_read(dev);
+
+ dev_dbg(&dev->pdev->dev,
+ "host_hw_state = 0x%08x.\n",
+ dev->host_hw_state);
+
+ dev_dbg(&dev->pdev->dev,
+ "mei_write_message header=%08x.\n",
+ *((u32 *) header));
+
+ buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+ filled_slots = _host_get_filled_slots(dev);
+ empty_slots = buffer_depth - filled_slots;
+ dev_dbg(&dev->pdev->dev,
+ "filled = %hu, empty = %hu.\n",
+ filled_slots, empty_slots);
+
+ dw_to_write = ((write_length + 3) / 4);
+
+ if (dw_to_write > empty_slots)
+ return 0;
+
+ mei_reg_write(dev, H_CB_WW, *((u32 *) header));
+
+ while (write_length >= 4) {
+ mei_reg_write(dev, H_CB_WW,
+ *(u32 *) (write_buffer + bytes_written));
+ bytes_written += 4;
+ write_length -= 4;
+ }
+
+ if (write_length > 0) {
+ memcpy(&temp_msg, &write_buffer[bytes_written], write_length);
+ mei_reg_write(dev, H_CB_WW, temp_msg);
+ }
+
+ dev->host_hw_state |= H_IG;
+ mei_hcsr_set(dev);
+ dev->me_hw_state = mei_mecsr_read(dev);
+ if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+ return 0;
+
+ dev->write_hang = 0;
+ return 1;
+}
+
+/**
+ * mei_count_full_read_slots - counts read full slots.
+ *
+ * @dev: the device structure
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
+ */
+int mei_count_full_read_slots(struct mei_device *dev)
+{
+ char read_ptr, write_ptr;
+ unsigned char buffer_depth, filled_slots;
+
+ dev->me_hw_state = mei_mecsr_read(dev);
+ buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24);
+ read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8);
+ write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16);
+ filled_slots = (unsigned char) (write_ptr - read_ptr);
+
+ /* check for overflow */
+ if (filled_slots > buffer_depth)
+ return -EOVERFLOW;
+
+ dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots);
+ return (int)filled_slots;
+}
+
+/**
+ * mei_read_slots - reads a message from mei device.
+ *
+ * @dev: the device structure
+ * @buffer: message buffer will be written
+ * @buffer_length: message size will be read
+ */
+void mei_read_slots(struct mei_device *dev,
+ unsigned char *buffer, unsigned long buffer_length)
+{
+ u32 i = 0;
+ unsigned char temp_buf[sizeof(u32)];
+
+ while (buffer_length >= sizeof(u32)) {
+ ((u32 *) buffer)[i] = mei_mecbrw_read(dev);
+
+ dev_dbg(&dev->pdev->dev,
+ "buffer[%d]= %d\n",
+ i, ((u32 *) buffer)[i]);
+
+ i++;
+ buffer_length -= sizeof(u32);
+ }
+
+ if (buffer_length > 0) {
+ *((u32 *) &temp_buf) = mei_mecbrw_read(dev);
+ memcpy(&buffer[i * 4], temp_buf, buffer_length);
+ }
+
+ dev->host_hw_state |= H_IG;
+ mei_hcsr_set(dev);
+}
+
+/**
+ * mei_flow_ctrl_creds - checks flow_control credentials.
+ *
+ * @dev: the device structure
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
+ */
+int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *file_ext)
+{
+ int i;
+
+ if (!dev->num_mei_me_clients)
+ return 0;
+
+ if (file_ext == NULL)
+ return 0;
+
+ if (file_ext->mei_flow_ctrl_creds > 0)
+ return 1;
+
+ for (i = 0; i < dev->num_mei_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+ if (dev->me_clients[i].mei_flow_ctrl_creds > 0) {
+ BUG_ON(dev->me_clients[i].props.single_recv_buf
+ == 0);
+ return 1;
+ }
+ return 0;
+ }
+ }
+ BUG();
+ return 0;
+}
+
+/**
+ * mei_flow_ctrl_reduce - reduces flow_control.
+ *
+ * @dev: the device structure
+ * @file_ext: private data of the file object
+ */
+void mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *file_ext)
+{
+ int i;
+
+ if (!dev->num_mei_me_clients)
+ return;
+
+ for (i = 0; i < dev->num_mei_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+ if (dev->me_clients[i].props.single_recv_buf != 0) {
+ BUG_ON(dev->me_clients[i].mei_flow_ctrl_creds
+ <= 0);
+ dev->me_clients[i].mei_flow_ctrl_creds--;
+ } else {
+ BUG_ON(file_ext->mei_flow_ctrl_creds <= 0);
+ file_ext->mei_flow_ctrl_creds--;
+ }
+ return;
+ }
+ }
+ BUG();
+}
+
+/**
+ * mei_send_flow_control - sends flow control to fw.
+ *
+ * @dev: the device structure
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_send_flow_control(struct mei_device *dev, struct mei_cl *file_ext)
+{
+ struct mei_msg_hdr *mei_hdr;
+ struct hbm_flow_control *mei_flow_control;
+
+ mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+ mei_hdr->host_addr = 0;
+ mei_hdr->me_addr = 0;
+ mei_hdr->length = sizeof(struct hbm_flow_control);
+ mei_hdr->msg_complete = 1;
+ mei_hdr->reserved = 0;
+
+ mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1];
+ memset(mei_flow_control, 0, sizeof(mei_flow_control));
+ mei_flow_control->host_addr = file_ext->host_client_id;
+ mei_flow_control->me_addr = file_ext->me_client_id;
+ mei_flow_control->cmd.cmd = MEI_FLOW_CONTROL_CMD;
+ memset(mei_flow_control->reserved, 0,
+ sizeof(mei_flow_control->reserved));
+ dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
+ file_ext->host_client_id, file_ext->me_client_id);
+ if (!mei_write_message(dev, mei_hdr,
+ (unsigned char *) mei_flow_control,
+ sizeof(struct hbm_flow_control)))
+ return 0;
+
+ return 1;
+
+}
+
+/**
+ * mei_other_client_is_connecting - checks if other
+ * client with the same client id is connected.
+ *
+ * @dev: the device structure
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if other client is connected, 0 - otherwise.
+ */
+int mei_other_client_is_connecting(struct mei_device *dev,
+ struct mei_cl *file_ext)
+{
+ struct mei_cl *file_pos = NULL;
+ struct mei_cl *file_next = NULL;
+
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if ((file_pos->state == MEI_FILE_CONNECTING) &&
+ (file_pos != file_ext) &&
+ file_ext->me_client_id == file_pos->me_client_id)
+ return 1;
+
+ }
+ return 0;
+}
+
+/**
+ * mei_disconnect - sends disconnect message to fw.
+ *
+ * @dev: the device structure
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_disconnect(struct mei_device *dev, struct mei_cl *file_ext)
+{
+ struct mei_msg_hdr *mei_hdr;
+ struct hbm_client_disconnect_request *mei_cli_disconnect;
+
+ mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+ mei_hdr->host_addr = 0;
+ mei_hdr->me_addr = 0;
+ mei_hdr->length = sizeof(struct hbm_client_disconnect_request);
+ mei_hdr->msg_complete = 1;
+ mei_hdr->reserved = 0;
+
+ mei_cli_disconnect =
+ (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1];
+ memset(mei_cli_disconnect, 0, sizeof(mei_cli_disconnect));
+ mei_cli_disconnect->host_addr = file_ext->host_client_id;
+ mei_cli_disconnect->me_addr = file_ext->me_client_id;
+ mei_cli_disconnect->cmd.cmd = CLIENT_DISCONNECT_REQ_CMD;
+ mei_cli_disconnect->reserved[0] = 0;
+
+ if (!mei_write_message(dev, mei_hdr,
+ (unsigned char *) mei_cli_disconnect,
+ sizeof(struct hbm_client_disconnect_request)))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * mei_connect - sends connect message to fw.
+ *
+ * @dev: the device structure
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_connect(struct mei_device *dev, struct mei_cl *file_ext)
+{
+ struct mei_msg_hdr *mei_hdr;
+ struct hbm_client_connect_request *mei_cli_connect;
+
+ mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+ mei_hdr->host_addr = 0;
+ mei_hdr->me_addr = 0;
+ mei_hdr->length = sizeof(struct hbm_client_connect_request);
+ mei_hdr->msg_complete = 1;
+ mei_hdr->reserved = 0;
+
+ mei_cli_connect =
+ (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
+ mei_cli_connect->host_addr = file_ext->host_client_id;
+ mei_cli_connect->me_addr = file_ext->me_client_id;
+ mei_cli_connect->cmd.cmd = CLIENT_CONNECT_REQ_CMD;
+ mei_cli_connect->reserved = 0;
+
+ if (!mei_write_message(dev, mei_hdr,
+ (unsigned char *) mei_cli_connect,
+ sizeof(struct hbm_client_connect_request)))
+ return 0;
+
+ return 1;
+}
diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h
new file mode 100644
index 0000000..1bac32a
--- /dev/null
+++ b/drivers/staging/mei/interface.h
@@ -0,0 +1,124 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+
+
+#ifndef _MEI_INTERFACE_H_
+#define _MEI_INTERFACE_H_
+
+#include <linux/mei.h>
+#include "hw.h"
+
+
+#define HBM_MINOR_VERSION 0
+#define HBM_MAJOR_VERSION 1
+#define HBM_TIMEOUT 1 /* 1 second */
+
+
+#define HOST_START_REQ_CMD 0x01
+#define HOST_START_RES_CMD 0x81
+
+#define HOST_STOP_REQ_CMD 0x02
+#define HOST_STOP_RES_CMD 0x82
+
+#define ME_STOP_REQ_CMD 0x03
+
+#define HOST_ENUM_REQ_CMD 0x04
+#define HOST_ENUM_RES_CMD 0x84
+
+#define HOST_CLIENT_PROPERTIES_REQ_CMD 0x05
+#define HOST_CLIENT_PROPERTIES_RES_CMD 0x85
+
+#define CLIENT_CONNECT_REQ_CMD 0x06
+#define CLIENT_CONNECT_RES_CMD 0x86
+
+#define CLIENT_DISCONNECT_REQ_CMD 0x07
+#define CLIENT_DISCONNECT_RES_CMD 0x87
+
+#define MEI_FLOW_CONTROL_CMD 0x08
+
+
+#define AMT_WD_VALUE 120 /* seconds */
+
+#define MEI_WATCHDOG_DATA_SIZE 16
+#define MEI_START_WD_DATA_SIZE 20
+#define MEI_WD_PARAMS_SIZE 4
+
+
+enum mei_stop_reason_types {
+ DRIVER_STOP_REQUEST = 0x00,
+ DEVICE_D1_ENTRY = 0x01,
+ DEVICE_D2_ENTRY = 0x02,
+ DEVICE_D3_ENTRY = 0x03,
+ SYSTEM_S1_ENTRY = 0x04,
+ SYSTEM_S2_ENTRY = 0x05,
+ SYSTEM_S3_ENTRY = 0x06,
+ SYSTEM_S4_ENTRY = 0x07,
+ SYSTEM_S5_ENTRY = 0x08
+};
+
+enum me_stop_reason_types {
+ FW_UPDATE = 0x00
+};
+
+enum client_connect_status_types {
+ CCS_SUCCESS = 0x00,
+ CCS_NOT_FOUND = 0x01,
+ CCS_ALREADY_STARTED = 0x02,
+ CCS_OUT_OF_RESOURCES = 0x03,
+ CCS_MESSAGE_SMALL = 0x04
+};
+
+enum client_disconnect_status_types {
+ CDS_SUCCESS = 0x00
+};
+
+
+void mei_read_slots(struct mei_device *dev,
+ unsigned char *buffer, unsigned long buffer_length);
+
+int mei_write_message(struct mei_device *dev,
+ struct mei_msg_hdr *header,
+ unsigned char *write_buffer,
+ unsigned long write_length);
+
+int mei_host_buffer_is_empty(struct mei_device *dev);
+
+int mei_count_full_read_slots(struct mei_device *dev);
+
+int mei_count_empty_write_slots(struct mei_device *dev);
+
+int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *file_ext);
+
+int mei_wd_send(struct mei_device *dev);
+int mei_wd_stop(struct mei_device *dev, bool preserve);
+void mei_wd_host_init(struct mei_device *dev);
+void mei_wd_start_setup(struct mei_device *dev);
+
+void mei_flow_ctrl_reduce(struct mei_device *dev,
+ struct mei_cl *file_ext);
+
+int mei_send_flow_control(struct mei_device *dev,
+ struct mei_cl *file_ext);
+
+int mei_disconnect(struct mei_device *dev,
+ struct mei_cl *file_ext);
+int mei_other_client_is_connecting(struct mei_device *dev,
+ struct mei_cl *file_ext);
+int mei_connect(struct mei_device *dev,
+ struct mei_cl *file_ext);
+
+#endif /* _MEI_INTERFACE_H_ */
--
1.7.1
---------------------------------------------------------------------
Intel Israel (74) Limited
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
next prev parent reply other threads:[~2011-04-27 10:31 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-27 10:27 [PATCH 0/8] staging/mei: Intel MEI Driver Oren Weil
2011-04-27 10:27 ` [PATCH 1/8] staging/mei: PCI device and char driver support Oren Weil
2011-04-27 12:24 ` Jiri Slaby
2011-04-27 15:05 ` Greg KH
2011-04-28 5:47 ` Weil, Oren jer
2011-04-28 13:37 ` Greg KH
2011-04-27 10:27 ` [PATCH 2/8] staging/mei: Interrupt handling Oren Weil
2011-04-27 10:27 ` Oren Weil [this message]
2011-04-27 15:18 ` [PATCH 3/8] staging/mei: MEI "Link" layer code - MEI Hardware communications Greg KH
2011-04-27 10:27 ` [PATCH 4/8] staging/mei: MEI driver init flow Oren Weil
2011-04-27 10:27 ` [PATCH 5/8] staging/mei: Hardware and MEI driver internal struct definition Oren Weil
2011-04-27 10:27 ` [PATCH 6/8] staging/mei: Header file contain the Userland API, (IOCTL and its struct) Oren Weil
2011-04-27 15:02 ` Greg KH
2011-04-27 15:15 ` Randy Dunlap
2011-04-27 15:33 ` Greg KH
2011-04-28 6:29 ` Weil, Oren jer
2011-04-28 13:40 ` Greg KH
2011-04-28 14:12 ` Weil, Oren jer
2011-04-28 15:04 ` Greg KH
2011-04-28 15:39 ` David Woodhouse
2011-04-28 14:43 ` Alan Cox
2011-04-27 10:27 ` [PATCH 7/8] staging/mei: AMT Watchdog Oren Weil
2011-04-27 13:53 ` Arnd Bergmann
2011-04-27 15:07 ` Greg KH
2011-04-28 5:51 ` Weil, Oren jer
2011-04-28 12:50 ` Arnd Bergmann
2011-04-28 13:38 ` Greg KH
2011-04-27 10:27 ` [PATCH 8/8] staging/mei: Updates to staging/Kconfig ane staging/Makefile and a new Makefile and Kconfig Oren Weil
2011-04-27 15:06 ` Greg KH
2011-04-28 6:39 ` Weil, Oren jer
2011-04-28 8:22 ` Alan Cox
2011-04-27 15:19 ` Randy Dunlap
2011-04-28 0:05 ` Valdis.Kletnieks
2011-04-27 15:03 ` [PATCH 0/8] staging/mei: Intel MEI Driver Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1303900057-21694-4-git-send-email-oren.jer.weil@intel.com \
--to=oren.jer.weil@intel.com \
--cc=alan@linux.intel.com \
--cc=david@woodhou.se \
--cc=devel@driverdev.osuosl.org \
--cc=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome