From f6a4e494e059b7f0e361dba28f0e2d13144da1d1 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 29 May 2012 16:39:09 +0300 Subject: [PATCH 01/17] mei: mei.txt: minor grammar fixes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- Documentation/misc-devices/mei/mei.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/misc-devices/mei/mei.txt b/Documentation/misc-devices/mei/mei.txt index 2785697da59d..6ec702950719 100644 --- a/Documentation/misc-devices/mei/mei.txt +++ b/Documentation/misc-devices/mei/mei.txt @@ -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. From 98dcd59dd063dd8099d8dbccd84a40e927dc7138 Mon Sep 17 00:00:00 2001 From: "Camuso, Tony" Date: Sun, 10 Jun 2012 14:39:20 +0100 Subject: [PATCH 02/17] misc: hpilo: increase number of max supported channels Increase number of supported channels from 8 to 24. Make the number of channels configurable via module parameter max_ccb. Signed-off-by: Mark Rusk Signed-off-by: Tony Camuso Signed-off-by: Greg Kroah-Hartman --- drivers/misc/hpilo.c | 33 +++++++++++++++++++++------------ drivers/misc/hpilo.h | 4 +++- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index fffc227181b0..6df0da4085e3 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -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 "); 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); diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index 54e43adbdea1..b97672e0cf90 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h @@ -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 */ From 002176db8113c92d0bda02a47e3d2a4b8f9f55ea Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Thu, 14 Jun 2012 09:59:23 -0300 Subject: [PATCH 03/17] misc: at25: Parse dt settings This adds dt support to the at25 eeprom driver. Signed-off-by: Alexandre Pereira da Silva Tested-by: Roland Stigge Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/misc/at25.txt | 21 +++++++ drivers/misc/eeprom/at25.c | 61 ++++++++++++++----- 2 files changed, 66 insertions(+), 16 deletions(-) create mode 100644 Documentation/devicetree/bindings/misc/at25.txt diff --git a/Documentation/devicetree/bindings/misc/at25.txt b/Documentation/devicetree/bindings/misc/at25.txt new file mode 100644 index 000000000000..ab3c327929dd --- /dev/null +++ b/Documentation/devicetree/bindings/misc/at25.txt @@ -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>; +}; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 0842c2994ee2..25003d6ceb56 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -19,7 +19,7 @@ #include #include - +#include /* * 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: From d20411588d2f47ded7b0a02ed1005c7e3ce0df40 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:34 +0300 Subject: [PATCH 04/17] mei: check for error codes that mei_flow_ctrl_creds retuns we cannot use if(!mei_flow_ctrl_creds()) logic as mei_flow_ctrl_creds also negative error codes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 93936f1b75eb..83e80bc08d77 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1326,7 +1326,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, 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" @@ -1343,7 +1343,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, } 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" From 169d1338ed4ed91412761a77095a13b9992993ba Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:35 +0300 Subject: [PATCH 05/17] mei: make mei_write_message more readable 1. reduce hairy casting 2. replace open code with mei_count_empty_write_slots 4. include header size in check for overflow 3. use concise for loop instead of a while loop Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interface.c | 51 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 428d21e36416..6c0569177646 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -127,52 +127,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_count_empty_write_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 = (length + sizeof(*header) + 3) / 4; + 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); From 7d5e0e59542ac452585e3a33abcad6e26b4dec4a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:36 +0300 Subject: [PATCH 06/17] mei: mei_irq_thread_write_handler check for overflow check for overflow when retrieving empty write slots Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 83e80bc08d77..8e4dd74b96e5 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1204,6 +1204,9 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, return 0; } *slots = mei_count_empty_write_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"); From 21c66d1be7c586b56c2902ada4ba030a12b00063 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 19 Jun 2012 09:13:37 +0300 Subject: [PATCH 07/17] mei: group wd_interface_reg with watchdog variables within struct mei_device Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/mei_dev.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 63d7ee97c5fb..4fe653392a49 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -237,6 +237,7 @@ 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 */ @@ -245,7 +246,6 @@ struct mei_device { 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 +259,6 @@ struct mei_device { bool iamthif_flow_control_pending; bool iamthif_ioctl; bool iamthif_canceled; - - bool wd_interface_reg; }; From 24aadc809f270857743e62d0882865fb3ba195d9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 25 Jun 2012 23:46:27 +0300 Subject: [PATCH 08/17] mei: don't query HCSR for host buffer depth 1. We record host (write) buffer depth during reset so we don't need to query HCSR register later on. The host buffer depth doesn't change after the reset 2. Use mei_hbuf_max_data function to compute payload size in bytes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 3 +++ drivers/misc/mei/interface.c | 7 +++---- drivers/misc/mei/interface.h | 6 ++++++ drivers/misc/mei/interrupt.c | 6 +++--- drivers/misc/mei/iorw.c | 8 ++------ drivers/misc/mei/main.c | 9 ++------- drivers/misc/mei/mei_dev.h | 6 +++++- 7 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index a7d0bb0880ec..d39b2774535b 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -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"); diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 6c0569177646..784a60626fa1 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -103,15 +103,14 @@ int mei_host_buffer_is_empty(struct mei_device *dev) */ int mei_count_empty_write_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; + 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; diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index ddff5d16616f..8723d8880149 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -49,6 +49,12 @@ int mei_count_empty_write_slots(struct mei_device *dev); int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); +static inline size_t mei_hbuf_max_data(const struct mei_device *dev) +{ + return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); +} + + 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); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 8e4dd74b96e5..4ad6a6bab5a3 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -951,7 +951,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; @@ -1046,8 +1046,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; diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index f9cced69b65e..50f52e21f587 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -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; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index c70333228337..aaf2683ea154 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -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; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 4fe653392a49..d60250d663c6 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -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 */ From 726917f052e62d8012f63a763884957610399afb Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 25 Jun 2012 23:46:28 +0300 Subject: [PATCH 09/17] mei: revamp host buffer interface function 1. Use unified _hbuf_ prefix for host/write buffer functions. 2. Cleanup the code w/o functional changes. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interface.c | 31 ++++++++++++------------------- drivers/misc/mei/interface.h | 14 ++++++++------ drivers/misc/mei/interrupt.c | 8 ++++---- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 784a60626fa1..88ada64c0b54 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -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,38 +77,29 @@ 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 filled_slots, empty_slots; - dev->host_hw_state = mei_hcsr_read(dev); - filled_slots = _host_get_filled_slots(dev); + filled_slots = mei_hbuf_filled_slots(dev); empty_slots = dev->hbuf_depth - filled_slots; /* check for overflow */ @@ -139,7 +132,7 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, "mei_write_message header=%08x.\n", *((u32 *) header)); - empty_slots = mei_count_empty_write_slots(dev); + empty_slots = mei_hbuf_empty_slots(dev); dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); dw_cnt = (length + sizeof(*header) + 3) / 4; diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index 8723d8880149..cd9b778e8dc5 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -41,19 +41,21 @@ 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_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_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); } +int mei_count_full_read_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); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 4ad6a6bab5a3..1872a2a760e5 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -280,7 +280,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; } @@ -1199,11 +1199,11 @@ 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; @@ -1558,7 +1558,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)) { From 4a0d6a74638f44055ea536abdd428007e5f2f89e Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Jul 2012 19:24:49 +0300 Subject: [PATCH 10/17] mei: mei_device can be const for mei register access functions Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/mei_dev.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index d60250d663c6..772f74dcd2ad 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -363,7 +363,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); } @@ -375,8 +376,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); } @@ -388,7 +389,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); } @@ -400,7 +401,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); } @@ -412,7 +413,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); } From d242a0afb2e5bf1db83c6a0504e55addef425e61 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Jul 2012 19:24:50 +0300 Subject: [PATCH 11/17] mei: remove write only wariable wd_due_counter Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 1 - drivers/misc/mei/interrupt.c | 12 ++++-------- drivers/misc/mei/mei_dev.h | 1 - drivers/misc/mei/wd.c | 3 --- 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index d39b2774535b..e77f86e69fb5 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -306,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; } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 1872a2a760e5..4c1afcf6f4e9 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -575,10 +575,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 */ @@ -1266,15 +1265,12 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, dev->wd_pending = false; - if (dev->wd_timeout) { + if (dev->wd_timeout) *slots -= (sizeof(struct mei_msg_hdr) + MEI_START_WD_DATA_SIZE + 3) / 4; - dev->wd_due_counter = 2; - } else { + else *slots -= (sizeof(struct mei_msg_hdr) + MEI_WD_PARAMS_SIZE + 3) / 4; - dev->wd_due_counter = 0; - } } } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 772f74dcd2ad..d61c4ddfc80c 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -246,7 +246,6 @@ struct mei_device { 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]; diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 6be5605707b4..325d26f29746 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -137,7 +137,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 +356,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"); From 7cb1ba9b679afe5fc335205fd6fb25fd3e51e33a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Jul 2012 19:24:51 +0300 Subject: [PATCH 12/17] mei: mei_wd_host_init: update the comment Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/wd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 325d26f29746..0a893389f6cb 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -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) { From 7bdf72d3d8059a50214069ea4b87c2174645f40f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Jul 2012 19:24:52 +0300 Subject: [PATCH 13/17] mei: introduce mei_data2slots wrapper Introduce mei_data2slots wrapper for sake of readability. This wrapper close up the open code for computing slots from a message length: rond up dwords count from payload and header byte size Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interface.c | 2 +- drivers/misc/mei/interface.h | 6 ++++++ drivers/misc/mei/interrupt.c | 33 +++++++++++---------------------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 88ada64c0b54..509c3957ff45 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -135,7 +135,7 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, empty_slots = mei_hbuf_empty_slots(dev); dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); - dw_cnt = (length + sizeof(*header) + 3) / 4; + dw_cnt = mei_data2slots(length); if (empty_slots < 0 || dw_cnt > empty_slots) return -EIO; diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index cd9b778e8dc5..fb5c7db4723b 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -50,6 +50,12 @@ 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); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 4c1afcf6f4e9..92d762100268 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -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; @@ -302,8 +301,7 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, { 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; + *slots -= mei_data2slots(sizeof(struct hbm_client_disconnect_request)); if (mei_disconnect(dev, cl)) { cl->status = 0; @@ -841,8 +839,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; @@ -874,8 +872,7 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, 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; + *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); if (mei_connect(dev, cl)) { cl->status = -ENODEV; cb_pos->information = 0; @@ -931,8 +928,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 + @@ -959,9 +955,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 + @@ -1020,8 +1014,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 + @@ -1055,8 +1048,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 + @@ -1266,12 +1258,9 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, dev->wd_pending = false; if (dev->wd_timeout) - *slots -= (sizeof(struct mei_msg_hdr) + - MEI_START_WD_DATA_SIZE + 3) / 4; + *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); else - *slots -= (sizeof(struct mei_msg_hdr) + - MEI_WD_PARAMS_SIZE + 3) / 4; - + *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); } } if (dev->stop) From b45f3ccf80fb3e9e86bba2ad3640880d6fe85bfc Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Jul 2012 19:24:53 +0300 Subject: [PATCH 14/17] mei: streamline the _mei_irq_thread_close/ioctol functions change statements of types if (ok) do something else return err into if (err) return err do something Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 65 +++++++++++++++++------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 92d762100268..b4afc1211fd2 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -299,27 +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 -= 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; - } - } 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; @@ -869,26 +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 -= 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; - } - } 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; } From 483136ea0e2b23f2aebf57e1a36a06dec4223a92 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 4 Jul 2012 19:24:54 +0300 Subject: [PATCH 15/17] mei: mei_irq_thread_write_handler - line break fix 1. straight up lines that doesn't cross 80 characters 2. don't break strings Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 44 +++++++++++++----------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index b4afc1211fd2..b428b3fe4092 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1199,8 +1199,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, 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; @@ -1210,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; } @@ -1245,12 +1242,11 @@ 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; @@ -1305,7 +1301,7 @@ 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; @@ -1313,15 +1309,12 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, if (cl != &dev->iamthif_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; @@ -1330,17 +1323,12 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n"); 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; From 8397c76a2c209997c7119bede2f26e51d8c786bc Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sun, 15 Jul 2012 18:52:02 +0530 Subject: [PATCH 16/17] powerpc/BSR: cleanup the error path of bsr_init class_create if succeeded returns a pointer to the struct class, and if it fails, it returns a value enclosed by the pointer, which can be read by using PTR_ERR. Handle the error and return it. result is for error checking of the alloc_chrdev_region, instead ret can be used, and also if the alloc_chrdev_region fail, we are still returning -ENODEV, use ret and the error path will take care of returning of the ret. Signed-off-by: Devendra Naga Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/char/bsr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 0c688232aab3..97467053a01b 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -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; } From 6078188e2ba1d61a2119ddb2289e88c2c2a015ab Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 19 Jul 2012 09:45:32 +0300 Subject: [PATCH 17/17] mei: use module_pci_driver use module_pci_driver() macro to wrap standard pci module registration into a single line Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 0d98c2ee6fe3..092330208869 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1182,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");