CHAR/MISC patches for 3.6-rc1
Here's the "big" pull request for 3.6-rc1 for the char/misc drivers. It's really just a few updates to the mei driver, plus 4 other tiny patches, nothing big at all. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) iEYEABECAAYFAlARf9IACgkQMUfUDdst+ymMWwCeJD2h/CN1UDRP+7zqxcEmQ70N 9oMAoJrZnvbqTIGmq7zZAMITO9zCbWqi =Kke0 -----END PGP SIGNATURE----- Merge tag 'char-misc-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc patches from Greg Kroah-Hartman: "Here's the "big" pull request for 3.6-rc1 for the char/misc drivers. It's really just a few updates to the mei driver, plus 4 other tiny patches, nothing big at all. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'char-misc-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: mei: use module_pci_driver powerpc/BSR: cleanup the error path of bsr_init mei: mei_irq_thread_write_handler - line break fix mei: streamline the _mei_irq_thread_close/ioctol functions mei: introduce mei_data2slots wrapper mei: mei_wd_host_init: update the comment mei: remove write only wariable wd_due_counter mei: mei_device can be const for mei register access functions mei: revamp host buffer interface function mei: don't query HCSR for host buffer depth mei: group wd_interface_reg with watchdog variables within struct mei_device mei: mei_irq_thread_write_handler check for overflow mei: make mei_write_message more readable mei: check for error codes that mei_flow_ctrl_creds retuns misc: at25: Parse dt settings misc: hpilo: increase number of max supported channels mei: mei.txt: minor grammar fixes
This commit is contained in:
commit
b84382f514
21
Documentation/devicetree/bindings/misc/at25.txt
Normal file
21
Documentation/devicetree/bindings/misc/at25.txt
Normal file
@ -0,0 +1,21 @@
|
||||
Atmel AT25 eeprom
|
||||
|
||||
Required properties:
|
||||
- compatible : "atmel,at25".
|
||||
- reg : chip select number
|
||||
- spi-max-frequency : max spi frequency to use
|
||||
|
||||
- at25,byte-len : total eeprom size in bytes
|
||||
- at25,addr-mode : addr-mode flags, as defined in include/linux/spi/eeprom.h
|
||||
- at25,page-size : size of the eeprom page
|
||||
|
||||
Examples:
|
||||
at25@0 {
|
||||
compatible = "atmel,at25";
|
||||
reg = <0>
|
||||
spi-max-frequency = <5000000>;
|
||||
|
||||
at25,byte-len = <0x8000>;
|
||||
at25,addr-mode = <2>;
|
||||
at25,page-size = <64>;
|
||||
};
|
@ -50,25 +50,25 @@ Intel MEI Driver
|
||||
The driver exposes a misc device called /dev/mei.
|
||||
|
||||
An application maintains communication with an Intel ME feature while
|
||||
/dev/mei is open. The binding to a specific features is performed by calling
|
||||
/dev/mei is open. The binding to a specific feature is performed by calling
|
||||
MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID.
|
||||
The number of instances of an Intel ME feature that can be opened
|
||||
at the same time depends on the Intel ME feature, but most of the
|
||||
features allow only a single instance.
|
||||
|
||||
The Intel AMT Host Interface (Intel AMTHI) feature supports multiple
|
||||
simultaneous user applications. Therefore, the Intel MEI driver handles
|
||||
this internally by maintaining request queues for the applications.
|
||||
simultaneous user connected applications. The Intel MEI driver
|
||||
handles this internally by maintaining request queues for the applications.
|
||||
|
||||
The driver is oblivious to data that is passed between firmware feature
|
||||
The driver is transparent to data that are passed between firmware feature
|
||||
and host application.
|
||||
|
||||
Because some of the Intel ME features can change the system
|
||||
configuration, the driver by default allows only a privileged
|
||||
user to access it.
|
||||
|
||||
A code snippet for an application communicating with
|
||||
Intel AMTHI client:
|
||||
A code snippet for an application communicating with Intel AMTHI client:
|
||||
|
||||
struct mei_connect_client_data data;
|
||||
fd = open(MEI_DEVICE);
|
||||
|
||||
@ -185,7 +185,7 @@ The Intel AMT Watchdog is composed of two parts:
|
||||
2) Intel MEI driver - connects to the watchdog feature, configures the
|
||||
watchdog and sends the heartbeats.
|
||||
|
||||
The Intel MEI driver uses the kernel watchdog to configure the Intel AMT
|
||||
The Intel MEI driver uses the kernel watchdog API to configure the Intel AMT
|
||||
Watchdog and to send heartbeats to it. The default timeout of the
|
||||
watchdog is 120 seconds.
|
||||
|
||||
|
@ -297,7 +297,6 @@ static int __init bsr_init(void)
|
||||
struct device_node *np;
|
||||
dev_t bsr_dev;
|
||||
int ret = -ENODEV;
|
||||
int result;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "ibm,bsr");
|
||||
if (!np)
|
||||
@ -306,13 +305,14 @@ static int __init bsr_init(void)
|
||||
bsr_class = class_create(THIS_MODULE, "bsr");
|
||||
if (IS_ERR(bsr_class)) {
|
||||
printk(KERN_ERR "class_create() failed for bsr_class\n");
|
||||
ret = PTR_ERR(bsr_class);
|
||||
goto out_err_1;
|
||||
}
|
||||
bsr_class->dev_attrs = bsr_dev_attrs;
|
||||
|
||||
result = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr");
|
||||
ret = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr");
|
||||
bsr_major = MAJOR(bsr_dev);
|
||||
if (result < 0) {
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "alloc_chrdev_region() failed for bsr\n");
|
||||
goto out_err_2;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/eeprom.h>
|
||||
|
||||
#include <linux/of.h>
|
||||
|
||||
/*
|
||||
* NOTE: this is an *EEPROM* driver. The vagaries of product naming
|
||||
@ -305,25 +305,54 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
|
||||
static int at25_probe(struct spi_device *spi)
|
||||
{
|
||||
struct at25_data *at25 = NULL;
|
||||
const struct spi_eeprom *chip;
|
||||
struct spi_eeprom chip;
|
||||
struct device_node *np = spi->dev.of_node;
|
||||
int err;
|
||||
int sr;
|
||||
int addrlen;
|
||||
|
||||
/* Chip description */
|
||||
chip = spi->dev.platform_data;
|
||||
if (!chip) {
|
||||
dev_dbg(&spi->dev, "no chip description\n");
|
||||
err = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
if (!spi->dev.platform_data) {
|
||||
if (np) {
|
||||
u32 val;
|
||||
|
||||
memset(&chip, 0, sizeof(chip));
|
||||
strncpy(chip.name, np->name, 10);
|
||||
|
||||
err = of_property_read_u32(np, "at25,byte-len", &val);
|
||||
if (err) {
|
||||
dev_dbg(&spi->dev, "invalid chip dt description\n");
|
||||
goto fail;
|
||||
}
|
||||
chip.byte_len = val;
|
||||
|
||||
err = of_property_read_u32(np, "at25,addr-mode", &val);
|
||||
if (err) {
|
||||
dev_dbg(&spi->dev, "invalid chip dt description\n");
|
||||
goto fail;
|
||||
}
|
||||
chip.flags = (u16)val;
|
||||
|
||||
err = of_property_read_u32(np, "at25,page-size", &val);
|
||||
if (err) {
|
||||
dev_dbg(&spi->dev, "invalid chip dt description\n");
|
||||
goto fail;
|
||||
}
|
||||
chip.page_size = (u16)val;
|
||||
} else {
|
||||
dev_dbg(&spi->dev, "no chip description\n");
|
||||
err = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
} else
|
||||
chip = *(struct spi_eeprom *)spi->dev.platform_data;
|
||||
|
||||
/* For now we only support 8/16/24 bit addressing */
|
||||
if (chip->flags & EE_ADDR1)
|
||||
if (chip.flags & EE_ADDR1)
|
||||
addrlen = 1;
|
||||
else if (chip->flags & EE_ADDR2)
|
||||
else if (chip.flags & EE_ADDR2)
|
||||
addrlen = 2;
|
||||
else if (chip->flags & EE_ADDR3)
|
||||
else if (chip.flags & EE_ADDR3)
|
||||
addrlen = 3;
|
||||
else {
|
||||
dev_dbg(&spi->dev, "unsupported address type\n");
|
||||
@ -348,7 +377,7 @@ static int at25_probe(struct spi_device *spi)
|
||||
}
|
||||
|
||||
mutex_init(&at25->lock);
|
||||
at25->chip = *chip;
|
||||
at25->chip = chip;
|
||||
at25->spi = spi_dev_get(spi);
|
||||
dev_set_drvdata(&spi->dev, at25);
|
||||
at25->addrlen = addrlen;
|
||||
@ -369,7 +398,7 @@ static int at25_probe(struct spi_device *spi)
|
||||
at25->mem.read = at25_mem_read;
|
||||
|
||||
at25->bin.size = at25->chip.byte_len;
|
||||
if (!(chip->flags & EE_READONLY)) {
|
||||
if (!(chip.flags & EE_READONLY)) {
|
||||
at25->bin.write = at25_bin_write;
|
||||
at25->bin.attr.mode |= S_IWUSR;
|
||||
at25->mem.write = at25_mem_write;
|
||||
@ -379,8 +408,8 @@ static int at25_probe(struct spi_device *spi)
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
if (chip->setup)
|
||||
chip->setup(&at25->mem, chip->context);
|
||||
if (chip.setup)
|
||||
chip.setup(&at25->mem, chip.context);
|
||||
|
||||
dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
|
||||
(at25->bin.size < 1024)
|
||||
@ -388,7 +417,7 @@ static int at25_probe(struct spi_device *spi)
|
||||
: (at25->bin.size / 1024),
|
||||
(at25->bin.size < 1024) ? "Byte" : "KByte",
|
||||
at25->chip.name,
|
||||
(chip->flags & EE_READONLY) ? " (readonly)" : "",
|
||||
(chip.flags & EE_READONLY) ? " (readonly)" : "",
|
||||
at25->chip.page_size);
|
||||
return 0;
|
||||
fail:
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
static struct class *ilo_class;
|
||||
static unsigned int ilo_major;
|
||||
static unsigned int max_ccb = MIN_CCB;
|
||||
static char ilo_hwdev[MAX_ILO_DEV];
|
||||
|
||||
static inline int get_entry_id(int entry)
|
||||
@ -424,7 +425,7 @@ static void ilo_set_reset(struct ilo_hwinfo *hw)
|
||||
* Mapped memory is zeroed on ilo reset, so set a per ccb flag
|
||||
* to indicate that this ccb needs to be closed and reopened.
|
||||
*/
|
||||
for (slot = 0; slot < MAX_CCB; slot++) {
|
||||
for (slot = 0; slot < max_ccb; slot++) {
|
||||
if (!hw->ccb_alloc[slot])
|
||||
continue;
|
||||
set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb);
|
||||
@ -535,7 +536,7 @@ static int ilo_close(struct inode *ip, struct file *fp)
|
||||
struct ilo_hwinfo *hw;
|
||||
unsigned long flags;
|
||||
|
||||
slot = iminor(ip) % MAX_CCB;
|
||||
slot = iminor(ip) % max_ccb;
|
||||
hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
|
||||
|
||||
spin_lock(&hw->open_lock);
|
||||
@ -566,7 +567,7 @@ static int ilo_open(struct inode *ip, struct file *fp)
|
||||
struct ilo_hwinfo *hw;
|
||||
unsigned long flags;
|
||||
|
||||
slot = iminor(ip) % MAX_CCB;
|
||||
slot = iminor(ip) % max_ccb;
|
||||
hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
|
||||
|
||||
/* new ccb allocation */
|
||||
@ -663,7 +664,7 @@ static irqreturn_t ilo_isr(int irq, void *data)
|
||||
ilo_set_reset(hw);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CCB; i++) {
|
||||
for (i = 0; i < max_ccb; i++) {
|
||||
if (!hw->ccb_alloc[i])
|
||||
continue;
|
||||
if (pending & (1 << i))
|
||||
@ -697,14 +698,14 @@ static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
|
||||
}
|
||||
|
||||
/* map the adapter shared memory region */
|
||||
hw->ram_vaddr = pci_iomap(pdev, 2, MAX_CCB * ILOHW_CCB_SZ);
|
||||
hw->ram_vaddr = pci_iomap(pdev, 2, max_ccb * ILOHW_CCB_SZ);
|
||||
if (hw->ram_vaddr == NULL) {
|
||||
dev_err(&pdev->dev, "Error mapping shared mem\n");
|
||||
goto mmio_free;
|
||||
}
|
||||
|
||||
/* map the doorbell aperture */
|
||||
hw->db_vaddr = pci_iomap(pdev, 3, MAX_CCB * ONE_DB_SIZE);
|
||||
hw->db_vaddr = pci_iomap(pdev, 3, max_ccb * ONE_DB_SIZE);
|
||||
if (hw->db_vaddr == NULL) {
|
||||
dev_err(&pdev->dev, "Error mapping doorbell\n");
|
||||
goto ram_free;
|
||||
@ -727,7 +728,7 @@ static void ilo_remove(struct pci_dev *pdev)
|
||||
clear_device(ilo_hw);
|
||||
|
||||
minor = MINOR(ilo_hw->cdev.dev);
|
||||
for (i = minor; i < minor + MAX_CCB; i++)
|
||||
for (i = minor; i < minor + max_ccb; i++)
|
||||
device_destroy(ilo_class, MKDEV(ilo_major, i));
|
||||
|
||||
cdev_del(&ilo_hw->cdev);
|
||||
@ -737,7 +738,7 @@ static void ilo_remove(struct pci_dev *pdev)
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
kfree(ilo_hw);
|
||||
ilo_hwdev[(minor / MAX_CCB)] = 0;
|
||||
ilo_hwdev[(minor / max_ccb)] = 0;
|
||||
}
|
||||
|
||||
static int __devinit ilo_probe(struct pci_dev *pdev,
|
||||
@ -746,6 +747,11 @@ static int __devinit ilo_probe(struct pci_dev *pdev,
|
||||
int devnum, minor, start, error;
|
||||
struct ilo_hwinfo *ilo_hw;
|
||||
|
||||
if (max_ccb > MAX_CCB)
|
||||
max_ccb = MAX_CCB;
|
||||
else if (max_ccb < MIN_CCB)
|
||||
max_ccb = MIN_CCB;
|
||||
|
||||
/* find a free range for device files */
|
||||
for (devnum = 0; devnum < MAX_ILO_DEV; devnum++) {
|
||||
if (ilo_hwdev[devnum] == 0) {
|
||||
@ -795,14 +801,14 @@ static int __devinit ilo_probe(struct pci_dev *pdev,
|
||||
|
||||
cdev_init(&ilo_hw->cdev, &ilo_fops);
|
||||
ilo_hw->cdev.owner = THIS_MODULE;
|
||||
start = devnum * MAX_CCB;
|
||||
error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB);
|
||||
start = devnum * max_ccb;
|
||||
error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), max_ccb);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "Could not add cdev\n");
|
||||
goto remove_isr;
|
||||
}
|
||||
|
||||
for (minor = 0 ; minor < MAX_CCB; minor++) {
|
||||
for (minor = 0 ; minor < max_ccb; minor++) {
|
||||
struct device *dev;
|
||||
dev = device_create(ilo_class, &pdev->dev,
|
||||
MKDEV(ilo_major, minor), NULL,
|
||||
@ -879,11 +885,14 @@ static void __exit ilo_exit(void)
|
||||
class_destroy(ilo_class);
|
||||
}
|
||||
|
||||
MODULE_VERSION("1.2");
|
||||
MODULE_VERSION("1.3");
|
||||
MODULE_ALIAS(ILO_NAME);
|
||||
MODULE_DESCRIPTION(ILO_NAME);
|
||||
MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
module_param(max_ccb, uint, 0444);
|
||||
MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (8)");
|
||||
|
||||
module_init(ilo_init);
|
||||
module_exit(ilo_exit);
|
||||
|
@ -14,7 +14,9 @@
|
||||
#define ILO_NAME "hpilo"
|
||||
|
||||
/* max number of open channel control blocks per device, hw limited to 32 */
|
||||
#define MAX_CCB 8
|
||||
#define MAX_CCB 24
|
||||
/* min number of open channel control blocks per device, hw limited to 32 */
|
||||
#define MIN_CCB 8
|
||||
/* max number of supported devices */
|
||||
#define MAX_ILO_DEV 1
|
||||
/* max number of files */
|
||||
|
@ -162,6 +162,9 @@ int mei_hw_init(struct mei_device *dev)
|
||||
if ((dev->host_hw_state & H_IS) == H_IS)
|
||||
mei_reg_write(dev, H_CSR, dev->host_hw_state);
|
||||
|
||||
/* Doesn't change in runtime */
|
||||
dev->hbuf_depth = (dev->host_hw_state & H_CBD) >> 24;
|
||||
|
||||
dev->recvd_msg = false;
|
||||
dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
|
||||
|
||||
@ -303,7 +306,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
|
||||
dev->iamthif_cl.host_client_id);
|
||||
|
||||
mei_reset_iamthif_params(dev);
|
||||
dev->wd_due_counter = 0;
|
||||
dev->extra_write_index = 0;
|
||||
}
|
||||
|
||||
|
@ -58,16 +58,18 @@ void mei_disable_interrupts(struct mei_device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* _host_get_filled_slots - gets number of device filled buffer slots
|
||||
* mei_hbuf_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)
|
||||
static unsigned char mei_hbuf_filled_slots(struct mei_device *dev)
|
||||
{
|
||||
char read_ptr, write_ptr;
|
||||
|
||||
dev->host_hw_state = mei_hcsr_read(dev);
|
||||
|
||||
read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
|
||||
write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
|
||||
|
||||
@ -75,43 +77,33 @@ static unsigned char _host_get_filled_slots(const struct mei_device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_host_buffer_is_empty - checks if host buffer is empty.
|
||||
* mei_hbuf_is_empty - checks if host buffer is empty.
|
||||
*
|
||||
* @dev: the device structure
|
||||
*
|
||||
* returns 1 if empty, 0 - otherwise.
|
||||
* returns true if empty, false - otherwise.
|
||||
*/
|
||||
int mei_host_buffer_is_empty(struct mei_device *dev)
|
||||
bool mei_hbuf_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;
|
||||
return mei_hbuf_filled_slots(dev) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_count_empty_write_slots - counts write empty slots.
|
||||
* mei_hbuf_empty_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)
|
||||
int mei_hbuf_empty_slots(struct mei_device *dev)
|
||||
{
|
||||
unsigned char buffer_depth, filled_slots, empty_slots;
|
||||
unsigned char 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;
|
||||
filled_slots = mei_hbuf_filled_slots(dev);
|
||||
empty_slots = dev->hbuf_depth - filled_slots;
|
||||
|
||||
/* check for overflow */
|
||||
if (filled_slots > buffer_depth)
|
||||
if (filled_slots > dev->hbuf_depth)
|
||||
return -EOVERFLOW;
|
||||
|
||||
return empty_slots;
|
||||
@ -127,52 +119,39 @@ int mei_count_empty_write_slots(struct mei_device *dev)
|
||||
*
|
||||
* This function returns -EIO if write has failed
|
||||
*/
|
||||
int mei_write_message(struct mei_device *dev,
|
||||
struct mei_msg_hdr *header,
|
||||
unsigned char *write_buffer,
|
||||
unsigned long write_length)
|
||||
int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
|
||||
unsigned char *buf, unsigned long length)
|
||||
{
|
||||
u32 temp_msg = 0;
|
||||
unsigned long bytes_written = 0;
|
||||
unsigned char buffer_depth, filled_slots, empty_slots;
|
||||
unsigned long dw_to_write;
|
||||
unsigned long rem, dw_cnt;
|
||||
u32 *reg_buf = (u32 *)buf;
|
||||
int i;
|
||||
int empty_slots;
|
||||
|
||||
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);
|
||||
empty_slots = mei_hbuf_empty_slots(dev);
|
||||
dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots);
|
||||
|
||||
dw_to_write = ((write_length + 3) / 4);
|
||||
|
||||
if (dw_to_write > empty_slots)
|
||||
dw_cnt = mei_data2slots(length);
|
||||
if (empty_slots < 0 || dw_cnt > empty_slots)
|
||||
return -EIO;
|
||||
|
||||
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);
|
||||
for (i = 0; i < length / 4; i++)
|
||||
mei_reg_write(dev, H_CB_WW, reg_buf[i]);
|
||||
|
||||
rem = length & 0x3;
|
||||
if (rem > 0) {
|
||||
u32 reg = 0;
|
||||
memcpy(®, &buf[length - rem], rem);
|
||||
mei_reg_write(dev, H_CB_WW, reg);
|
||||
}
|
||||
|
||||
dev->host_hw_state = mei_hcsr_read(dev);
|
||||
dev->host_hw_state |= H_IG;
|
||||
mei_hcsr_set(dev);
|
||||
dev->me_hw_state = mei_mecsr_read(dev);
|
||||
|
@ -41,14 +41,28 @@ int mei_write_message(struct mei_device *dev,
|
||||
unsigned char *write_buffer,
|
||||
unsigned long write_length);
|
||||
|
||||
int mei_host_buffer_is_empty(struct mei_device *dev);
|
||||
bool mei_hbuf_is_empty(struct mei_device *dev);
|
||||
|
||||
int mei_hbuf_empty_slots(struct mei_device *dev);
|
||||
|
||||
static inline size_t mei_hbuf_max_data(const struct mei_device *dev)
|
||||
{
|
||||
return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
|
||||
}
|
||||
|
||||
/* get slots (dwords) from a message length + header (bytes) */
|
||||
static inline unsigned char mei_data2slots(size_t length)
|
||||
{
|
||||
return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
|
||||
}
|
||||
|
||||
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 *cl);
|
||||
|
||||
|
||||
|
||||
int mei_wd_send(struct mei_device *dev);
|
||||
int mei_wd_stop(struct mei_device *dev, bool preserve);
|
||||
int mei_wd_host_init(struct mei_device *dev);
|
||||
|
@ -267,8 +267,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
|
||||
+ sizeof(struct hbm_flow_control))) {
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
sizeof(struct hbm_flow_control) + 3) / 4;
|
||||
*slots -= mei_data2slots(sizeof(struct hbm_flow_control));
|
||||
if (mei_send_flow_control(dev, &dev->iamthif_cl)) {
|
||||
dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
|
||||
return -EIO;
|
||||
@ -280,7 +279,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
|
||||
dev->iamthif_msg_buf_index = 0;
|
||||
dev->iamthif_msg_buf_size = 0;
|
||||
dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
|
||||
dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev);
|
||||
dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -300,28 +299,25 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
|
||||
struct mei_cl *cl,
|
||||
struct mei_io_list *cmpl_list)
|
||||
{
|
||||
if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
|
||||
sizeof(struct hbm_client_disconnect_request))) {
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
sizeof(struct hbm_client_disconnect_request) + 3) / 4;
|
||||
|
||||
if (mei_disconnect(dev, cl)) {
|
||||
cl->status = 0;
|
||||
cb_pos->information = 0;
|
||||
list_move_tail(&cb_pos->cb_list,
|
||||
&cmpl_list->mei_cb.cb_list);
|
||||
return -EMSGSIZE;
|
||||
} else {
|
||||
cl->state = MEI_FILE_DISCONNECTING;
|
||||
cl->status = 0;
|
||||
cb_pos->information = 0;
|
||||
list_move_tail(&cb_pos->cb_list,
|
||||
&dev->ctrl_rd_list.mei_cb.cb_list);
|
||||
cl->timer_count = MEI_CONNECT_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
/* return the cancel routine */
|
||||
if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
|
||||
sizeof(struct hbm_client_disconnect_request)))
|
||||
return -EBADMSG;
|
||||
|
||||
*slots -= mei_data2slots(sizeof(struct hbm_client_disconnect_request));
|
||||
|
||||
if (mei_disconnect(dev, cl)) {
|
||||
cl->status = 0;
|
||||
cb_pos->information = 0;
|
||||
list_move_tail(&cb_pos->cb_list,
|
||||
&cmpl_list->mei_cb.cb_list);
|
||||
return -EMSGSIZE;
|
||||
} else {
|
||||
cl->state = MEI_FILE_DISCONNECTING;
|
||||
cl->status = 0;
|
||||
cb_pos->information = 0;
|
||||
list_move_tail(&cb_pos->cb_list,
|
||||
&dev->ctrl_rd_list.mei_cb.cb_list);
|
||||
cl->timer_count = MEI_CONNECT_TIMEOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -575,10 +571,9 @@ static void mei_client_disconnect_request(struct mei_device *dev,
|
||||
disconnect_req->me_addr);
|
||||
cl_pos->state = MEI_FILE_DISCONNECTED;
|
||||
cl_pos->timer_count = 0;
|
||||
if (cl_pos == &dev->wd_cl) {
|
||||
dev->wd_due_counter = 0;
|
||||
if (cl_pos == &dev->wd_cl)
|
||||
dev->wd_pending = false;
|
||||
} else if (cl_pos == &dev->iamthif_cl)
|
||||
else if (cl_pos == &dev->iamthif_cl)
|
||||
dev->iamthif_timer = 0;
|
||||
|
||||
/* prepare disconnect response */
|
||||
@ -842,8 +837,8 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
sizeof(struct hbm_flow_control) + 3) / 4;
|
||||
*slots -= mei_data2slots(sizeof(struct hbm_flow_control));
|
||||
|
||||
if (mei_send_flow_control(dev, cl)) {
|
||||
cl->status = -ENODEV;
|
||||
cb_pos->information = 0;
|
||||
@ -872,27 +867,25 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
|
||||
struct mei_cl *cl,
|
||||
struct mei_io_list *cmpl_list)
|
||||
{
|
||||
if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
|
||||
if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
|
||||
sizeof(struct hbm_client_connect_request))) {
|
||||
cl->state = MEI_FILE_CONNECTING;
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
sizeof(struct hbm_client_connect_request) + 3) / 4;
|
||||
if (mei_connect(dev, cl)) {
|
||||
cl->status = -ENODEV;
|
||||
cb_pos->information = 0;
|
||||
list_del(&cb_pos->cb_list);
|
||||
return -ENODEV;
|
||||
} else {
|
||||
list_move_tail(&cb_pos->cb_list,
|
||||
&dev->ctrl_rd_list.mei_cb.cb_list);
|
||||
cl->timer_count = MEI_CONNECT_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
/* return the cancel routine */
|
||||
list_del(&cb_pos->cb_list);
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
cl->state = MEI_FILE_CONNECTING;
|
||||
*slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
|
||||
if (mei_connect(dev, cl)) {
|
||||
cl->status = -ENODEV;
|
||||
cb_pos->information = 0;
|
||||
list_del(&cb_pos->cb_list);
|
||||
return -ENODEV;
|
||||
} else {
|
||||
list_move_tail(&cb_pos->cb_list,
|
||||
&dev->ctrl_rd_list.mei_cb.cb_list);
|
||||
cl->timer_count = MEI_CONNECT_TIMEOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -932,8 +925,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
|
||||
cb_pos->information);
|
||||
dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
|
||||
mei_hdr->length);
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
mei_hdr->length + 3) / 4;
|
||||
*slots -= mei_data2slots(mei_hdr->length);
|
||||
if (mei_write_message(dev, mei_hdr,
|
||||
(unsigned char *)
|
||||
(cb_pos->request_buffer.data +
|
||||
@ -951,7 +943,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
|
||||
list_move_tail(&cb_pos->cb_list,
|
||||
&dev->write_waiting_list.mei_cb.cb_list);
|
||||
}
|
||||
} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
|
||||
} else if (*slots == dev->hbuf_depth) {
|
||||
/* buffer is still empty */
|
||||
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
|
||||
mei_hdr->host_addr = cl->host_client_id;
|
||||
@ -960,9 +952,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
|
||||
(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
|
||||
mei_hdr->msg_complete = 0;
|
||||
mei_hdr->reserved = 0;
|
||||
|
||||
(*slots) -= (sizeof(struct mei_msg_hdr) +
|
||||
mei_hdr->length + 3) / 4;
|
||||
*slots -= mei_data2slots(mei_hdr->length);
|
||||
if (mei_write_message(dev, mei_hdr,
|
||||
(unsigned char *)
|
||||
(cb_pos->request_buffer.data +
|
||||
@ -1021,8 +1011,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
|
||||
mei_hdr->msg_complete = 1;
|
||||
mei_hdr->reserved = 0;
|
||||
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
mei_hdr->length + 3) / 4;
|
||||
*slots -= mei_data2slots(mei_hdr->length);
|
||||
|
||||
if (mei_write_message(dev, mei_hdr,
|
||||
(dev->iamthif_msg_buf +
|
||||
@ -1046,8 +1035,8 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
|
||||
&dev->write_waiting_list.mei_cb.cb_list);
|
||||
|
||||
}
|
||||
} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
|
||||
/* buffer is still empty */
|
||||
} else if (*slots == dev->hbuf_depth) {
|
||||
/* buffer is still empty */
|
||||
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
|
||||
mei_hdr->host_addr = cl->host_client_id;
|
||||
mei_hdr->me_addr = cl->me_client_id;
|
||||
@ -1056,8 +1045,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
|
||||
mei_hdr->msg_complete = 0;
|
||||
mei_hdr->reserved = 0;
|
||||
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
mei_hdr->length + 3) / 4;
|
||||
*slots -= mei_data2slots(mei_hdr->length);
|
||||
|
||||
if (mei_write_message(dev, mei_hdr,
|
||||
(dev->iamthif_msg_buf +
|
||||
@ -1199,17 +1187,19 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
||||
struct mei_io_list *list;
|
||||
int ret;
|
||||
|
||||
if (!mei_host_buffer_is_empty(dev)) {
|
||||
if (!mei_hbuf_is_empty(dev)) {
|
||||
dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
|
||||
return 0;
|
||||
}
|
||||
*slots = mei_count_empty_write_slots(dev);
|
||||
*slots = mei_hbuf_empty_slots(dev);
|
||||
if (*slots <= 0)
|
||||
return -EMSGSIZE;
|
||||
|
||||
/* complete all waiting for write CB */
|
||||
dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
|
||||
|
||||
list = &dev->write_waiting_list;
|
||||
list_for_each_entry_safe(pos, next,
|
||||
&list->mei_cb.cb_list, cb_list) {
|
||||
list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) {
|
||||
cl = (struct mei_cl *)pos->file_private;
|
||||
if (cl == NULL)
|
||||
continue;
|
||||
@ -1219,17 +1209,15 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
||||
if (MEI_WRITING == cl->writing_state &&
|
||||
(pos->major_file_operations == MEI_WRITE) &&
|
||||
(cl != &dev->iamthif_cl)) {
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"MEI WRITE COMPLETE\n");
|
||||
dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
|
||||
cl->writing_state = MEI_WRITE_COMPLETE;
|
||||
list_add_tail(&pos->cb_list,
|
||||
&cmpl_list->mei_cb.cb_list);
|
||||
&cmpl_list->mei_cb.cb_list);
|
||||
}
|
||||
if (cl == &dev->iamthif_cl) {
|
||||
dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
|
||||
if (dev->iamthif_flow_control_pending) {
|
||||
ret = _mei_irq_thread_iamthif_read(
|
||||
dev, slots);
|
||||
ret = _mei_irq_thread_iamthif_read(dev, slots);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -1254,25 +1242,18 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
||||
}
|
||||
if (dev->mei_state == MEI_ENABLED) {
|
||||
if (dev->wd_pending &&
|
||||
mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
|
||||
mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
|
||||
if (mei_wd_send(dev))
|
||||
dev_dbg(&dev->pdev->dev, "wd send failed.\n");
|
||||
else
|
||||
if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
|
||||
return -ENODEV;
|
||||
else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
|
||||
return -ENODEV;
|
||||
|
||||
dev->wd_pending = false;
|
||||
|
||||
if (dev->wd_timeout) {
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
MEI_START_WD_DATA_SIZE + 3) / 4;
|
||||
dev->wd_due_counter = 2;
|
||||
} else {
|
||||
*slots -= (sizeof(struct mei_msg_hdr) +
|
||||
MEI_WD_PARAMS_SIZE + 3) / 4;
|
||||
dev->wd_due_counter = 0;
|
||||
}
|
||||
|
||||
if (dev->wd_timeout)
|
||||
*slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
|
||||
else
|
||||
*slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
|
||||
}
|
||||
}
|
||||
if (dev->stop)
|
||||
@ -1320,42 +1301,34 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
||||
/* complete write list CB */
|
||||
dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
|
||||
list_for_each_entry_safe(pos, next,
|
||||
&dev->write_list.mei_cb.cb_list, cb_list) {
|
||||
&dev->write_list.mei_cb.cb_list, cb_list) {
|
||||
cl = (struct mei_cl *)pos->file_private;
|
||||
if (cl == NULL)
|
||||
continue;
|
||||
|
||||
if (cl != &dev->iamthif_cl) {
|
||||
if (!mei_flow_ctrl_creds(dev, cl)) {
|
||||
if (mei_flow_ctrl_creds(dev, cl) <= 0) {
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"No flow control"
|
||||
" credentials for client"
|
||||
" %d, not sending.\n",
|
||||
cl->host_client_id);
|
||||
"No flow control credentials for client %d, not sending.\n",
|
||||
cl->host_client_id);
|
||||
continue;
|
||||
}
|
||||
ret = _mei_irq_thread_cmpl(dev, slots,
|
||||
pos,
|
||||
cl, cmpl_list);
|
||||
ret = _mei_irq_thread_cmpl(dev, slots, pos,
|
||||
cl, cmpl_list);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
} else if (cl == &dev->iamthif_cl) {
|
||||
/* IAMTHIF IOCTL */
|
||||
dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
|
||||
if (!mei_flow_ctrl_creds(dev, cl)) {
|
||||
if (mei_flow_ctrl_creds(dev, cl) <= 0) {
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"No flow control"
|
||||
" credentials for amthi"
|
||||
" client %d.\n",
|
||||
cl->host_client_id);
|
||||
"No flow control credentials for amthi client %d.\n",
|
||||
cl->host_client_id);
|
||||
continue;
|
||||
}
|
||||
ret = _mei_irq_thread_cmpl_iamthif(dev,
|
||||
slots,
|
||||
pos,
|
||||
cl,
|
||||
cmpl_list);
|
||||
ret = _mei_irq_thread_cmpl_iamthif(dev, slots, pos,
|
||||
cl, cmpl_list);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1555,7 +1528,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
|
||||
end:
|
||||
dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
|
||||
dev->host_hw_state = mei_hcsr_read(dev);
|
||||
dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev);
|
||||
dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
|
||||
|
||||
bus_message_received = false;
|
||||
if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
|
||||
|
@ -481,12 +481,8 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb)
|
||||
if (ret && dev->mei_host_buffer_is_empty) {
|
||||
ret = 0;
|
||||
dev->mei_host_buffer_is_empty = false;
|
||||
if (cb->request_buffer.size >
|
||||
(((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32))
|
||||
-sizeof(struct mei_msg_hdr)) {
|
||||
mei_hdr.length =
|
||||
(((dev->host_hw_state & H_CBD) >> 24) *
|
||||
sizeof(u32)) - sizeof(struct mei_msg_hdr);
|
||||
if (cb->request_buffer.size > mei_hbuf_max_data(dev)) {
|
||||
mei_hdr.length = mei_hbuf_max_data(dev);
|
||||
mei_hdr.msg_complete = 0;
|
||||
} else {
|
||||
mei_hdr.length = cb->request_buffer.size;
|
||||
|
@ -714,13 +714,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
|
||||
if (rets && dev->mei_host_buffer_is_empty) {
|
||||
rets = 0;
|
||||
dev->mei_host_buffer_is_empty = false;
|
||||
if (length > ((((dev->host_hw_state & H_CBD) >> 24) *
|
||||
sizeof(u32)) - sizeof(struct mei_msg_hdr))) {
|
||||
|
||||
mei_hdr.length =
|
||||
(((dev->host_hw_state & H_CBD) >> 24) *
|
||||
sizeof(u32)) -
|
||||
sizeof(struct mei_msg_hdr);
|
||||
if (length > mei_hbuf_max_data(dev)) {
|
||||
mei_hdr.length = mei_hbuf_max_data(dev);
|
||||
mei_hdr.msg_complete = 0;
|
||||
} else {
|
||||
mei_hdr.length = length;
|
||||
@ -1187,44 +1182,7 @@ static struct pci_driver mei_driver = {
|
||||
.driver.pm = MEI_PM_OPS,
|
||||
};
|
||||
|
||||
/**
|
||||
* mei_init_module - Driver Registration Routine
|
||||
*
|
||||
* mei_init_module is the first routine called when the driver is
|
||||
* loaded. All it does is to register with the PCI subsystem.
|
||||
*
|
||||
* returns 0 on success, <0 on failure.
|
||||
*/
|
||||
static int __init mei_init_module(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pr_debug("loading.\n");
|
||||
/* init pci module */
|
||||
ret = pci_register_driver(&mei_driver);
|
||||
if (ret < 0)
|
||||
pr_err("error registering driver.\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
module_init(mei_init_module);
|
||||
|
||||
/**
|
||||
* mei_exit_module - Driver Exit Cleanup Routine
|
||||
*
|
||||
* mei_exit_module is called just before the driver is removed
|
||||
* from memory.
|
||||
*/
|
||||
static void __exit mei_exit_module(void)
|
||||
{
|
||||
pci_unregister_driver(&mei_driver);
|
||||
|
||||
pr_debug("unloaded successfully.\n");
|
||||
}
|
||||
|
||||
module_exit(mei_exit_module);
|
||||
|
||||
module_pci_driver(mei_driver);
|
||||
|
||||
MODULE_AUTHOR("Intel Corporation");
|
||||
MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
|
||||
|
@ -167,7 +167,10 @@ struct mei_io_list {
|
||||
struct mei_cl_cb mei_cb;
|
||||
};
|
||||
|
||||
/* MEI private device struct */
|
||||
/**
|
||||
* struct mei_deive - MEI private device struct
|
||||
* @hbuf_depth - depth of host(write) buffer
|
||||
*/
|
||||
struct mei_device {
|
||||
struct pci_dev *pdev; /* pointer to pci device struct */
|
||||
/*
|
||||
@ -205,6 +208,7 @@ struct mei_device {
|
||||
*/
|
||||
u32 host_hw_state;
|
||||
u32 me_hw_state;
|
||||
u8 hbuf_depth;
|
||||
/*
|
||||
* waiting queue for receive message from FW
|
||||
*/
|
||||
@ -237,15 +241,14 @@ struct mei_device {
|
||||
bool mei_host_buffer_is_empty;
|
||||
|
||||
struct mei_cl wd_cl;
|
||||
bool wd_interface_reg;
|
||||
bool wd_pending;
|
||||
bool wd_stopped;
|
||||
bool wd_bypass; /* if false, don't refresh watchdog ME client */
|
||||
u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */
|
||||
u16 wd_due_counter;
|
||||
unsigned char wd_data[MEI_START_WD_DATA_SIZE];
|
||||
|
||||
|
||||
|
||||
struct file *iamthif_file_object;
|
||||
struct mei_cl iamthif_cl;
|
||||
struct mei_cl_cb *iamthif_current_cb;
|
||||
@ -259,8 +262,6 @@ struct mei_device {
|
||||
bool iamthif_flow_control_pending;
|
||||
bool iamthif_ioctl;
|
||||
bool iamthif_canceled;
|
||||
|
||||
bool wd_interface_reg;
|
||||
};
|
||||
|
||||
|
||||
@ -361,7 +362,8 @@ int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid);
|
||||
*
|
||||
* returns register value (u32)
|
||||
*/
|
||||
static inline u32 mei_reg_read(struct mei_device *dev, unsigned long offset)
|
||||
static inline u32 mei_reg_read(const struct mei_device *dev,
|
||||
unsigned long offset)
|
||||
{
|
||||
return ioread32(dev->mem_addr + offset);
|
||||
}
|
||||
@ -373,8 +375,8 @@ static inline u32 mei_reg_read(struct mei_device *dev, unsigned long offset)
|
||||
* @offset: offset from which to write the data
|
||||
* @value: register value to write (u32)
|
||||
*/
|
||||
static inline void mei_reg_write(struct mei_device *dev,
|
||||
unsigned long offset, u32 value)
|
||||
static inline void mei_reg_write(const struct mei_device *dev,
|
||||
unsigned long offset, u32 value)
|
||||
{
|
||||
iowrite32(value, dev->mem_addr + offset);
|
||||
}
|
||||
@ -386,7 +388,7 @@ static inline void mei_reg_write(struct mei_device *dev,
|
||||
*
|
||||
* returns the byte read.
|
||||
*/
|
||||
static inline u32 mei_hcsr_read(struct mei_device *dev)
|
||||
static inline u32 mei_hcsr_read(const struct mei_device *dev)
|
||||
{
|
||||
return mei_reg_read(dev, H_CSR);
|
||||
}
|
||||
@ -398,7 +400,7 @@ static inline u32 mei_hcsr_read(struct mei_device *dev)
|
||||
*
|
||||
* returns ME_CSR_HA register value (u32)
|
||||
*/
|
||||
static inline u32 mei_mecsr_read(struct mei_device *dev)
|
||||
static inline u32 mei_mecsr_read(const struct mei_device *dev)
|
||||
{
|
||||
return mei_reg_read(dev, ME_CSR_HA);
|
||||
}
|
||||
@ -410,7 +412,7 @@ static inline u32 mei_mecsr_read(struct mei_device *dev)
|
||||
*
|
||||
* returns ME_CB_RW register value (u32)
|
||||
*/
|
||||
static inline u32 mei_mecbrw_read(struct mei_device *dev)
|
||||
static inline u32 mei_mecbrw_read(const struct mei_device *dev)
|
||||
{
|
||||
return mei_reg_read(dev, ME_CB_RW);
|
||||
}
|
||||
|
@ -53,11 +53,12 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
|
||||
}
|
||||
|
||||
/**
|
||||
* host_init_wd - mei initialization wd.
|
||||
* 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)
|
||||
{
|
||||
@ -137,7 +138,6 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
|
||||
return 0;
|
||||
|
||||
dev->wd_timeout = 0;
|
||||
dev->wd_due_counter = 0;
|
||||
memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE);
|
||||
dev->stop = true;
|
||||
|
||||
@ -357,8 +357,6 @@ void mei_watchdog_register(struct mei_device *dev)
|
||||
{
|
||||
dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout);
|
||||
|
||||
dev->wd_due_counter = !!dev->wd_timeout;
|
||||
|
||||
if (watchdog_register_device(&amt_wd_dev)) {
|
||||
dev_err(&dev->pdev->dev,
|
||||
"wd: unable to register watchdog device.\n");
|
||||
|
Loading…
Reference in New Issue
Block a user