diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 12:15:41 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 12:15:41 -0700 |
commit | b84382f5141875230b7c55eb29443596fd2d8d53 (patch) | |
tree | 87c66fcec04a0851c0a8c732b115e246541898b5 | |
parent | fa93669a1917f93b09142d4b2298329b82d7d36d (diff) | |
parent | 6078188e2ba1d61a2119ddb2289e88c2c2a015ab (diff) |
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
-rw-r--r-- | Documentation/devicetree/bindings/misc/at25.txt | 21 | ||||
-rw-r--r-- | Documentation/misc-devices/mei/mei.txt | 14 | ||||
-rw-r--r-- | drivers/char/bsr.c | 6 | ||||
-rw-r--r-- | drivers/misc/eeprom/at25.c | 61 | ||||
-rw-r--r-- | drivers/misc/hpilo.c | 33 | ||||
-rw-r--r-- | drivers/misc/hpilo.h | 4 | ||||
-rw-r--r-- | drivers/misc/mei/init.c | 4 | ||||
-rw-r--r-- | drivers/misc/mei/interface.c | 85 | ||||
-rw-r--r-- | drivers/misc/mei/interface.h | 18 | ||||
-rw-r--r-- | drivers/misc/mei/interrupt.c | 169 | ||||
-rw-r--r-- | drivers/misc/mei/iorw.c | 8 | ||||
-rw-r--r-- | drivers/misc/mei/main.c | 48 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 24 | ||||
-rw-r--r-- | drivers/misc/mei/wd.c | 6 |
14 files changed, 242 insertions, 259 deletions
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/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. 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; } 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 <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: 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 <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); 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 */ diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index a7d0bb0880ec..e77f86e69fb5 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"); @@ -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; } diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 428d21e36416..509c3957ff45 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,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; - - dev->host_hw_state = mei_hcsr_read(dev); + unsigned long rem, dw_cnt; + u32 *reg_buf = (u32 *)buf; + int i; + int empty_slots; - 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); + empty_slots = mei_hbuf_empty_slots(dev); + dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); - 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; - } + for (i = 0; i < length / 4; i++) + mei_reg_write(dev, H_CB_WW, reg_buf[i]); - if (write_length > 0) { - memcpy(&temp_msg, &write_buffer[bytes_written], write_length); - mei_reg_write(dev, H_CB_WW, temp_msg); + 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); diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h index ddff5d16616f..fb5c7db4723b 100644 --- a/drivers/misc/mei/interface.h +++ b/drivers/misc/mei/interface.h @@ -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); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 23f5463d4cae..c6ffbbe5a6c0 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; @@ -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 ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_client_disconnect_request))) + return -EBADMSG; - 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; - } + *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 { - /* return the cancel routine */ - return -EBADMSG; + 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)) { 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) {< |